summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Cynthia Wasonga <wasonga@google.com> 2022-08-29 12:50:54 +0000
committer Android (Google) Code Review <android-gerrit@google.com> 2022-08-29 12:50:54 +0000
commit53a2440bd9475b26bcb749565eb60785f4355b88 (patch)
tree5c6af7f069f6410461fcb7f446ccbe59dcf0362c
parent92e7c989363412831769cfce2b8aaaa8bbf4bccd (diff)
parent4abe61d065ad24d71eec58a1f66cb35829a6f12c (diff)
Merge changes from topic "profile-removed-intent-and-tests"
* changes: Send ACTION_PROFILE_REMOVED broadcast Add ACTION_PROFILE_ADDED and REMOVED intents
-rw-r--r--core/api/current.txt2
-rw-r--r--core/java/android/content/Intent.java39
-rw-r--r--core/res/AndroidManifest.xml4
-rw-r--r--services/core/java/com/android/server/pm/UserManagerService.java45
4 files changed, 82 insertions, 8 deletions
diff --git a/core/api/current.txt b/core/api/current.txt
index 72ee7f741338..fd1fb4c36020 100644
--- a/core/api/current.txt
+++ b/core/api/current.txt
@@ -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_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_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_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_QUICK_CLOCK = "android.intent.action.QUICK_CLOCK";
field public static final String ACTION_QUICK_VIEW = "android.intent.action.QUICK_VIEW";
diff --git a/core/java/android/content/Intent.java b/core/java/android/content/Intent.java
index 0e0b2dc3df8a..896fe91696db 100644
--- a/core/java/android/content/Intent.java
+++ b/core/java/android/content/Intent.java
@@ -4092,6 +4092,45 @@ public class Intent implements Parcelable, Cloneable {
"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.
* Carries an extra {@link #EXTRA_USER_HANDLE} that specifies the ID of the user for which
* the device was locked or unlocked.
diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml
index cd518cea8d87..5b4fc56bc8ba 100644
--- a/core/res/AndroidManifest.xml
+++ b/core/res/AndroidManifest.xml
@@ -815,6 +815,10 @@
<protected-broadcast android:name="android.app.action.PROVISIONING_COMPLETED" />
<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 -->
<!-- ====================================================================== -->
diff --git a/services/core/java/com/android/server/pm/UserManagerService.java b/services/core/java/com/android/server/pm/UserManagerService.java
index ce77c8b1171c..d8b7fdab70f7 100644
--- a/services/core/java/com/android/server/pm/UserManagerService.java
+++ b/services/core/java/com/android/server/pm/UserManagerService.java
@@ -5099,12 +5099,9 @@ public class UserManagerService extends IUserManager.Stub {
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
- && userData.info.isManagedProfile()) {
- // Send broadcast to notify system that the user removed was a
- // managed user.
- sendProfileRemovedBroadcast(userData.info.profileGroupId, userData.info.id);
+ if (userData.info.profileGroupId != UserInfo.NO_PROFILE_GROUP_ID) {
+ sendProfileRemovedBroadcast(userData.info.profileGroupId, userData.info.id,
+ userData.info.userType);
}
if (DBG) Slog.i(LOG_TAG, "Stopping user " + userId);
@@ -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);
managedProfileIntent.putExtra(Intent.EXTRA_USER, new UserHandle(removedUserId));
managedProfileIntent.putExtra(Intent.EXTRA_USER_HANDLE, removedUserId);
- final UserHandle parentHandle = new UserHandle(parentUserId);
+ final UserHandle parentHandle = UserHandle.of(parentUserId);
getDevicePolicyManagerInternal().broadcastIntentToManifestReceivers(
managedProfileIntent, parentHandle, /* requiresPermission= */ false);
managedProfileIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY