mirror of
https://github.com/topjohnwu/Magisk.git
synced 2024-12-24 18:57:37 +00:00
Better stub launch flow
This commit is contained in:
parent
fa60daf9b5
commit
317153c53a
@ -27,8 +27,7 @@ abstract class UIActivity<Binding : ViewDataBinding> : BaseActivity(), ViewModel
|
||||
open val snackbarAnchorView: View? get() = null
|
||||
|
||||
init {
|
||||
val theme = Config.darkTheme
|
||||
AppCompatDelegate.setDefaultNightMode(theme)
|
||||
AppCompatDelegate.setDefaultNightMode(Config.darkTheme)
|
||||
}
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
|
@ -2,6 +2,7 @@ package com.topjohnwu.magisk.core.base
|
||||
|
||||
import android.Manifest.permission.REQUEST_INSTALL_PACKAGES
|
||||
import android.Manifest.permission.WRITE_EXTERNAL_STORAGE
|
||||
import android.app.Activity
|
||||
import android.content.ActivityNotFoundException
|
||||
import android.content.Context
|
||||
import android.content.Intent
|
||||
@ -54,6 +55,18 @@ abstract class BaseActivity : AppCompatActivity() {
|
||||
uninstallLatch.countDown()
|
||||
}
|
||||
|
||||
private val mReferrerField by lazy(LazyThreadSafetyMode.NONE) {
|
||||
Activity::class.java.reflectField("mReferrer")
|
||||
}
|
||||
|
||||
val realCallingPackage: String? get() {
|
||||
callingPackage?.let { return it }
|
||||
if (Build.VERSION.SDK_INT >= 22) {
|
||||
mReferrerField.get(this)?.let { return it as String }
|
||||
}
|
||||
return null
|
||||
}
|
||||
|
||||
override fun attachBaseContext(base: Context) {
|
||||
super.attachBaseContext(base.wrap())
|
||||
}
|
||||
|
@ -99,8 +99,7 @@ object HideAPK {
|
||||
val flag = Intent.FLAG_GRANT_READ_URI_PERMISSION
|
||||
activity.grantUriPermission(pkg, Provider.preferencesUri(self), flag)
|
||||
intent.putExtra(Const.Key.PREV_PKG, self)
|
||||
intent.flags = 0
|
||||
activity.startActivityForResult(intent, Int.MAX_VALUE)
|
||||
activity.startActivity(intent)
|
||||
activity.finish()
|
||||
}
|
||||
|
||||
|
@ -3,6 +3,7 @@ package com.topjohnwu.magisk.events.dialog
|
||||
import android.app.Activity
|
||||
import androidx.appcompat.app.AppCompatDelegate
|
||||
import com.topjohnwu.magisk.R
|
||||
import com.topjohnwu.magisk.arch.UIActivity
|
||||
import com.topjohnwu.magisk.core.Config
|
||||
import com.topjohnwu.magisk.view.MagiskDialog
|
||||
|
||||
@ -33,6 +34,6 @@ class DarkThemeDialog : DialogEvent() {
|
||||
|
||||
private fun selectTheme(mode: Int, activity: Activity) {
|
||||
Config.darkTheme = mode
|
||||
activity.recreate()
|
||||
(activity as UIActivity<*>).delegate.localNightMode = mode
|
||||
}
|
||||
}
|
||||
|
@ -13,7 +13,6 @@ import androidx.core.view.isVisible
|
||||
import androidx.navigation.NavDirections
|
||||
import com.topjohnwu.magisk.MainDirections
|
||||
import com.topjohnwu.magisk.R
|
||||
import com.topjohnwu.magisk.arch.BaseMainActivity
|
||||
import com.topjohnwu.magisk.arch.BaseViewModel
|
||||
import com.topjohnwu.magisk.arch.viewModel
|
||||
import com.topjohnwu.magisk.core.Config
|
||||
@ -31,7 +30,7 @@ import java.io.File
|
||||
|
||||
class MainViewModel : BaseViewModel()
|
||||
|
||||
class MainActivity : BaseMainActivity<ActivityMainMd2Binding>() {
|
||||
class MainActivity : SplashActivity<ActivityMainMd2Binding>() {
|
||||
|
||||
override val layoutRes = R.layout.activity_main_md2
|
||||
override val viewModel by viewModel<MainViewModel>()
|
||||
|
@ -1,4 +1,4 @@
|
||||
package com.topjohnwu.magisk.arch
|
||||
package com.topjohnwu.magisk.ui
|
||||
|
||||
import android.Manifest.permission.REQUEST_INSTALL_PACKAGES
|
||||
import android.annotation.SuppressLint
|
||||
@ -9,7 +9,7 @@ import androidx.databinding.ViewDataBinding
|
||||
import androidx.lifecycle.lifecycleScope
|
||||
import com.topjohnwu.magisk.BuildConfig.APPLICATION_ID
|
||||
import com.topjohnwu.magisk.R
|
||||
import com.topjohnwu.magisk.StubApk
|
||||
import com.topjohnwu.magisk.arch.NavigationActivity
|
||||
import com.topjohnwu.magisk.core.Config
|
||||
import com.topjohnwu.magisk.core.Const
|
||||
import com.topjohnwu.magisk.core.JobService
|
||||
@ -25,16 +25,17 @@ import com.topjohnwu.magisk.view.Shortcuts
|
||||
import com.topjohnwu.superuser.Shell
|
||||
import kotlinx.coroutines.launch
|
||||
|
||||
abstract class BaseMainActivity<Binding : ViewDataBinding> : NavigationActivity<Binding>() {
|
||||
@SuppressLint("CustomSplashScreen")
|
||||
abstract class SplashActivity<Binding : ViewDataBinding> : NavigationActivity<Binding>() {
|
||||
|
||||
companion object {
|
||||
private var doPreload = true
|
||||
private var skipSplash = false
|
||||
}
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
setTheme(Theme.selected.themeRes)
|
||||
|
||||
if (isRunningAsStub && doPreload) {
|
||||
if (isRunningAsStub && !skipSplash) {
|
||||
// Manually apply splash theme for stub
|
||||
theme.applyStyle(R.style.StubSplashTheme, true)
|
||||
}
|
||||
@ -43,28 +44,19 @@ abstract class BaseMainActivity<Binding : ViewDataBinding> : NavigationActivity<
|
||||
|
||||
if (!isRunningAsStub) {
|
||||
val splashScreen = installSplashScreen()
|
||||
splashScreen.setKeepOnScreenCondition { doPreload }
|
||||
splashScreen.setKeepOnScreenCondition { !skipSplash }
|
||||
}
|
||||
|
||||
if (doPreload) {
|
||||
if (skipSplash) {
|
||||
showMainUI(savedInstanceState)
|
||||
} else {
|
||||
Shell.getShell(Shell.EXECUTOR) {
|
||||
if (isRunningAsStub && !it.isRoot) {
|
||||
showInvalidStateMessage()
|
||||
return@getShell
|
||||
}
|
||||
preLoad()
|
||||
runOnUiThread {
|
||||
doPreload = false
|
||||
if (isRunningAsStub) {
|
||||
// Re-launch main activity without splash theme
|
||||
relaunch()
|
||||
} else {
|
||||
showMainUI(savedInstanceState)
|
||||
}
|
||||
}
|
||||
preLoad(savedInstanceState)
|
||||
}
|
||||
} else {
|
||||
showMainUI(savedInstanceState)
|
||||
}
|
||||
}
|
||||
|
||||
@ -84,7 +76,7 @@ abstract class BaseMainActivity<Binding : ViewDataBinding> : NavigationActivity<
|
||||
showInvalidStateMessage()
|
||||
} else {
|
||||
lifecycleScope.launch {
|
||||
HideAPK.restore(this@BaseMainActivity)
|
||||
HideAPK.restore(this@SplashActivity)
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -95,10 +87,10 @@ abstract class BaseMainActivity<Binding : ViewDataBinding> : NavigationActivity<
|
||||
}
|
||||
}
|
||||
|
||||
private fun preLoad() {
|
||||
private fun preLoad(savedState: Bundle?) {
|
||||
val prevPkg = intent.getStringExtra(Const.Key.PREV_PKG)?.let {
|
||||
// Make sure the calling package matches (prevent DoS)
|
||||
if (it == callingPackage)
|
||||
if (it == realCallingPackage)
|
||||
it
|
||||
else
|
||||
null
|
||||
@ -106,9 +98,14 @@ abstract class BaseMainActivity<Binding : ViewDataBinding> : NavigationActivity<
|
||||
|
||||
Config.load(prevPkg)
|
||||
handleRepackage(prevPkg)
|
||||
if (prevPkg != null) {
|
||||
StubApk.restartProcess(this)
|
||||
if (prevPkg != null && !isRunningAsStub) {
|
||||
runOnUiThread {
|
||||
// Might have new configuration loaded, relaunch the activity
|
||||
relaunch()
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
Notifications.setup(this)
|
||||
JobService.schedule(this)
|
||||
Shortcuts.setupDynamic(this)
|
||||
@ -118,6 +115,16 @@ abstract class BaseMainActivity<Binding : ViewDataBinding> : NavigationActivity<
|
||||
|
||||
// Wait for root service
|
||||
RootUtils.Connection.await()
|
||||
|
||||
runOnUiThread {
|
||||
skipSplash = true
|
||||
if (isRunningAsStub) {
|
||||
// Re-launch main activity without splash theme
|
||||
relaunch()
|
||||
} else {
|
||||
showMainUI(savedState)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun handleRepackage(pkg: String?) {
|
@ -1,6 +1,7 @@
|
||||
package com.topjohnwu.magisk.ui.theme
|
||||
|
||||
import com.topjohnwu.magisk.arch.BaseViewModel
|
||||
import com.topjohnwu.magisk.core.Config
|
||||
import com.topjohnwu.magisk.events.RecreateEvent
|
||||
import com.topjohnwu.magisk.events.dialog.DarkThemeDialog
|
||||
import com.topjohnwu.magisk.view.TappableHeadlineItem
|
||||
@ -10,15 +11,13 @@ class ThemeViewModel : BaseViewModel(), TappableHeadlineItem.Listener {
|
||||
val themeHeadline = TappableHeadlineItem.ThemeMode
|
||||
|
||||
override fun onItemPressed(item: TappableHeadlineItem) = when (item) {
|
||||
is TappableHeadlineItem.ThemeMode -> darkModePressed()
|
||||
else -> Unit
|
||||
is TappableHeadlineItem.ThemeMode -> DarkThemeDialog().publish()
|
||||
}
|
||||
|
||||
fun saveTheme(theme: Theme) {
|
||||
theme.select()
|
||||
RecreateEvent().publish()
|
||||
if (!theme.isSelected) {
|
||||
Config.themeOrdinal = theme.ordinal
|
||||
RecreateEvent().publish()
|
||||
}
|
||||
}
|
||||
|
||||
private fun darkModePressed() = DarkThemeDialog().publish()
|
||||
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user