Loading core/java/android/content/pm/multiuser.aconfig +7 −0 Original line number Diff line number Diff line Loading @@ -135,3 +135,10 @@ flag { description: "Allow the use of a profileApiAvailability user property to exclude HIDDEN profiles in API results" bug: "316362775" } flag { name: "enable_launcher_apps_hidden_profile_checks" namespace: "profile_experiences" description: "Enable extra check to limit access to hidden prfiles data in Launcher apps APIs." bug: "321988638" } data/etc/privapp-permissions-platform.xml +2 −0 Original line number Diff line number Diff line Loading @@ -316,6 +316,8 @@ applications that come with the platform <permission name="android.permission.SET_LOW_POWER_STANDBY_PORTS" /> <permission name="android.permission.MANAGE_ROLLBACKS"/> <permission name="android.permission.MANAGE_USB"/> <!-- Permission required to test Launcher Apps APIs for hidden profiles --> <permission name="android.permission.ACCESS_HIDDEN_PROFILES_FULL" /> <!-- Needed for tests only --> <permission name="android.permission.MANAGE_CLOUDSEARCH" /> <permission name="android.permission.MANAGE_WALLPAPER_EFFECTS_GENERATION" /> Loading packages/Shell/AndroidManifest.xml +2 −0 Original line number Diff line number Diff line Loading @@ -250,6 +250,8 @@ <uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS" /> <uses-permission android:name="android.permission.MOUNT_FORMAT_FILESYSTEMS" /> <uses-permission android:name="android.permission.MODIFY_PHONE_STATE" /> <!-- Permission required to test LauncherApps APIs for hidden profiles --> <uses-permission android:name="android.permission.ACCESS_HIDDEN_PROFILES_FULL" /> <!-- Shell only holds android.permission.NETWORK_SCAN in order to to enable CTS testing --> <uses-permission android:name="android.permission.NETWORK_SCAN" /> <uses-permission android:name="android.permission.REGISTER_CALL_PROVIDER" /> Loading services/core/java/com/android/server/pm/LauncherAppsService.java +47 −16 Original line number Diff line number Diff line Loading @@ -38,6 +38,7 @@ import static android.content.pm.LauncherApps.FLAG_CACHE_PEOPLE_TILE_SHORTCUTS; import static com.android.server.pm.PackageArchiver.isArchivingEnabled; import android.Manifest; import android.annotation.AppIdInt; import android.annotation.NonNull; import android.annotation.Nullable; Loading @@ -52,6 +53,7 @@ import android.app.IApplicationThread; import android.app.PendingIntent; import android.app.admin.DevicePolicyCache; import android.app.admin.DevicePolicyManager; import android.app.role.RoleManager; import android.app.usage.UsageStatsManagerInternal; import android.content.ActivityNotFoundException; import android.content.BroadcastReceiver; Loading Loading @@ -84,7 +86,9 @@ import android.content.pm.ShortcutQueryWrapper; import android.content.pm.ShortcutServiceInternal; import android.content.pm.ShortcutServiceInternal.ShortcutChangeListener; import android.content.pm.UserInfo; import android.content.pm.UserProperties; import android.graphics.Rect; import android.multiuser.Flags; import android.net.Uri; import android.os.Binder; import android.os.Bundle; Loading Loading @@ -211,6 +215,7 @@ public class LauncherAppsService extends SystemService { private final Context mContext; private final UserManager mUm; private final RoleManager mRoleManager; private final IPackageManager mIPM; private final UserManagerInternal mUserManagerInternal; private final UsageStatsManagerInternal mUsageStatsManagerInternal; Loading Loading @@ -247,6 +252,7 @@ public class LauncherAppsService extends SystemService { mContext = context; mIPM = AppGlobals.getPackageManager(); mUm = (UserManager) mContext.getSystemService(Context.USER_SERVICE); mRoleManager = mContext.getSystemService(RoleManager.class); mUserManagerInternal = Objects.requireNonNull( LocalServices.getService(UserManagerInternal.class)); mUsageStatsManagerInternal = Objects.requireNonNull( Loading Loading @@ -451,7 +457,6 @@ public class LauncherAppsService extends SystemService { private boolean canAccessProfile(int callingUid, int callingUserId, int callingPid, int targetUserId, String message) { if (targetUserId == callingUserId) return true; if (injectHasInteractAcrossUsersFullPermission(callingPid, callingUid)) { return true; Loading @@ -465,6 +470,14 @@ public class LauncherAppsService extends SystemService { + targetUserId + " from " + callingUserId + " not allowed"); return false; } if (areHiddenApisChecksEnabled() && mUm.getUserProperties(UserHandle.of(targetUserId)) .getProfileApiVisibility() == UserProperties.PROFILE_API_VISIBILITY_HIDDEN && !canAccessHiddenProfileInjected(callingUid, callingPid)) { return false; } } finally { injectRestoreCallingIdentity(ident); } Loading @@ -473,10 +486,43 @@ public class LauncherAppsService extends SystemService { message, true); } boolean areHiddenApisChecksEnabled() { return android.os.Flags.allowPrivateProfile() && Flags.enableLauncherAppsHiddenProfileChecks() && Flags.enablePermissionToAccessHiddenProfiles(); } private void verifyCallingPackage(String callingPackage) { verifyCallingPackage(callingPackage, injectBinderCallingUid()); } boolean canAccessHiddenProfileInjected(int callingUid, int callingPid) { AndroidPackage callingPackage = mPackageManagerInternal.getPackage(callingUid); if (callingPackage == null) { return false; } if (!mRoleManager .getRoleHoldersAsUser( RoleManager.ROLE_HOME, UserHandle.getUserHandleForUid(callingUid)) .contains(callingPackage.getPackageName())) { return false; } if (mContext.checkPermission( Manifest.permission.ACCESS_HIDDEN_PROFILES_FULL, callingPid, callingUid) == PackageManager.PERMISSION_GRANTED) { return true; } // TODO(b/321988638): add option to disable with a flag return mContext.checkPermission( android.Manifest.permission.ACCESS_HIDDEN_PROFILES, callingPid, callingUid) == PackageManager.PERMISSION_GRANTED; } @VisibleForTesting // We override it in unit tests void verifyCallingPackage(String callingPackage, int callerUid) { int packageUid = -1; Loading Loading @@ -1566,11 +1612,6 @@ public class LauncherAppsService extends SystemService { @Override public @Nullable LauncherUserInfo getLauncherUserInfo(@NonNull UserHandle user) { // Only system launchers, which have access to recents should have access to this API. // TODO(b/303803157): Add the new permission check if we decide to have one. if (!mActivityTaskManagerInternal.isCallerRecents(Binder.getCallingUid())) { throw new SecurityException("Caller is not the recents app"); } if (!canAccessProfile(user.getIdentifier(), "Can't access LauncherUserInfo for another user")) { return null; Loading @@ -1585,11 +1626,6 @@ public class LauncherAppsService extends SystemService { @Override public List<String> getPreInstalledSystemPackages(UserHandle user) { // Only system launchers, which have access to recents should have access to this API. // TODO(b/303803157): Update access control for this API to default Launcher app. if (!mActivityTaskManagerInternal.isCallerRecents(Binder.getCallingUid())) { throw new SecurityException("Caller is not the recents app"); } if (!canAccessProfile(user.getIdentifier(), "Can't access preinstalled packages for another user")) { return null; Loading @@ -1610,11 +1646,6 @@ public class LauncherAppsService extends SystemService { @Override public @Nullable IntentSender getAppMarketActivityIntent(@NonNull String callingPackage, @Nullable String packageName, @NonNull UserHandle user) { // Only system launchers, which have access to recents should have access to this API. // TODO(b/303803157): Update access control for this API to default Launcher app. if (!mActivityTaskManagerInternal.isCallerRecents(Binder.getCallingUid())) { throw new SecurityException("Caller is not the recents app"); } if (!canAccessProfile(user.getIdentifier(), "Can't access AppMarketActivity for another user")) { return null; Loading Loading
core/java/android/content/pm/multiuser.aconfig +7 −0 Original line number Diff line number Diff line Loading @@ -135,3 +135,10 @@ flag { description: "Allow the use of a profileApiAvailability user property to exclude HIDDEN profiles in API results" bug: "316362775" } flag { name: "enable_launcher_apps_hidden_profile_checks" namespace: "profile_experiences" description: "Enable extra check to limit access to hidden prfiles data in Launcher apps APIs." bug: "321988638" }
data/etc/privapp-permissions-platform.xml +2 −0 Original line number Diff line number Diff line Loading @@ -316,6 +316,8 @@ applications that come with the platform <permission name="android.permission.SET_LOW_POWER_STANDBY_PORTS" /> <permission name="android.permission.MANAGE_ROLLBACKS"/> <permission name="android.permission.MANAGE_USB"/> <!-- Permission required to test Launcher Apps APIs for hidden profiles --> <permission name="android.permission.ACCESS_HIDDEN_PROFILES_FULL" /> <!-- Needed for tests only --> <permission name="android.permission.MANAGE_CLOUDSEARCH" /> <permission name="android.permission.MANAGE_WALLPAPER_EFFECTS_GENERATION" /> Loading
packages/Shell/AndroidManifest.xml +2 −0 Original line number Diff line number Diff line Loading @@ -250,6 +250,8 @@ <uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS" /> <uses-permission android:name="android.permission.MOUNT_FORMAT_FILESYSTEMS" /> <uses-permission android:name="android.permission.MODIFY_PHONE_STATE" /> <!-- Permission required to test LauncherApps APIs for hidden profiles --> <uses-permission android:name="android.permission.ACCESS_HIDDEN_PROFILES_FULL" /> <!-- Shell only holds android.permission.NETWORK_SCAN in order to to enable CTS testing --> <uses-permission android:name="android.permission.NETWORK_SCAN" /> <uses-permission android:name="android.permission.REGISTER_CALL_PROVIDER" /> Loading
services/core/java/com/android/server/pm/LauncherAppsService.java +47 −16 Original line number Diff line number Diff line Loading @@ -38,6 +38,7 @@ import static android.content.pm.LauncherApps.FLAG_CACHE_PEOPLE_TILE_SHORTCUTS; import static com.android.server.pm.PackageArchiver.isArchivingEnabled; import android.Manifest; import android.annotation.AppIdInt; import android.annotation.NonNull; import android.annotation.Nullable; Loading @@ -52,6 +53,7 @@ import android.app.IApplicationThread; import android.app.PendingIntent; import android.app.admin.DevicePolicyCache; import android.app.admin.DevicePolicyManager; import android.app.role.RoleManager; import android.app.usage.UsageStatsManagerInternal; import android.content.ActivityNotFoundException; import android.content.BroadcastReceiver; Loading Loading @@ -84,7 +86,9 @@ import android.content.pm.ShortcutQueryWrapper; import android.content.pm.ShortcutServiceInternal; import android.content.pm.ShortcutServiceInternal.ShortcutChangeListener; import android.content.pm.UserInfo; import android.content.pm.UserProperties; import android.graphics.Rect; import android.multiuser.Flags; import android.net.Uri; import android.os.Binder; import android.os.Bundle; Loading Loading @@ -211,6 +215,7 @@ public class LauncherAppsService extends SystemService { private final Context mContext; private final UserManager mUm; private final RoleManager mRoleManager; private final IPackageManager mIPM; private final UserManagerInternal mUserManagerInternal; private final UsageStatsManagerInternal mUsageStatsManagerInternal; Loading Loading @@ -247,6 +252,7 @@ public class LauncherAppsService extends SystemService { mContext = context; mIPM = AppGlobals.getPackageManager(); mUm = (UserManager) mContext.getSystemService(Context.USER_SERVICE); mRoleManager = mContext.getSystemService(RoleManager.class); mUserManagerInternal = Objects.requireNonNull( LocalServices.getService(UserManagerInternal.class)); mUsageStatsManagerInternal = Objects.requireNonNull( Loading Loading @@ -451,7 +457,6 @@ public class LauncherAppsService extends SystemService { private boolean canAccessProfile(int callingUid, int callingUserId, int callingPid, int targetUserId, String message) { if (targetUserId == callingUserId) return true; if (injectHasInteractAcrossUsersFullPermission(callingPid, callingUid)) { return true; Loading @@ -465,6 +470,14 @@ public class LauncherAppsService extends SystemService { + targetUserId + " from " + callingUserId + " not allowed"); return false; } if (areHiddenApisChecksEnabled() && mUm.getUserProperties(UserHandle.of(targetUserId)) .getProfileApiVisibility() == UserProperties.PROFILE_API_VISIBILITY_HIDDEN && !canAccessHiddenProfileInjected(callingUid, callingPid)) { return false; } } finally { injectRestoreCallingIdentity(ident); } Loading @@ -473,10 +486,43 @@ public class LauncherAppsService extends SystemService { message, true); } boolean areHiddenApisChecksEnabled() { return android.os.Flags.allowPrivateProfile() && Flags.enableLauncherAppsHiddenProfileChecks() && Flags.enablePermissionToAccessHiddenProfiles(); } private void verifyCallingPackage(String callingPackage) { verifyCallingPackage(callingPackage, injectBinderCallingUid()); } boolean canAccessHiddenProfileInjected(int callingUid, int callingPid) { AndroidPackage callingPackage = mPackageManagerInternal.getPackage(callingUid); if (callingPackage == null) { return false; } if (!mRoleManager .getRoleHoldersAsUser( RoleManager.ROLE_HOME, UserHandle.getUserHandleForUid(callingUid)) .contains(callingPackage.getPackageName())) { return false; } if (mContext.checkPermission( Manifest.permission.ACCESS_HIDDEN_PROFILES_FULL, callingPid, callingUid) == PackageManager.PERMISSION_GRANTED) { return true; } // TODO(b/321988638): add option to disable with a flag return mContext.checkPermission( android.Manifest.permission.ACCESS_HIDDEN_PROFILES, callingPid, callingUid) == PackageManager.PERMISSION_GRANTED; } @VisibleForTesting // We override it in unit tests void verifyCallingPackage(String callingPackage, int callerUid) { int packageUid = -1; Loading Loading @@ -1566,11 +1612,6 @@ public class LauncherAppsService extends SystemService { @Override public @Nullable LauncherUserInfo getLauncherUserInfo(@NonNull UserHandle user) { // Only system launchers, which have access to recents should have access to this API. // TODO(b/303803157): Add the new permission check if we decide to have one. if (!mActivityTaskManagerInternal.isCallerRecents(Binder.getCallingUid())) { throw new SecurityException("Caller is not the recents app"); } if (!canAccessProfile(user.getIdentifier(), "Can't access LauncherUserInfo for another user")) { return null; Loading @@ -1585,11 +1626,6 @@ public class LauncherAppsService extends SystemService { @Override public List<String> getPreInstalledSystemPackages(UserHandle user) { // Only system launchers, which have access to recents should have access to this API. // TODO(b/303803157): Update access control for this API to default Launcher app. if (!mActivityTaskManagerInternal.isCallerRecents(Binder.getCallingUid())) { throw new SecurityException("Caller is not the recents app"); } if (!canAccessProfile(user.getIdentifier(), "Can't access preinstalled packages for another user")) { return null; Loading @@ -1610,11 +1646,6 @@ public class LauncherAppsService extends SystemService { @Override public @Nullable IntentSender getAppMarketActivityIntent(@NonNull String callingPackage, @Nullable String packageName, @NonNull UserHandle user) { // Only system launchers, which have access to recents should have access to this API. // TODO(b/303803157): Update access control for this API to default Launcher app. if (!mActivityTaskManagerInternal.isCallerRecents(Binder.getCallingUid())) { throw new SecurityException("Caller is not the recents app"); } if (!canAccessProfile(user.getIdentifier(), "Can't access AppMarketActivity for another user")) { return null; Loading