Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 3e9f981c authored by Sumedh Sen's avatar Sumedh Sen
Browse files

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
parent d6783aaf
Loading
Loading
Loading
Loading
+15 −4
Original line number Diff line number Diff line
@@ -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)
        )

        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()) {
+16 −3
Original line number Diff line number Diff line
@@ -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)
        )

        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)
    }
}
+14 −11
Original line number Diff line number Diff line
@@ -49,19 +49,14 @@ class InstallViewModel(application: Application, val repository: InstallReposito
                _currentInstallStage.value = installStage
            }
        }
    }

    fun preprocessIntent(intent: Intent, callerInfo: InstallRepository.CallerInfo) {
        val stage = repository.performPreInstallChecks(intent, callerInfo)
        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 ->
        _currentInstallStage.addSource(
            repository.stagingResult.distinctUntilChanged()
        ) { installStage: InstallStage ->
            if (installStage.stageCode != InstallStage.STAGE_READY) {
                _currentInstallStage.value = installStage
            } else {
@@ -69,6 +64,14 @@ class InstallViewModel(application: Application, val repository: InstallReposito
            }
        }
    }

    fun preprocessIntent(intent: Intent, callerInfo: InstallRepository.CallerInfo) {
        val stage = repository.performPreInstallChecks(intent, callerInfo)
        if (stage.stageCode == InstallStage.STAGE_ABORTED) {
            _currentInstallStage.value = stage
        } else {
            repository.stageForInstall()
        }
    }

    val stagingProgress: LiveData<Int>