diff options
| author | 2025-02-11 16:33:35 -0800 | |
|---|---|---|
| committer | 2025-02-12 15:22:39 -0800 | |
| commit | 3e9f981c1f669460af027a50d51e5a425ebda073 (patch) | |
| tree | 321f7099cd61d727775e16fdcffb6667c940c3f9 | |
| parent | d6783aaf377fe6856e777db8675e59d20dcb92ac (diff) | |
Do not restart an install or uninstall on config change
If an install or uninstall is already in progress and
(Un)InstallLaunch.java is recreated due to a configuration change, do
not process the incoming request again. The correct stage will already
be set in current(un)installStage liveData.
Bug: 394724957
Test: atest CtsPackageInstallTestCases CtsPackageUninstallTestCases CtsPackageInstallerCUJInstallationTestCases
Flag: android.content.pm.use_pia_v2
Change-Id: Ib570d499a656ce31cc03201c27cd885b103a4e00
3 files changed, 45 insertions, 18 deletions
diff --git a/packages/PackageInstaller/src/com/android/packageinstaller/v2/ui/InstallLaunch.kt b/packages/PackageInstaller/src/com/android/packageinstaller/v2/ui/InstallLaunch.kt index c61a2ac9f0dd..481023ed5677 100644 --- a/packages/PackageInstaller/src/com/android/packageinstaller/v2/ui/InstallLaunch.kt +++ b/packages/PackageInstaller/src/com/android/packageinstaller/v2/ui/InstallLaunch.kt @@ -16,9 +16,6 @@ package com.android.packageinstaller.v2.ui -import android.app.Activity.RESULT_CANCELED -import android.app.Activity.RESULT_FIRST_USER -import android.app.Activity.RESULT_OK import android.app.AppOpsManager import android.content.ActivityNotFoundException import android.content.Intent @@ -67,6 +64,7 @@ class InstallLaunch : FragmentActivity(), InstallActionListener { InstallLaunch::class.java.packageName + ".callingPkgName" private val LOG_TAG = InstallLaunch::class.java.simpleName private const val TAG_DIALOG = "dialog" + private const val ARGS_SAVED_INTENT = "saved_intent" } /** @@ -96,7 +94,15 @@ class InstallLaunch : FragmentActivity(), InstallActionListener { intent.getStringExtra(EXTRA_CALLING_PKG_NAME), intent.getIntExtra(EXTRA_CALLING_PKG_UID, Process.INVALID_UID) ) - installViewModel!!.preprocessIntent(intent, info) + + var savedIntent: Intent? = null + if (savedInstanceState != null) { + savedIntent = savedInstanceState.getParcelable(ARGS_SAVED_INTENT, Intent::class.java) + } + if (!intent.filterEquals(savedIntent)) { + installViewModel!!.preprocessIntent(intent, info) + } + installViewModel!!.currentInstallStage.observe(this) { installStage: InstallStage -> onInstallStageChange(installStage) } @@ -344,6 +350,11 @@ class InstallLaunch : FragmentActivity(), InstallActionListener { appOpsManager!!.stopWatchingMode(listener) } + override fun onSaveInstanceState(outState: Bundle) { + outState.putParcelable(ARGS_SAVED_INTENT, intent) + super.onSaveInstanceState(outState) + } + override fun onDestroy() { super.onDestroy() while (activeUnknownSourcesListeners.isNotEmpty()) { diff --git a/packages/PackageInstaller/src/com/android/packageinstaller/v2/ui/UninstallLaunch.kt b/packages/PackageInstaller/src/com/android/packageinstaller/v2/ui/UninstallLaunch.kt index c4ca27247575..0a02845e0dd3 100644 --- a/packages/PackageInstaller/src/com/android/packageinstaller/v2/ui/UninstallLaunch.kt +++ b/packages/PackageInstaller/src/com/android/packageinstaller/v2/ui/UninstallLaunch.kt @@ -16,7 +16,6 @@ package com.android.packageinstaller.v2.ui -import android.app.Activity import android.app.NotificationManager import android.content.Intent import android.os.Bundle @@ -51,6 +50,7 @@ class UninstallLaunch : FragmentActivity(), UninstallActionListener { UninstallLaunch::class.java.packageName + ".callingActivityName" val LOG_TAG = UninstallLaunch::class.java.simpleName private const val TAG_DIALOG = "dialog" + private const val ARGS_SAVED_INTENT = "saved_intent" } private var uninstallViewModel: UninstallViewModel? = null @@ -76,7 +76,15 @@ class UninstallLaunch : FragmentActivity(), UninstallActionListener { intent.getStringExtra(EXTRA_CALLING_ACTIVITY_NAME), intent.getIntExtra(EXTRA_CALLING_PKG_UID, Process.INVALID_UID) ) - uninstallViewModel!!.preprocessIntent(intent, callerInfo) + + var savedIntent: Intent? = null + if (savedInstanceState != null) { + savedIntent = savedInstanceState.getParcelable(ARGS_SAVED_INTENT, Intent::class.java) + } + if (!intent.filterEquals(savedIntent)) { + uninstallViewModel!!.preprocessIntent(intent, callerInfo) + } + uninstallViewModel!!.currentUninstallStage.observe(this) { uninstallStage: UninstallStage -> onUninstallStageChange(uninstallStage) } @@ -171,6 +179,11 @@ class UninstallLaunch : FragmentActivity(), UninstallActionListener { Log.d(LOG_TAG, "Cancelling uninstall") } uninstallViewModel!!.cancelUninstall() - setResult(Activity.RESULT_FIRST_USER, null, true) + setResult(RESULT_FIRST_USER, null, true) + } + + override fun onSaveInstanceState(outState: Bundle) { + outState.putParcelable(ARGS_SAVED_INTENT, intent) + super.onSaveInstanceState(outState) } } diff --git a/packages/PackageInstaller/src/com/android/packageinstaller/v2/viewmodel/InstallViewModel.kt b/packages/PackageInstaller/src/com/android/packageinstaller/v2/viewmodel/InstallViewModel.kt index 388e03f023a1..5a2b122f0bec 100644 --- a/packages/PackageInstaller/src/com/android/packageinstaller/v2/viewmodel/InstallViewModel.kt +++ b/packages/PackageInstaller/src/com/android/packageinstaller/v2/viewmodel/InstallViewModel.kt @@ -49,6 +49,20 @@ class InstallViewModel(application: Application, val repository: InstallReposito _currentInstallStage.value = installStage } } + + // Since staging is an async operation, we will get the staging result later in time. + // Result of the file staging will be set in InstallRepository#mStagingResult. + // As such, mCurrentInstallStage will need to add another MutableLiveData + // as a data source + _currentInstallStage.addSource( + repository.stagingResult.distinctUntilChanged() + ) { installStage: InstallStage -> + if (installStage.stageCode != InstallStage.STAGE_READY) { + _currentInstallStage.value = installStage + } else { + checkIfAllowedAndInitiateInstall() + } + } } fun preprocessIntent(intent: Intent, callerInfo: InstallRepository.CallerInfo) { @@ -56,18 +70,7 @@ class InstallViewModel(application: Application, val repository: InstallReposito if (stage.stageCode == InstallStage.STAGE_ABORTED) { _currentInstallStage.value = stage } else { - // Since staging is an async operation, we will get the staging result later in time. - // Result of the file staging will be set in InstallRepository#mStagingResult. - // As such, mCurrentInstallStage will need to add another MutableLiveData - // as a data source repository.stageForInstall() - _currentInstallStage.addSource(repository.stagingResult) { installStage: InstallStage -> - if (installStage.stageCode != InstallStage.STAGE_READY) { - _currentInstallStage.value = installStage - } else { - checkIfAllowedAndInitiateInstall() - } - } } } |