From 69b66ef6371ee0b52bc6a3816fa89af2494a3d1b Mon Sep 17 00:00:00 2001 From: topjohnwu Date: Wed, 5 Apr 2023 23:04:33 -0700 Subject: [PATCH] Make core package more self contained --- .../com/topjohnwu/magisk/arch/BaseFragment.kt | 1 - .../com/topjohnwu/magisk/arch/UIActivity.kt | 16 ++++++++ .../java/com/topjohnwu/magisk/core/Hacks.kt | 2 +- .../java/com/topjohnwu/magisk/core/Info.kt | 7 +++- .../magisk/core/base/BaseActivity.kt | 6 +-- .../magisk/core/data/magiskdb/MagiskDB.kt | 2 +- .../magisk/core/di/ServiceLocator.kt | 2 +- .../magisk/core/download/DownloadService.kt | 2 +- .../core/download/NotificationService.kt | 2 +- .../topjohnwu/magisk/core/download/Subject.kt | 2 +- .../magisk/{ => core}/ktx/XAndroid.kt | 34 ++++++---------- .../topjohnwu/magisk/{ => core}/ktx/XJVM.kt | 4 +- .../topjohnwu/magisk/{ => core}/ktx/XSU.kt | 2 +- .../topjohnwu/magisk/core/model/su/SuLog.kt | 2 +- .../magisk/core/repository/LogRepository.kt | 2 +- .../magisk/core/su/SuCallbackHandler.kt | 8 ++-- .../magisk/core/su/SuRequestHandler.kt | 2 +- .../topjohnwu/magisk/core/tasks/FlashZip.kt | 2 +- .../topjohnwu/magisk/core/tasks/HideAPK.kt | 10 ++--- .../magisk/core/tasks/MagiskInstaller.kt | 10 ++--- .../magisk/core/utils/DispatcherExecutor.kt | 6 ++- .../com/topjohnwu/magisk/core/utils/Keygen.kt | 4 +- .../magisk/core/utils/NetworkObserver.kt | 2 +- .../topjohnwu/magisk/core/utils/ShellInit.kt | 8 ++-- .../magisk/dialog/UninstallDialog.kt | 6 +-- .../com/topjohnwu/magisk/ui/MainActivity.kt | 5 +-- .../com/topjohnwu/magisk/ui/SplashActivity.kt | 4 +- .../magisk/ui/deny/AppProcessInfo.kt | 2 +- .../magisk/ui/deny/DenyListFragment.kt | 2 +- .../magisk/ui/deny/DenyListRvItem.kt | 2 +- .../magisk/ui/deny/DenyListViewModel.kt | 2 +- .../magisk/ui/flash/FlashViewModel.kt | 8 ++-- .../topjohnwu/magisk/ui/home/HomeViewModel.kt | 17 ++++++-- .../topjohnwu/magisk/ui/home/RebootMenu.kt | 2 +- .../magisk/ui/install/InstallViewModel.kt | 4 +- .../topjohnwu/magisk/ui/log/LogViewModel.kt | 4 +- .../topjohnwu/magisk/ui/log/SuLogRvItem.kt | 4 +- .../magisk/ui/settings/BaseSettingsItem.kt | 2 +- .../magisk/ui/settings/SettingsItems.kt | 5 +-- .../magisk/ui/settings/SettingsViewModel.kt | 8 ++-- .../magisk/ui/superuser/SuperuserViewModel.kt | 6 +-- .../magisk/ui/surequest/SuRequestViewModel.kt | 6 +-- .../java/com/topjohnwu/magisk/utils/Utils.kt | 39 ------------------- .../topjohnwu/magisk/view/Notifications.kt | 4 +- .../com/topjohnwu/magisk/view/Shortcuts.kt | 5 +-- 45 files changed, 129 insertions(+), 146 deletions(-) rename app/src/main/java/com/topjohnwu/magisk/{ => core}/ktx/XAndroid.kt (91%) rename app/src/main/java/com/topjohnwu/magisk/{ => core}/ktx/XJVM.kt (96%) rename app/src/main/java/com/topjohnwu/magisk/{ => core}/ktx/XSU.kt (96%) delete mode 100644 app/src/main/java/com/topjohnwu/magisk/utils/Utils.kt diff --git a/app/src/main/java/com/topjohnwu/magisk/arch/BaseFragment.kt b/app/src/main/java/com/topjohnwu/magisk/arch/BaseFragment.kt index 69852a265..549a1f074 100644 --- a/app/src/main/java/com/topjohnwu/magisk/arch/BaseFragment.kt +++ b/app/src/main/java/com/topjohnwu/magisk/arch/BaseFragment.kt @@ -12,7 +12,6 @@ import androidx.databinding.ViewDataBinding import androidx.fragment.app.Fragment import androidx.navigation.NavDirections import com.topjohnwu.magisk.BR -import com.topjohnwu.magisk.ktx.startAnimations abstract class BaseFragment : Fragment(), ViewModelHolder { diff --git a/app/src/main/java/com/topjohnwu/magisk/arch/UIActivity.kt b/app/src/main/java/com/topjohnwu/magisk/arch/UIActivity.kt index c40f15fb5..904802b09 100644 --- a/app/src/main/java/com/topjohnwu/magisk/arch/UIActivity.kt +++ b/app/src/main/java/com/topjohnwu/magisk/arch/UIActivity.kt @@ -5,13 +5,18 @@ import android.graphics.Color import android.os.Build import android.os.Bundle import android.view.View +import android.view.ViewGroup import androidx.appcompat.app.AppCompatDelegate import androidx.core.content.res.use import androidx.core.view.WindowCompat import androidx.databinding.DataBindingUtil import androidx.databinding.ViewDataBinding +import androidx.interpolator.view.animation.FastOutSlowInInterpolator +import androidx.transition.AutoTransition +import androidx.transition.TransitionManager import com.google.android.material.snackbar.Snackbar import com.topjohnwu.magisk.BR +import com.topjohnwu.magisk.R import com.topjohnwu.magisk.core.Config import com.topjohnwu.magisk.core.base.BaseActivity import rikka.insets.WindowInsetsHelper @@ -97,3 +102,14 @@ abstract class UIActivity : BaseActivity(), ViewModel else -> Unit } } + +fun ViewGroup.startAnimations() { + val transition = AutoTransition() + .setInterpolator(FastOutSlowInInterpolator()) + .setDuration(400) + .excludeTarget(R.id.main_toolbar, true) + TransitionManager.beginDelayedTransition( + this, + transition + ) +} diff --git a/app/src/main/java/com/topjohnwu/magisk/core/Hacks.kt b/app/src/main/java/com/topjohnwu/magisk/core/Hacks.kt index bc5a67ead..d62698e27 100644 --- a/app/src/main/java/com/topjohnwu/magisk/core/Hacks.kt +++ b/app/src/main/java/com/topjohnwu/magisk/core/Hacks.kt @@ -13,8 +13,8 @@ import android.util.DisplayMetrics import com.topjohnwu.magisk.R import com.topjohnwu.magisk.StubApk import com.topjohnwu.magisk.core.di.AppContext +import com.topjohnwu.magisk.core.ktx.unwrap import com.topjohnwu.magisk.core.utils.syncLocale -import com.topjohnwu.magisk.ktx.unwrap lateinit var AppApkPath: String diff --git a/app/src/main/java/com/topjohnwu/magisk/core/Info.kt b/app/src/main/java/com/topjohnwu/magisk/core/Info.kt index 5aa8b1fc4..7441497a7 100644 --- a/app/src/main/java/com/topjohnwu/magisk/core/Info.kt +++ b/app/src/main/java/com/topjohnwu/magisk/core/Info.kt @@ -5,10 +5,10 @@ import androidx.lifecycle.LiveData import androidx.lifecycle.MutableLiveData import com.topjohnwu.magisk.StubApk import com.topjohnwu.magisk.core.di.AppContext +import com.topjohnwu.magisk.core.ktx.getProperty import com.topjohnwu.magisk.core.model.UpdateInfo import com.topjohnwu.magisk.core.repository.NetworkService import com.topjohnwu.magisk.core.utils.NetworkObserver -import com.topjohnwu.magisk.ktx.getProperty import com.topjohnwu.superuser.ShellUtils.fastCmd val isRunningAsStub get() = Info.stub != null @@ -52,6 +52,11 @@ object Info { } } + val showSuperUser: Boolean get() { + return env.isActive && (Const.USER_ID == 0 + || Config.suMultiuserMode == Config.Value.MULTIUSER_MODE_USER) + } + private fun loadState(): Env { val v = fastCmd("magisk -v").split(":".toRegex()) return Env( diff --git a/app/src/main/java/com/topjohnwu/magisk/core/base/BaseActivity.kt b/app/src/main/java/com/topjohnwu/magisk/core/base/BaseActivity.kt index 90caba970..9435b5ea0 100644 --- a/app/src/main/java/com/topjohnwu/magisk/core/base/BaseActivity.kt +++ b/app/src/main/java/com/topjohnwu/magisk/core/base/BaseActivity.kt @@ -18,10 +18,10 @@ import androidx.activity.result.contract.ActivityResultContracts.RequestPermissi import androidx.appcompat.app.AppCompatActivity import com.topjohnwu.magisk.R import com.topjohnwu.magisk.core.isRunningAsStub +import com.topjohnwu.magisk.core.ktx.reflectField +import com.topjohnwu.magisk.core.ktx.toast import com.topjohnwu.magisk.core.utils.RequestInstall import com.topjohnwu.magisk.core.wrap -import com.topjohnwu.magisk.ktx.reflectField -import com.topjohnwu.magisk.utils.Utils interface ContentResultCallback: ActivityResultCallback, Parcelable { fun onActivityLaunch() {} @@ -110,7 +110,7 @@ abstract class BaseActivity : AppCompatActivity() { getContent.launch(type) callback.onActivityLaunch() } catch (e: ActivityNotFoundException) { - Utils.toast(R.string.app_not_found, Toast.LENGTH_SHORT) + toast(R.string.app_not_found, Toast.LENGTH_SHORT) } } diff --git a/app/src/main/java/com/topjohnwu/magisk/core/data/magiskdb/MagiskDB.kt b/app/src/main/java/com/topjohnwu/magisk/core/data/magiskdb/MagiskDB.kt index f78b27226..cd7dd8a16 100644 --- a/app/src/main/java/com/topjohnwu/magisk/core/data/magiskdb/MagiskDB.kt +++ b/app/src/main/java/com/topjohnwu/magisk/core/data/magiskdb/MagiskDB.kt @@ -1,6 +1,6 @@ package com.topjohnwu.magisk.core.data.magiskdb -import com.topjohnwu.magisk.ktx.await +import com.topjohnwu.magisk.core.ktx.await import com.topjohnwu.superuser.Shell import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.withContext diff --git a/app/src/main/java/com/topjohnwu/magisk/core/di/ServiceLocator.kt b/app/src/main/java/com/topjohnwu/magisk/core/di/ServiceLocator.kt index c206a39bf..c5034424e 100644 --- a/app/src/main/java/com/topjohnwu/magisk/core/di/ServiceLocator.kt +++ b/app/src/main/java/com/topjohnwu/magisk/core/di/ServiceLocator.kt @@ -9,9 +9,9 @@ import com.topjohnwu.magisk.core.data.SuLogDatabase import com.topjohnwu.magisk.core.data.magiskdb.PolicyDao import com.topjohnwu.magisk.core.data.magiskdb.SettingsDao import com.topjohnwu.magisk.core.data.magiskdb.StringDao +import com.topjohnwu.magisk.core.ktx.deviceProtectedContext import com.topjohnwu.magisk.core.repository.LogRepository import com.topjohnwu.magisk.core.repository.NetworkService -import com.topjohnwu.magisk.ktx.deviceProtectedContext import io.noties.markwon.Markwon import io.noties.markwon.utils.NoCopySpannableFactory diff --git a/app/src/main/java/com/topjohnwu/magisk/core/download/DownloadService.kt b/app/src/main/java/com/topjohnwu/magisk/core/download/DownloadService.kt index ba4804ab1..591a3c457 100644 --- a/app/src/main/java/com/topjohnwu/magisk/core/download/DownloadService.kt +++ b/app/src/main/java/com/topjohnwu/magisk/core/download/DownloadService.kt @@ -17,10 +17,10 @@ import com.topjohnwu.magisk.core.Info import com.topjohnwu.magisk.core.base.BaseActivity import com.topjohnwu.magisk.core.intent import com.topjohnwu.magisk.core.isRunningAsStub +import com.topjohnwu.magisk.core.ktx.* import com.topjohnwu.magisk.core.tasks.HideAPK import com.topjohnwu.magisk.core.utils.MediaStoreUtils import com.topjohnwu.magisk.core.utils.MediaStoreUtils.outputStream -import com.topjohnwu.magisk.ktx.* import com.topjohnwu.magisk.utils.APKInstall import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.Dispatchers diff --git a/app/src/main/java/com/topjohnwu/magisk/core/download/NotificationService.kt b/app/src/main/java/com/topjohnwu/magisk/core/download/NotificationService.kt index a957a17eb..ef7c4c55d 100644 --- a/app/src/main/java/com/topjohnwu/magisk/core/download/NotificationService.kt +++ b/app/src/main/java/com/topjohnwu/magisk/core/download/NotificationService.kt @@ -7,8 +7,8 @@ import androidx.lifecycle.MutableLiveData import com.topjohnwu.magisk.R import com.topjohnwu.magisk.core.base.BaseService import com.topjohnwu.magisk.core.di.ServiceLocator +import com.topjohnwu.magisk.core.ktx.synchronized import com.topjohnwu.magisk.core.utils.ProgressInputStream -import com.topjohnwu.magisk.ktx.synchronized import com.topjohnwu.magisk.view.Notifications import okhttp3.ResponseBody import java.io.InputStream diff --git a/app/src/main/java/com/topjohnwu/magisk/core/download/Subject.kt b/app/src/main/java/com/topjohnwu/magisk/core/download/Subject.kt index 5e0e777c8..4c9ea4600 100644 --- a/app/src/main/java/com/topjohnwu/magisk/core/download/Subject.kt +++ b/app/src/main/java/com/topjohnwu/magisk/core/download/Subject.kt @@ -9,10 +9,10 @@ import android.os.Parcelable import androidx.core.net.toUri import com.topjohnwu.magisk.core.Info import com.topjohnwu.magisk.core.di.AppContext +import com.topjohnwu.magisk.core.ktx.cachedFile import com.topjohnwu.magisk.core.model.MagiskJson import com.topjohnwu.magisk.core.model.module.OnlineModule import com.topjohnwu.magisk.core.utils.MediaStoreUtils -import com.topjohnwu.magisk.ktx.cachedFile import com.topjohnwu.magisk.ui.flash.FlashFragment import com.topjohnwu.magisk.view.Notifications import kotlinx.parcelize.IgnoredOnParcel diff --git a/app/src/main/java/com/topjohnwu/magisk/ktx/XAndroid.kt b/app/src/main/java/com/topjohnwu/magisk/core/ktx/XAndroid.kt similarity index 91% rename from app/src/main/java/com/topjohnwu/magisk/ktx/XAndroid.kt rename to app/src/main/java/com/topjohnwu/magisk/core/ktx/XAndroid.kt index e0c6151b2..277912da4 100644 --- a/app/src/main/java/com/topjohnwu/magisk/ktx/XAndroid.kt +++ b/app/src/main/java/com/topjohnwu/magisk/core/ktx/XAndroid.kt @@ -1,4 +1,4 @@ -package com.topjohnwu.magisk.ktx +package com.topjohnwu.magisk.core.ktx import android.annotation.SuppressLint import android.app.Activity @@ -6,7 +6,6 @@ import android.content.* import android.content.pm.ApplicationInfo import android.content.pm.PackageInfo import android.content.pm.PackageManager -import android.content.pm.PackageManager.PERMISSION_GRANTED import android.content.res.Configuration import android.graphics.Bitmap import android.graphics.Canvas @@ -18,20 +17,16 @@ import android.os.Build import android.os.Build.VERSION.SDK_INT import android.os.Process import android.view.View -import android.view.ViewGroup import android.view.inputmethod.InputMethodManager +import android.widget.Toast import androidx.appcompat.content.res.AppCompatResources -import androidx.core.content.ContextCompat import androidx.core.content.getSystemService -import androidx.interpolator.view.animation.FastOutSlowInInterpolator -import androidx.transition.AutoTransition -import androidx.transition.TransitionManager -import com.topjohnwu.magisk.R import com.topjohnwu.magisk.core.Const import com.topjohnwu.magisk.core.utils.RootUtils import com.topjohnwu.magisk.core.utils.currentLocale import com.topjohnwu.magisk.utils.APKInstall import com.topjohnwu.superuser.Shell +import com.topjohnwu.superuser.internal.UiThreadHandler import java.io.File import kotlin.Array import kotlin.String @@ -188,10 +183,6 @@ fun Context.unwrap(): Context { return context } -fun Context.hasPermissions(vararg permissions: String) = permissions.all { - ContextCompat.checkSelfPermission(this, it) == PERMISSION_GRANTED -} - fun Activity.hideKeyboard() { val view = currentFocus ?: return getSystemService() @@ -199,17 +190,6 @@ fun Activity.hideKeyboard() { view.clearFocus() } -fun ViewGroup.startAnimations() { - val transition = AutoTransition() - .setInterpolator(FastOutSlowInInterpolator()) - .setDuration(400) - .excludeTarget(R.id.main_toolbar, true) - TransitionManager.beginDelayedTransition( - this, - transition - ) -} - val View.activity: Activity get() { var context = context while(true) { @@ -271,3 +251,11 @@ fun Context.selfLaunchIntent(): Intent { intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TASK) return intent } + +fun Context.toast(msg: CharSequence, duration: Int) { + UiThreadHandler.run { Toast.makeText(this, msg, duration).show() } +} + +fun Context.toast(resId: Int, duration: Int) { + UiThreadHandler.run { Toast.makeText(this, resId, duration).show() } +} diff --git a/app/src/main/java/com/topjohnwu/magisk/ktx/XJVM.kt b/app/src/main/java/com/topjohnwu/magisk/core/ktx/XJVM.kt similarity index 96% rename from app/src/main/java/com/topjohnwu/magisk/ktx/XJVM.kt rename to app/src/main/java/com/topjohnwu/magisk/core/ktx/XJVM.kt index 195a05a0c..c95945b04 100644 --- a/app/src/main/java/com/topjohnwu/magisk/ktx/XJVM.kt +++ b/app/src/main/java/com/topjohnwu/magisk/core/ktx/XJVM.kt @@ -1,4 +1,4 @@ -package com.topjohnwu.magisk.ktx +package com.topjohnwu.magisk.core.ktx import androidx.collection.SparseArrayCompat import com.topjohnwu.magisk.core.utils.currentLocale @@ -11,7 +11,7 @@ import java.io.OutputStream import java.lang.reflect.Field import java.text.DateFormat import java.text.SimpleDateFormat -import java.util.* +import java.util.Collections import java.util.zip.ZipEntry import java.util.zip.ZipInputStream diff --git a/app/src/main/java/com/topjohnwu/magisk/ktx/XSU.kt b/app/src/main/java/com/topjohnwu/magisk/core/ktx/XSU.kt similarity index 96% rename from app/src/main/java/com/topjohnwu/magisk/ktx/XSU.kt rename to app/src/main/java/com/topjohnwu/magisk/core/ktx/XSU.kt index e051c65a1..d21b9a8da 100644 --- a/app/src/main/java/com/topjohnwu/magisk/ktx/XSU.kt +++ b/app/src/main/java/com/topjohnwu/magisk/core/ktx/XSU.kt @@ -1,4 +1,4 @@ -package com.topjohnwu.magisk.ktx +package com.topjohnwu.magisk.core.ktx import android.content.Context import com.topjohnwu.magisk.core.Config diff --git a/app/src/main/java/com/topjohnwu/magisk/core/model/su/SuLog.kt b/app/src/main/java/com/topjohnwu/magisk/core/model/su/SuLog.kt index 0d53abfb3..96f76c016 100644 --- a/app/src/main/java/com/topjohnwu/magisk/core/model/su/SuLog.kt +++ b/app/src/main/java/com/topjohnwu/magisk/core/model/su/SuLog.kt @@ -4,7 +4,7 @@ import android.content.pm.PackageInfo import android.content.pm.PackageManager import androidx.room.Entity import androidx.room.PrimaryKey -import com.topjohnwu.magisk.ktx.getLabel +import com.topjohnwu.magisk.core.ktx.getLabel @Entity(tableName = "logs") class SuLog( diff --git a/app/src/main/java/com/topjohnwu/magisk/core/repository/LogRepository.kt b/app/src/main/java/com/topjohnwu/magisk/core/repository/LogRepository.kt index cbd93bb9d..f561283a5 100644 --- a/app/src/main/java/com/topjohnwu/magisk/core/repository/LogRepository.kt +++ b/app/src/main/java/com/topjohnwu/magisk/core/repository/LogRepository.kt @@ -3,8 +3,8 @@ package com.topjohnwu.magisk.core.repository import com.topjohnwu.magisk.core.Const import com.topjohnwu.magisk.core.Info import com.topjohnwu.magisk.core.data.SuLogDao +import com.topjohnwu.magisk.core.ktx.await import com.topjohnwu.magisk.core.model.su.SuLog -import com.topjohnwu.magisk.ktx.await import com.topjohnwu.superuser.Shell diff --git a/app/src/main/java/com/topjohnwu/magisk/core/su/SuCallbackHandler.kt b/app/src/main/java/com/topjohnwu/magisk/core/su/SuCallbackHandler.kt index e98cd95f5..3c9ddea21 100644 --- a/app/src/main/java/com/topjohnwu/magisk/core/su/SuCallbackHandler.kt +++ b/app/src/main/java/com/topjohnwu/magisk/core/su/SuCallbackHandler.kt @@ -7,11 +7,11 @@ import com.topjohnwu.magisk.BuildConfig import com.topjohnwu.magisk.R import com.topjohnwu.magisk.core.Config import com.topjohnwu.magisk.core.di.ServiceLocator +import com.topjohnwu.magisk.core.ktx.getLabel +import com.topjohnwu.magisk.core.ktx.getPackageInfo +import com.topjohnwu.magisk.core.ktx.toast import com.topjohnwu.magisk.core.model.su.SuPolicy import com.topjohnwu.magisk.core.model.su.createSuLog -import com.topjohnwu.magisk.ktx.getLabel -import com.topjohnwu.magisk.ktx.getPackageInfo -import com.topjohnwu.magisk.utils.Utils import kotlinx.coroutines.runBlocking import timber.log.Timber @@ -93,7 +93,7 @@ object SuCallbackHandler { else R.string.su_deny_toast - Utils.toast(context.getString(resId, appName), Toast.LENGTH_SHORT) + context.toast(context.getString(resId, appName), Toast.LENGTH_SHORT) } } } diff --git a/app/src/main/java/com/topjohnwu/magisk/core/su/SuRequestHandler.kt b/app/src/main/java/com/topjohnwu/magisk/core/su/SuRequestHandler.kt index 207273a0d..7ed990a0a 100644 --- a/app/src/main/java/com/topjohnwu/magisk/core/su/SuRequestHandler.kt +++ b/app/src/main/java/com/topjohnwu/magisk/core/su/SuRequestHandler.kt @@ -6,8 +6,8 @@ import android.content.pm.PackageManager import com.topjohnwu.magisk.BuildConfig import com.topjohnwu.magisk.core.Config import com.topjohnwu.magisk.core.data.magiskdb.PolicyDao +import com.topjohnwu.magisk.core.ktx.getPackageInfo import com.topjohnwu.magisk.core.model.su.SuPolicy -import com.topjohnwu.magisk.ktx.getPackageInfo import com.topjohnwu.superuser.Shell import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.withContext diff --git a/app/src/main/java/com/topjohnwu/magisk/core/tasks/FlashZip.kt b/app/src/main/java/com/topjohnwu/magisk/core/tasks/FlashZip.kt index d26bce8b2..303c9a8bd 100644 --- a/app/src/main/java/com/topjohnwu/magisk/core/tasks/FlashZip.kt +++ b/app/src/main/java/com/topjohnwu/magisk/core/tasks/FlashZip.kt @@ -4,10 +4,10 @@ import android.net.Uri import androidx.core.net.toFile import com.topjohnwu.magisk.core.Const import com.topjohnwu.magisk.core.di.AppContext +import com.topjohnwu.magisk.core.ktx.writeTo import com.topjohnwu.magisk.core.utils.MediaStoreUtils.displayName import com.topjohnwu.magisk.core.utils.MediaStoreUtils.inputStream import com.topjohnwu.magisk.core.utils.unzip -import com.topjohnwu.magisk.ktx.writeTo import com.topjohnwu.superuser.Shell import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.withContext diff --git a/app/src/main/java/com/topjohnwu/magisk/core/tasks/HideAPK.kt b/app/src/main/java/com/topjohnwu/magisk/core/tasks/HideAPK.kt index d7c23a609..cd4f82d64 100644 --- a/app/src/main/java/com/topjohnwu/magisk/core/tasks/HideAPK.kt +++ b/app/src/main/java/com/topjohnwu/magisk/core/tasks/HideAPK.kt @@ -11,14 +11,14 @@ import com.topjohnwu.magisk.StubApk import com.topjohnwu.magisk.core.Config import com.topjohnwu.magisk.core.Const import com.topjohnwu.magisk.core.Provider +import com.topjohnwu.magisk.core.ktx.await +import com.topjohnwu.magisk.core.ktx.toast +import com.topjohnwu.magisk.core.ktx.writeTo import com.topjohnwu.magisk.core.utils.AXML import com.topjohnwu.magisk.core.utils.Keygen -import com.topjohnwu.magisk.ktx.await -import com.topjohnwu.magisk.ktx.writeTo import com.topjohnwu.magisk.signing.JarMap import com.topjohnwu.magisk.signing.SignApk import com.topjohnwu.magisk.utils.APKInstall -import com.topjohnwu.magisk.utils.Utils import com.topjohnwu.superuser.Shell import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.Runnable @@ -214,7 +214,7 @@ object HideAPK { } val onFailure = Runnable { dialog.dismiss() - Utils.toast(R.string.failure, Toast.LENGTH_LONG) + activity.toast(R.string.failure, Toast.LENGTH_LONG) } val success = withContext(Dispatchers.IO) { patchAndHide(activity, label, onFailure) @@ -232,7 +232,7 @@ object HideAPK { } val onFailure = Runnable { dialog.dismiss() - Utils.toast(R.string.failure, Toast.LENGTH_LONG) + activity.toast(R.string.failure, Toast.LENGTH_LONG) } val apk = StubApk.current(activity) val session = APKInstall.startSession(activity, APPLICATION_ID, onFailure) { diff --git a/app/src/main/java/com/topjohnwu/magisk/core/tasks/MagiskInstaller.kt b/app/src/main/java/com/topjohnwu/magisk/core/tasks/MagiskInstaller.kt index a073978a8..5aaddb935 100644 --- a/app/src/main/java/com/topjohnwu/magisk/core/tasks/MagiskInstaller.kt +++ b/app/src/main/java/com/topjohnwu/magisk/core/tasks/MagiskInstaller.kt @@ -10,15 +10,15 @@ import com.topjohnwu.magisk.R import com.topjohnwu.magisk.StubApk import com.topjohnwu.magisk.core.* import com.topjohnwu.magisk.core.di.ServiceLocator +import com.topjohnwu.magisk.core.ktx.reboot +import com.topjohnwu.magisk.core.ktx.toast +import com.topjohnwu.magisk.core.ktx.withStreams +import com.topjohnwu.magisk.core.ktx.writeTo import com.topjohnwu.magisk.core.utils.MediaStoreUtils import com.topjohnwu.magisk.core.utils.MediaStoreUtils.inputStream import com.topjohnwu.magisk.core.utils.MediaStoreUtils.outputStream import com.topjohnwu.magisk.core.utils.RootUtils -import com.topjohnwu.magisk.ktx.reboot -import com.topjohnwu.magisk.ktx.withStreams -import com.topjohnwu.magisk.ktx.writeTo import com.topjohnwu.magisk.signing.SignBoot -import com.topjohnwu.magisk.utils.Utils import com.topjohnwu.superuser.Shell import com.topjohnwu.superuser.ShellUtils import com.topjohnwu.superuser.internal.NOPList @@ -513,7 +513,7 @@ abstract class MagiskInstaller( override suspend fun exec(): Boolean { val success = super.exec() callback() - Utils.toast( + context.toast( if (success) R.string.reboot_delay_toast else R.string.setup_fail, Toast.LENGTH_LONG ) diff --git a/app/src/main/java/com/topjohnwu/magisk/core/utils/DispatcherExecutor.kt b/app/src/main/java/com/topjohnwu/magisk/core/utils/DispatcherExecutor.kt index 6b2dbbad7..6d2160864 100644 --- a/app/src/main/java/com/topjohnwu/magisk/core/utils/DispatcherExecutor.kt +++ b/app/src/main/java/com/topjohnwu/magisk/core/utils/DispatcherExecutor.kt @@ -1,6 +1,10 @@ package com.topjohnwu.magisk.core.utils -import kotlinx.coroutines.* +import kotlinx.coroutines.CoroutineDispatcher +import kotlinx.coroutines.CoroutineScope +import kotlinx.coroutines.Runnable +import kotlinx.coroutines.SupervisorJob +import kotlinx.coroutines.launch import java.util.concurrent.AbstractExecutorService import java.util.concurrent.CountDownLatch import java.util.concurrent.TimeUnit diff --git a/app/src/main/java/com/topjohnwu/magisk/core/utils/Keygen.kt b/app/src/main/java/com/topjohnwu/magisk/core/utils/Keygen.kt index f4e834815..283a5c5a8 100644 --- a/app/src/main/java/com/topjohnwu/magisk/core/utils/Keygen.kt +++ b/app/src/main/java/com/topjohnwu/magisk/core/utils/Keygen.kt @@ -14,7 +14,9 @@ import java.security.KeyPairGenerator import java.security.KeyStore import java.security.PrivateKey import java.security.cert.X509Certificate -import java.util.* +import java.util.Calendar +import java.util.Locale +import java.util.Random import java.util.zip.GZIPInputStream import java.util.zip.GZIPOutputStream diff --git a/app/src/main/java/com/topjohnwu/magisk/core/utils/NetworkObserver.kt b/app/src/main/java/com/topjohnwu/magisk/core/utils/NetworkObserver.kt index 717549d9b..543903075 100644 --- a/app/src/main/java/com/topjohnwu/magisk/core/utils/NetworkObserver.kt +++ b/app/src/main/java/com/topjohnwu/magisk/core/utils/NetworkObserver.kt @@ -14,7 +14,7 @@ import androidx.core.content.getSystemService import androidx.lifecycle.DefaultLifecycleObserver import androidx.lifecycle.LifecycleOwner import androidx.lifecycle.ProcessLifecycleOwner -import com.topjohnwu.magisk.ktx.registerRuntimeReceiver +import com.topjohnwu.magisk.core.ktx.registerRuntimeReceiver typealias ConnectionCallback = (Boolean) -> Unit diff --git a/app/src/main/java/com/topjohnwu/magisk/core/utils/ShellInit.kt b/app/src/main/java/com/topjohnwu/magisk/core/utils/ShellInit.kt index 25d12fb93..f4c7b630e 100644 --- a/app/src/main/java/com/topjohnwu/magisk/core/utils/ShellInit.kt +++ b/app/src/main/java/com/topjohnwu/magisk/core/utils/ShellInit.kt @@ -7,10 +7,10 @@ import com.topjohnwu.magisk.core.Config import com.topjohnwu.magisk.core.Const import com.topjohnwu.magisk.core.Info import com.topjohnwu.magisk.core.isRunningAsStub -import com.topjohnwu.magisk.ktx.cachedFile -import com.topjohnwu.magisk.ktx.deviceProtectedContext -import com.topjohnwu.magisk.ktx.rawResource -import com.topjohnwu.magisk.ktx.writeTo +import com.topjohnwu.magisk.core.ktx.cachedFile +import com.topjohnwu.magisk.core.ktx.deviceProtectedContext +import com.topjohnwu.magisk.core.ktx.rawResource +import com.topjohnwu.magisk.core.ktx.writeTo import com.topjohnwu.superuser.Shell import com.topjohnwu.superuser.ShellUtils import java.io.File diff --git a/app/src/main/java/com/topjohnwu/magisk/dialog/UninstallDialog.kt b/app/src/main/java/com/topjohnwu/magisk/dialog/UninstallDialog.kt index cd24280cb..1da85a696 100644 --- a/app/src/main/java/com/topjohnwu/magisk/dialog/UninstallDialog.kt +++ b/app/src/main/java/com/topjohnwu/magisk/dialog/UninstallDialog.kt @@ -5,9 +5,9 @@ import android.content.Context import android.widget.Toast import com.topjohnwu.magisk.R import com.topjohnwu.magisk.arch.NavigationActivity +import com.topjohnwu.magisk.core.ktx.toast import com.topjohnwu.magisk.events.DialogBuilder import com.topjohnwu.magisk.ui.flash.FlashFragment -import com.topjohnwu.magisk.utils.Utils import com.topjohnwu.magisk.view.MagiskDialog import com.topjohnwu.superuser.Shell @@ -38,9 +38,9 @@ class UninstallDialog : DialogBuilder { Shell.cmd("restore_imgs").submit { result -> dialog.dismiss() if (result.isSuccess) { - Utils.toast(R.string.restore_done, Toast.LENGTH_SHORT) + context.toast(R.string.restore_done, Toast.LENGTH_SHORT) } else { - Utils.toast(R.string.restore_fail, Toast.LENGTH_LONG) + context.toast(R.string.restore_fail, Toast.LENGTH_LONG) } } } 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 0a81e17c3..16d682574 100644 --- a/app/src/main/java/com/topjohnwu/magisk/ui/MainActivity.kt +++ b/app/src/main/java/com/topjohnwu/magisk/ui/MainActivity.kt @@ -17,6 +17,7 @@ import androidx.navigation.NavDirections import com.topjohnwu.magisk.MainDirections import com.topjohnwu.magisk.R import com.topjohnwu.magisk.arch.BaseViewModel +import com.topjohnwu.magisk.arch.startAnimations import com.topjohnwu.magisk.arch.viewModel import com.topjohnwu.magisk.core.Config import com.topjohnwu.magisk.core.Const @@ -25,9 +26,7 @@ import com.topjohnwu.magisk.core.isRunningAsStub import com.topjohnwu.magisk.core.model.module.LocalModule import com.topjohnwu.magisk.core.tasks.HideAPK import com.topjohnwu.magisk.databinding.ActivityMainMd2Binding -import com.topjohnwu.magisk.ktx.startAnimations import com.topjohnwu.magisk.ui.home.HomeFragmentDirections -import com.topjohnwu.magisk.utils.Utils import com.topjohnwu.magisk.view.MagiskDialog import com.topjohnwu.magisk.view.Shortcuts import kotlinx.coroutines.Dispatchers @@ -103,7 +102,7 @@ class MainActivity : SplashActivity() { // https://issuetracker.google.com/issues/124538620 } binding.mainNavigation.menu.apply { - findItem(R.id.superuserFragment)?.isEnabled = Utils.showSuperUser() + findItem(R.id.superuserFragment)?.isEnabled = Info.showSuperUser findItem(R.id.modulesFragment)?.isEnabled = Info.env.isActive && LocalModule.loaded() } diff --git a/app/src/main/java/com/topjohnwu/magisk/ui/SplashActivity.kt b/app/src/main/java/com/topjohnwu/magisk/ui/SplashActivity.kt index f103cb6ce..ea694f240 100644 --- a/app/src/main/java/com/topjohnwu/magisk/ui/SplashActivity.kt +++ b/app/src/main/java/com/topjohnwu/magisk/ui/SplashActivity.kt @@ -17,10 +17,10 @@ import com.topjohnwu.magisk.core.Const import com.topjohnwu.magisk.core.JobService import com.topjohnwu.magisk.core.di.ServiceLocator import com.topjohnwu.magisk.core.isRunningAsStub +import com.topjohnwu.magisk.core.ktx.toast import com.topjohnwu.magisk.core.tasks.HideAPK import com.topjohnwu.magisk.core.utils.RootUtils import com.topjohnwu.magisk.ui.theme.Theme -import com.topjohnwu.magisk.utils.Utils import com.topjohnwu.magisk.view.MagiskDialog import com.topjohnwu.magisk.view.Shortcuts import com.topjohnwu.superuser.Shell @@ -80,7 +80,7 @@ abstract class SplashActivity : NavigationActivity { diff --git a/app/src/main/java/com/topjohnwu/magisk/ui/settings/BaseSettingsItem.kt b/app/src/main/java/com/topjohnwu/magisk/ui/settings/BaseSettingsItem.kt index ab5a06484..582688bec 100644 --- a/app/src/main/java/com/topjohnwu/magisk/ui/settings/BaseSettingsItem.kt +++ b/app/src/main/java/com/topjohnwu/magisk/ui/settings/BaseSettingsItem.kt @@ -6,9 +6,9 @@ import android.view.View import androidx.databinding.Bindable import com.topjohnwu.magisk.BR import com.topjohnwu.magisk.R +import com.topjohnwu.magisk.core.ktx.activity import com.topjohnwu.magisk.databinding.ObservableRvItem import com.topjohnwu.magisk.databinding.set -import com.topjohnwu.magisk.ktx.activity import com.topjohnwu.magisk.utils.TextHolder import com.topjohnwu.magisk.view.MagiskDialog diff --git a/app/src/main/java/com/topjohnwu/magisk/ui/settings/SettingsItems.kt b/app/src/main/java/com/topjohnwu/magisk/ui/settings/SettingsItems.kt index ef1029190..8cf8ef135 100644 --- a/app/src/main/java/com/topjohnwu/magisk/ui/settings/SettingsItems.kt +++ b/app/src/main/java/com/topjohnwu/magisk/ui/settings/SettingsItems.kt @@ -12,6 +12,7 @@ import com.topjohnwu.magisk.R import com.topjohnwu.magisk.core.Config import com.topjohnwu.magisk.core.Const import com.topjohnwu.magisk.core.Info +import com.topjohnwu.magisk.core.ktx.activity import com.topjohnwu.magisk.core.tasks.HideAPK import com.topjohnwu.magisk.core.utils.BiometricHelper import com.topjohnwu.magisk.core.utils.MediaStoreUtils @@ -21,8 +22,6 @@ import com.topjohnwu.magisk.databinding.DialogSettingsAppNameBinding import com.topjohnwu.magisk.databinding.DialogSettingsDownloadPathBinding import com.topjohnwu.magisk.databinding.DialogSettingsUpdateChannelBinding import com.topjohnwu.magisk.databinding.set -import com.topjohnwu.magisk.ktx.activity -import com.topjohnwu.magisk.utils.Utils import com.topjohnwu.magisk.utils.asText import com.topjohnwu.magisk.view.MagiskDialog import com.topjohnwu.superuser.Shell @@ -357,6 +356,6 @@ object Reauthenticate : BaseSettingsItem.Toggle() { override var value by Config::suReAuth override fun refresh() { - isEnabled = Build.VERSION.SDK_INT < Build.VERSION_CODES.O && Utils.showSuperUser() + isEnabled = Build.VERSION.SDK_INT < Build.VERSION_CODES.O && Info.showSuperUser } } 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 0c6f01488..0f9434e48 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 @@ -13,13 +13,13 @@ import com.topjohnwu.magisk.core.Const import com.topjohnwu.magisk.core.Info import com.topjohnwu.magisk.core.di.AppContext import com.topjohnwu.magisk.core.isRunningAsStub +import com.topjohnwu.magisk.core.ktx.activity +import com.topjohnwu.magisk.core.ktx.toast import com.topjohnwu.magisk.core.tasks.HideAPK import com.topjohnwu.magisk.databinding.bindExtra import com.topjohnwu.magisk.events.AddHomeIconEvent import com.topjohnwu.magisk.events.BiometricEvent import com.topjohnwu.magisk.events.SnackbarEvent -import com.topjohnwu.magisk.ktx.activity -import com.topjohnwu.magisk.utils.Utils import com.topjohnwu.superuser.Shell import kotlinx.coroutines.launch @@ -69,7 +69,7 @@ class SettingsViewModel : BaseViewModel(), BaseSettingsItem.Handler { } // Superuser - if (Utils.showSuperUser()) { + if (Info.showSuperUser) { list.addAll(listOf( Superuser, Tapjack, Biometrics, AccessMode, MultiuserMode, MountNamespaceMode, @@ -128,7 +128,7 @@ class SettingsViewModel : BaseViewModel(), BaseSettingsItem.Handler { private fun createHosts() { Shell.cmd("add_hosts_module").submit { - Utils.toast(R.string.settings_hosts_toast, Toast.LENGTH_SHORT) + AppContext.toast(R.string.settings_hosts_toast, Toast.LENGTH_SHORT) } } } diff --git a/app/src/main/java/com/topjohnwu/magisk/ui/superuser/SuperuserViewModel.kt b/app/src/main/java/com/topjohnwu/magisk/ui/superuser/SuperuserViewModel.kt index 46ae5cdc7..68697e26c 100644 --- a/app/src/main/java/com/topjohnwu/magisk/ui/superuser/SuperuserViewModel.kt +++ b/app/src/main/java/com/topjohnwu/magisk/ui/superuser/SuperuserViewModel.kt @@ -10,8 +10,10 @@ import androidx.lifecycle.viewModelScope import com.topjohnwu.magisk.BR import com.topjohnwu.magisk.R import com.topjohnwu.magisk.arch.AsyncLoadViewModel +import com.topjohnwu.magisk.core.Info import com.topjohnwu.magisk.core.data.magiskdb.PolicyDao import com.topjohnwu.magisk.core.di.AppContext +import com.topjohnwu.magisk.core.ktx.getLabel import com.topjohnwu.magisk.core.model.su.SuPolicy import com.topjohnwu.magisk.core.utils.BiometricHelper import com.topjohnwu.magisk.core.utils.currentLocale @@ -19,8 +21,6 @@ import com.topjohnwu.magisk.databinding.* import com.topjohnwu.magisk.dialog.SuperuserRevokeDialog import com.topjohnwu.magisk.events.BiometricEvent import com.topjohnwu.magisk.events.SnackbarEvent -import com.topjohnwu.magisk.ktx.getLabel -import com.topjohnwu.magisk.utils.Utils import com.topjohnwu.magisk.utils.asText import com.topjohnwu.magisk.view.TextItem import kotlinx.coroutines.Dispatchers @@ -49,7 +49,7 @@ class SuperuserViewModel( @SuppressLint("InlinedApi") override suspend fun doLoadWork() { - if (!Utils.showSuperUser()) { + if (!Info.showSuperUser) { loading = false return } diff --git a/app/src/main/java/com/topjohnwu/magisk/ui/surequest/SuRequestViewModel.kt b/app/src/main/java/com/topjohnwu/magisk/ui/surequest/SuRequestViewModel.kt index 4f74d3845..fd4103208 100644 --- a/app/src/main/java/com/topjohnwu/magisk/ui/surequest/SuRequestViewModel.kt +++ b/app/src/main/java/com/topjohnwu/magisk/ui/surequest/SuRequestViewModel.kt @@ -22,6 +22,8 @@ import com.topjohnwu.magisk.arch.BaseViewModel import com.topjohnwu.magisk.core.Config import com.topjohnwu.magisk.core.data.magiskdb.PolicyDao import com.topjohnwu.magisk.core.di.AppContext +import com.topjohnwu.magisk.core.ktx.getLabel +import com.topjohnwu.magisk.core.ktx.toast import com.topjohnwu.magisk.core.model.su.SuPolicy.Companion.ALLOW import com.topjohnwu.magisk.core.model.su.SuPolicy.Companion.DENY import com.topjohnwu.magisk.core.su.SuRequestHandler @@ -30,9 +32,7 @@ import com.topjohnwu.magisk.databinding.set import com.topjohnwu.magisk.events.BiometricEvent import com.topjohnwu.magisk.events.DieEvent import com.topjohnwu.magisk.events.ShowUIEvent -import com.topjohnwu.magisk.ktx.getLabel import com.topjohnwu.magisk.utils.TextHolder -import com.topjohnwu.magisk.utils.Utils import kotlinx.coroutines.launch import java.util.concurrent.TimeUnit.SECONDS @@ -62,7 +62,7 @@ class SuRequestViewModel( if (event.flags and MotionEvent.FLAG_WINDOW_IS_OBSCURED != 0 || event.flags and MotionEvent.FLAG_WINDOW_IS_PARTIALLY_OBSCURED != 0) { if (event.action == MotionEvent.ACTION_UP) { - Utils.toast(R.string.touch_filtered_warning, Toast.LENGTH_SHORT) + AppContext.toast(R.string.touch_filtered_warning, Toast.LENGTH_SHORT) } return@OnTouchListener Config.suTapjack } diff --git a/app/src/main/java/com/topjohnwu/magisk/utils/Utils.kt b/app/src/main/java/com/topjohnwu/magisk/utils/Utils.kt deleted file mode 100644 index 6b72afcde..000000000 --- a/app/src/main/java/com/topjohnwu/magisk/utils/Utils.kt +++ /dev/null @@ -1,39 +0,0 @@ -package com.topjohnwu.magisk.utils - -import android.content.ActivityNotFoundException -import android.content.Context -import android.content.Intent -import android.net.Uri -import android.widget.Toast -import com.topjohnwu.magisk.R -import com.topjohnwu.magisk.core.Config -import com.topjohnwu.magisk.core.Const -import com.topjohnwu.magisk.core.Info -import com.topjohnwu.magisk.core.di.AppContext -import com.topjohnwu.superuser.internal.UiThreadHandler - -object Utils { - - fun toast(msg: CharSequence, duration: Int) { - UiThreadHandler.run { Toast.makeText(AppContext, msg, duration).show() } - } - - fun toast(resId: Int, duration: Int) { - UiThreadHandler.run { Toast.makeText(AppContext, resId, duration).show() } - } - - fun showSuperUser(): Boolean { - return Info.env.isActive && (Const.USER_ID == 0 - || Config.suMultiuserMode == Config.Value.MULTIUSER_MODE_USER) - } - - fun openLink(context: Context, link: Uri) { - val intent = Intent(Intent.ACTION_VIEW, link) - intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK) - try { - context.startActivity(intent) - } catch (e: ActivityNotFoundException) { - toast(R.string.open_link_failed_toast, Toast.LENGTH_SHORT) - } - } -} diff --git a/app/src/main/java/com/topjohnwu/magisk/view/Notifications.kt b/app/src/main/java/com/topjohnwu/magisk/view/Notifications.kt index 512ea4088..229139e6a 100644 --- a/app/src/main/java/com/topjohnwu/magisk/view/Notifications.kt +++ b/app/src/main/java/com/topjohnwu/magisk/view/Notifications.kt @@ -13,8 +13,8 @@ import com.topjohnwu.magisk.R import com.topjohnwu.magisk.core.di.AppContext import com.topjohnwu.magisk.core.download.DownloadService import com.topjohnwu.magisk.core.download.Subject -import com.topjohnwu.magisk.ktx.getBitmap -import com.topjohnwu.magisk.ktx.selfLaunchIntent +import com.topjohnwu.magisk.core.ktx.getBitmap +import com.topjohnwu.magisk.core.ktx.selfLaunchIntent import java.util.concurrent.atomic.AtomicInteger @Suppress("DEPRECATION") diff --git a/app/src/main/java/com/topjohnwu/magisk/view/Shortcuts.kt b/app/src/main/java/com/topjohnwu/magisk/view/Shortcuts.kt index 029edc304..718d4ebc8 100644 --- a/app/src/main/java/com/topjohnwu/magisk/view/Shortcuts.kt +++ b/app/src/main/java/com/topjohnwu/magisk/view/Shortcuts.kt @@ -13,8 +13,7 @@ import androidx.core.graphics.drawable.IconCompat import com.topjohnwu.magisk.R import com.topjohnwu.magisk.core.Const import com.topjohnwu.magisk.core.Info -import com.topjohnwu.magisk.ktx.getBitmap -import com.topjohnwu.magisk.utils.Utils +import com.topjohnwu.magisk.core.ktx.getBitmap object Shortcuts { @@ -51,7 +50,7 @@ object Shortcuts { val shortCuts = mutableListOf() - if (Utils.showSuperUser()) { + if (Info.showSuperUser) { shortCuts.add( ShortcutInfo.Builder(context, Const.Nav.SUPERUSER) .setShortLabel(context.getString(R.string.superuser))