diff options
5 files changed, 106 insertions, 12 deletions
diff --git a/services/core/java/com/android/server/pm/InstallPackageHelper.java b/services/core/java/com/android/server/pm/InstallPackageHelper.java index 2a3b939c5295..d41727fc781f 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_DE; 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 @@ final class InstallPackageHelper { 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 @@ final class InstallPackageHelper { // 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 4dcee04f8124..6d385174a8a1 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.os.UserHandle; 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 @@ final class InstallRequest { @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 @@ final class InstallRequest { 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 @@ final class InstallRequest { 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 fda4dc6087f5..fb0e50eb49b2 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.ParcelableException; 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 @@ public class PackageArchiver { @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 @@ public class PackageArchiver { 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 @@ public class PackageArchiver { 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 @@ public class PackageArchiver { 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 d69737aef98f..9206759ba9f4 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 class PackageManagerException extends Exception { 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 @@ public class PackageManagerException extends Exception { 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 614828add52b..0f4e4821dee8 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 @@ public class PackageManagerService implements PackageSender, TestUtilityService } 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 @@ public class PackageManagerService implements PackageSender, TestUtilityService } for (int userId : userIds) { var archiveState = mInstallerService.mPackageArchiver.createArchiveState( - archivePackage, userId, responsibleInstallerPackage); + archivePackage, userId, responsibleInstallerPackage, + responsibleInstallerTitles.get(userId)); if (archiveState != null) { pkgSetting .modifyUserState(userId) |