summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--services/core/java/com/android/server/pm/PackageArchiver.java43
1 files changed, 35 insertions, 8 deletions
diff --git a/services/core/java/com/android/server/pm/PackageArchiver.java b/services/core/java/com/android/server/pm/PackageArchiver.java
index 6b7b702b9157..5e45b4c2d5af 100644
--- a/services/core/java/com/android/server/pm/PackageArchiver.java
+++ b/services/core/java/com/android/server/pm/PackageArchiver.java
@@ -869,18 +869,25 @@ public class PackageArchiver {
private int createDraftSession(String packageName, String installerPackage,
String callerPackageName,
IntentSender statusReceiver, int userId) throws IOException {
+ Computer snapshot = mPm.snapshotComputer();
PackageInstaller.SessionParams sessionParams = new PackageInstaller.SessionParams(
PackageInstaller.SessionParams.MODE_FULL_INSTALL);
sessionParams.setAppPackageName(packageName);
sessionParams.setAppLabel(
mContext.getString(com.android.internal.R.string.unarchival_session_app_label));
- sessionParams.setAppIcon(
- getArchivedAppIcon(packageName, UserHandle.of(userId), callerPackageName));
+ // The draft session's app icon is based on the current launcher's icon overlay appops mode
+ String launcherPackageName = getCurrentLauncherPackageName(userId);
+ int launcherUid = launcherPackageName != null
+ ? snapshot.getPackageUid(launcherPackageName, 0, userId)
+ : Process.SYSTEM_UID;
+ sessionParams.setAppIcon(getArchivedAppIcon(packageName, UserHandle.of(userId),
+ isOverlayEnabled(launcherUid,
+ launcherPackageName == null ? callerPackageName : launcherPackageName)));
// To make sure SessionInfo::isUnarchival returns true for draft sessions,
// INSTALL_UNARCHIVE is also set.
sessionParams.installFlags = (INSTALL_UNARCHIVE_DRAFT | INSTALL_UNARCHIVE);
- int installerUid = mPm.snapshotComputer().getPackageUid(installerPackage, 0, userId);
+ int installerUid = snapshot.getPackageUid(installerPackage, 0, userId);
// Handles case of repeated unarchival calls for the same package.
int existingSessionId = mPm.mInstallerService.getExistingDraftSessionId(installerUid,
sessionParams,
@@ -926,12 +933,27 @@ public class PackageArchiver {
/**
* Returns the icon of an archived app. This is the icon of the main activity of the app.
*
- * <p> The icon is returned without any treatment/overlay. In the rare case the app had multiple
- * launcher activities, only one of the icons is returned arbitrarily.
+ * <p> In the rare case the app had multiple launcher activities, only one of the icons is
+ * returned arbitrarily.
+ *
+ * <p> By default, the icon will be overlay'd with a cloud icon on top. A launcher app can
+ * disable the cloud overlay via the
+ * {@link LauncherApps.ArchiveCompatibilityParams#setEnableIconOverlay(boolean)} API.
+ * The default launcher's cloud overlay mode determines the cloud overlay status returned by
+ * any other callers. That is, if the current launcher has the cloud overlay disabled, any other
+ * app that fetches the app icon will also get an icon that has the cloud overlay disabled.
+ * This is to prevent style mismatch caused by icons that are fetched by different callers.
*/
@Nullable
public Bitmap getArchivedAppIcon(@NonNull String packageName, @NonNull UserHandle user,
String callingPackageName) {
+ return getArchivedAppIcon(packageName, user,
+ isOverlayEnabled(Binder.getCallingUid(), callingPackageName));
+ }
+
+ @Nullable
+ private Bitmap getArchivedAppIcon(@NonNull String packageName, @NonNull UserHandle user,
+ boolean isOverlayEnabled) {
Objects.requireNonNull(packageName);
Objects.requireNonNull(user);
@@ -955,14 +977,19 @@ public class PackageArchiver {
// In the rare case the archived app defined more than two launcher activities, we choose
// the first one arbitrarily.
Bitmap icon = decodeIcon(archiveState.getActivityInfos().get(0));
- if (icon != null && getAppOpsManager().checkOp(
- AppOpsManager.OP_ARCHIVE_ICON_OVERLAY, callingUid, callingPackageName)
- == MODE_ALLOWED) {
+
+ if (icon != null && isOverlayEnabled) {
icon = includeCloudOverlay(icon);
}
return icon;
}
+ private boolean isOverlayEnabled(int callingUid, String packageName) {
+ return getAppOpsManager().checkOp(
+ AppOpsManager.OP_ARCHIVE_ICON_OVERLAY, callingUid, packageName)
+ == MODE_ALLOWED;
+ }
+
/**
* This method first checks the ArchiveState for the provided userId and then tries to fallback
* to other users if the current user is not archived.