Skip to content

Commit 20e8098

Browse files
author
Dianne Hackborn
committed
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
1 parent 2701f32 commit 20e8098

22 files changed

+205
-71
lines changed

core/java/android/app/ActivityManagerNative.java

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -300,7 +300,8 @@ public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
300300
= b != null ? IIntentReceiver.Stub.asInterface(b) : null;
301301
IntentFilter filter = IntentFilter.CREATOR.createFromParcel(data);
302302
String perm = data.readString();
303-
Intent intent = registerReceiver(app, packageName, rec, filter, perm);
303+
int userId = data.readInt();
304+
Intent intent = registerReceiver(app, packageName, rec, filter, perm, userId);
304305
reply.writeNoException();
305306
if (intent != null) {
306307
reply.writeInt(1);
@@ -1999,7 +2000,7 @@ public boolean willActivityBeVisible(IBinder token) throws RemoteException {
19992000
}
20002001
public Intent registerReceiver(IApplicationThread caller, String packageName,
20012002
IIntentReceiver receiver,
2002-
IntentFilter filter, String perm) throws RemoteException
2003+
IntentFilter filter, String perm, int userId) throws RemoteException
20032004
{
20042005
Parcel data = Parcel.obtain();
20052006
Parcel reply = Parcel.obtain();
@@ -2009,6 +2010,7 @@ public Intent registerReceiver(IApplicationThread caller, String packageName,
20092010
data.writeStrongBinder(receiver != null ? receiver.asBinder() : null);
20102011
filter.writeToParcel(data, 0);
20112012
data.writeString(perm);
2013+
data.writeInt(userId);
20122014
mRemote.transact(REGISTER_RECEIVER_TRANSACTION, data, reply, 0);
20132015
reply.readException();
20142016
Intent intent = null;

core/java/android/app/ActivityThread.java

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -320,8 +320,9 @@ public String toString() {
320320

321321
static final class ReceiverData extends BroadcastReceiver.PendingResult {
322322
public ReceiverData(Intent intent, int resultCode, String resultData, Bundle resultExtras,
323-
boolean ordered, boolean sticky, IBinder token) {
324-
super(resultCode, resultData, resultExtras, TYPE_COMPONENT, ordered, sticky, token);
323+
boolean ordered, boolean sticky, IBinder token, int sendingUser) {
324+
super(resultCode, resultData, resultExtras, TYPE_COMPONENT, ordered, sticky,
325+
token, sendingUser);
325326
this.intent = intent;
326327
}
327328

@@ -613,9 +614,9 @@ public final void scheduleDestroyActivity(IBinder token, boolean finishing,
613614

614615
public final void scheduleReceiver(Intent intent, ActivityInfo info,
615616
CompatibilityInfo compatInfo, int resultCode, String data, Bundle extras,
616-
boolean sync) {
617+
boolean sync, int sendingUser) {
617618
ReceiverData r = new ReceiverData(intent, resultCode, data, extras,
618-
sync, false, mAppThread.asBinder());
619+
sync, false, mAppThread.asBinder(), sendingUser);
619620
r.info = info;
620621
r.compatInfo = compatInfo;
621622
queueOrSendMessage(H.RECEIVER, r);
@@ -774,8 +775,9 @@ public void dumpService(FileDescriptor fd, IBinder servicetoken, String[] args)
774775
// applies transaction ordering per object for such calls.
775776
public void scheduleRegisteredReceiver(IIntentReceiver receiver, Intent intent,
776777
int resultCode, String dataStr, Bundle extras, boolean ordered,
777-
boolean sticky) throws RemoteException {
778-
receiver.performReceive(intent, resultCode, dataStr, extras, ordered, sticky);
778+
boolean sticky, int sendingUser) throws RemoteException {
779+
receiver.performReceive(intent, resultCode, dataStr, extras, ordered,
780+
sticky, sendingUser);
779781
}
780782

781783
public void scheduleLowMemory() {

core/java/android/app/ApplicationThreadNative.java

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -193,8 +193,9 @@ public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
193193
String resultData = data.readString();
194194
Bundle resultExtras = data.readBundle();
195195
boolean sync = data.readInt() != 0;
196+
int sendingUser = data.readInt();
196197
scheduleReceiver(intent, info, compatInfo, resultCode, resultData,
197-
resultExtras, sync);
198+
resultExtras, sync, sendingUser);
198199
return true;
199200
}
200201

@@ -378,8 +379,9 @@ public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
378379
Bundle extras = data.readBundle();
379380
boolean ordered = data.readInt() != 0;
380381
boolean sticky = data.readInt() != 0;
382+
int sendingUser = data.readInt();
381383
scheduleRegisteredReceiver(receiver, intent,
382-
resultCode, dataStr, extras, ordered, sticky);
384+
resultCode, dataStr, extras, ordered, sticky, sendingUser);
383385
return true;
384386
}
385387

@@ -755,7 +757,7 @@ public final void scheduleDestroyActivity(IBinder token, boolean finishing,
755757

756758
public final void scheduleReceiver(Intent intent, ActivityInfo info,
757759
CompatibilityInfo compatInfo, int resultCode, String resultData,
758-
Bundle map, boolean sync) throws RemoteException {
760+
Bundle map, boolean sync, int sendingUser) throws RemoteException {
759761
Parcel data = Parcel.obtain();
760762
data.writeInterfaceToken(IApplicationThread.descriptor);
761763
intent.writeToParcel(data, 0);
@@ -765,6 +767,7 @@ public final void scheduleReceiver(Intent intent, ActivityInfo info,
765767
data.writeString(resultData);
766768
data.writeBundle(map);
767769
data.writeInt(sync ? 1 : 0);
770+
data.writeInt(sendingUser);
768771
mRemote.transact(SCHEDULE_RECEIVER_TRANSACTION, data, null,
769772
IBinder.FLAG_ONEWAY);
770773
data.recycle();
@@ -991,8 +994,8 @@ public void dumpProvider(FileDescriptor fd, IBinder token, String[] args)
991994
}
992995

993996
public void scheduleRegisteredReceiver(IIntentReceiver receiver, Intent intent,
994-
int resultCode, String dataStr, Bundle extras, boolean ordered, boolean sticky)
995-
throws RemoteException {
997+
int resultCode, String dataStr, Bundle extras, boolean ordered,
998+
boolean sticky, int sendingUser) throws RemoteException {
996999
Parcel data = Parcel.obtain();
9971000
data.writeInterfaceToken(IApplicationThread.descriptor);
9981001
data.writeStrongBinder(receiver.asBinder());
@@ -1002,6 +1005,7 @@ public void scheduleRegisteredReceiver(IIntentReceiver receiver, Intent intent,
10021005
data.writeBundle(extras);
10031006
data.writeInt(ordered ? 1 : 0);
10041007
data.writeInt(sticky ? 1 : 0);
1008+
data.writeInt(sendingUser);
10051009
mRemote.transact(SCHEDULE_REGISTERED_RECEIVER_TRANSACTION, data, null,
10061010
IBinder.FLAG_ONEWAY);
10071011
data.recycle();

core/java/android/app/ContextImpl.java

Lines changed: 22 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -137,6 +137,17 @@ public Intent registerReceiver(BroadcastReceiver receiver, IntentFilter filter,
137137
// scheduler);
138138
}
139139

140+
@Override
141+
public Intent registerReceiverAsUser(BroadcastReceiver receiver, UserHandle user,
142+
IntentFilter filter, String broadcastPermission, Handler scheduler) {
143+
throw new ReceiverCallNotAllowedException(
144+
"IntentReceiver components are not allowed to register to receive intents");
145+
//ex.fillInStackTrace();
146+
//Log.e("IntentReceiver", ex.getMessage(), ex);
147+
//return mContext.registerReceiver(receiver, filter, broadcastPermission,
148+
// scheduler);
149+
}
150+
140151
@Override
141152
public boolean bindService(Intent service, ServiceConnection conn, int flags) {
142153
throw new ReceiverCallNotAllowedException(
@@ -1252,11 +1263,18 @@ public Intent registerReceiver(BroadcastReceiver receiver, IntentFilter filter)
12521263
@Override
12531264
public Intent registerReceiver(BroadcastReceiver receiver, IntentFilter filter,
12541265
String broadcastPermission, Handler scheduler) {
1255-
return registerReceiverInternal(receiver, filter, broadcastPermission,
1256-
scheduler, getOuterContext());
1266+
return registerReceiverInternal(receiver, UserHandle.myUserId(),
1267+
filter, broadcastPermission, scheduler, getOuterContext());
1268+
}
1269+
1270+
@Override
1271+
public Intent registerReceiverAsUser(BroadcastReceiver receiver, UserHandle user,
1272+
IntentFilter filter, String broadcastPermission, Handler scheduler) {
1273+
return registerReceiverInternal(receiver, user.getIdentifier(),
1274+
filter, broadcastPermission, scheduler, getOuterContext());
12571275
}
12581276

1259-
private Intent registerReceiverInternal(BroadcastReceiver receiver,
1277+
private Intent registerReceiverInternal(BroadcastReceiver receiver, int userId,
12601278
IntentFilter filter, String broadcastPermission,
12611279
Handler scheduler, Context context) {
12621280
IIntentReceiver rd = null;
@@ -1279,7 +1297,7 @@ private Intent registerReceiverInternal(BroadcastReceiver receiver,
12791297
try {
12801298
return ActivityManagerNative.getDefault().registerReceiver(
12811299
mMainThread.getApplicationThread(), mBasePackageName,
1282-
rd, filter, broadcastPermission);
1300+
rd, filter, broadcastPermission, userId);
12831301
} catch (RemoteException e) {
12841302
return null;
12851303
}

core/java/android/app/IActivityManager.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,7 @@ public boolean finishActivity(IBinder token, int code, Intent data)
8080
public boolean willActivityBeVisible(IBinder token) throws RemoteException;
8181
public Intent registerReceiver(IApplicationThread caller, String callerPackage,
8282
IIntentReceiver receiver, IntentFilter filter,
83-
String requiredPermission) throws RemoteException;
83+
String requiredPermission, int userId) throws RemoteException;
8484
public void unregisterReceiver(IIntentReceiver receiver) throws RemoteException;
8585
public int broadcastIntent(IApplicationThread caller, Intent intent,
8686
String resolvedType, IIntentReceiver resultTo, int resultCode,

core/java/android/app/IApplicationThread.java

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,8 @@ void scheduleRelaunchActivity(IBinder token, List<ResultInfo> pendingResults,
6565
void scheduleDestroyActivity(IBinder token, boolean finished,
6666
int configChanges) throws RemoteException;
6767
void scheduleReceiver(Intent intent, ActivityInfo info, CompatibilityInfo compatInfo,
68-
int resultCode, String data, Bundle extras, boolean sync) throws RemoteException;
68+
int resultCode, String data, Bundle extras, boolean sync,
69+
int sendingUser) throws RemoteException;
6970
static final int BACKUP_MODE_INCREMENTAL = 0;
7071
static final int BACKUP_MODE_FULL = 1;
7172
static final int BACKUP_MODE_RESTORE = 2;
@@ -105,8 +106,8 @@ void dumpService(FileDescriptor fd, IBinder servicetoken, String[] args)
105106
void dumpProvider(FileDescriptor fd, IBinder servicetoken, String[] args)
106107
throws RemoteException;
107108
void scheduleRegisteredReceiver(IIntentReceiver receiver, Intent intent,
108-
int resultCode, String data, Bundle extras, boolean ordered, boolean sticky)
109-
throws RemoteException;
109+
int resultCode, String data, Bundle extras, boolean ordered,
110+
boolean sticky, int sendingUser) throws RemoteException;
110111
void scheduleLowMemory() throws RemoteException;
111112
void scheduleActivityConfigurationChanged(IBinder token) throws RemoteException;
112113
void profilerControl(boolean start, String path, ParcelFileDescriptor fd, int profileType)

core/java/android/app/LoadedApk.java

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -670,8 +670,8 @@ final static class InnerReceiver extends IIntentReceiver.Stub {
670670
mDispatcher = new WeakReference<LoadedApk.ReceiverDispatcher>(rd);
671671
mStrongRef = strong ? rd : null;
672672
}
673-
public void performReceive(Intent intent, int resultCode,
674-
String data, Bundle extras, boolean ordered, boolean sticky) {
673+
public void performReceive(Intent intent, int resultCode, String data,
674+
Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
675675
LoadedApk.ReceiverDispatcher rd = mDispatcher.get();
676676
if (ActivityThread.DEBUG_BROADCAST) {
677677
int seq = intent.getIntExtra("seq", -1);
@@ -680,7 +680,7 @@ public void performReceive(Intent intent, int resultCode,
680680
}
681681
if (rd != null) {
682682
rd.performReceive(intent, resultCode, data, extras,
683-
ordered, sticky);
683+
ordered, sticky, sendingUser);
684684
} else {
685685
// The activity manager dispatched a broadcast to a registered
686686
// receiver in this process, but before it could be delivered the
@@ -716,10 +716,10 @@ final class Args extends BroadcastReceiver.PendingResult implements Runnable {
716716
private final boolean mOrdered;
717717

718718
public Args(Intent intent, int resultCode, String resultData, Bundle resultExtras,
719-
boolean ordered, boolean sticky) {
719+
boolean ordered, boolean sticky, int sendingUser) {
720720
super(resultCode, resultData, resultExtras,
721721
mRegistered ? TYPE_REGISTERED : TYPE_UNREGISTERED,
722-
ordered, sticky, mIIntentReceiver.asBinder());
722+
ordered, sticky, mIIntentReceiver.asBinder(), sendingUser);
723723
mCurIntent = intent;
724724
mOrdered = ordered;
725725
}
@@ -830,14 +830,15 @@ RuntimeException getUnregisterLocation() {
830830
return mUnregisterLocation;
831831
}
832832

833-
public void performReceive(Intent intent, int resultCode,
834-
String data, Bundle extras, boolean ordered, boolean sticky) {
833+
public void performReceive(Intent intent, int resultCode, String data,
834+
Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
835835
if (ActivityThread.DEBUG_BROADCAST) {
836836
int seq = intent.getIntExtra("seq", -1);
837837
Slog.i(ActivityThread.TAG, "Enqueueing broadcast " + intent.getAction() + " seq=" + seq
838838
+ " to " + mReceiver);
839839
}
840-
Args args = new Args(intent, resultCode, data, extras, ordered, sticky);
840+
Args args = new Args(intent, resultCode, data, extras, ordered,
841+
sticky, sendingUser);
841842
if (!mActivityThread.post(args)) {
842843
if (mRegistered && ordered) {
843844
IActivityManager mgr = ActivityManagerNative.getDefault();

core/java/android/app/PendingIntent.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -147,8 +147,8 @@ private static class FinishedDispatcher extends IIntentReceiver.Stub
147147
mWho = who;
148148
mHandler = handler;
149149
}
150-
public void performReceive(Intent intent, int resultCode,
151-
String data, Bundle extras, boolean serialized, boolean sticky) {
150+
public void performReceive(Intent intent, int resultCode, String data,
151+
Bundle extras, boolean serialized, boolean sticky, int sendingUser) {
152152
mIntent = intent;
153153
mResultCode = resultCode;
154154
mResultData = data;

core/java/android/content/BroadcastReceiver.java

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -237,23 +237,25 @@ public static class PendingResult {
237237
final boolean mOrderedHint;
238238
final boolean mInitialStickyHint;
239239
final IBinder mToken;
240+
final int mSendingUser;
240241

241242
int mResultCode;
242243
String mResultData;
243244
Bundle mResultExtras;
244245
boolean mAbortBroadcast;
245246
boolean mFinished;
246-
247+
247248
/** @hide */
248249
public PendingResult(int resultCode, String resultData, Bundle resultExtras,
249-
int type, boolean ordered, boolean sticky, IBinder token) {
250+
int type, boolean ordered, boolean sticky, IBinder token, int userId) {
250251
mResultCode = resultCode;
251252
mResultData = resultData;
252253
mResultExtras = resultExtras;
253254
mType = type;
254255
mOrderedHint = ordered;
255256
mInitialStickyHint = sticky;
256257
mToken = token;
258+
mSendingUser = userId;
257259
}
258260

259261
/**
@@ -425,7 +427,12 @@ public void sendFinished(IActivityManager am) {
425427
}
426428
}
427429
}
428-
430+
431+
/** @hide */
432+
public int getSendingUserId() {
433+
return mSendingUser;
434+
}
435+
429436
void checkSynchronousHint() {
430437
// Note that we don't assert when receiving the initial sticky value,
431438
// since that may have come from an ordered broadcast. We'll catch
@@ -733,6 +740,11 @@ public final PendingResult getPendingResult() {
733740
return mPendingResult;
734741
}
735742

743+
/** @hide */
744+
public int getSendingUserId() {
745+
return mPendingResult.mSendingUser;
746+
}
747+
736748
/**
737749
* Control inclusion of debugging help for mismatched
738750
* calls to {@link Context#registerReceiver(BroadcastReceiver, IntentFilter)

core/java/android/content/Context.java

Lines changed: 29 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1410,9 +1410,35 @@ public abstract Intent registerReceiver(BroadcastReceiver receiver,
14101410
* @see #unregisterReceiver
14111411
*/
14121412
public abstract Intent registerReceiver(BroadcastReceiver receiver,
1413-
IntentFilter filter,
1414-
String broadcastPermission,
1415-
Handler scheduler);
1413+
IntentFilter filter, String broadcastPermission, Handler scheduler);
1414+
1415+
/**
1416+
* @hide
1417+
* Same as {@link #registerReceiver(BroadcastReceiver, IntentFilter, String, Handler)
1418+
* but for a specific user. This receiver will receiver broadcasts that
1419+
* are sent to the requested user. It
1420+
* requires holding the {@link android.Manifest.permission#INTERACT_ACROSS_USERS_FULL}
1421+
* permission.
1422+
*
1423+
* @param receiver The BroadcastReceiver to handle the broadcast.
1424+
* @param user UserHandle to send the intent to.
1425+
* @param filter Selects the Intent broadcasts to be received.
1426+
* @param broadcastPermission String naming a permissions that a
1427+
* broadcaster must hold in order to send an Intent to you. If null,
1428+
* no permission is required.
1429+
* @param scheduler Handler identifying the thread that will receive
1430+
* the Intent. If null, the main thread of the process will be used.
1431+
*
1432+
* @return The first sticky intent found that matches <var>filter</var>,
1433+
* or null if there are none.
1434+
*
1435+
* @see #registerReceiver(BroadcastReceiver, IntentFilter, String, Handler
1436+
* @see #sendBroadcast
1437+
* @see #unregisterReceiver
1438+
*/
1439+
public abstract Intent registerReceiverAsUser(BroadcastReceiver receiver,
1440+
UserHandle user, IntentFilter filter, String broadcastPermission,
1441+
Handler scheduler);
14161442

14171443
/**
14181444
* Unregister a previously registered BroadcastReceiver. <em>All</em>

0 commit comments

Comments
 (0)