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

Commit 56f2bf41 authored by Sumedh Sen's avatar Sumedh Sen
Browse files

Implement Unarchival dialogs in new UI

Bug: 274120822
Test: atest CtsPackageUninstallTestCases:ArchiveTest
Flag: android.content.pm.use_pia_v2
Change-Id: I5abf9301182df10d2618f4adb3d16617855b77ea
parent de72d81f
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -180,7 +180,7 @@

        <activity android:name=".v2.ui.UnarchiveLaunch"
            android:configChanges="orientation|keyboardHidden|screenSize"
            android:theme="@style/Theme.AlertDialogActivity"
            android:theme="@style/Theme.PackageInstaller"
            android:exported="false"/>
    </application>

+18 −0
Original line number Diff line number Diff line
@@ -58,6 +58,14 @@
    <string name="title_archive">Archive this app?</string>
    <string name="title_archive_all_users">Archive this app for all users?</string>
    <string name="title_archive_other_user">Archive this app for user \'<xliff:g id="user_name">%1$s</xliff:g>\'?</string>
    <string name="title_restore">Restore this app?</string>
    <string name="title_restore_error_user_action_needed">Action required</string>
    <string name="title_restore_error_less_storage">Not enough storage</string>
    <string name="title_restore_error_offline">You\'re offline</string>
    <string name="title_restore_error_installer_disabled"><xliff:g id="installer_name">%1$s</xliff:g> is disabled</string>
    <string name="title_restore_error_installer_absent"><xliff:g id="installer_name">%1$s</xliff:g> is uninstalled</string>
    <string name="title_restore_error_generic">Something went wrong</string>

    <!-- Dialog Titles end -->

    <!-- Dialog Messages -->
@@ -93,6 +101,14 @@
    <string name="message_archive_work_profile">This app will be archived from your work profile. Your app data will be saved.</string>
    <string name="message_archive_private_space">This app will be archived from your private space. Your app data will be saved.</string>

    <string name="message_restore">This app download from <xliff:g id="installer_name">%1$s</xliff:g> in the background</string>
    <string name="message_restore_error_user_action_needed"><xliff:g id="installer_name">%1$s</xliff:g> needs more information before you can restore this app</string>
    <string name="message_restore_error_less_storage">To restore this app, free up &lt;b><xliff:g id="bytes">%1$s</xliff:g>&lt;/b> and try again </string>
    <string name="message_restore_error_offline">To restore this app, check your internet connection and try again</string>
    <string name="message_restore_error_installer_disabled">To restore this app, enable <xliff:g id="installername" example="App Store">%1$s</xliff:g> in Settings</string>
    <string name="message_restore_error_installer_absent">To restore this app, you\'ll need to install <xliff:g id="installer_name">%1$s</xliff:g></string>
    <string name="message_restore_error_generic">There was a problem trying to restore this app</string>

    <!-- TODO: These strings are placeholders, until UX finalizes strings for Uninstall flow. -->
    <string name="message_uninstall_activity"><xliff:g id="activity_name">%1$s</xliff:g> is part of the following app: <xliff:g id="app_name">%2$s</xliff:g></string>
    <!-- End of placeholder strings -->
@@ -112,7 +128,9 @@
    <string name="button_reinstall">Reinstall</string>
    <string name="button_manage_apps">Manage apps</string>
    <string name="button_archive">Archive</string>
    <string name="button_restore">Restore</string>
    <string name="button_uninstall_updates_system_app">Uninstall updates</string>
    <string name="button_settings">Settings</string>
    <!-- Dialog Buttons end -->

    <!-- Miscellaneous -->
+18 −6
Original line number Diff line number Diff line
@@ -28,11 +28,10 @@ import android.content.pm.PackageManager
import android.content.pm.PackageManager.NameNotFoundException
import android.os.Process
import android.util.Log

import com.android.packageinstaller.v2.model.PackageUtil.getAppSnippet
import com.android.packageinstaller.v2.model.PackageUtil.getPackageNameForUid
import com.android.packageinstaller.v2.model.PackageUtil.isPermissionGranted
import com.android.packageinstaller.v2.model.PackageUtil.isUidRequestingPermission

