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

Commit 59584dcb authored by Sumedh Sen's avatar Sumedh Sen
Browse files

[piav2] Add more conditions for showing InstallFailed dialog

InstallFailed dialog must be shown when a verifier blocks an install. Since the
statusCode in this case is repeated even for ownership update denial, we
must add more conditions to ensure InstallFailed is shown for the
verifier block case.

This was implemented in Pia V1 in ag/27774218

Bug: 345705476
Test: atest CtsPackageInstallTestCases:IntentTest
Flag: android.content.pm.use_pia_v2
Change-Id: I9d5b96991b867cfef8bde13368fb44bf62d54d62
parent f6be4be5
Loading
Loading
Loading
Loading
+28 −4
Original line number Diff line number Diff line
@@ -912,8 +912,10 @@ class InstallRepository(private val context: Context) {
                    "message: $message"
            )
        }
        if (statusCode == PackageInstaller.STATUS_SUCCESS) {

        val shouldReturnResult = intent.getBooleanExtra(Intent.EXTRA_RETURN_RESULT, false)

        if (statusCode == PackageInstaller.STATUS_SUCCESS) {
            val resultIntent = if (shouldReturnResult) {
                Intent().putExtra(Intent.EXTRA_INSTALL_RESULT, PackageManager.INSTALL_SUCCEEDED)
            } else {
@@ -922,12 +924,34 @@ class InstallRepository(private val context: Context) {
            }
            _installResult.setValue(InstallSuccess(appSnippet, shouldReturnResult, resultIntent))
        } else {
            if (statusCode != PackageInstaller.STATUS_FAILURE_ABORTED) {
            // TODO (b/346655018): Use INSTALL_FAILED_ABORTED legacyCode in the condition
            // statusCode can be STATUS_FAILURE_ABORTED if:
            // 1. GPP blocks an install.
            // 2. User denies ownership update explicitly.
            // InstallFailed dialog must not be shown only when the user denies ownership update. We
            // must show this dialog for all other install failures.

            val userDenied =
                    statusCode == PackageInstaller.STATUS_FAILURE_ABORTED &&
                    legacyStatus != PackageManager.INSTALL_FAILED_VERIFICATION_TIMEOUT &&
                    legacyStatus != PackageManager.INSTALL_FAILED_VERIFICATION_FAILURE

            if (shouldReturnResult) {
                val resultIntent = Intent().putExtra(Intent.EXTRA_INSTALL_RESULT, legacyStatus)
                _installResult.setValue(
                    InstallFailed(appSnippet, statusCode, legacyStatus, message)
                    InstallFailed(
                        legacyCode = legacyStatus,
                        statusCode = statusCode,
                        shouldReturnResult = true,
                        resultIntent = resultIntent
                    )
            } else {
                )
            } else if (userDenied) {
                _installResult.setValue(InstallAborted(ABORT_REASON_INTERNAL_ERROR))
            } else {
                _installResult.setValue(
                    InstallFailed(appSnippet, legacyStatus, statusCode, message)
                )
            }
        }
    }
+14 −8
Original line number Diff line number Diff line
@@ -19,6 +19,7 @@ package com.android.packageinstaller.v2.model
import android.app.Activity
import android.content.Intent
import android.content.pm.PackageManager
import android.content.pm.PackageInstaller
import android.graphics.drawable.Drawable

sealed class InstallStage(val stageCode: Int) {
@@ -77,11 +78,10 @@ data class InstallSuccess(
    val shouldReturnResult: Boolean = false,
    /**
     *
     * * If the caller is requesting a result back, this will hold the Intent with
     * [Intent.EXTRA_INSTALL_RESULT] set to [PackageManager.INSTALL_SUCCEEDED] which is sent
     * back to the caller.
     * * If the caller is requesting a result back, this will hold an Intent with
     * [Intent.EXTRA_INSTALL_RESULT] set to [PackageManager.INSTALL_SUCCEEDED].
     *
     * * If the caller doesn't want the result back, this will hold the Intent that launches
     * * If the caller doesn't want the result back, this will hold an Intent that launches
     * the newly installed / updated app if a launchable activity exists.
     */
    val resultIntent: Intent? = null,
@@ -95,17 +95,23 @@ data class InstallSuccess(
}

data class InstallFailed(
    private val appSnippet: PackageUtil.AppSnippet,
    private val appSnippet: PackageUtil.AppSnippet? = null,
    val legacyCode: Int,
    val statusCode: Int,
    val message: String?,
    val message: String? = null,
    val shouldReturnResult: Boolean = false,
    /**
     * If the caller is requesting a result back, this will hold an Intent with
     * [Intent.EXTRA_INSTALL_RESULT] set to the [PackageInstaller.EXTRA_LEGACY_STATUS].
     */
    val resultIntent: Intent? = null
) : InstallStage(STAGE_FAILED) {

    val appIcon: Drawable?
        get() = appSnippet.icon
        get() = appSnippet?.icon

    val appLabel: String?
        get() = appSnippet.label as String?
        get() = appSnippet?.label as String?
}

data class InstallAborted(
+9 −4
Original line number Diff line number Diff line
@@ -171,15 +171,20 @@ class InstallLaunch : FragmentActivity(), InstallActionListener {
                    val successIntent = success.resultIntent
                    setResult(Activity.RESULT_OK, successIntent, true)
                } else {
                    val successFragment = InstallSuccessFragment(success)
                    showDialogInner(successFragment)
                    val successDialog = InstallSuccessFragment(success)
                    showDialogInner(successDialog)
                }
            }

            InstallStage.STAGE_FAILED -> {
                val failed = installStage as InstallFailed
                val failedDialog = InstallFailedFragment(failed)
                showDialogInner(failedDialog)
                if (failed.shouldReturnResult) {
                    val failureIntent = failed.resultIntent
                    setResult(Activity.RESULT_FIRST_USER, failureIntent, true)
                } else {
                    val failureDialog = InstallFailedFragment(failed)
                    showDialogInner(failureDialog)
                }
            }

            else -> {