diff --git a/app/shared/src/main/AndroidManifest.xml b/app/shared/src/main/AndroidManifest.xml index 2d2f9323b..9d351b52f 100644 --- a/app/shared/src/main/AndroidManifest.xml +++ b/app/shared/src/main/AndroidManifest.xml @@ -9,6 +9,7 @@ + = Build.VERSION_CODES.O) { + // noinspection InlinedApi + context.registerReceiver(receiver, filter, Context.RECEIVER_NOT_EXPORTED); + } else { + context.registerReceiver(receiver, filter); + } + } + public static Session startSession(Context context) { return startSession(context, null, null, null); } @@ -51,9 +61,9 @@ public final class APKInstall { // If pkg is not null, look for package added event var filter = new IntentFilter(Intent.ACTION_PACKAGE_ADDED); filter.addDataScheme("package"); - context.registerReceiver(receiver, filter); + registerReceiver(context, receiver, filter); } - context.registerReceiver(receiver, new IntentFilter(receiver.sessionId)); + registerReceiver(context, receiver, new IntentFilter(receiver.sessionId)); return receiver; } diff --git a/app/src/main/java/com/topjohnwu/magisk/arch/BaseViewModel.kt b/app/src/main/java/com/topjohnwu/magisk/arch/BaseViewModel.kt index 20c5da318..b55445e7f 100644 --- a/app/src/main/java/com/topjohnwu/magisk/arch/BaseViewModel.kt +++ b/app/src/main/java/com/topjohnwu/magisk/arch/BaseViewModel.kt @@ -1,7 +1,6 @@ package com.topjohnwu.magisk.arch -import android.Manifest.permission.REQUEST_INSTALL_PACKAGES -import android.Manifest.permission.WRITE_EXTERNAL_STORAGE +import android.Manifest.permission.* import android.annotation.SuppressLint import android.os.Bundle import androidx.databinding.PropertyChangeRegistry @@ -53,6 +52,17 @@ abstract class BaseViewModel : ViewModel(), ObservableHost { } } + @SuppressLint("InlinedApi") + inline fun withPostNotificationPermission(crossinline callback: () -> Unit) { + withPermission(POST_NOTIFICATIONS) { + if (!it) { + SnackbarEvent(R.string.post_notifications_denied).publish() + } else { + callback() + } + } + } + fun back() = BackPressEvent().publish() fun Event.publish() { 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 400582813..78ef64ce4 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 @@ -1,7 +1,6 @@ package com.topjohnwu.magisk.core.base -import android.Manifest.permission.REQUEST_INSTALL_PACKAGES -import android.Manifest.permission.WRITE_EXTERNAL_STORAGE +import android.Manifest.permission.* import android.app.Activity import android.content.ActivityNotFoundException import android.content.Context @@ -82,12 +81,18 @@ abstract class BaseActivity : AppCompatActivity() { } fun withPermission(permission: String, callback: (Boolean) -> Unit) { - if (permission == WRITE_EXTERNAL_STORAGE && - Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) { + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R && + permission == WRITE_EXTERNAL_STORAGE) { // We do not need external rw on R+ callback(true) return } + if (Build.VERSION.SDK_INT < Build.VERSION_CODES.TIRAMISU && + permission == POST_NOTIFICATIONS) { + // All apps have notification permissions before T + callback(true) + return + } permissionCallback = callback if (permission == REQUEST_INSTALL_PACKAGES) { requestInstall.launch(Unit) 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 e8bfd65cb..89951f531 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 @@ -1,5 +1,6 @@ package com.topjohnwu.magisk.core.download +import android.Manifest import android.annotation.SuppressLint import android.app.PendingIntent import android.app.PendingIntent.* @@ -13,17 +14,14 @@ import com.topjohnwu.magisk.R import com.topjohnwu.magisk.StubApk import com.topjohnwu.magisk.core.ActivityTracker 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.tasks.HideAPK import com.topjohnwu.magisk.core.utils.MediaStoreUtils import com.topjohnwu.magisk.core.utils.MediaStoreUtils.outputStream -import com.topjohnwu.magisk.ktx.copyAndClose -import com.topjohnwu.magisk.ktx.forEach -import com.topjohnwu.magisk.ktx.withStreams -import com.topjohnwu.magisk.ktx.writeTo +import com.topjohnwu.magisk.ktx.* import com.topjohnwu.magisk.utils.APKInstall -import com.topjohnwu.magisk.view.Notifications import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.Job @@ -51,7 +49,7 @@ class DownloadService : NotificationService() { } private fun download(subject: Subject) { - update(subject.notifyId) + notifyUpdate(subject.notifyId) val coroutineScope = CoroutineScope(job + Dispatchers.IO) coroutineScope.launch { try { @@ -62,7 +60,7 @@ class DownloadService : NotificationService() { } val activity = ActivityTracker.foreground if (activity != null && subject.autoLaunch) { - remove(subject.notifyId) + notifyRemove(subject.notifyId) subject.pendingIntent(activity)?.send() } else { notifyFinish(subject) @@ -92,7 +90,7 @@ class DownloadService : NotificationService() { if (Info.stub!!.version < subject.stub.versionCode) { // Also upgrade stub - update(subject.notifyId) { + notifyUpdate(subject.notifyId) { it.setProgress(0, 0, true) .setContentTitle(getString(R.string.hide_app_title)) .setContentText("") @@ -118,7 +116,7 @@ class DownloadService : NotificationService() { StubApk.restartProcess(it) } ?: run { // Or else kill the current process after posting notification - subject.intent = Notifications.selfLaunchIntent(this) + subject.intent = selfLaunchIntent() subject.postDownload = { Runtime.getRuntime().exit(0) } } return @@ -206,12 +204,16 @@ class DownloadService : NotificationService() { } } - fun start(context: Context, subject: Subject) { - val app = context.applicationContext - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { - app.startForegroundService(intent(app, subject)) - } else { - app.startService(intent(app, subject)) + @SuppressLint("InlinedApi") + fun start(activity: BaseActivity, subject: Subject) { + activity.withPermission(Manifest.permission.POST_NOTIFICATIONS) { + // Always download regardless of notification permission status + val app = activity.applicationContext + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { + app.startForegroundService(intent(app, subject)) + } else { + app.startService(intent(app, subject)) + } } } } 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 e163f74cf..35a74d359 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 @@ -2,6 +2,7 @@ package com.topjohnwu.magisk.core.download import android.app.Notification import android.content.Intent +import android.os.Build import androidx.lifecycle.MutableLiveData import com.topjohnwu.magisk.R import com.topjohnwu.magisk.core.base.BaseService @@ -30,11 +31,11 @@ open class NotificationService : BaseService() { val total = max.toFloat() / 1048576 val id = subject.notifyId - update(id) { it.setContentTitle(subject.title) } + notifyUpdate(id) { it.setContentTitle(subject.title) } return ProgressInputStream(byteStream()) { val progress = it.toFloat() / 1048576 - update(id) { notification -> + notifyUpdate(id) { notification -> if (max > 0) { broadcast(progress / total, subject) notification @@ -49,7 +50,7 @@ open class NotificationService : BaseService() { } private fun finalNotify(id: Int, editor: (Notification.Builder) -> Unit): Int { - val notification = remove(id)?.also(editor) ?: return -1 + val notification = notifyRemove(id)?.also(editor) ?: return -1 val newId = Notifications.nextId() Notifications.mgr.notify(newId, notification.build()) return newId @@ -73,28 +74,31 @@ open class NotificationService : BaseService() { subject.pendingIntent(this)?.let { intent -> it.setContentIntent(intent) } } - private fun create() = Notifications.progress(this, "") - - private fun updateForeground() { + private fun updateForegroundState() { if (hasNotifications) { val (id, notification) = notifications.entries.first() startForeground(id, notification.build()) + } else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { + stopForeground(STOP_FOREGROUND_DETACH) } else { + @Suppress("DEPRECATION") stopForeground(false) } } - protected fun update(id: Int, editor: (Notification.Builder) -> Unit = {}) { + protected fun notifyUpdate(id: Int, editor: (Notification.Builder) -> Unit = {}) { + fun create() = Notifications.startProgress(this, "") + val wasEmpty = !hasNotifications val notification = notifications.getOrPut(id, ::create).also(editor) if (wasEmpty) - updateForeground() + updateForegroundState() else Notifications.mgr.notify(id, notification.build()) } - protected fun remove(id: Int): Notification.Builder? { - val n = notifications.remove(id)?.also { updateForeground() } + protected fun notifyRemove(id: Int): Notification.Builder? { + val n = notifications.remove(id)?.also { updateForegroundState() } Notifications.mgr.cancel(id) return n } diff --git a/app/src/main/java/com/topjohnwu/magisk/core/utils/net/MarshmallowNetworkObserver.kt b/app/src/main/java/com/topjohnwu/magisk/core/utils/net/MarshmallowNetworkObserver.kt index d688ba3bf..8f6eebab1 100644 --- a/app/src/main/java/com/topjohnwu/magisk/core/utils/net/MarshmallowNetworkObserver.kt +++ b/app/src/main/java/com/topjohnwu/magisk/core/utils/net/MarshmallowNetworkObserver.kt @@ -10,6 +10,7 @@ import android.content.IntentFilter import android.net.NetworkCapabilities import android.os.PowerManager import androidx.core.content.getSystemService +import com.topjohnwu.magisk.ktx.registerRuntimeReceiver @TargetApi(23) class MarshmallowNetworkObserver( @@ -21,7 +22,7 @@ class MarshmallowNetworkObserver( init { val filter = IntentFilter(PowerManager.ACTION_DEVICE_IDLE_MODE_CHANGED) - app.registerReceiver(receiver, filter) + app.registerRuntimeReceiver(receiver, filter) } override fun stopObserving() { diff --git a/app/src/main/java/com/topjohnwu/magisk/events/dialog/DialogEvent.kt b/app/src/main/java/com/topjohnwu/magisk/events/dialog/DialogEvent.kt index 1ad528d4d..9407abaa6 100644 --- a/app/src/main/java/com/topjohnwu/magisk/events/dialog/DialogEvent.kt +++ b/app/src/main/java/com/topjohnwu/magisk/events/dialog/DialogEvent.kt @@ -8,9 +8,7 @@ import com.topjohnwu.magisk.view.MagiskDialog abstract class DialogEvent : ViewEvent(), ActivityExecutor { override fun invoke(activity: UIActivity<*>) { - MagiskDialog(activity) - .apply { setOwnerActivity(activity) } - .apply(this::build).show() + MagiskDialog(activity).apply(this::build).show() } abstract fun build(dialog: MagiskDialog) diff --git a/app/src/main/java/com/topjohnwu/magisk/events/dialog/ManagerInstallDialog.kt b/app/src/main/java/com/topjohnwu/magisk/events/dialog/ManagerInstallDialog.kt index e40f32af5..480a666ab 100644 --- a/app/src/main/java/com/topjohnwu/magisk/events/dialog/ManagerInstallDialog.kt +++ b/app/src/main/java/com/topjohnwu/magisk/events/dialog/ManagerInstallDialog.kt @@ -29,7 +29,7 @@ class ManagerInstallDialog : MarkDownDialog() { setCancelable(true) setButton(MagiskDialog.ButtonType.POSITIVE) { text = R.string.install - onClick { DownloadService.start(context, Subject.App()) } + onClick { DownloadService.start(activity, Subject.App()) } } setButton(MagiskDialog.ButtonType.NEGATIVE) { text = android.R.string.cancel diff --git a/app/src/main/java/com/topjohnwu/magisk/events/dialog/MarkDownDialog.kt b/app/src/main/java/com/topjohnwu/magisk/events/dialog/MarkDownDialog.kt index 0b8efa1dd..7c572a969 100644 --- a/app/src/main/java/com/topjohnwu/magisk/events/dialog/MarkDownDialog.kt +++ b/app/src/main/java/com/topjohnwu/magisk/events/dialog/MarkDownDialog.kt @@ -5,7 +5,6 @@ import android.widget.TextView import androidx.annotation.CallSuper import androidx.lifecycle.lifecycleScope import com.topjohnwu.magisk.R -import com.topjohnwu.magisk.core.base.BaseActivity import com.topjohnwu.magisk.core.di.ServiceLocator import com.topjohnwu.magisk.view.MagiskDialog import kotlinx.coroutines.Dispatchers @@ -24,7 +23,7 @@ abstract class MarkDownDialog : DialogEvent() { val view = LayoutInflater.from(context).inflate(R.layout.markdown_window_md2, null) setView(view) val tv = view.findViewById(R.id.md_txt) - (ownerActivity as BaseActivity).lifecycleScope.launch { + activity.lifecycleScope.launch { try { val text = withContext(Dispatchers.IO) { getMarkdownText() } ServiceLocator.markwon.setMarkdown(tv, text) diff --git a/app/src/main/java/com/topjohnwu/magisk/events/dialog/ModuleInstallDialog.kt b/app/src/main/java/com/topjohnwu/magisk/events/dialog/ModuleInstallDialog.kt index 37134847f..88700627b 100644 --- a/app/src/main/java/com/topjohnwu/magisk/events/dialog/ModuleInstallDialog.kt +++ b/app/src/main/java/com/topjohnwu/magisk/events/dialog/ModuleInstallDialog.kt @@ -24,7 +24,7 @@ class ModuleInstallDialog(private val item: OnlineModule) : MarkDownDialog() { fun download(install: Boolean) { val action = if (install) Action.Flash else Action.Download val subject = Subject.Module(item, action) - DownloadService.start(context, subject) + DownloadService.start(activity, subject) } val title = context.getString(R.string.repo_install_title, 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 a722ff9b2..494a323ac 100644 --- a/app/src/main/java/com/topjohnwu/magisk/ktx/XAndroid.kt +++ b/app/src/main/java/com/topjohnwu/magisk/ktx/XAndroid.kt @@ -2,10 +2,7 @@ package com.topjohnwu.magisk.ktx import android.annotation.SuppressLint import android.app.Activity -import android.content.ComponentName -import android.content.Context -import android.content.ContextWrapper -import android.content.Intent +import android.content.* import android.content.pm.ApplicationInfo import android.content.pm.PackageInfo import android.content.pm.PackageManager @@ -33,6 +30,7 @@ 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 java.io.File import kotlin.Array @@ -266,3 +264,14 @@ fun PackageManager.getPackageInfo(uid: Int, pid: Int): PackageInfo? { } throw PackageManager.NameNotFoundException() } + +fun Context.registerRuntimeReceiver(receiver: BroadcastReceiver, filter: IntentFilter) { + APKInstall.registerReceiver(this, receiver, filter) +} + +fun Context.selfLaunchIntent(): Intent { + val pm = packageManager + val intent = pm.getLaunchIntentForPackage(packageName)!! + intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TASK) + return intent +} 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 0c7e64024..6dd1de199 100644 --- a/app/src/main/java/com/topjohnwu/magisk/ui/MainActivity.kt +++ b/app/src/main/java/com/topjohnwu/magisk/ui/MainActivity.kt @@ -1,5 +1,7 @@ package com.topjohnwu.magisk.ui +import android.Manifest +import android.annotation.SuppressLint import android.content.Intent import android.content.pm.ApplicationInfo import android.os.Bundle @@ -52,11 +54,19 @@ class MainActivity : SplashActivity() { private var isRootFragment = true + @SuppressLint("InlinedApi") override fun showMainUI(savedInstanceState: Bundle?) { setContentView() showUnsupportedMessage() askForHomeShortcut() + // Ask permission to post notifications for background update check + if (Config.checkUpdate) { + withPermission(Manifest.permission.POST_NOTIFICATIONS) { + Config.checkUpdate = it + } + } + window.setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE) navigation.addOnDestinationChangedListener { _, destination, _ -> 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 7cdbb9cbf..ab5a06484 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 @@ -8,6 +8,7 @@ import com.topjohnwu.magisk.BR import com.topjohnwu.magisk.R 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 @@ -57,6 +58,8 @@ sealed class BaseSettingsItem : ObservableRvItem() { set(checked, value, { onPressed(view, handler) }) override fun onPressed(view: View, handler: Handler) { + // Make sure the checked state is synced + notifyPropertyChanged(BR.checked) handler.onItemPressed(view, this) { value = !value notifyPropertyChanged(BR.checked) @@ -72,7 +75,7 @@ sealed class BaseSettingsItem : ObservableRvItem() { override fun onPressed(view: View, handler: Handler) { handler.onItemPressed(view, this) { - MagiskDialog(view.context).apply { + MagiskDialog(view.activity).apply { setTitle(title.getText(view.resources)) setView(getView(view.context)) setButton(MagiskDialog.ButtonType.POSITIVE) { @@ -115,7 +118,7 @@ sealed class BaseSettingsItem : ObservableRvItem() { override fun onPressed(view: View, handler: Handler) { handler.onItemPressed(view, this) { - MagiskDialog(view.context).apply { + MagiskDialog(view.activity).apply { setTitle(title.getText(view.resources)) setButton(MagiskDialog.ButtonType.NEGATIVE) { text = android.R.string.cancel 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 daf9ca5d9..7d3886790 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 @@ -23,6 +23,7 @@ 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 @@ -111,7 +112,7 @@ object Restore : BaseSettingsItem.Blank() { override fun onPressed(view: View, handler: Handler) { handler.onItemPressed(view, this) { - MagiskDialog(view.context).apply { + MagiskDialog(view.activity).apply { setTitle(R.string.settings_restore_app_title) setMessage(R.string.restore_app_confirmation) setButton(MagiskDialog.ButtonType.POSITIVE) { 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 d58378e46..0cf6c1377 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 @@ -96,6 +96,7 @@ class SettingsViewModel : BaseViewModel(), BaseSettingsItem.Handler { override fun onItemPressed(view: View, item: BaseSettingsItem, andThen: () -> Unit) { when (item) { DownloadPath -> withExternalRW(andThen) + UpdateChecker -> withPostNotificationPermission(andThen) Biometrics -> authenticate(andThen) Theme -> SettingsFragmentDirections.actionSettingsFragmentToThemeFragment().navigate() DenyListConfig -> SettingsFragmentDirections.actionSettingsFragmentToDenyFragment().navigate() diff --git a/app/src/main/java/com/topjohnwu/magisk/view/MagiskDialog.kt b/app/src/main/java/com/topjohnwu/magisk/view/MagiskDialog.kt index 0d3392ef9..fafebb7e8 100644 --- a/app/src/main/java/com/topjohnwu/magisk/view/MagiskDialog.kt +++ b/app/src/main/java/com/topjohnwu/magisk/view/MagiskDialog.kt @@ -1,6 +1,6 @@ package com.topjohnwu.magisk.view -import android.content.Context +import android.app.Activity import android.content.DialogInterface import android.content.res.ColorStateList import android.graphics.drawable.Drawable @@ -21,22 +21,26 @@ import com.google.android.material.color.MaterialColors import com.google.android.material.shape.MaterialShapeDrawable import com.topjohnwu.magisk.BR import com.topjohnwu.magisk.R +import com.topjohnwu.magisk.core.base.BaseActivity import com.topjohnwu.magisk.databinding.* import com.topjohnwu.magisk.view.MagiskDialog.DialogClickListener typealias DialogButtonClickListener = (DialogInterface) -> Unit class MagiskDialog( - context: Context, theme: Int = 0 + context: Activity, theme: Int = 0 ) : AppCompatDialog(context, theme) { private val binding: DialogMagiskBaseBinding = DialogMagiskBaseBinding.inflate(LayoutInflater.from(context)) private val data = Data() + val activity: BaseActivity get() = ownerActivity as BaseActivity + init { binding.setVariable(BR.data, data) setCancelable(true) + setOwnerActivity(context) } inner class Data : ObservableHost { 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 9e3063251..d836be853 100644 --- a/app/src/main/java/com/topjohnwu/magisk/view/Notifications.kt +++ b/app/src/main/java/com/topjohnwu/magisk/view/Notifications.kt @@ -6,7 +6,6 @@ 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 android.os.Build.VERSION.SDK_INT import androidx.core.content.getSystemService @@ -16,6 +15,7 @@ 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 java.util.concurrent.atomic.AtomicInteger @Suppress("DEPRECATION") @@ -44,18 +44,10 @@ object Notifications { } } - fun selfLaunchIntent(context: Context): Intent { - val pm = context.packageManager - val intent = pm.getLaunchIntentForPackage(context.packageName)!! - intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TASK) - return intent - } - @SuppressLint("InlinedApi") fun updateDone(context: Context) { - setup(context) val flag = PendingIntent.FLAG_IMMUTABLE or PendingIntent.FLAG_UPDATE_CURRENT - val pending = PendingIntent.getActivity(context, 0, selfLaunchIntent(context), flag) + val pending = PendingIntent.getActivity(context, 0, context.selfLaunchIntent(), flag) val builder = if (SDK_INT >= Build.VERSION_CODES.O) { Notification.Builder(context, UPDATED_CHANNEL) .setSmallIcon(context.getBitmap(R.drawable.ic_magisk_outline).toIcon()) @@ -72,7 +64,6 @@ object Notifications { fun updateAvailable(context: Context) { val intent = DownloadService.getPendingIntent(context, Subject.App()) - val bitmap = context.getBitmap(R.drawable.ic_magisk_outline) val builder = if (SDK_INT >= Build.VERSION_CODES.O) { Notification.Builder(context, UPDATE_CHANNEL) @@ -90,7 +81,7 @@ object Notifications { mgr.notify(APP_UPDATE_NOTIFICATION_ID, builder.build()) } - fun progress(context: Context, title: CharSequence): Notification.Builder { + fun startProgress(context: Context, title: CharSequence): Notification.Builder { val builder = if (SDK_INT >= Build.VERSION_CODES.O) { Notification.Builder(context, PROGRESS_CHANNEL) } else { diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index e2e3471aa..26d912099 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -230,6 +230,7 @@ The hidden Magisk app cannot continue to work because root was lost. Please restore the original APK. @string/settings_restore_app_title Grant storage permission to enable this functionality + Grant notifications permission to enable this functionality Allow "install unknown apps" to enable this functionality Add shortcut to home screen After hiding this app, its name and icon might become difficult to recognize. Do you want to add a pretty shortcut to the home screen? diff --git a/buildSrc/src/main/java/Setup.kt b/buildSrc/src/main/java/Setup.kt index 5276e1840..f2fbd7ebd 100644 --- a/buildSrc/src/main/java/Setup.kt +++ b/buildSrc/src/main/java/Setup.kt @@ -43,13 +43,13 @@ private val Project.android: BaseAppModuleExtension fun Project.setupCommon() { androidBase { - compileSdkVersion(32) + compileSdkVersion(33) buildToolsVersion = "32.0.0" ndkPath = "$sdkDirectory/ndk/magisk" defaultConfig { minSdk = 21 - targetSdk = 32 + targetSdk = 33 } compileOptions {