Merge "[PM] Get the title of the installer outside of the lock" into main
diff --git a/services/core/java/com/android/server/pm/InstallPackageHelper.java b/services/core/java/com/android/server/pm/InstallPackageHelper.java
index 2a3b939..d41727f 100644
--- a/services/core/java/com/android/server/pm/InstallPackageHelper.java
+++ b/services/core/java/com/android/server/pm/InstallPackageHelper.java
@@ -48,6 +48,7 @@
 import static android.os.storage.StorageManager.FLAG_STORAGE_EXTERNAL;
 
 import static com.android.server.pm.InstructionSets.getAppDexInstructionSets;
+import static com.android.server.pm.PackageManagerException.INTERNAL_ERROR_ARCHIVE_NO_INSTALLER_TITLE;
 import static com.android.server.pm.PackageManagerService.APP_METADATA_FILE_NAME;
 import static com.android.server.pm.PackageManagerService.DEBUG_COMPRESSION;
 import static com.android.server.pm.PackageManagerService.DEBUG_INSTALL;
@@ -1050,6 +1051,20 @@
                     request.setError("Scanning Failed.", e);
                     return;
                 }
+                if (request.isArchived()) {
+                    final SparseArray<String> responsibleInstallerTitles =
+                            PackageArchiver.getResponsibleInstallerTitles(mContext,
+                                    mPm.snapshotComputer(), request.getInstallSource(),
+                                    request.getUserId(), mPm.mUserManager.getUserIds());
+                    if (responsibleInstallerTitles == null
+                            || responsibleInstallerTitles.size() == 0) {
+                        request.setError(PackageManagerException.ofInternalError(
+                                "Failed to obtain the responsible installer info",
+                                INTERNAL_ERROR_ARCHIVE_NO_INSTALLER_TITLE));
+                        return;
+                    }
+                    request.setResponsibleInstallerTitles(responsibleInstallerTitles);
+                }
             }
 
             List<ReconciledPackage> reconciledPackages;
@@ -2226,6 +2241,7 @@
                 // to figure out which users were changed.
                 mPm.markPackageAsArchivedIfNeeded(ps,
                         installRequest.getArchivedPackage(),
+                        installRequest.getResponsibleInstallerTitles(),
                         installRequest.getNewUsers());
                 mPm.updateSequenceNumberLP(ps, installRequest.getNewUsers());
                 mPm.updateInstantAppInstallerLocked(packageName);
diff --git a/services/core/java/com/android/server/pm/InstallRequest.java b/services/core/java/com/android/server/pm/InstallRequest.java
index 4dcee04..6d38517 100644
--- a/services/core/java/com/android/server/pm/InstallRequest.java
+++ b/services/core/java/com/android/server/pm/InstallRequest.java
@@ -49,6 +49,7 @@
 import android.util.ArrayMap;
 import android.util.ExceptionUtils;
 import android.util.Slog;
+import android.util.SparseArray;
 
 import com.android.internal.pm.parsing.pkg.ParsedPackage;
 import com.android.internal.pm.pkg.parsing.ParsingPackageUtils;
@@ -130,6 +131,12 @@
     @Nullable
     private String mApexModuleName;
 
+    /**
+     * The title of the responsible installer for the archive behavior used
+     */
+    @Nullable
+    private SparseArray<String> mResponsibleInstallerTitles;
+
     @Nullable
     private ScanResult mScanResult;
 
@@ -418,6 +425,12 @@
     public String getApexModuleName() {
         return mApexModuleName;
     }
+
+    @Nullable
+    public SparseArray<String> getResponsibleInstallerTitles() {
+        return mResponsibleInstallerTitles;
+    }
+
     public boolean isRollback() {
         return mInstallArgs != null
                 && mInstallArgs.mInstallReason == PackageManager.INSTALL_REASON_ROLLBACK;
@@ -756,6 +769,11 @@
         mApexModuleName = apexModuleName;
     }
 
+    public void setResponsibleInstallerTitles(
+            @NonNull SparseArray<String> responsibleInstallerTitles) {
+        mResponsibleInstallerTitles = responsibleInstallerTitles;
+    }
+
     public void setPkg(AndroidPackage pkg) {
         mPkg = pkg;
     }
