├── app ├── .gitignore ├── src │ └── main │ │ ├── res │ │ ├── values │ │ │ ├── strings.xml │ │ │ ├── themes.xml │ │ │ └── colors.xml │ │ ├── mipmap-hdpi │ │ │ ├── ic_launcher.webp │ │ │ └── ic_launcher_round.webp │ │ ├── mipmap-mdpi │ │ │ ├── ic_launcher.webp │ │ │ └── ic_launcher_round.webp │ │ ├── mipmap-xhdpi │ │ │ ├── ic_launcher.webp │ │ │ └── ic_launcher_round.webp │ │ ├── mipmap-xxhdpi │ │ │ ├── ic_launcher.webp │ │ │ └── ic_launcher_round.webp │ │ ├── mipmap-xxxhdpi │ │ │ ├── ic_launcher.webp │ │ │ └── ic_launcher_round.webp │ │ ├── xml │ │ │ ├── preferences.xml │ │ │ ├── backup_rules.xml │ │ │ └── data_extraction_rules.xml │ │ ├── mipmap-anydpi │ │ │ ├── ic_launcher.xml │ │ │ └── ic_launcher_round.xml │ │ ├── menu │ │ │ ├── browser_debug_menu.xml │ │ │ └── browser_menu.xml │ │ ├── drawable │ │ │ ├── baseline_arrow_back_24.xml │ │ │ ├── baseline_arrow_forward_24.xml │ │ │ ├── baseline_refresh_24.xml │ │ │ ├── baseline_settings_24.xml │ │ │ ├── ic_launcher_foreground.xml │ │ │ └── ic_launcher_background.xml │ │ └── layout │ │ │ ├── activity_main.xml │ │ │ └── activity_app_browser_preferences.xml │ │ ├── java │ │ └── net │ │ │ └── bloople │ │ │ └── appbrowser │ │ │ ├── Extensions.kt │ │ │ ├── AppBrowserApplication.kt │ │ │ ├── AppBrowserPreferencesActivity.kt │ │ │ ├── AppBrowserPreferencesFragment.kt │ │ │ └── MainActivity.kt │ │ └── AndroidManifest.xml ├── proguard-rules.pro └── build.gradle.kts ├── AppWebView ├── .gitignore ├── consumer-rules.pro ├── src │ └── main │ │ ├── res │ │ ├── values │ │ │ └── public.xml │ │ ├── xml │ │ │ └── network_security_config.xml │ │ ├── drawable │ │ │ ├── appwebview_outline_open_with_24.xml │ │ │ └── appwebview_baseline_open_in_new_24.xml │ │ ├── menu │ │ │ └── appwebview_context_menu.xml │ │ └── layout │ │ │ ├── appwebview_dialog_prompt.xml │ │ │ └── appwebview_dialog_http_auth.xml │ │ ├── java │ │ └── net │ │ │ └── bloople │ │ │ └── appwebview │ │ │ ├── Origin.kt │ │ │ ├── Util.kt │ │ │ ├── AppWebViewHost.kt │ │ │ ├── AppWebViewContext.kt │ │ │ ├── Extensions.kt │ │ │ ├── HttpAuthCredentialManager.kt │ │ │ ├── HttpAuthUrlBuilder.kt │ │ │ ├── AppWebViewActions.kt │ │ │ ├── AppWebChromeClient.kt │ │ │ ├── AppWebViewClient.kt │ │ │ └── AppWebView.kt │ │ └── AndroidManifest.xml ├── proguard-rules.pro └── build.gradle.kts ├── gradle └── wrapper │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── .gitignore ├── settings.gradle.kts ├── gradle.properties ├── gradlew.bat └── gradlew /app/.gitignore: -------------------------------------------------------------------------------- 1 | /build -------------------------------------------------------------------------------- /AppWebView/.gitignore: -------------------------------------------------------------------------------- 1 | /build -------------------------------------------------------------------------------- /AppWebView/consumer-rules.pro: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /app/src/main/res/values/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | App Browser 3 | -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bloopletech/AppBrowser/master/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /AppWebView/src/main/res/values/public.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /app/src/main/res/mipmap-hdpi/ic_launcher.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bloopletech/AppBrowser/master/app/src/main/res/mipmap-hdpi/ic_launcher.webp -------------------------------------------------------------------------------- /app/src/main/res/mipmap-mdpi/ic_launcher.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bloopletech/AppBrowser/master/app/src/main/res/mipmap-mdpi/ic_launcher.webp -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xhdpi/ic_launcher.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bloopletech/AppBrowser/master/app/src/main/res/mipmap-xhdpi/ic_launcher.webp -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xxhdpi/ic_launcher.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bloopletech/AppBrowser/master/app/src/main/res/mipmap-xxhdpi/ic_launcher.webp -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xxxhdpi/ic_launcher.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bloopletech/AppBrowser/master/app/src/main/res/mipmap-xxxhdpi/ic_launcher.webp -------------------------------------------------------------------------------- /app/src/main/res/mipmap-hdpi/ic_launcher_round.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bloopletech/AppBrowser/master/app/src/main/res/mipmap-hdpi/ic_launcher_round.webp -------------------------------------------------------------------------------- /app/src/main/res/mipmap-mdpi/ic_launcher_round.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bloopletech/AppBrowser/master/app/src/main/res/mipmap-mdpi/ic_launcher_round.webp -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xhdpi/ic_launcher_round.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bloopletech/AppBrowser/master/app/src/main/res/mipmap-xhdpi/ic_launcher_round.webp -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xxhdpi/ic_launcher_round.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bloopletech/AppBrowser/master/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.webp -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bloopletech/AppBrowser/master/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.webp -------------------------------------------------------------------------------- /app/src/main/res/values/themes.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | -------------------------------------------------------------------------------- /AppWebView/src/main/java/net/bloople/appwebview/Origin.kt: -------------------------------------------------------------------------------- 1 | package net.bloople.appwebview 2 | 3 | data class Origin(val scheme: String, val host: String, val port: Int) 4 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | *.iml 2 | .gradle 3 | /local.properties 4 | /.idea/ 5 | .DS_Store 6 | /build 7 | /captures 8 | .externalNativeBuild 9 | .cxx 10 | local.properties 11 | /app/release/ 12 | -------------------------------------------------------------------------------- /app/src/main/res/values/colors.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | #FF000000 4 | #FFFFFFFF 5 | -------------------------------------------------------------------------------- /AppWebView/src/main/java/net/bloople/appwebview/Util.kt: -------------------------------------------------------------------------------- 1 | package net.bloople.appwebview 2 | 3 | import android.os.Looper 4 | 5 | internal fun assertOffUIThread() { 6 | assert(!Looper.getMainLooper().isCurrentThread) 7 | } -------------------------------------------------------------------------------- /app/src/main/res/xml/preferences.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /AppWebView/src/main/java/net/bloople/appwebview/AppWebViewHost.kt: -------------------------------------------------------------------------------- 1 | package net.bloople.appwebview 2 | 3 | import android.graphics.Bitmap 4 | 5 | interface AppWebViewHost { 6 | fun onReceivedIcon(icon: Bitmap?) 7 | fun onTitleChanged(title: String) 8 | } -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | #Fri Nov 17 05:00:43 AEDT 2023 2 | distributionBase=GRADLE_USER_HOME 3 | distributionPath=wrapper/dists 4 | distributionUrl=https\://services.gradle.org/distributions/gradle-8.14-bin.zip 5 | zipStoreBase=GRADLE_USER_HOME 6 | zipStorePath=wrapper/dists 7 | -------------------------------------------------------------------------------- /app/src/main/res/mipmap-anydpi/ic_launcher.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /app/src/main/res/mipmap-anydpi/ic_launcher_round.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /app/src/main/res/menu/browser_debug_menu.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 9 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/baseline_arrow_back_24.xml: -------------------------------------------------------------------------------- 1 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/baseline_arrow_forward_24.xml: -------------------------------------------------------------------------------- 1 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /settings.gradle.kts: -------------------------------------------------------------------------------- 1 | pluginManagement { 2 | repositories { 3 | google() 4 | mavenCentral() 5 | gradlePluginPortal() 6 | } 7 | } 8 | dependencyResolutionManagement { 9 | repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS) 10 | repositories { 11 | google() 12 | mavenCentral() 13 | } 14 | } 15 | 16 | include(":AppWebView") 17 | include(":app") 18 | rootProject.name = "AppBrowser" 19 | -------------------------------------------------------------------------------- /AppWebView/src/main/res/xml/network_security_config.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /AppWebView/src/main/res/drawable/appwebview_outline_open_with_24.xml: -------------------------------------------------------------------------------- 1 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /AppWebView/src/main/res/drawable/appwebview_baseline_open_in_new_24.xml: -------------------------------------------------------------------------------- 1 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/baseline_refresh_24.xml: -------------------------------------------------------------------------------- 1 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /app/src/main/res/xml/backup_rules.xml: -------------------------------------------------------------------------------- 1 | 8 | 9 | 13 | -------------------------------------------------------------------------------- /app/src/main/java/net/bloople/appbrowser/Extensions.kt: -------------------------------------------------------------------------------- 1 | package net.bloople.appbrowser 2 | 3 | import android.content.res.Resources 4 | import android.graphics.Bitmap 5 | import android.util.TypedValue 6 | import kotlin.math.roundToInt 7 | 8 | fun Bitmap.resizeTo(targetSize: Float): Bitmap { 9 | val scale = (targetSize / width).coerceAtMost(targetSize / height) 10 | return Bitmap.createScaledBitmap(this, (width * scale).roundToInt(), (height * scale).roundToInt(), true) 11 | } 12 | 13 | fun Resources.toDips(input: Float) = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, input, displayMetrics) -------------------------------------------------------------------------------- /AppWebView/src/main/java/net/bloople/appwebview/AppWebViewContext.kt: -------------------------------------------------------------------------------- 1 | package net.bloople.appwebview 2 | 3 | import android.content.Context 4 | import android.net.Uri 5 | import java.util.concurrent.ConcurrentHashMap 6 | 7 | internal class AppWebViewContext(context: Context, var userAgent: String) { 8 | val origins: MutableSet = ConcurrentHashMap.newKeySet() 9 | val httpAuthCredentialManager = HttpAuthCredentialManager(context) 10 | val httpAuthUrlBuilder = HttpAuthUrlBuilder(this) 11 | 12 | fun canOpenUrl(uri: Uri): Boolean { 13 | val origin = uri.origin ?: return false 14 | return origins.contains(origin) 15 | } 16 | } -------------------------------------------------------------------------------- /app/src/main/res/xml/data_extraction_rules.xml: -------------------------------------------------------------------------------- 1 | 6 | 7 | 8 | 12 | 13 | 19 | -------------------------------------------------------------------------------- /AppWebView/src/main/res/menu/appwebview_context_menu.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 8 | 12 | 15 | -------------------------------------------------------------------------------- /AppWebView/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 7 | 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /app/src/main/res/layout/activity_main.xml: -------------------------------------------------------------------------------- 1 | 2 | 8 | 9 | 14 | 15 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /app/proguard-rules.pro: -------------------------------------------------------------------------------- 1 | # Add project specific ProGuard rules here. 2 | # You can control the set of applied configuration files using the 3 | # proguardFiles setting in build.gradle. 4 | # 5 | # For more details, see 6 | # http://developer.android.com/guide/developing/tools/proguard.html 7 | 8 | # If your project uses WebView with JS, uncomment the following 9 | # and specify the fully qualified class name to the JavaScript interface 10 | # class: 11 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview { 12 | # public *; 13 | #} 14 | 15 | # Uncomment this to preserve the line number information for 16 | # debugging stack traces. 17 | #-keepattributes SourceFile,LineNumberTable 18 | 19 | # If you keep the line number information, uncomment this to 20 | # hide the original source file name. 21 | #-renamesourcefileattribute SourceFile -------------------------------------------------------------------------------- /AppWebView/proguard-rules.pro: -------------------------------------------------------------------------------- 1 | # Add project specific ProGuard rules here. 2 | # You can control the set of applied configuration files using the 3 | # proguardFiles setting in build.gradle. 4 | # 5 | # For more details, see 6 | # http://developer.android.com/guide/developing/tools/proguard.html 7 | 8 | # If your project uses WebView with JS, uncomment the following 9 | # and specify the fully qualified class name to the JavaScript interface 10 | # class: 11 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview { 12 | # public *; 13 | #} 14 | 15 | # Uncomment this to preserve the line number information for 16 | # debugging stack traces. 17 | #-keepattributes SourceFile,LineNumberTable 18 | 19 | # If you keep the line number information, uncomment this to 20 | # hide the original source file name. 21 | #-renamesourcefileattribute SourceFile -------------------------------------------------------------------------------- /app/src/main/res/menu/browser_menu.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 10 | 15 | 20 | -------------------------------------------------------------------------------- /app/src/main/java/net/bloople/appbrowser/AppBrowserApplication.kt: -------------------------------------------------------------------------------- 1 | @file: Suppress("DEPRECATION") 2 | 3 | package net.bloople.appbrowser 4 | 5 | import android.annotation.SuppressLint 6 | import android.app.Application 7 | import android.content.Context 8 | import android.content.pm.ApplicationInfo 9 | import android.preference.PreferenceManager 10 | 11 | 12 | class AppBrowserApplication: Application() { 13 | override fun onCreate() { 14 | super.onCreate() 15 | context = applicationContext 16 | isDebuggable = 0 != applicationInfo.flags and ApplicationInfo.FLAG_DEBUGGABLE 17 | } 18 | 19 | companion object { 20 | @SuppressLint("StaticFieldLeak") 21 | lateinit var context: Context 22 | private set 23 | 24 | var isDebuggable: Boolean = false 25 | 26 | val preferences get() = PreferenceManager.getDefaultSharedPreferences(context) 27 | } 28 | } -------------------------------------------------------------------------------- /AppWebView/src/main/res/layout/appwebview_dialog_prompt.xml: -------------------------------------------------------------------------------- 1 | 2 | 11 | 16 | 17 | 22 | -------------------------------------------------------------------------------- /app/build.gradle.kts: -------------------------------------------------------------------------------- 1 | plugins { 2 | id("com.android.application") 3 | id("org.jetbrains.kotlin.android") 4 | } 5 | 6 | android { 7 | namespace = "net.bloople.appbrowser" 8 | compileSdk = 34 9 | 10 | defaultConfig { 11 | applicationId = "net.bloople.appbrowser" 12 | minSdk = 30 13 | targetSdk = 34 14 | versionCode = 7 15 | versionName = "1.0" 16 | } 17 | 18 | buildTypes { 19 | debug { 20 | isDebuggable = true 21 | applicationIdSuffix = ".debug" 22 | } 23 | 24 | release { 25 | isMinifyEnabled = true 26 | proguardFiles(getDefaultProguardFile("proguard-android-optimize.txt"), "proguard-rules.pro") 27 | } 28 | } 29 | 30 | compileOptions { 31 | sourceCompatibility = JavaVersion.VERSION_17 32 | targetCompatibility = JavaVersion.VERSION_17 33 | } 34 | 35 | kotlinOptions { 36 | jvmTarget = "17" 37 | } 38 | } 39 | dependencies { 40 | implementation(project(":AppWebView")) 41 | } 42 | 43 | -------------------------------------------------------------------------------- /AppWebView/src/main/java/net/bloople/appwebview/Extensions.kt: -------------------------------------------------------------------------------- 1 | package net.bloople.appwebview 2 | 3 | import android.app.AlertDialog 4 | import android.content.Context 5 | import android.net.Uri 6 | import android.view.LayoutInflater 7 | import java.net.URL 8 | 9 | val AlertDialog.Builder.layoutInflater: LayoutInflater 10 | get() = context.getSystemService(Context.LAYOUT_INFLATER_SERVICE) as LayoutInflater 11 | 12 | val Uri.origin: Origin? 13 | get() = if(scheme != null && host != null) Origin(scheme!!, host!!, port) else null 14 | 15 | internal fun Uri.withCredential(credential: HttpAuthCredential): Uri { 16 | if(scheme == null) return this 17 | if(scheme!!.lowercase() != "http" && scheme!!.lowercase() != "https") return this 18 | 19 | if(encodedAuthority == null) return this 20 | if(encodedAuthority!!.contains('@')) return this 21 | 22 | val encodedUserInfo = "${Uri.encode(credential.username)}:${Uri.encode(credential.password)}@" 23 | return buildUpon().encodedAuthority("$encodedUserInfo$encodedAuthority").build() 24 | } 25 | 26 | fun Uri.toUrl() = URL(toString()) 27 | 28 | fun URL.toUri() = Uri.parse(toString()) -------------------------------------------------------------------------------- /app/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 14 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/baseline_settings_24.xml: -------------------------------------------------------------------------------- 1 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /AppWebView/src/main/res/layout/appwebview_dialog_http_auth.xml: -------------------------------------------------------------------------------- 1 | 2 | 11 | 16 | 17 | 24 | 25 | 32 | -------------------------------------------------------------------------------- /AppWebView/build.gradle.kts: -------------------------------------------------------------------------------- 1 | plugins { 2 | id("com.android.library") 3 | id("org.jetbrains.kotlin.android") 4 | `maven-publish` 5 | } 6 | 7 | android { 8 | namespace = "net.bloople.appwebview" 9 | resourcePrefix = "appwebview_" 10 | compileSdk = 34 11 | 12 | defaultConfig { 13 | minSdk = 30 14 | targetSdk = 34 15 | 16 | aarMetadata { 17 | minCompileSdk = 30 18 | } 19 | 20 | consumerProguardFiles("consumer-rules.pro") 21 | } 22 | 23 | buildTypes { 24 | release { 25 | } 26 | } 27 | 28 | compileOptions { 29 | sourceCompatibility = JavaVersion.VERSION_17 30 | targetCompatibility = JavaVersion.VERSION_17 31 | } 32 | 33 | kotlinOptions { 34 | jvmTarget = "17" 35 | } 36 | 37 | publishing { 38 | singleVariant("release") { 39 | } 40 | } 41 | } 42 | 43 | dependencies { 44 | } 45 | 46 | publishing { 47 | publications { 48 | register("release") { 49 | groupId = "net.bloople" 50 | artifactId = "appwebview" 51 | version = "0.1-SNAPSHOT" 52 | 53 | afterEvaluate { 54 | from(components["release"]) 55 | } 56 | } 57 | } 58 | } -------------------------------------------------------------------------------- /app/src/main/res/layout/activity_app_browser_preferences.xml: -------------------------------------------------------------------------------- 1 | 2 | 8 | 9 | 15 | 16 | 17 | 22 |