Better stub launch flow

This commit is contained in:
topjohnwu 2022-06-05 19:15:43 -07:00
parent fa60daf9b5
commit 317153c53a
7 changed files with 55 additions and 38 deletions

View File

@ -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?) {

View File

@ -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())
}

View File

@ -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()
}

View File

@ -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
}
}

View File

@ -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>()

View File

@ -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?) {

View File

@ -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()
}