diff --git a/services/core/java/com/android/server/pm/PackageArchiver.java b/services/core/java/com/android/server/pm/PackageArchiver.java
index fda4dc6..fb0e50e 100644
--- a/services/core/java/com/android/server/pm/PackageArchiver.java
+++ b/services/core/java/com/android/server/pm/PackageArchiver.java
@@ -85,13 +85,13 @@
 import android.os.Process;
 import android.os.RemoteException;
 import android.os.SELinux;
-import android.os.SystemProperties;
 import android.os.UserHandle;
 import android.os.UserManager;
 import android.text.TextUtils;
 import android.util.ExceptionUtils;
 import android.util.Pair;
 import android.util.Slog;
+import android.util.SparseArray;
 
 import com.android.internal.R;
 import com.android.internal.annotations.GuardedBy;
@@ -476,7 +476,7 @@
 
     @Nullable
     ArchiveState createArchiveState(@NonNull ArchivedPackageParcel archivedPackage,
-            int userId, String installerPackage) {
+            int userId, String installerPackage, String responsibleInstallerTitle) {
         ApplicationInfo installerInfo = mPm.snapshotComputer().getApplicationInfo(
                 installerPackage, /* flags= */ 0, userId);
         if (installerInfo == null) {
@@ -484,6 +484,11 @@
             Slog.e(TAG, "Couldn't find installer " + installerPackage);
             return null;
         }
+        if (responsibleInstallerTitle == null) {
+            Slog.e(TAG, "Couldn't get the title of the installer");
+            return null;
+        }
+
         final int iconSize = mContext.getSystemService(
                 ActivityManager.class).getLauncherLargeIconSize();
 
@@ -508,8 +513,7 @@
                 archiveActivityInfos.add(activityInfo);
             }
 
-            return new ArchiveState(archiveActivityInfos,
-                    installerInfo.loadLabel(mContext.getPackageManager()).toString());
+            return new ArchiveState(archiveActivityInfos, responsibleInstallerTitle);
         } catch (IOException e) {
             Slog.e(TAG, "Failed to create archive state", e);
             return null;
@@ -1106,10 +1110,61 @@
         return DEFAULT_UNARCHIVE_FOREGROUND_TIMEOUT_MS;
     }
 
