diff --git a/app/build.gradle.kts b/app/build.gradle.kts index 802e89726..c066d6ccf 100644 --- a/app/build.gradle.kts +++ b/app/build.gradle.kts @@ -221,12 +221,8 @@ dependencies { implementation("com.squareup.retrofit2:converter-moshi:${vRetrofit}") implementation("com.squareup.retrofit2:converter-scalars:${vRetrofit}") - val vOkHttp = "3.12.12" - implementation("com.squareup.okhttp3:okhttp") { - version { - strictly(vOkHttp) - } - } + val vOkHttp = "4.9.1" + implementation("com.squareup.okhttp3:okhttp:${vOkHttp}") implementation("com.squareup.okhttp3:logging-interceptor:${vOkHttp}") implementation("com.squareup.okhttp3:okhttp-dnsoverhttps:${vOkHttp}") @@ -234,7 +230,7 @@ dependencies { implementation("com.squareup.moshi:moshi:${vMoshi}") kapt("com.squareup.moshi:moshi-kotlin-codegen:${vMoshi}") - val vRoom = "2.3.0-beta03" + val vRoom = "2.3.0-rc01" implementation("androidx.room:room-runtime:${vRoom}") implementation("androidx.room:room-ktx:${vRoom}") kapt("androidx.room:room-compiler:${vRoom}") @@ -248,11 +244,10 @@ dependencies { implementation("androidx.swiperefreshlayout:swiperefreshlayout:1.1.0") implementation("androidx.browser:browser:1.3.0") implementation("androidx.preference:preference:1.1.1") - implementation("androidx.recyclerview:recyclerview:1.1.0") - implementation("androidx.fragment:fragment-ktx:1.3.1") + implementation("androidx.recyclerview:recyclerview:1.2.0") + implementation("androidx.fragment:fragment-ktx:1.3.2") implementation("androidx.work:work-runtime-ktx:2.5.0") implementation("androidx.transition:transition:1.4.0") - implementation("androidx.multidex:multidex:2.0.1") implementation("androidx.core:core-ktx:1.3.2") implementation("com.google.android.material:material:1.3.0") } diff --git a/app/src/main/java/com/topjohnwu/magisk/core/App.kt b/app/src/main/java/com/topjohnwu/magisk/core/App.kt index 1348caa4e..ee8f3c3ac 100644 --- a/app/src/main/java/com/topjohnwu/magisk/core/App.kt +++ b/app/src/main/java/com/topjohnwu/magisk/core/App.kt @@ -1,14 +1,13 @@ package com.topjohnwu.magisk.core +import android.annotation.SuppressLint import android.app.Activity import android.app.Application import android.content.Context import android.content.res.Configuration import android.os.Bundle import androidx.appcompat.app.AppCompatDelegate -import androidx.multidex.MultiDex import androidx.work.WorkManager -import com.topjohnwu.magisk.BuildConfig import com.topjohnwu.magisk.DynAPK import com.topjohnwu.magisk.core.utils.AppShellInit import com.topjohnwu.magisk.core.utils.BusyBoxInit @@ -46,10 +45,6 @@ open class App() : Application() { } override fun attachBaseContext(base: Context) { - // Basic setup - if (BuildConfig.DEBUG) - MultiDex.install(base) - // Some context magic val app: Application val impl: Context @@ -91,6 +86,7 @@ open class App() : Application() { } } +@SuppressLint("StaticFieldLeak") object ForegroundTracker : Application.ActivityLifecycleCallbacks { @Volatile diff --git a/app/src/main/java/com/topjohnwu/magisk/core/Const.kt b/app/src/main/java/com/topjohnwu/magisk/core/Const.kt index 447c11852..d8557e849 100644 --- a/app/src/main/java/com/topjohnwu/magisk/core/Const.kt +++ b/app/src/main/java/com/topjohnwu/magisk/core/Const.kt @@ -63,7 +63,6 @@ object Const { const val GITHUB_RAW_URL = "https://raw.githubusercontent.com/" const val GITHUB_API_URL = "https://api.github.com/" const val GITHUB_PAGE_URL = "https://topjohnwu.github.io/magisk-files/" - const val GITHUB_OLD_PAGE_URL = "https://topjohnwu.github.io/magisk_files/" const val JS_DELIVR_URL = "https://cdn.jsdelivr.net/gh/" const val OFFICIAL_REPO = "https://magisk-modules-repo.github.io/submission/modules.json" } diff --git a/app/src/main/java/com/topjohnwu/magisk/core/utils/Locales.kt b/app/src/main/java/com/topjohnwu/magisk/core/utils/Locales.kt index 97b72bbe1..69f68fe52 100644 --- a/app/src/main/java/com/topjohnwu/magisk/core/utils/Locales.kt +++ b/app/src/main/java/com/topjohnwu/magisk/core/utils/Locales.kt @@ -8,8 +8,6 @@ import android.content.res.Resources import com.topjohnwu.magisk.R import com.topjohnwu.magisk.core.AssetHack import com.topjohnwu.magisk.core.Config -import com.topjohnwu.magisk.ktx.langTagToLocale -import com.topjohnwu.magisk.ktx.toLangTag import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.withContext import java.util.* @@ -40,7 +38,7 @@ withContext(Dispatchers.Default) { // Then add all supported locales addAll(Resources.getSystem().assets.locales) }.map { - it.langTagToLocale() + Locale.forLanguageTag(it) }.distinctBy { res.updateLocale(it) res.getString(compareId) @@ -59,7 +57,7 @@ withContext(Dispatchers.Default) { locales.forEach { locale -> names.add(locale.getDisplayName(locale)) - values.add(locale.toLangTag()) + values.add(locale.toLanguageTag()) } (names.toTypedArray() to values.toTypedArray()).also { cachedLocales = it } @@ -79,7 +77,7 @@ fun refreshLocale() { val localeConfig = Config.locale currentLocale = when { localeConfig.isEmpty() -> defaultLocale - else -> localeConfig.langTagToLocale() + else -> Locale.forLanguageTag(localeConfig) } Locale.setDefault(currentLocale) AssetHack.resource.updateConfig() diff --git a/app/src/main/java/com/topjohnwu/magisk/data/repository/NetworkService.kt b/app/src/main/java/com/topjohnwu/magisk/data/repository/NetworkService.kt index 825a0a039..391e11e70 100644 --- a/app/src/main/java/com/topjohnwu/magisk/data/repository/NetworkService.kt +++ b/app/src/main/java/com/topjohnwu/magisk/data/repository/NetworkService.kt @@ -21,10 +21,6 @@ class NetworkService( private val api: GithubApiServices ) { suspend fun fetchUpdate() = safe { - // Pre SDK 21 no longer receives any major updates - if (Build.VERSION.SDK_INT < 21) - return fetchStableUpdate() - var info = when (Config.updateChannel) { DEFAULT_CHANNEL, STABLE_CHANNEL -> fetchStableUpdate() BETA_CHANNEL -> fetchBetaUpdate() diff --git a/app/src/main/java/com/topjohnwu/magisk/di/NetworkingModule.kt b/app/src/main/java/com/topjohnwu/magisk/di/NetworkingModule.kt index f3600e23c..a0b85104a 100644 --- a/app/src/main/java/com/topjohnwu/magisk/di/NetworkingModule.kt +++ b/app/src/main/java/com/topjohnwu/magisk/di/NetworkingModule.kt @@ -1,7 +1,6 @@ package com.topjohnwu.magisk.di import android.content.Context -import android.os.Build import com.squareup.moshi.Moshi import com.topjohnwu.magisk.BuildConfig import com.topjohnwu.magisk.core.Config @@ -13,12 +12,11 @@ import com.topjohnwu.magisk.data.network.JSDelivrServices import com.topjohnwu.magisk.data.network.RawServices import com.topjohnwu.magisk.ktx.precomputedText import com.topjohnwu.magisk.net.Networking -import com.topjohnwu.magisk.net.NoSSLv3SocketFactory import com.topjohnwu.magisk.utils.MarkwonImagePlugin import io.noties.markwon.Markwon import io.noties.markwon.html.HtmlPlugin import okhttp3.Dns -import okhttp3.HttpUrl +import okhttp3.HttpUrl.Companion.toHttpUrl import okhttp3.OkHttpClient import okhttp3.dnsoverhttps.DnsOverHttps import okhttp3.logging.HttpLoggingInterceptor @@ -34,10 +32,7 @@ val networkingModule = module { single { createRetrofit(get()) } single { createApiService(get(), Const.Url.GITHUB_RAW_URL) } single { createApiService(get(), Const.Url.GITHUB_API_URL) } - single { createApiService(get(), - if (Build.VERSION.SDK_INT < 21) Const.Url.GITHUB_OLD_PAGE_URL - else Const.Url.GITHUB_PAGE_URL - ) } + single { createApiService(get(), Const.Url.GITHUB_PAGE_URL) } single { createApiService(get(), Const.Url.JS_DELIVR_URL) } single { createMarkwon(get(), get()) } } @@ -46,7 +41,7 @@ private class DnsResolver(client: OkHttpClient) : Dns { private val doh by lazy { DnsOverHttps.Builder().client(client) - .url(HttpUrl.get("https://cloudflare-dns.com/dns-query")) + .url("https://cloudflare-dns.com/dns-query".toHttpUrl()) .bootstrapDnsHosts(listOf( InetAddress.getByName("162.159.36.1"), InetAddress.getByName("162.159.46.1"), @@ -84,8 +79,6 @@ fun createOkHttpClient(context: Context): OkHttpClient { if (!Networking.init(context)) { Info.hasGMS = false - if (Build.VERSION.SDK_INT < 21) - builder.sslSocketFactory(NoSSLv3SocketFactory()) } builder.dns(DnsResolver(builder.build())) diff --git a/app/src/main/java/com/topjohnwu/magisk/ktx/XAndroid.kt b/app/src/main/java/com/topjohnwu/magisk/ktx/XAndroid.kt index 040d07a53..e136bd41b 100644 --- a/app/src/main/java/com/topjohnwu/magisk/ktx/XAndroid.kt +++ b/app/src/main/java/com/topjohnwu/magisk/ktx/XAndroid.kt @@ -339,16 +339,6 @@ var TextView.precomputedText: CharSequence set(value) { val callback = tag as? Runnable - // Don't even bother pre 21 - if (SDK_INT < 21) { - post { - text = value - isGone = false - callback?.run() - } - return - } - coroutineScope.launch(Dispatchers.IO) { if (SDK_INT >= 29) { // Internally PrecomputedTextCompat will use platform API on API 29+ diff --git a/app/src/main/java/com/topjohnwu/magisk/ktx/XJava.kt b/app/src/main/java/com/topjohnwu/magisk/ktx/XJava.kt index 324ab5f61..07705f78e 100644 --- a/app/src/main/java/com/topjohnwu/magisk/ktx/XJava.kt +++ b/app/src/main/java/com/topjohnwu/magisk/ktx/XJava.kt @@ -1,6 +1,5 @@ package com.topjohnwu.magisk.ktx -import android.os.Build import androidx.collection.SparseArrayCompat import timber.log.Timber import java.io.File @@ -47,64 +46,5 @@ fun MutableList.synchronized() = Collections.synchronizedList(this) fun MutableSet.synchronized() = Collections.synchronizedSet(this) fun MutableMap.synchronized() = Collections.synchronizedMap(this) -fun String.langTagToLocale(): Locale { - if (Build.VERSION.SDK_INT >= 21) { - return Locale.forLanguageTag(this) - } else { - val tok = split("[-_]".toRegex()).dropLastWhile { it.isEmpty() }.toTypedArray() - if (tok.isEmpty()) { - return Locale("") - } - val language = when (tok[0]) { - "und" -> "" // Undefined - "fil" -> "tl" // Filipino - else -> tok[0] - } - if (language.length != 2 && language.length != 3) - return Locale("") - if (tok.size == 1) - return Locale(language) - val country = tok[1] - - return if (country.length != 2 && country.length != 3) Locale(language) - else Locale(language, country) - } -} - -fun Locale.toLangTag(): String { - if (Build.VERSION.SDK_INT >= 21) { - return toLanguageTag() - } else { - var language = language - var country = country - var variant = variant - when { - language.isEmpty() || !language.matches("\\p{Alpha}{2,8}".toRegex()) -> - language = "und" // Follow the Locale#toLanguageTag() implementation - language == "iw" -> language = "he" // correct deprecated "Hebrew" - language == "in" -> language = "id" // correct deprecated "Indonesian" - language == "ji" -> language = "yi" // correct deprecated "Yiddish" - } - // ensure valid country code, if not well formed, it's omitted - - // variant subtags that begin with a letter must be at least 5 characters long - // ensure valid country code, if not well formed, it's omitted - if (!country.matches("\\p{Alpha}{2}|\\p{Digit}{3}".toRegex())) { - country = "" - } - - // variant subtags that begin with a letter must be at least 5 characters long - if (!variant.matches("\\p{Alnum}{5,8}|\\p{Digit}\\p{Alnum}{3}".toRegex())) { - variant = "" - } - val tag = StringBuilder(language) - if (country.isNotEmpty()) - tag.append('-').append(country) - if (variant.isNotEmpty()) - tag.append('-').append(variant) - return tag.toString() - } -} - fun SimpleDateFormat.parseOrNull(date: String) = runCatching { parse(date) }.onFailure { Timber.e(it) }.getOrNull() diff --git a/app/src/main/java/com/topjohnwu/magisk/ktx/XString.kt b/app/src/main/java/com/topjohnwu/magisk/ktx/XString.kt index c48027411..59529d334 100644 --- a/app/src/main/java/com/topjohnwu/magisk/ktx/XString.kt +++ b/app/src/main/java/com/topjohnwu/magisk/ktx/XString.kt @@ -1,7 +1,6 @@ package com.topjohnwu.magisk.ktx import android.content.res.Resources -import android.os.Build val specialChars = arrayOf('!', '@', '#', '$', '%', '&', '?') val fullSpecialChars = arrayOf('!', '@', '#', '$', '%', '&', '?') @@ -13,10 +12,7 @@ fun String.isCJK(): Boolean { return false } -fun isCJK(codepoint: Int): Boolean { - return if (Build.VERSION.SDK_INT < 19) false /* Pre 5.0 don't need to be pretty.. */ - else Character.isIdeographic(codepoint) -} +fun isCJK(codepoint: Int) = Character.isIdeographic(codepoint) fun String.replaceRandomWithSpecial(passes: Int): String { var string = this diff --git a/app/src/main/java/com/topjohnwu/magisk/ui/MainActivity.kt b/app/src/main/java/com/topjohnwu/magisk/ui/MainActivity.kt index c8a5219c3..83b3394c1 100644 --- a/app/src/main/java/com/topjohnwu/magisk/ui/MainActivity.kt +++ b/app/src/main/java/com/topjohnwu/magisk/ui/MainActivity.kt @@ -2,7 +2,6 @@ package com.topjohnwu.magisk.ui import android.content.Intent import android.content.pm.ApplicationInfo -import android.os.Build import android.os.Bundle import android.view.MenuItem import android.view.View @@ -123,10 +122,7 @@ open class MainActivity : BaseUIActivity( val topView = binding.mainToolbarWrapper val bottomView = binding.mainBottomBar - if ( - Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT && - !binding.mainBottomBar.isAttachedToWindow - ) { + if (!binding.mainBottomBar.isAttachedToWindow) { binding.mainBottomBar.viewTreeObserver.addOnWindowAttachListener(object : ViewTreeObserver.OnWindowAttachListener { diff --git a/app/src/main/java/com/topjohnwu/magisk/ui/settings/SettingsViewModel.kt b/app/src/main/java/com/topjohnwu/magisk/ui/settings/SettingsViewModel.kt index 240ad4343..948bb9910 100644 --- a/app/src/main/java/com/topjohnwu/magisk/ui/settings/SettingsViewModel.kt +++ b/app/src/main/java/com/topjohnwu/magisk/ui/settings/SettingsViewModel.kt @@ -74,10 +74,6 @@ class SettingsViewModel( Magisk, MagiskHide, SystemlessHosts )) - if (Build.VERSION.SDK_INT < 19) { - // MagiskHide is only available on 4.4+ - list.remove(MagiskHide) - } } // Superuser diff --git a/app/src/main/java/com/topjohnwu/magisk/ui/surequest/SuRequestActivity.kt b/app/src/main/java/com/topjohnwu/magisk/ui/surequest/SuRequestActivity.kt index ed0a5d7f8..99782ec0f 100644 --- a/app/src/main/java/com/topjohnwu/magisk/ui/surequest/SuRequestActivity.kt +++ b/app/src/main/java/com/topjohnwu/magisk/ui/surequest/SuRequestActivity.kt @@ -3,7 +3,6 @@ package com.topjohnwu.magisk.ui.surequest import android.content.Intent import android.content.pm.ActivityInfo import android.content.res.Resources -import android.os.Build import android.os.Bundle import android.view.Window import android.view.WindowManager @@ -62,9 +61,6 @@ open class SuRequestActivity : BaseUIActivity - - - - - - - - - - - \ No newline at end of file diff --git a/app/src/main/res/values-v21/themes.xml b/app/src/main/res/values-v21/themes.xml deleted file mode 100644 index 54ccddd36..000000000 --- a/app/src/main/res/values-v21/themes.xml +++ /dev/null @@ -1,38 +0,0 @@ - - - - - - - - - - - - diff --git a/app/src/main/res/values/themes.xml b/app/src/main/res/values/themes.xml index 5bc16dee5..29d57a7df 100644 --- a/app/src/main/res/values/themes.xml +++ b/app/src/main/res/values/themes.xml @@ -1,41 +1,55 @@ - - - - - -