Loading core/api/current.txt +2 −0 Original line number Original line Diff line number Diff line Loading @@ -10317,7 +10317,9 @@ package android.content { field public static final String ACTION_POWER_USAGE_SUMMARY = "android.intent.action.POWER_USAGE_SUMMARY"; field public static final String ACTION_POWER_USAGE_SUMMARY = "android.intent.action.POWER_USAGE_SUMMARY"; field public static final String ACTION_PROCESS_TEXT = "android.intent.action.PROCESS_TEXT"; field public static final String ACTION_PROCESS_TEXT = "android.intent.action.PROCESS_TEXT"; field public static final String ACTION_PROFILE_ACCESSIBLE = "android.intent.action.PROFILE_ACCESSIBLE"; field public static final String ACTION_PROFILE_ACCESSIBLE = "android.intent.action.PROFILE_ACCESSIBLE"; field public static final String ACTION_PROFILE_ADDED = "android.intent.action.PROFILE_ADDED"; field public static final String ACTION_PROFILE_INACCESSIBLE = "android.intent.action.PROFILE_INACCESSIBLE"; field public static final String ACTION_PROFILE_INACCESSIBLE = "android.intent.action.PROFILE_INACCESSIBLE"; field public static final String ACTION_PROFILE_REMOVED = "android.intent.action.PROFILE_REMOVED"; field public static final String ACTION_PROVIDER_CHANGED = "android.intent.action.PROVIDER_CHANGED"; field public static final String ACTION_PROVIDER_CHANGED = "android.intent.action.PROVIDER_CHANGED"; field public static final String ACTION_QUICK_CLOCK = "android.intent.action.QUICK_CLOCK"; field public static final String ACTION_QUICK_CLOCK = "android.intent.action.QUICK_CLOCK"; field public static final String ACTION_QUICK_VIEW = "android.intent.action.QUICK_VIEW"; field public static final String ACTION_QUICK_VIEW = "android.intent.action.QUICK_VIEW"; core/java/android/content/Intent.java +39 −0 Original line number Original line Diff line number Diff line Loading @@ -4091,6 +4091,45 @@ public class Intent implements Parcelable, Cloneable { public static final String ACTION_PROFILE_INACCESSIBLE = public static final String ACTION_PROFILE_INACCESSIBLE = "android.intent.action.PROFILE_INACCESSIBLE"; "android.intent.action.PROFILE_INACCESSIBLE"; /** * Broadcast sent to the parent user when an associated profile is removed. * Carries an extra {@link #EXTRA_USER} that specifies the {@link UserHandle} of the profile * that was removed. * * <p>This broadcast is similar to {@link #ACTION_MANAGED_PROFILE_REMOVED} but functions as a * generic broadcast for all users of type {@link android.content.pm.UserInfo#isProfile()}}. * It is sent in addition to the {@link #ACTION_MANAGED_PROFILE_REMOVED} broadcast when a * managed user is removed. * * <p>Only applications (for example Launchers) that need to display merged content across both * the parent user and its associated profiles need to worry about this broadcast. * This is only sent to registered receivers created with {@link Context#registerReceiver}. * It is not sent to manifest receivers. */ @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION) public static final String ACTION_PROFILE_REMOVED = "android.intent.action.PROFILE_REMOVED"; /** * Broadcast sent to the parent user when an associated profile is added (the profile was * created and is ready to be used). * Carries an extra {@link #EXTRA_USER} that specifies the {@link UserHandle} of the profile * that was added. * * <p>This broadcast is similar to {@link #ACTION_MANAGED_PROFILE_ADDED} but functions as a * generic broadcast for all users of type {@link android.content.pm.UserInfo#isProfile()}}. * It is sent in addition to the {@link #ACTION_MANAGED_PROFILE_ADDED} broadcast when a * managed user is added. * * <p>Only applications (for example Launchers) that need to display merged content across both * the parent user and its associated profiles need to worry about this broadcast. * This is only sent to registered receivers created with {@link Context#registerReceiver}. * It is not sent to manifest receivers. */ @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION) public static final String ACTION_PROFILE_ADDED = "android.intent.action.PROFILE_ADDED"; /** /** * Broadcast sent to the system user when the 'device locked' state changes for any user. * Broadcast sent to the system user when the 'device locked' state changes for any user. * Carries an extra {@link #EXTRA_USER_HANDLE} that specifies the ID of the user for which * Carries an extra {@link #EXTRA_USER_HANDLE} that specifies the ID of the user for which Loading core/res/AndroidManifest.xml +4 −0 Original line number Original line Diff line number Diff line Loading @@ -815,6 +815,10 @@ <protected-broadcast android:name="android.app.action.PROVISIONING_COMPLETED" /> <protected-broadcast android:name="android.app.action.PROVISIONING_COMPLETED" /> <protected-broadcast android:name="android.app.action.LOST_MODE_LOCATION_UPDATE" /> <protected-broadcast android:name="android.app.action.LOST_MODE_LOCATION_UPDATE" /> <!-- Added in U --> <protected-broadcast android:name="android.intent.action.PROFILE_ADDED" /> <protected-broadcast android:name="android.intent.action.PROFILE_REMOVED" /> <!-- ====================================================================== --> <!-- ====================================================================== --> <!-- RUNTIME PERMISSIONS --> <!-- RUNTIME PERMISSIONS --> <!-- ====================================================================== --> <!-- ====================================================================== --> Loading services/core/java/com/android/server/pm/UserManagerService.java +37 −8 Original line number Original line Diff line number Diff line Loading @@ -5099,12 +5099,9 @@ public class UserManagerService extends IUserManager.Stub { Slog.w(LOG_TAG, "Unable to notify AppOpsService of removing user.", e); Slog.w(LOG_TAG, "Unable to notify AppOpsService of removing user.", e); } } // TODO(b/142482943): Send some sort of broadcast for profiles even if non-managed? if (userData.info.profileGroupId != UserInfo.NO_PROFILE_GROUP_ID) { if (userData.info.profileGroupId != UserInfo.NO_PROFILE_GROUP_ID sendProfileRemovedBroadcast(userData.info.profileGroupId, userData.info.id, && userData.info.isManagedProfile()) { userData.info.userType); // Send broadcast to notify system that the user removed was a // managed user. sendProfileRemovedBroadcast(userData.info.profileGroupId, userData.info.id); } } if (DBG) Slog.i(LOG_TAG, "Stopping user " + userId); if (DBG) Slog.i(LOG_TAG, "Stopping user " + userId); Loading Loading @@ -5331,11 +5328,43 @@ public class UserManagerService extends IUserManager.Stub { } } } } private void sendProfileRemovedBroadcast(int parentUserId, int removedUserId) { /** * Send {@link Intent#ACTION_PROFILE_REMOVED} broadcast when a user of type * {@link UserInfo#isProfile()} is removed. Additionally sends * {@link Intent#ACTION_MANAGED_PROFILE_REMOVED} broadcast if the profile is of type * {@link UserManager#USER_TYPE_PROFILE_MANAGED} * * <p> {@link Intent#ACTION_PROFILE_REMOVED} is a generalized broadcast for all users of type * {@link UserInfo#isProfile()} and is sent only to dynamic receivers. * * <p> In contrast, the {@link Intent#ACTION_MANAGED_PROFILE_REMOVED} broadcast is specific to * {@link UserManager#USER_TYPE_PROFILE_MANAGED} and is sent to both manifest and dynamic * receivers thus it is still needed as manifest receivers will not be able to listen to * the aforementioned generalized broadcast. */ private void sendProfileRemovedBroadcast(int parentUserId, int removedUserId, String userType) { if (Objects.equals(userType, UserManager.USER_TYPE_PROFILE_MANAGED)) { sendManagedProfileRemovedBroadcast(parentUserId, removedUserId); } sendProfileBroadcastToRegisteredReceivers( new Intent(Intent.ACTION_PROFILE_REMOVED), parentUserId, removedUserId); } private void sendProfileBroadcastToRegisteredReceivers(Intent intent, int parentUserId, int userId) { final UserHandle parentHandle = UserHandle.of(parentUserId); intent.putExtra(Intent.EXTRA_USER, UserHandle.of(userId)); intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY | Intent.FLAG_RECEIVER_FOREGROUND); mContext.sendBroadcastAsUser(intent, parentHandle, /* receiverPermission= */null); } private void sendManagedProfileRemovedBroadcast(int parentUserId, int removedUserId) { Intent managedProfileIntent = new Intent(Intent.ACTION_MANAGED_PROFILE_REMOVED); Intent managedProfileIntent = new Intent(Intent.ACTION_MANAGED_PROFILE_REMOVED); managedProfileIntent.putExtra(Intent.EXTRA_USER, new UserHandle(removedUserId)); managedProfileIntent.putExtra(Intent.EXTRA_USER, new UserHandle(removedUserId)); managedProfileIntent.putExtra(Intent.EXTRA_USER_HANDLE, removedUserId); managedProfileIntent.putExtra(Intent.EXTRA_USER_HANDLE, removedUserId); final UserHandle parentHandle = new UserHandle(parentUserId); final UserHandle parentHandle = UserHandle.of(parentUserId); getDevicePolicyManagerInternal().broadcastIntentToManifestReceivers( getDevicePolicyManagerInternal().broadcastIntentToManifestReceivers( managedProfileIntent, parentHandle, /* requiresPermission= */ false); managedProfileIntent, parentHandle, /* requiresPermission= */ false); managedProfileIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY managedProfileIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY Loading Loading
core/api/current.txt +2 −0 Original line number Original line Diff line number Diff line Loading @@ -10317,7 +10317,9 @@ package android.content { field public static final String ACTION_POWER_USAGE_SUMMARY = "android.intent.action.POWER_USAGE_SUMMARY"; field public static final String ACTION_POWER_USAGE_SUMMARY = "android.intent.action.POWER_USAGE_SUMMARY"; field public static final String ACTION_PROCESS_TEXT = "android.intent.action.PROCESS_TEXT"; field public static final String ACTION_PROCESS_TEXT = "android.intent.action.PROCESS_TEXT"; field public static final String ACTION_PROFILE_ACCESSIBLE = "android.intent.action.PROFILE_ACCESSIBLE"; field public static final String ACTION_PROFILE_ACCESSIBLE = "android.intent.action.PROFILE_ACCESSIBLE"; field public static final String ACTION_PROFILE_ADDED = "android.intent.action.PROFILE_ADDED"; field public static final String ACTION_PROFILE_INACCESSIBLE = "android.intent.action.PROFILE_INACCESSIBLE"; field public static final String ACTION_PROFILE_INACCESSIBLE = "android.intent.action.PROFILE_INACCESSIBLE"; field public static final String ACTION_PROFILE_REMOVED = "android.intent.action.PROFILE_REMOVED"; field public static final String ACTION_PROVIDER_CHANGED = "android.intent.action.PROVIDER_CHANGED"; field public static final String ACTION_PROVIDER_CHANGED = "android.intent.action.PROVIDER_CHANGED"; field public static final String ACTION_QUICK_CLOCK = "android.intent.action.QUICK_CLOCK"; field public static final String ACTION_QUICK_CLOCK = "android.intent.action.QUICK_CLOCK"; field public static final String ACTION_QUICK_VIEW = "android.intent.action.QUICK_VIEW"; field public static final String ACTION_QUICK_VIEW = "android.intent.action.QUICK_VIEW";
core/java/android/content/Intent.java +39 −0 Original line number Original line Diff line number Diff line Loading @@ -4091,6 +4091,45 @@ public class Intent implements Parcelable, Cloneable { public static final String ACTION_PROFILE_INACCESSIBLE = public static final String ACTION_PROFILE_INACCESSIBLE = "android.intent.action.PROFILE_INACCESSIBLE"; "android.intent.action.PROFILE_INACCESSIBLE"; /** * Broadcast sent to the parent user when an associated profile is removed. * Carries an extra {@link #EXTRA_USER} that specifies the {@link UserHandle} of the profile * that was removed. * * <p>This broadcast is similar to {@link #ACTION_MANAGED_PROFILE_REMOVED} but functions as a * generic broadcast for all users of type {@link android.content.pm.UserInfo#isProfile()}}. * It is sent in addition to the {@link #ACTION_MANAGED_PROFILE_REMOVED} broadcast when a * managed user is removed. * * <p>Only applications (for example Launchers) that need to display merged content across both * the parent user and its associated profiles need to worry about this broadcast. * This is only sent to registered receivers created with {@link Context#registerReceiver}. * It is not sent to manifest receivers. */ @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION) public static final String ACTION_PROFILE_REMOVED = "android.intent.action.PROFILE_REMOVED"; /** * Broadcast sent to the parent user when an associated profile is added (the profile was * created and is ready to be used). * Carries an extra {@link #EXTRA_USER} that specifies the {@link UserHandle} of the profile * that was added. * * <p>This broadcast is similar to {@link #ACTION_MANAGED_PROFILE_ADDED} but functions as a * generic broadcast for all users of type {@link android.content.pm.UserInfo#isProfile()}}. * It is sent in addition to the {@link #ACTION_MANAGED_PROFILE_ADDED} broadcast when a * managed user is added. * * <p>Only applications (for example Launchers) that need to display merged content across both * the parent user and its associated profiles need to worry about this broadcast. * This is only sent to registered receivers created with {@link Context#registerReceiver}. * It is not sent to manifest receivers. */ @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION) public static final String ACTION_PROFILE_ADDED = "android.intent.action.PROFILE_ADDED"; /** /** * Broadcast sent to the system user when the 'device locked' state changes for any user. * Broadcast sent to the system user when the 'device locked' state changes for any user. * Carries an extra {@link #EXTRA_USER_HANDLE} that specifies the ID of the user for which * Carries an extra {@link #EXTRA_USER_HANDLE} that specifies the ID of the user for which Loading
core/res/AndroidManifest.xml +4 −0 Original line number Original line Diff line number Diff line Loading @@ -815,6 +815,10 @@ <protected-broadcast android:name="android.app.action.PROVISIONING_COMPLETED" /> <protected-broadcast android:name="android.app.action.PROVISIONING_COMPLETED" /> <protected-broadcast android:name="android.app.action.LOST_MODE_LOCATION_UPDATE" /> <protected-broadcast android:name="android.app.action.LOST_MODE_LOCATION_UPDATE" /> <!-- Added in U --> <protected-broadcast android:name="android.intent.action.PROFILE_ADDED" /> <protected-broadcast android:name="android.intent.action.PROFILE_REMOVED" /> <!-- ====================================================================== --> <!-- ====================================================================== --> <!-- RUNTIME PERMISSIONS --> <!-- RUNTIME PERMISSIONS --> <!-- ====================================================================== --> <!-- ====================================================================== --> Loading
services/core/java/com/android/server/pm/UserManagerService.java +37 −8 Original line number Original line Diff line number Diff line Loading @@ -5099,12 +5099,9 @@ public class UserManagerService extends IUserManager.Stub { Slog.w(LOG_TAG, "Unable to notify AppOpsService of removing user.", e); Slog.w(LOG_TAG, "Unable to notify AppOpsService of removing user.", e); } } // TODO(b/142482943): Send some sort of broadcast for profiles even if non-managed? if (userData.info.profileGroupId != UserInfo.NO_PROFILE_GROUP_ID) { if (userData.info.profileGroupId != UserInfo.NO_PROFILE_GROUP_ID sendProfileRemovedBroadcast(userData.info.profileGroupId, userData.info.id, && userData.info.isManagedProfile()) { userData.info.userType); // Send broadcast to notify system that the user removed was a // managed user. sendProfileRemovedBroadcast(userData.info.profileGroupId, userData.info.id); } } if (DBG) Slog.i(LOG_TAG, "Stopping user " + userId); if (DBG) Slog.i(LOG_TAG, "Stopping user " + userId); Loading Loading @@ -5331,11 +5328,43 @@ public class UserManagerService extends IUserManager.Stub { } } } } private void sendProfileRemovedBroadcast(int parentUserId, int removedUserId) { /** * Send {@link Intent#ACTION_PROFILE_REMOVED} broadcast when a user of type * {@link UserInfo#isProfile()} is removed. Additionally sends * {@link Intent#ACTION_MANAGED_PROFILE_REMOVED} broadcast if the profile is of type * {@link UserManager#USER_TYPE_PROFILE_MANAGED} * * <p> {@link Intent#ACTION_PROFILE_REMOVED} is a generalized broadcast for all users of type * {@link UserInfo#isProfile()} and is sent only to dynamic receivers. * * <p> In contrast, the {@link Intent#ACTION_MANAGED_PROFILE_REMOVED} broadcast is specific to * {@link UserManager#USER_TYPE_PROFILE_MANAGED} and is sent to both manifest and dynamic * receivers thus it is still needed as manifest receivers will not be able to listen to * the aforementioned generalized broadcast. */ private void sendProfileRemovedBroadcast(int parentUserId, int removedUserId, String userType) { if (Objects.equals(userType, UserManager.USER_TYPE_PROFILE_MANAGED)) { sendManagedProfileRemovedBroadcast(parentUserId, removedUserId); } sendProfileBroadcastToRegisteredReceivers( new Intent(Intent.ACTION_PROFILE_REMOVED), parentUserId, removedUserId); } private void sendProfileBroadcastToRegisteredReceivers(Intent intent, int parentUserId, int userId) { final UserHandle parentHandle = UserHandle.of(parentUserId); intent.putExtra(Intent.EXTRA_USER, UserHandle.of(userId)); intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY | Intent.FLAG_RECEIVER_FOREGROUND); mContext.sendBroadcastAsUser(intent, parentHandle, /* receiverPermission= */null); } private void sendManagedProfileRemovedBroadcast(int parentUserId, int removedUserId) { Intent managedProfileIntent = new Intent(Intent.ACTION_MANAGED_PROFILE_REMOVED); Intent managedProfileIntent = new Intent(Intent.ACTION_MANAGED_PROFILE_REMOVED); managedProfileIntent.putExtra(Intent.EXTRA_USER, new UserHandle(removedUserId)); managedProfileIntent.putExtra(Intent.EXTRA_USER, new UserHandle(removedUserId)); managedProfileIntent.putExtra(Intent.EXTRA_USER_HANDLE, removedUserId); managedProfileIntent.putExtra(Intent.EXTRA_USER_HANDLE, removedUserId); final UserHandle parentHandle = new UserHandle(parentUserId); final UserHandle parentHandle = UserHandle.of(parentUserId); getDevicePolicyManagerInternal().broadcastIntentToManifestReceivers( getDevicePolicyManagerInternal().broadcastIntentToManifestReceivers( managedProfileIntent, parentHandle, /* requiresPermission= */ false); managedProfileIntent, parentHandle, /* requiresPermission= */ false); managedProfileIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY managedProfileIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY Loading