Fix an issue for work profiles (or any profile with a shared UI).
If a profile shares its UI with another profile then the launcher runs
on a different userId, this caused some checks to fail.
Removed one useless check about package name and adjusted the second to
consider the profile parent instead if it exists.
Bug: N/A (just found it)
Test: manually (this wasn't caught by CTS tests because in tests we have to set
the default launcher manually first in the test itself)
Change-Id: I5f09f90a0807efb1f49d82e4326ade026748f2c4
diff --git a/services/core/java/com/android/server/pm/PackageArchiver.java b/services/core/java/com/android/server/pm/PackageArchiver.java
index dc97e5f..6b63901 100644
--- a/services/core/java/com/android/server/pm/PackageArchiver.java
+++ b/services/core/java/com/android/server/pm/PackageArchiver.java
@@ -62,6 +62,7 @@
import android.content.pm.PackageManager;
import android.content.pm.ParceledListSlice;
import android.content.pm.ResolveInfo;
+import android.content.pm.UserInfo;
import android.content.pm.VersionedPackage;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
@@ -85,6 +86,7 @@
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;
@@ -163,6 +165,9 @@
@Nullable
private AppOpsManager mAppOpsManager;
+ @Nullable
+ private UserManager mUserManager;
+
/* IntentSender store that maps key: {userId, appPackageName} to respective existing attached
unarchival intent sender. */
private final Map<Pair<Integer, String>, IntentSender> mLauncherIntentSenders;
@@ -272,12 +277,8 @@
Slog.e(TAG, "callerPackageName cannot be null for unarchival!");
return START_CLASS_NOT_FOUND;
}
- if (!isCallingPackageValid(callerPackageName, callingUid, userId)) {
- // Return early as the calling UID does not match caller package's UID.
- return START_CLASS_NOT_FOUND;
- }
- String currentLauncherPackageName = getCurrentLauncherPackageName(userId);
+ String currentLauncherPackageName = getCurrentLauncherPackageName(getParentUserId(userId));
if ((currentLauncherPackageName == null || !callerPackageName.equals(
currentLauncherPackageName)) && callingUid != Process.SHELL_UID) {
// TODO(b/311619990): Remove dependency on SHELL_UID for testing
@@ -312,6 +313,13 @@
return START_ABORTED;
}
+ // Profiles share their UI and default apps, so we have to get the profile parent before
+ // fetching the default launcher.
+ private int getParentUserId(int userId) {
+ UserInfo profileParent = getUserManager().getProfileParent(userId);
+ return profileParent == null ? userId : profileParent.id;
+ }
+
/**
* Returns true if the componentName targeted by the intent corresponds to that of an archived
* app.
@@ -1120,6 +1128,13 @@
return mAppOpsManager;
}
+ private UserManager getUserManager() {
+ if (mUserManager == null) {
+ mUserManager = mContext.getSystemService(UserManager.class);
+ }
+ return mUserManager;
+ }
+
private void storeArchiveState(String packageName, ArchiveState archiveState, int userId)
throws PackageManager.NameNotFoundException {
synchronized (mPm.mLock) {