+    private static String getResponsibleInstallerPackage(InstallSource installSource) {
+        return TextUtils.isEmpty(installSource.mUpdateOwnerPackageName)
+                ? installSource.mInstallerPackageName
+                : installSource.mUpdateOwnerPackageName;
+    }
+
+    private static String getResponsibleInstallerTitle(Context context, ApplicationInfo appInfo,
+            String responsibleInstallerPackage, int userId)
+            throws PackageManager.NameNotFoundException {
+        final Context userContext = context.createPackageContextAsUser(
+                responsibleInstallerPackage, /* flags= */ 0, new UserHandle(userId));
+        return appInfo.loadLabel(userContext.getPackageManager()).toString();
+    }
+
     static String getResponsibleInstallerPackage(PackageStateInternal ps) {
-        return TextUtils.isEmpty(ps.getInstallSource().mUpdateOwnerPackageName)
-                ? ps.getInstallSource().mInstallerPackageName
-                : ps.getInstallSource().mUpdateOwnerPackageName;
+        return getResponsibleInstallerPackage(ps.getInstallSource());
+    }
+
+    @Nullable
+    static SparseArray<String> getResponsibleInstallerTitles(Context context, Computer snapshot,
+            InstallSource installSource, int requestUserId, int[] allUserIds) {
+        final String responsibleInstallerPackage = getResponsibleInstallerPackage(installSource);
+        final SparseArray<String> responsibleInstallerTitles = new SparseArray<>();
+        try {
+            if (requestUserId != UserHandle.USER_ALL) {
+                final ApplicationInfo responsibleInstallerInfo = snapshot.getApplicationInfo(
+                        responsibleInstallerPackage, /* flags= */ 0, requestUserId);
+                if (responsibleInstallerInfo == null) {
+                    return null;
+                }
+
+                final String title = getResponsibleInstallerTitle(context,
+                        responsibleInstallerInfo, responsibleInstallerPackage, requestUserId);
+                responsibleInstallerTitles.put(requestUserId, title);
+            } else {
+                // Go through all userIds.
+                for (int i = 0; i < allUserIds.length; i++) {
+                    final int userId = allUserIds[i];
+                    final ApplicationInfo responsibleInstallerInfo = snapshot.getApplicationInfo(
+                            responsibleInstallerPackage, /* flags= */ 0, userId);
+                    // Can't get the applicationInfo on the user.
+                    // Maybe the installer isn't installed on the user.
+                    if (responsibleInstallerInfo == null) {
+                        continue;
+                    }
+
+                    final String title = getResponsibleInstallerTitle(context,
+                            responsibleInstallerInfo, responsibleInstallerPackage, userId);
+                    responsibleInstallerTitles.put(userId, title);
+                }
+            }
+        } catch (PackageManager.NameNotFoundException ex) {
+            return null;
+        }
+        return responsibleInstallerTitles;
     }
 
     void notifyUnarchivalListener(int status, String installerPackageName, String appPackageName,
diff --git a/services/core/java/com/android/server/pm/PackageManagerException.java b/services/core/java/com/android/server/pm/PackageManagerException.java
index d69737a..9206759 100644
--- a/services/core/java/com/android/server/pm/PackageManagerException.java
+++ b/services/core/java/com/android/server/pm/PackageManagerException.java
@@ -64,6 +64,7 @@
     public static final int INTERNAL_ERROR_APEX_NOT_DIRECTORY = -36;
     public static final int INTERNAL_ERROR_APEX_MORE_THAN_ONE_FILE = -37;
     public static final int INTERNAL_ERROR_MISSING_USER = -38;
+    public static final int INTERNAL_ERROR_ARCHIVE_NO_INSTALLER_TITLE = -39;
 
     @IntDef(prefix = { "INTERNAL_ERROR_" }, value = {
             INTERNAL_ERROR_NATIVE_LIBRARY_COPY,
@@ -103,7 +104,8 @@
             INTERNAL_ERROR_STATIC_SHARED_LIB_OVERLAY_TARGETS,
             INTERNAL_ERROR_APEX_NOT_DIRECTORY,
             INTERNAL_ERROR_APEX_MORE_THAN_ONE_FILE,
-            INTERNAL_ERROR_MISSING_USER
+            INTERNAL_ERROR_MISSING_USER,
+            INTERNAL_ERROR_ARCHIVE_NO_INSTALLER_TITLE
     })
     @Retention(RetentionPolicy.SOURCE)
     public @interface InternalErrorCode {}
diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java
index 614828a..0f4e482 100644
--- a/services/core/java/com/android/server/pm/PackageManagerService.java
+++ b/services/core/java/com/android/server/pm/PackageManagerService.java
@@ -1523,10 +1523,12 @@
     }
 
     void markPackageAsArchivedIfNeeded(PackageSetting pkgSetting,
-                                       ArchivedPackageParcel archivePackage, int[] userIds) {
+            ArchivedPackageParcel archivePackage, SparseArray<String> responsibleInstallerTitles,
+            int[] userIds) {
         if (pkgSetting == null || archivePackage == null
-                || archivePackage.archivedActivities == null || userIds == null
-                || userIds.length == 0) {
+                || archivePackage.archivedActivities == null
+                || responsibleInstallerTitles == null
+                || userIds == null || userIds.length == 0) {
             return;
         }
 
@@ -1552,7 +1554,8 @@
         }
         for (int userId : userIds) {
             var archiveState = mInstallerService.mPackageArchiver.createArchiveState(
-                    archivePackage, userId, responsibleInstallerPackage);
+                    archivePackage, userId, responsibleInstallerPackage,
+                    responsibleInstallerTitles.get(userId));
             if (archiveState != null) {
                 pkgSetting
                     .modifyUserState(userId)