import java.io.IOException

class UnarchiveRepository(private val context: Context) {
@@ -85,9 +84,11 @@ class UnarchiveRepository(private val context: Context) {
    }

    fun showUnarchivalConfirmation(): UnarchiveStage {
        var appTitle: String
        var appSnippet: PackageUtil.AppSnippet
        try {
            appTitle = getAppTitle(targetPackageName, PackageManager.MATCH_ARCHIVED_PACKAGES)
            val applicationInfo = packageManager.getApplicationInfo(targetPackageName,
                PackageManager.ApplicationInfoFlags.of(PackageManager.MATCH_ARCHIVED_PACKAGES))
            appSnippet = getAppSnippet(context, applicationInfo)
        } catch (e: NameNotFoundException) {
            Log.e(LOG_TAG, "Invalid packageName $targetPackageName: ", e)
            return UnarchiveAborted(UnarchiveAborted.ABORT_REASON_GENERIC_ERROR)
@@ -108,7 +109,7 @@ class UnarchiveRepository(private val context: Context) {
            return UnarchiveAborted(UnarchiveAborted.ABORT_REASON_GENERIC_ERROR)
        }

        return UnarchiveUserActionRequired(appTitle, installerTitle)
        return UnarchiveUserActionRequired(appSnippet, installerTitle)
    }

    @Throws(NameNotFoundException::class)
@@ -146,7 +147,7 @@ class UnarchiveRepository(private val context: Context) {
            PendingIntent::class.java
        )
        when (unarchivalStatus) {
            PackageInstaller.UNARCHIVAL_ERROR_USER_ACTION_NEEDED ->
            PackageInstaller.UNARCHIVAL_ERROR_USER_ACTION_NEEDED -> {
                if (pendingIntent == null) {
                    Log.e(
                        LOG_TAG,
@@ -156,6 +157,17 @@ class UnarchiveRepository(private val context: Context) {
                    return UnarchiveAborted(UnarchiveAborted.ABORT_REASON_GENERIC_ERROR)
                }

                if (installerAppTitle == null) {
                    Log.e(
                        LOG_TAG,
                        "Installer app title is required for unarchive error code " +
                                "${PackageInstaller.UNARCHIVAL_ERROR_USER_ACTION_NEEDED}"
                    )
                    return UnarchiveAborted(UnarchiveAborted.ABORT_REASON_GENERIC_ERROR)
                }
            }


            PackageInstaller.UNARCHIVAL_ERROR_INSUFFICIENT_STORAGE -> {
                if (requiredBytes == 0L) {
                    Log.w(
+12 −2
Original line number Diff line number Diff line
@@ -18,6 +18,7 @@ package com.android.packageinstaller.v2.model

import android.app.Activity
import android.app.PendingIntent
import android.graphics.drawable.Drawable

sealed class UnarchiveStage(val stageCode: Int) {

@@ -42,8 +43,17 @@ data class UnarchiveAborted(

class UnarchiveReady() : UnarchiveStage(STAGE_READY)

data class UnarchiveUserActionRequired(val appTitle: String, val installerTitle: String) :
    UnarchiveStage(STAGE_USER_ACTION_REQUIRED)
data class UnarchiveUserActionRequired(
    val appSnippet: PackageUtil.AppSnippet? = null,
    val installerTitle: String
) :
    UnarchiveStage(STAGE_USER_ACTION_REQUIRED) {
    val appIcon: Drawable?
        get() = appSnippet?.icon

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

data class UnarchiveError(
    val unarchivalStatus: Int,
+7 −0
Original line number Diff line number Diff line
@@ -66,6 +66,13 @@ class UnarchiveLaunch : FragmentActivity(), UnarchiveActionListener {
        )
        super.onCreate(savedInstanceState)

        // The base theme inherits a deviceDefault theme. Applying a material style on the base
        // theme below will enable using Material components, like the Material Progress Bar in the
        // fragments
        theme.applyStyle(
            com.google.android.material.R.style.Theme_Material3_DynamicColors_DayNight,
            /* force= */ false)

        fragmentManager = supportFragmentManager

        unarchiveRepository = UnarchiveRepository(applicationContext)
Loading