From 71d855e836c04c1f703a950b9c64e7d237d86d9b Mon Sep 17 00:00:00 2001 From: topjohnwu Date: Sun, 4 Aug 2019 13:47:14 -0700 Subject: [PATCH] Cleanup more code --- app/src/main/java/com/topjohnwu/magisk/App.kt | 7 - .../topjohnwu/magisk/extensions/XAndroid.kt | 2 +- .../com/topjohnwu/magisk/extensions/XJava.kt | 62 ++++++++ .../com/topjohnwu/magisk/extensions/XTime.kt | 11 +- .../magisk/model/entity/SuLogEntry.java | 56 -------- .../magisk/model/receiver/GeneralReceiver.kt | 2 +- .../magisk/model/update/UpdateCheckService.kt | 4 +- .../magisk/ui/base/MagiskActivity.kt | 5 +- .../topjohnwu/magisk/ui/home/HomeFragment.kt | 9 +- .../magisk/ui/settings/SettingsFragment.kt | 17 +-- .../topjohnwu/magisk/utils/LocaleManager.kt | 132 +++++------------- .../java/com/topjohnwu/magisk/utils/Utils.kt | 11 +- .../topjohnwu/magisk/view/Notifications.java | 109 --------------- .../topjohnwu/magisk/view/Notifications.kt | 100 +++++++++++++ 14 files changed, 221 insertions(+), 306 deletions(-) delete mode 100644 app/src/main/java/com/topjohnwu/magisk/model/entity/SuLogEntry.java delete mode 100644 app/src/main/java/com/topjohnwu/magisk/view/Notifications.java create mode 100644 app/src/main/java/com/topjohnwu/magisk/view/Notifications.kt diff --git a/app/src/main/java/com/topjohnwu/magisk/App.kt b/app/src/main/java/com/topjohnwu/magisk/App.kt index 05495595e..e34d496a8 100644 --- a/app/src/main/java/com/topjohnwu/magisk/App.kt +++ b/app/src/main/java/com/topjohnwu/magisk/App.kt @@ -1,6 +1,5 @@ package com.topjohnwu.magisk -import android.annotation.SuppressLint import android.app.Application import android.content.Context import android.content.res.Configuration @@ -39,7 +38,6 @@ open class App : Application() { } deContext = base - self = this if (Build.VERSION.SDK_INT >= 24) { deContext = base.createDeviceProtectedStorageContext() @@ -61,11 +59,6 @@ open class App : Application() { companion object { - @SuppressLint("StaticFieldLeak") - @Deprecated("Use dependency injection") - @JvmStatic - lateinit var self: App - init { AppCompatDelegate.setCompatVectorFromResourcesEnabled(true) Shell.Config.setFlags(Shell.FLAG_MOUNT_MASTER or Shell.FLAG_USE_MAGISK_BUSYBOX) diff --git a/app/src/main/java/com/topjohnwu/magisk/extensions/XAndroid.kt b/app/src/main/java/com/topjohnwu/magisk/extensions/XAndroid.kt index f6e5dec1a..c6f6a675e 100644 --- a/app/src/main/java/com/topjohnwu/magisk/extensions/XAndroid.kt +++ b/app/src/main/java/com/topjohnwu/magisk/extensions/XAndroid.kt @@ -55,7 +55,7 @@ val ApplicationInfo.packageInfo: PackageInfo? val Uri.fileName: String get() { var name: String? = null - App.self.contentResolver.query(this, null, null, null, null)?.use { c -> + get().contentResolver.query(this, null, null, null, null)?.use { c -> val nameIndex = c.getColumnIndex(OpenableColumns.DISPLAY_NAME) if (nameIndex != -1) { c.moveToFirst() diff --git a/app/src/main/java/com/topjohnwu/magisk/extensions/XJava.kt b/app/src/main/java/com/topjohnwu/magisk/extensions/XJava.kt index 9ad5caa7e..1f8c7c007 100644 --- a/app/src/main/java/com/topjohnwu/magisk/extensions/XJava.kt +++ b/app/src/main/java/com/topjohnwu/magisk/extensions/XJava.kt @@ -1,12 +1,15 @@ package com.topjohnwu.magisk.extensions import android.net.Uri +import android.os.Build import androidx.core.net.toFile import java.io.File import java.io.InputStream import java.io.OutputStream +import java.util.* import java.util.zip.ZipEntry import java.util.zip.ZipInputStream +import kotlin.NoSuchElementException fun ZipInputStream.forEach(callback: (ZipEntry) -> Unit) { var entry: ZipEntry? = nextEntry @@ -38,4 +41,63 @@ inline fun List.firstMap(mapper: (T) -> R?): R { return mapper(item) ?: continue } throw NoSuchElementException("Collection contains no element matching the predicate.") +} + +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() + } } \ No newline at end of file diff --git a/app/src/main/java/com/topjohnwu/magisk/extensions/XTime.kt b/app/src/main/java/com/topjohnwu/magisk/extensions/XTime.kt index 154ac8d12..c3fa76291 100644 --- a/app/src/main/java/com/topjohnwu/magisk/extensions/XTime.kt +++ b/app/src/main/java/com/topjohnwu/magisk/extensions/XTime.kt @@ -1,6 +1,6 @@ package com.topjohnwu.magisk.extensions -import com.topjohnwu.magisk.utils.LocaleManager +import com.topjohnwu.magisk.utils.currentLocale import java.text.DateFormat import java.text.ParseException import java.text.SimpleDateFormat @@ -14,8 +14,7 @@ fun String.toTime(format: DateFormat) = try { -1L } -private val locale get() = LocaleManager.locale -val timeFormatFull by lazy { SimpleDateFormat("yyyy/MM/dd_HH:mm:ss", locale) } -val timeFormatStandard by lazy { SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'", locale) } -val timeFormatMedium by lazy { DateFormat.getDateInstance(DateFormat.MEDIUM, LocaleManager.locale) } -val timeFormatTime by lazy { SimpleDateFormat("h:mm a", LocaleManager.locale) } \ No newline at end of file +val timeFormatFull by lazy { SimpleDateFormat("yyyy/MM/dd_HH:mm:ss", currentLocale) } +val timeFormatStandard by lazy { SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'", currentLocale) } +val timeFormatMedium by lazy { DateFormat.getDateInstance(DateFormat.MEDIUM, currentLocale) } +val timeFormatTime by lazy { SimpleDateFormat("h:mm a", currentLocale) } diff --git a/app/src/main/java/com/topjohnwu/magisk/model/entity/SuLogEntry.java b/app/src/main/java/com/topjohnwu/magisk/model/entity/SuLogEntry.java deleted file mode 100644 index c6c6ff7fa..000000000 --- a/app/src/main/java/com/topjohnwu/magisk/model/entity/SuLogEntry.java +++ /dev/null @@ -1,56 +0,0 @@ -package com.topjohnwu.magisk.model.entity; - -import android.content.ContentValues; - -import com.topjohnwu.magisk.utils.LocaleManager; - -import java.text.DateFormat; -import java.text.SimpleDateFormat; -import java.util.Date; - -public class SuLogEntry { - - public int fromUid, toUid, fromPid; - public String packageName, appName, command; - public boolean action; - public Date date; - - public SuLogEntry(MagiskPolicy policy) { - fromUid = policy.getUid(); - packageName = policy.getPackageName(); - appName = policy.getAppName(); - action = policy.getPolicy() == Policy.ALLOW; - } - - public SuLogEntry(ContentValues values) { - fromUid = values.getAsInteger("from_uid"); - packageName = values.getAsString("package_name"); - appName = values.getAsString("app_name"); - fromPid = values.getAsInteger("from_pid"); - command = values.getAsString("command"); - toUid = values.getAsInteger("to_uid"); - action = values.getAsInteger("action") != 0; - date = new Date(values.getAsLong("time")); - } - - public ContentValues getContentValues() { - ContentValues values = new ContentValues(); - values.put("from_uid", fromUid); - values.put("package_name", packageName); - values.put("app_name", appName); - values.put("from_pid", fromPid); - values.put("command", command); - values.put("to_uid", toUid); - values.put("action", action ? 1 : 0); - values.put("time", date.getTime()); - return values; - } - - public String getDateString() { - return DateFormat.getDateInstance(DateFormat.MEDIUM, LocaleManager.getLocale()).format(date); - } - - public String getTimeString() { - return new SimpleDateFormat("h:mm a", LocaleManager.getLocale()).format(date); - } -} diff --git a/app/src/main/java/com/topjohnwu/magisk/model/receiver/GeneralReceiver.kt b/app/src/main/java/com/topjohnwu/magisk/model/receiver/GeneralReceiver.kt index e789a3c1a..b8b2bdae7 100644 --- a/app/src/main/java/com/topjohnwu/magisk/model/receiver/GeneralReceiver.kt +++ b/app/src/main/java/com/topjohnwu/magisk/model/receiver/GeneralReceiver.kt @@ -47,7 +47,7 @@ open class GeneralReceiver : BroadcastReceiver() { // Actual boot completed event Shell.su("mm_patch_dtbo").submit { result -> if (result.isSuccess) - Notifications.dtboPatched() + Notifications.dtboPatched(context) } return } diff --git a/app/src/main/java/com/topjohnwu/magisk/model/update/UpdateCheckService.kt b/app/src/main/java/com/topjohnwu/magisk/model/update/UpdateCheckService.kt index 7e60c2000..68c3043a6 100644 --- a/app/src/main/java/com/topjohnwu/magisk/model/update/UpdateCheckService.kt +++ b/app/src/main/java/com/topjohnwu/magisk/model/update/UpdateCheckService.kt @@ -19,9 +19,9 @@ class UpdateCheckService : DelegateWorker() { return runCatching { magiskRepo.fetchUpdate().blockingGet() if (BuildConfig.VERSION_CODE < Info.remote.app.versionCode) - Notifications.managerUpdate() + Notifications.managerUpdate(applicationContext) else if (Info.magiskVersionCode < Info.remote.magisk.versionCode) - Notifications.magiskUpdate() + Notifications.magiskUpdate(applicationContext) ListenableWorker.Result.success() }.getOrElse { ListenableWorker.Result.failure() diff --git a/app/src/main/java/com/topjohnwu/magisk/ui/base/MagiskActivity.kt b/app/src/main/java/com/topjohnwu/magisk/ui/base/MagiskActivity.kt index dceeaba4c..f47d314db 100644 --- a/app/src/main/java/com/topjohnwu/magisk/ui/base/MagiskActivity.kt +++ b/app/src/main/java/com/topjohnwu/magisk/ui/base/MagiskActivity.kt @@ -32,6 +32,7 @@ import com.topjohnwu.magisk.model.navigation.Navigator import com.topjohnwu.magisk.model.permissions.PermissionRequestBuilder import com.topjohnwu.magisk.utils.LocaleManager import com.topjohnwu.magisk.utils.Utils +import com.topjohnwu.magisk.utils.currentLocale import timber.log.Timber import kotlin.reflect.KClass @@ -68,12 +69,12 @@ abstract class MagiskActivity(), } companion object { - val EXT_APK = File("${App.self.filesDir.parent}/snet", "snet.apk") + val EXT_APK by lazy { File("${get().filesDir.parent}/snet", "snet.apk") } } } diff --git a/app/src/main/java/com/topjohnwu/magisk/ui/settings/SettingsFragment.kt b/app/src/main/java/com/topjohnwu/magisk/ui/settings/SettingsFragment.kt index d59150a15..3d0dca305 100644 --- a/app/src/main/java/com/topjohnwu/magisk/ui/settings/SettingsFragment.kt +++ b/app/src/main/java/com/topjohnwu/magisk/ui/settings/SettingsFragment.kt @@ -21,15 +21,13 @@ import com.topjohnwu.magisk.Const import com.topjohnwu.magisk.R import com.topjohnwu.magisk.data.database.RepoDao import com.topjohnwu.magisk.databinding.CustomDownloadDialogBinding +import com.topjohnwu.magisk.extensions.toLangTag import com.topjohnwu.magisk.model.download.DownloadService import com.topjohnwu.magisk.model.entity.internal.Configuration import com.topjohnwu.magisk.model.entity.internal.DownloadSubject import com.topjohnwu.magisk.model.observer.Observer import com.topjohnwu.magisk.ui.base.BasePreferenceFragment -import com.topjohnwu.magisk.utils.FingerprintHelper -import com.topjohnwu.magisk.utils.LocaleManager -import com.topjohnwu.magisk.utils.PatchAPK -import com.topjohnwu.magisk.utils.Utils +import com.topjohnwu.magisk.utils.* import com.topjohnwu.magisk.view.dialogs.FingerprintAuthDialog import com.topjohnwu.net.Networking import com.topjohnwu.superuser.Shell @@ -226,21 +224,18 @@ class SettingsFragment : BasePreferenceFragment() { private fun setLocalePreference(lp: ListPreference) { lp.isEnabled = false - LocaleManager.availableLocales - .map { + availableLocales.map { val names = mutableListOf() val values = mutableListOf() names.add( - LocaleManager.getString( - LocaleManager.defaultLocale, R.string.system_default - ) + LocaleManager.getString(defaultLocale, R.string.system_default) ) values.add("") it.forEach { locale -> names.add(locale.getDisplayName(locale)) - values.add(LocaleManager.toLanguageTag(locale)) + values.add(locale.toLangTag()) } Pair(names.toTypedArray(), values.toTypedArray()) @@ -248,7 +243,7 @@ class SettingsFragment : BasePreferenceFragment() { lp.isEnabled = true lp.entries = names lp.entryValues = values - lp.summary = LocaleManager.locale.getDisplayName(LocaleManager.locale) + lp.summary = currentLocale.getDisplayName(currentLocale) } } diff --git a/app/src/main/java/com/topjohnwu/magisk/utils/LocaleManager.kt b/app/src/main/java/com/topjohnwu/magisk/utils/LocaleManager.kt index afcb621d0..e89241b0d 100644 --- a/app/src/main/java/com/topjohnwu/magisk/utils/LocaleManager.kt +++ b/app/src/main/java/com/topjohnwu/magisk/utils/LocaleManager.kt @@ -4,133 +4,65 @@ import android.content.Context import android.content.ContextWrapper import android.content.res.Configuration import android.content.res.Resources -import android.os.Build import androidx.annotation.StringRes -import com.topjohnwu.magisk.App import com.topjohnwu.magisk.Config import com.topjohnwu.magisk.R +import com.topjohnwu.magisk.extensions.get import com.topjohnwu.magisk.extensions.inject +import com.topjohnwu.magisk.extensions.langTagToLocale import com.topjohnwu.superuser.internal.InternalUtils import io.reactivex.Single import java.util.* -object LocaleManager { - @JvmStatic - var locale = Locale.getDefault() - @JvmStatic - val defaultLocale = Locale.getDefault() +var currentLocale = Locale.getDefault()!! + private set - @JvmStatic - val availableLocales = Single.fromCallable { - val compareId = R.string.app_changelog - val res: Resources by inject() - mutableListOf().apply { - // Add default locale - add(Locale.ENGLISH) +val defaultLocale = Locale.getDefault()!! - // Add some special locales - add(Locale.TAIWAN) - add(Locale("pt", "BR")) +val availableLocales = Single.fromCallable { + val compareId = R.string.app_changelog + val res: Resources by inject() + mutableListOf().apply { + // Add default locale + add(Locale.ENGLISH) - // Other locales - val otherLocales = res.assets.locales - .map { forLanguageTag(it) } - .distinctBy { getString(it, compareId) } + // Add some special locales + add(Locale.TAIWAN) + add(Locale("pt", "BR")) - listOf("", "").toTypedArray() + // Other locales + val otherLocales = res.assets.locales + .map { it.langTagToLocale() } + .distinctBy { LocaleManager.getString(it, compareId) } - addAll(otherLocales) - }.sortedWith(Comparator { a, b -> - a.getDisplayName(a).toLowerCase(a) + listOf("", "").toTypedArray() + + addAll(otherLocales) + }.sortedWith(Comparator { a, b -> + a.getDisplayName(a).toLowerCase(a) .compareTo(b.getDisplayName(b).toLowerCase(b)) - }) - }.cache() + }) +}.cache()!! - private fun forLanguageTag(tag: String): Locale { - if (Build.VERSION.SDK_INT >= 21) { - return Locale.forLanguageTag(tag) - } else { - val tok = tag.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] +object LocaleManager { - return if (country.length != 2 && country.length != 3) Locale(language) - else Locale(language, country) - } - } - - @JvmStatic - fun toLanguageTag(loc: Locale): String { - if (Build.VERSION.SDK_INT >= 21) { - return loc.toLanguageTag() - } else { - var language = loc.language - var country = loc.country - var variant = loc.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() - } - } - - @JvmStatic fun setLocale(wrapper: ContextWrapper) { val localeConfig = Config.locale - locale = when { + currentLocale = when { localeConfig.isEmpty() -> defaultLocale - else -> forLanguageTag(localeConfig) + else -> localeConfig.langTagToLocale() } - Locale.setDefault(locale) - InternalUtils.replaceBaseContext(wrapper, getLocaleContext(locale)) + Locale.setDefault(currentLocale) + InternalUtils.replaceBaseContext(wrapper, getLocaleContext(wrapper, currentLocale)) } - @JvmStatic - fun getLocaleContext(context: Context, locale: Locale): Context { + fun getLocaleContext(context: Context, locale: Locale = currentLocale): Context { val config = Configuration(context.resources.configuration) config.setLocale(locale) return context.createConfigurationContext(config) } - @JvmStatic - fun getLocaleContext(locale: Locale): Context { - return getLocaleContext(App.self.baseContext, locale) - } - - @JvmStatic fun getString(locale: Locale, @StringRes id: Int): String { - return getLocaleContext(locale).getString(id) + return getLocaleContext(get(), locale).getString(id) } } diff --git a/app/src/main/java/com/topjohnwu/magisk/utils/Utils.kt b/app/src/main/java/com/topjohnwu/magisk/utils/Utils.kt index 9337fec1b..e27c176f5 100644 --- a/app/src/main/java/com/topjohnwu/magisk/utils/Utils.kt +++ b/app/src/main/java/com/topjohnwu/magisk/utils/Utils.kt @@ -15,7 +15,6 @@ import com.topjohnwu.magisk.* import com.topjohnwu.magisk.R import com.topjohnwu.magisk.extensions.get import com.topjohnwu.magisk.model.update.UpdateCheckService -import com.topjohnwu.net.Networking import com.topjohnwu.superuser.Shell import com.topjohnwu.superuser.internal.UiThreadHandler import java.io.File @@ -24,8 +23,7 @@ import java.util.concurrent.TimeUnit object Utils { - val isCanary: Boolean - get() = BuildConfig.VERSION_NAME.contains("-") + val isCanary: Boolean = BuildConfig.VERSION_NAME.contains("-") fun toast(msg: CharSequence, duration: Int) { UiThreadHandler.run { Toast.makeText(get(), msg, duration).show() } @@ -35,11 +33,6 @@ object Utils { UiThreadHandler.run { Toast.makeText(get(), resId, duration).show() } } - fun dlString(url: String): String { - val s = Networking.get(url).execForString().result - return s ?: "" - } - fun getPrefsInt(prefs: SharedPreferences, key: String, def: Int = 0): Int { return prefs.getString(key, def.toString())!!.toInt() } @@ -58,7 +51,7 @@ object Utils { if (info.labelRes > 0) { val res = pm.getResourcesForApplication(info) val config = Configuration() - config.setLocale(LocaleManager.locale) + config.setLocale(currentLocale) res.updateConfiguration(config, res.displayMetrics) return res.getString(info.labelRes) } diff --git a/app/src/main/java/com/topjohnwu/magisk/view/Notifications.java b/app/src/main/java/com/topjohnwu/magisk/view/Notifications.java deleted file mode 100644 index 22b085b2e..000000000 --- a/app/src/main/java/com/topjohnwu/magisk/view/Notifications.java +++ /dev/null @@ -1,109 +0,0 @@ -package com.topjohnwu.magisk.view; - -import android.app.NotificationChannel; -import android.app.NotificationManager; -import android.app.PendingIntent; -import android.content.Context; -import android.content.Intent; -import android.os.Build; - -import androidx.core.app.NotificationCompat; -import androidx.core.app.NotificationManagerCompat; -import androidx.core.app.TaskStackBuilder; - -import com.topjohnwu.magisk.App; -import com.topjohnwu.magisk.ClassMap; -import com.topjohnwu.magisk.Const; -import com.topjohnwu.magisk.Info; -import com.topjohnwu.magisk.R; -import com.topjohnwu.magisk.model.receiver.GeneralReceiver; -import com.topjohnwu.magisk.ui.SplashActivity; - -public class Notifications { - - public static NotificationManagerCompat mgr = NotificationManagerCompat.from(App.self); - - public static void setup(Context c) { - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { - mgr.deleteNotificationChannel("magisk_notification"); - NotificationChannel channel = - new NotificationChannel(Const.ID.UPDATE_NOTIFICATION_CHANNEL, - c.getString(R.string.update_channel), NotificationManager.IMPORTANCE_DEFAULT); - mgr.createNotificationChannel(channel); - channel = new NotificationChannel(Const.ID.PROGRESS_NOTIFICATION_CHANNEL, - c.getString(R.string.progress_channel), NotificationManager.IMPORTANCE_LOW); - mgr.createNotificationChannel(channel); - } - } - - public static void magiskUpdate() { - App app = App.self; - - Intent intent = new Intent(app, ClassMap.get(SplashActivity.class)); - intent.putExtra(Const.Key.OPEN_SECTION, "magisk"); - TaskStackBuilder stackBuilder = TaskStackBuilder.create(app); - stackBuilder.addParentStack(ClassMap.get(SplashActivity.class)); - stackBuilder.addNextIntent(intent); - PendingIntent pendingIntent = stackBuilder.getPendingIntent(Const.ID.MAGISK_UPDATE_NOTIFICATION_ID, - PendingIntent.FLAG_UPDATE_CURRENT); - - NotificationCompat.Builder builder = new NotificationCompat.Builder(app, Const.ID.UPDATE_NOTIFICATION_CHANNEL); - builder.setSmallIcon(R.drawable.ic_magisk_outline) - .setContentTitle(app.getString(R.string.magisk_update_title)) - .setContentText(app.getString(R.string.manager_download_install)) - .setVibrate(new long[]{0, 100, 100, 100}) - .setAutoCancel(true) - .setContentIntent(pendingIntent); - - mgr.notify(Const.ID.MAGISK_UPDATE_NOTIFICATION_ID, builder.build()); - } - - public static void managerUpdate() { - App app = App.self; - - Intent intent = new Intent(app, ClassMap.get(GeneralReceiver.class)); - intent.setAction(Const.Key.BROADCAST_MANAGER_UPDATE); - intent.putExtra(Const.Key.INTENT_SET_APP, Info.remote.getApp()); - - PendingIntent pendingIntent = PendingIntent.getBroadcast(app, - Const.ID.APK_UPDATE_NOTIFICATION_ID, intent, PendingIntent.FLAG_UPDATE_CURRENT); - - NotificationCompat.Builder builder = new NotificationCompat.Builder(app, Const.ID.UPDATE_NOTIFICATION_CHANNEL); - builder.setSmallIcon(R.drawable.ic_magisk_outline) - .setContentTitle(app.getString(R.string.manager_update_title)) - .setContentText(app.getString(R.string.manager_download_install)) - .setVibrate(new long[]{0, 100, 100, 100}) - .setAutoCancel(true) - .setContentIntent(pendingIntent); - - mgr.notify(Const.ID.APK_UPDATE_NOTIFICATION_ID, builder.build()); - } - - public static void dtboPatched() { - App app = App.self; - - Intent intent = new Intent(app, ClassMap.get(GeneralReceiver.class)) - .setAction(Const.Key.BROADCAST_REBOOT); - PendingIntent pendingIntent = PendingIntent.getBroadcast(app, - Const.ID.DTBO_NOTIFICATION_ID, intent, PendingIntent.FLAG_UPDATE_CURRENT); - - NotificationCompat.Builder builder = new NotificationCompat.Builder(app, Const.ID.UPDATE_NOTIFICATION_CHANNEL); - builder.setSmallIcon(R.drawable.ic_magisk_outline) - .setContentTitle(app.getString(R.string.dtbo_patched_title)) - .setContentText(app.getString(R.string.dtbo_patched_reboot)) - .setVibrate(new long[]{0, 100, 100, 100}) - .addAction(R.drawable.ic_refresh, app.getString(R.string.reboot), pendingIntent); - - mgr.notify(Const.ID.DTBO_NOTIFICATION_ID, builder.build()); - } - - public static NotificationCompat.Builder progress(Context context, CharSequence title) { - NotificationCompat.Builder builder = new NotificationCompat.Builder(context, Const.ID.PROGRESS_NOTIFICATION_CHANNEL); - builder.setPriority(NotificationCompat.PRIORITY_LOW) - .setSmallIcon(android.R.drawable.stat_sys_download) - .setContentTitle(title) - .setProgress(0, 0, true) - .setOngoing(true); - return builder; - } -} diff --git a/app/src/main/java/com/topjohnwu/magisk/view/Notifications.kt b/app/src/main/java/com/topjohnwu/magisk/view/Notifications.kt new file mode 100644 index 000000000..38770a8d8 --- /dev/null +++ b/app/src/main/java/com/topjohnwu/magisk/view/Notifications.kt @@ -0,0 +1,100 @@ +package com.topjohnwu.magisk.view + +import android.app.NotificationChannel +import android.app.NotificationManager +import android.app.PendingIntent +import android.content.Context +import android.content.Intent +import android.os.Build +import androidx.core.app.NotificationCompat +import androidx.core.app.NotificationManagerCompat +import androidx.core.app.TaskStackBuilder +import com.topjohnwu.magisk.ClassMap +import com.topjohnwu.magisk.Const +import com.topjohnwu.magisk.Info +import com.topjohnwu.magisk.R +import com.topjohnwu.magisk.extensions.get +import com.topjohnwu.magisk.model.receiver.GeneralReceiver +import com.topjohnwu.magisk.ui.SplashActivity + +object Notifications { + + val mgr by lazy { NotificationManagerCompat.from(get()) } + + fun setup(context: Context) { + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { + mgr.deleteNotificationChannel("magisk_notification") + var channel = NotificationChannel(Const.ID.UPDATE_NOTIFICATION_CHANNEL, + context.getString(R.string.update_channel), NotificationManager.IMPORTANCE_DEFAULT) + mgr.createNotificationChannel(channel) + channel = NotificationChannel(Const.ID.PROGRESS_NOTIFICATION_CHANNEL, + context.getString(R.string.progress_channel), NotificationManager.IMPORTANCE_LOW) + mgr.createNotificationChannel(channel) + } + } + + fun magiskUpdate(context: Context) { + val intent = Intent(context, ClassMap[SplashActivity::class.java]) + intent.putExtra(Const.Key.OPEN_SECTION, "magisk") + val stackBuilder = TaskStackBuilder.create(context) + stackBuilder.addParentStack(ClassMap.get>(SplashActivity::class.java)) + stackBuilder.addNextIntent(intent) + val pendingIntent = stackBuilder.getPendingIntent(Const.ID.MAGISK_UPDATE_NOTIFICATION_ID, + PendingIntent.FLAG_UPDATE_CURRENT) + + val builder = NotificationCompat.Builder(context, Const.ID.UPDATE_NOTIFICATION_CHANNEL) + builder.setSmallIcon(R.drawable.ic_magisk_outline) + .setContentTitle(context.getString(R.string.magisk_update_title)) + .setContentText(context.getString(R.string.manager_download_install)) + .setVibrate(longArrayOf(0, 100, 100, 100)) + .setAutoCancel(true) + .setContentIntent(pendingIntent) + + mgr.notify(Const.ID.MAGISK_UPDATE_NOTIFICATION_ID, builder.build()) + } + + fun managerUpdate(context: Context) { + val intent = Intent(context, ClassMap[GeneralReceiver::class.java]) + intent.action = Const.Key.BROADCAST_MANAGER_UPDATE + intent.putExtra(Const.Key.INTENT_SET_APP, Info.remote.app) + + val pendingIntent = PendingIntent.getBroadcast(context, + Const.ID.APK_UPDATE_NOTIFICATION_ID, intent, PendingIntent.FLAG_UPDATE_CURRENT) + + val builder = NotificationCompat.Builder(context, Const.ID.UPDATE_NOTIFICATION_CHANNEL) + builder.setSmallIcon(R.drawable.ic_magisk_outline) + .setContentTitle(context.getString(R.string.manager_update_title)) + .setContentText(context.getString(R.string.manager_download_install)) + .setVibrate(longArrayOf(0, 100, 100, 100)) + .setAutoCancel(true) + .setContentIntent(pendingIntent) + + mgr.notify(Const.ID.APK_UPDATE_NOTIFICATION_ID, builder.build()) + } + + fun dtboPatched(context: Context) { + val intent = Intent(context, ClassMap[GeneralReceiver::class.java]) + .setAction(Const.Key.BROADCAST_REBOOT) + val pendingIntent = PendingIntent.getBroadcast(context, + Const.ID.DTBO_NOTIFICATION_ID, intent, PendingIntent.FLAG_UPDATE_CURRENT) + + val builder = NotificationCompat.Builder(context, Const.ID.UPDATE_NOTIFICATION_CHANNEL) + builder.setSmallIcon(R.drawable.ic_magisk_outline) + .setContentTitle(context.getString(R.string.dtbo_patched_title)) + .setContentText(context.getString(R.string.dtbo_patched_reboot)) + .setVibrate(longArrayOf(0, 100, 100, 100)) + .addAction(R.drawable.ic_refresh, context.getString(R.string.reboot), pendingIntent) + + mgr.notify(Const.ID.DTBO_NOTIFICATION_ID, builder.build()) + } + + fun progress(context: Context, title: CharSequence): NotificationCompat.Builder { + val builder = NotificationCompat.Builder(context, Const.ID.PROGRESS_NOTIFICATION_CHANNEL) + builder.setPriority(NotificationCompat.PRIORITY_LOW) + .setSmallIcon(android.R.drawable.stat_sys_download) + .setContentTitle(title) + .setProgress(0, 0, true) + .setOngoing(true) + return builder + } +}