Add registering for explicit users.
New API to register as an explicit user, which allows you to
also select ALL to see broadcasts for all users.
New BroadcastReceiver API to find out which user the broadcast
was sent to.
Use this in app widget service to handle per-user package broadcasts
and boot completed broadcasts correctly.
Change-Id: Ibbe28993bd4aa93900c79e412026c27863019eb8
diff --git a/services/java/com/android/server/am/ActivityManagerService.java b/services/java/com/android/server/am/ActivityManagerService.java
index 590e9d9..3c379d17 100644
--- a/services/java/com/android/server/am/ActivityManagerService.java
+++ b/services/java/com/android/server/am/ActivityManagerService.java
@@ -495,7 +495,8 @@
@Override
protected BroadcastFilter newResult(BroadcastFilter filter, int match, int userId) {
- if (userId == UserHandle.USER_ALL || userId == filter.owningUserId) {
+ if (userId == UserHandle.USER_ALL || filter.owningUserId == UserHandle.USER_ALL
+ || userId == filter.owningUserId) {
return super.newResult(filter, match, userId);
}
return null;
@@ -7549,7 +7550,7 @@
finisher = new IIntentReceiver.Stub() {
public void performReceive(Intent intent, int resultCode,
String data, Bundle extras, boolean ordered,
- boolean sticky) {
+ boolean sticky, int sendingUser) {
// The raw IIntentReceiver interface is called
// with the AM lock held, so redispatch to
// execute our code without the lock.
@@ -11038,9 +11039,10 @@
}
public Intent registerReceiver(IApplicationThread caller, String callerPackage,
- IIntentReceiver receiver, IntentFilter filter, String permission) {
+ IIntentReceiver receiver, IntentFilter filter, String permission, int userId) {
enforceNotIsolatedCaller("registerReceiver");
int callingUid;
+ int callingPid;
synchronized(this) {
ProcessRecord callerApp = null;
if (caller != null) {
@@ -11057,11 +11059,16 @@
+ " is not running in process " + callerApp);
}
callingUid = callerApp.info.uid;
+ callingPid = callerApp.pid;
} else {
callerPackage = null;
callingUid = Binder.getCallingUid();
+ callingPid = Binder.getCallingPid();
}
+ userId = this.handleIncomingUserLocked(callingPid, callingUid, userId,
+ true, true, "registerReceiver", callerPackage);
+
List allSticky = null;
// Look for any matching sticky broadcasts...
@@ -11095,9 +11102,8 @@
ReceiverList rl
= (ReceiverList)mRegisteredReceivers.get(receiver.asBinder());
if (rl == null) {
- rl = new ReceiverList(this, callerApp,
- Binder.getCallingPid(),
- Binder.getCallingUid(), receiver);
+ rl = new ReceiverList(this, callerApp, callingPid, callingUid,
+ userId, receiver);
if (rl.app != null) {
rl.app.receivers.add(rl);
} else {
@@ -11109,9 +11115,21 @@
rl.linkedToDeath = true;
}
mRegisteredReceivers.put(receiver.asBinder(), rl);
+ } else if (rl.uid != callingUid) {
+ throw new IllegalArgumentException(
+ "Receiver requested to register for uid " + callingUid
+ + " was previously registered for uid " + rl.uid);
+ } else if (rl.pid != callingPid) {
+ throw new IllegalArgumentException(
+ "Receiver requested to register for pid " + callingPid
+ + " was previously registered for pid " + rl.pid);
+ } else if (rl.userId != userId) {
+ throw new IllegalArgumentException(
+ "Receiver requested to register for user " + userId
+ + " was previously registered for user " + rl.userId);
}
BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage,
- permission, callingUid);
+ permission, callingUid, userId);
rl.add(bf);
if (!bf.debugCheck()) {
Slog.w(TAG, "==> For Dynamic broadast");
@@ -13834,7 +13852,7 @@
final IIntentReceiver resultReceiver = new IIntentReceiver.Stub() {
@Override
public void performReceive(Intent intent, int resultCode, String data,
- Bundle extras, boolean ordered, boolean sticky) {
+ Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
finishUserStop(uss);
}
};