Skip to content

Commit 5ac72a2

Browse files
author
Dianne Hackborn
committed
Improve multi-user broadcasts.
You can now use ALL and CURRENT when sending broadcasts, to specify where the broadcast goes. Sticky broadcasts are now correctly separated per user, and registered receivers are filtered based on the requested target user. New Context APIs for more kinds of sending broadcasts as users. Updating a bunch of system code that sends broadcasts to explicitly specify which user the broadcast goes to. Made a single version of the code for interpreting the requested target user ID that all entries to activity manager (start activity, send broadcast, start service) use. Change-Id: Ie29f02dd5242ef8c8fa56c54593a315cd2574e1c
1 parent e217ee4 commit 5ac72a2

File tree

50 files changed

+750
-285
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

50 files changed

+750
-285
lines changed

api/current.txt

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5323,15 +5323,19 @@ package android.content {
53235323
method public abstract android.content.Intent registerReceiver(android.content.BroadcastReceiver, android.content.IntentFilter);
53245324
method public abstract android.content.Intent registerReceiver(android.content.BroadcastReceiver, android.content.IntentFilter, java.lang.String, android.os.Handler);
53255325
method public abstract void removeStickyBroadcast(android.content.Intent);
5326+
method public abstract void removeStickyBroadcastAsUser(android.content.Intent, android.os.UserHandle);
53265327
method public abstract void revokeUriPermission(android.net.Uri, int);
53275328
method public abstract void sendBroadcast(android.content.Intent);
53285329
method public abstract void sendBroadcast(android.content.Intent, java.lang.String);
53295330
method public abstract void sendBroadcastAsUser(android.content.Intent, android.os.UserHandle);
5331+
method public abstract void sendBroadcastAsUser(android.content.Intent, android.os.UserHandle, java.lang.String);
53305332
method public abstract void sendOrderedBroadcast(android.content.Intent, java.lang.String);
53315333
method public abstract void sendOrderedBroadcast(android.content.Intent, java.lang.String, android.content.BroadcastReceiver, android.os.Handler, int, java.lang.String, android.os.Bundle);
5332-
method public abstract void sendOrderedBroadcastAsUser(android.content.Intent, android.os.UserHandle, android.content.BroadcastReceiver, android.os.Handler, int, java.lang.String, android.os.Bundle);
5334+
method public abstract void sendOrderedBroadcastAsUser(android.content.Intent, android.os.UserHandle, java.lang.String, android.content.BroadcastReceiver, android.os.Handler, int, java.lang.String, android.os.Bundle);
53335335
method public abstract void sendStickyBroadcast(android.content.Intent);
5336+
method public abstract void sendStickyBroadcastAsUser(android.content.Intent, android.os.UserHandle);
53345337
method public abstract void sendStickyOrderedBroadcast(android.content.Intent, android.content.BroadcastReceiver, android.os.Handler, int, java.lang.String, android.os.Bundle);
5338+
method public abstract void sendStickyOrderedBroadcastAsUser(android.content.Intent, android.os.UserHandle, android.content.BroadcastReceiver, android.os.Handler, int, java.lang.String, android.os.Bundle);
53355339
method public abstract void setTheme(int);
53365340
method public abstract deprecated void setWallpaper(android.graphics.Bitmap) throws java.io.IOException;
53375341
method public abstract deprecated void setWallpaper(java.io.InputStream) throws java.io.IOException;
@@ -5460,15 +5464,19 @@ package android.content {
54605464
method public android.content.Intent registerReceiver(android.content.BroadcastReceiver, android.content.IntentFilter);
54615465
method public android.content.Intent registerReceiver(android.content.BroadcastReceiver, android.content.IntentFilter, java.lang.String, android.os.Handler);
54625466
method public void removeStickyBroadcast(android.content.Intent);
5467+
method public void removeStickyBroadcastAsUser(android.content.Intent, android.os.UserHandle);
54635468
method public void revokeUriPermission(android.net.Uri, int);
54645469
method public void sendBroadcast(android.content.Intent);
54655470
method public void sendBroadcast(android.content.Intent, java.lang.String);
54665471
method public void sendBroadcastAsUser(android.content.Intent, android.os.UserHandle);
5472+
method public void sendBroadcastAsUser(android.content.Intent, android.os.UserHandle, java.lang.String);
54675473
method public void sendOrderedBroadcast(android.content.Intent, java.lang.String);
54685474
method public void sendOrderedBroadcast(android.content.Intent, java.lang.String, android.content.BroadcastReceiver, android.os.Handler, int, java.lang.String, android.os.Bundle);
5469-
method public void sendOrderedBroadcastAsUser(android.content.Intent, android.os.UserHandle, android.content.BroadcastReceiver, android.os.Handler, int, java.lang.String, android.os.Bundle);
5475+
method public void sendOrderedBroadcastAsUser(android.content.Intent, android.os.UserHandle, java.lang.String, android.content.BroadcastReceiver, android.os.Handler, int, java.lang.String, android.os.Bundle);
54705476
method public void sendStickyBroadcast(android.content.Intent);
5477+
method public void sendStickyBroadcastAsUser(android.content.Intent, android.os.UserHandle);
54715478
method public void sendStickyOrderedBroadcast(android.content.Intent, android.content.BroadcastReceiver, android.os.Handler, int, java.lang.String, android.os.Bundle);
5479+
method public void sendStickyOrderedBroadcastAsUser(android.content.Intent, android.os.UserHandle, android.content.BroadcastReceiver, android.os.Handler, int, java.lang.String, android.os.Bundle);
54725480
method public void setTheme(int);
54735481
method public void setWallpaper(android.graphics.Bitmap) throws java.io.IOException;
54745482
method public void setWallpaper(java.io.InputStream) throws java.io.IOException;
@@ -21264,15 +21272,19 @@ package android.test.mock {
2126421272
method public android.content.Intent registerReceiver(android.content.BroadcastReceiver, android.content.IntentFilter);
2126521273
method public android.content.Intent registerReceiver(android.content.BroadcastReceiver, android.content.IntentFilter, java.lang.String, android.os.Handler);
2126621274
method public void removeStickyBroadcast(android.content.Intent);
21275+
method public void removeStickyBroadcastAsUser(android.content.Intent, android.os.UserHandle);
2126721276
method public void revokeUriPermission(android.net.Uri, int);
2126821277
method public void sendBroadcast(android.content.Intent);
2126921278
method public void sendBroadcast(android.content.Intent, java.lang.String);
2127021279
method public void sendBroadcastAsUser(android.content.Intent, android.os.UserHandle);
21280+
method public void sendBroadcastAsUser(android.content.Intent, android.os.UserHandle, java.lang.String);
2127121281
method public void sendOrderedBroadcast(android.content.Intent, java.lang.String);
2127221282
method public void sendOrderedBroadcast(android.content.Intent, java.lang.String, android.content.BroadcastReceiver, android.os.Handler, int, java.lang.String, android.os.Bundle);
21273-
method public void sendOrderedBroadcastAsUser(android.content.Intent, android.os.UserHandle, android.content.BroadcastReceiver, android.os.Handler, int, java.lang.String, android.os.Bundle);
21283+
method public void sendOrderedBroadcastAsUser(android.content.Intent, android.os.UserHandle, java.lang.String, android.content.BroadcastReceiver, android.os.Handler, int, java.lang.String, android.os.Bundle);
2127421284
method public void sendStickyBroadcast(android.content.Intent);
21285+
method public void sendStickyBroadcastAsUser(android.content.Intent, android.os.UserHandle);
2127521286
method public void sendStickyOrderedBroadcast(android.content.Intent, android.content.BroadcastReceiver, android.os.Handler, int, java.lang.String, android.os.Bundle);
21287+
method public void sendStickyOrderedBroadcastAsUser(android.content.Intent, android.os.UserHandle, android.content.BroadcastReceiver, android.os.Handler, int, java.lang.String, android.os.Bundle);
2127621288
method public void setTheme(int);
2127721289
method public void setWallpaper(android.graphics.Bitmap) throws java.io.IOException;
2127821290
method public void setWallpaper(java.io.InputStream) throws java.io.IOException;

core/java/android/app/ActivityManagerNative.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -89,11 +89,11 @@ static public boolean isSystemReady() {
8989
* Convenience for sending a sticky broadcast. For internal use only.
9090
* If you don't care about permission, use null.
9191
*/
92-
static public void broadcastStickyIntent(Intent intent, String permission) {
92+
static public void broadcastStickyIntent(Intent intent, String permission, int userId) {
9393
try {
9494
getDefault().broadcastIntent(
9595
null, intent, null, null, Activity.RESULT_OK, null, null,
96-
null /*permission*/, false, true, Binder.getOrigCallingUser());
96+
null /*permission*/, false, true, userId);
9797
} catch (RemoteException ex) {
9898
}
9999
}

core/java/android/app/ContextImpl.java

Lines changed: 76 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1071,9 +1071,23 @@ public void sendBroadcastAsUser(Intent intent, UserHandle user) {
10711071
}
10721072
}
10731073

1074+
@Override
1075+
public void sendBroadcastAsUser(Intent intent, UserHandle user,
1076+
String receiverPermission) {
1077+
String resolvedType = intent.resolveTypeIfNeeded(getContentResolver());
1078+
try {
1079+
intent.setAllowFds(false);
1080+
ActivityManagerNative.getDefault().broadcastIntent(
1081+
mMainThread.getApplicationThread(), intent, resolvedType, null,
1082+
Activity.RESULT_OK, null, null, receiverPermission, false, false,
1083+
user.getIdentifier());
1084+
} catch (RemoteException e) {
1085+
}
1086+
}
1087+
10741088
@Override
10751089
public void sendOrderedBroadcastAsUser(Intent intent, UserHandle user,
1076-
BroadcastReceiver resultReceiver, Handler scheduler,
1090+
String receiverPermission, BroadcastReceiver resultReceiver, Handler scheduler,
10771091
int initialCode, String initialData, Bundle initialExtras) {
10781092
IIntentReceiver rd = null;
10791093
if (resultReceiver != null) {
@@ -1097,7 +1111,7 @@ resultReceiver, getOuterContext(), scheduler,
10971111
intent.setAllowFds(false);
10981112
ActivityManagerNative.getDefault().broadcastIntent(
10991113
mMainThread.getApplicationThread(), intent, resolvedType, rd,
1100-
initialCode, initialData, initialExtras, null,
1114+
initialCode, initialData, initialExtras, receiverPermission,
11011115
true, false, user.getIdentifier());
11021116
} catch (RemoteException e) {
11031117
}
@@ -1164,6 +1178,66 @@ public void removeStickyBroadcast(Intent intent) {
11641178
}
11651179
}
11661180

1181+
@Override
1182+
public void sendStickyBroadcastAsUser(Intent intent, UserHandle user) {
1183+
String resolvedType = intent.resolveTypeIfNeeded(getContentResolver());
1184+
try {
1185+
intent.setAllowFds(false);
1186+
ActivityManagerNative.getDefault().broadcastIntent(
1187+
mMainThread.getApplicationThread(), intent, resolvedType, null,
1188+
Activity.RESULT_OK, null, null, null, false, true, user.getIdentifier());
1189+
} catch (RemoteException e) {
1190+
}
1191+
}
1192+
1193+
@Override
1194+
public void sendStickyOrderedBroadcastAsUser(Intent intent,
1195+
UserHandle user, BroadcastReceiver resultReceiver,
1196+
Handler scheduler, int initialCode, String initialData,
1197+
Bundle initialExtras) {
1198+
IIntentReceiver rd = null;
1199+
if (resultReceiver != null) {
1200+
if (mPackageInfo != null) {
1201+
if (scheduler == null) {
1202+
scheduler = mMainThread.getHandler();
1203+
}
1204+
rd = mPackageInfo.getReceiverDispatcher(
1205+
resultReceiver, getOuterContext(), scheduler,
1206+
mMainThread.getInstrumentation(), false);
1207+
} else {
1208+
if (scheduler == null) {
1209+
scheduler = mMainThread.getHandler();
1210+
}
1211+
rd = new LoadedApk.ReceiverDispatcher(
1212+
resultReceiver, getOuterContext(), scheduler, null, false).getIIntentReceiver();
1213+
}
1214+
}
1215+
String resolvedType = intent.resolveTypeIfNeeded(getContentResolver());
1216+
try {
1217+
intent.setAllowFds(false);
1218+
ActivityManagerNative.getDefault().broadcastIntent(
1219+
mMainThread.getApplicationThread(), intent, resolvedType, rd,
1220+
initialCode, initialData, initialExtras, null,
1221+
true, true, user.getIdentifier());
1222+
} catch (RemoteException e) {
1223+
}
1224+
}
1225+
1226+
@Override
1227+
public void removeStickyBroadcastAsUser(Intent intent, UserHandle user) {
1228+
String resolvedType = intent.resolveTypeIfNeeded(getContentResolver());
1229+
if (resolvedType != null) {
1230+
intent = new Intent(intent);
1231+
intent.setDataAndType(intent.getData(), resolvedType);
1232+
}
1233+
try {
1234+
intent.setAllowFds(false);
1235+
ActivityManagerNative.getDefault().unbroadcastIntent(
1236+
mMainThread.getApplicationThread(), intent, user.getIdentifier());
1237+
} catch (RemoteException e) {
1238+
}
1239+
}
1240+
11671241
@Override
11681242
public Intent registerReceiver(BroadcastReceiver receiver, IntentFilter filter) {
11691243
return registerReceiver(receiver, filter, null, null);

core/java/android/content/Context.java

Lines changed: 89 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1126,6 +1126,24 @@ public abstract void sendOrderedBroadcast(Intent intent,
11261126
*/
11271127
public abstract void sendBroadcastAsUser(Intent intent, UserHandle user);
11281128

1129+
/**
1130+
* Same as {@link #sendBroadcast(Intent, String)}, but for a specific user. This broadcast
1131+
* can only be sent to receivers that are part of the calling application. It
1132+
* requires holding the {@link android.Manifest.permission#INTERACT_ACROSS_USERS}
1133+
* permission.
1134+
*
1135+
* @param intent The Intent to broadcast; all receivers matching this
1136+
* Intent will receive the broadcast.
1137+
* @param user UserHandle to send the intent to.
1138+
* @param receiverPermission (optional) String naming a permission that
1139+
* a receiver must hold in order to receive your broadcast.
1140+
* If null, no permission is required.
1141+
*
1142+
* @see #sendBroadcast(Intent, String)
1143+
*/
1144+
public abstract void sendBroadcastAsUser(Intent intent, UserHandle user,
1145+
String receiverPermission);
1146+
11291147
/**
11301148
* Same as
11311149
* {@link #sendOrderedBroadcast(Intent, String, BroadcastReceiver, Handler, int, String, Bundle)},
@@ -1139,6 +1157,9 @@ public abstract void sendOrderedBroadcast(Intent intent,
11391157
* @param intent The Intent to broadcast; all receivers matching this
11401158
* Intent will receive the broadcast.
11411159
* @param user UserHandle to send the intent to.
1160+
* @param receiverPermission String naming a permissions that
1161+
* a receiver must hold in order to receive your broadcast.
1162+
* If null, no permission is required.
11421163
* @param resultReceiver Your own BroadcastReceiver to treat as the final
11431164
* receiver of the broadcast.
11441165
* @param scheduler A custom Handler with which to schedule the
@@ -1154,7 +1175,7 @@ public abstract void sendOrderedBroadcast(Intent intent,
11541175
* @see #sendOrderedBroadcast(Intent, String, BroadcastReceiver, Handler, int, String, Bundle)
11551176
*/
11561177
public abstract void sendOrderedBroadcastAsUser(Intent intent, UserHandle user,
1157-
BroadcastReceiver resultReceiver, Handler scheduler,
1178+
String receiverPermission, BroadcastReceiver resultReceiver, Handler scheduler,
11581179
int initialCode, String initialData, Bundle initialExtras);
11591180

11601181
/**
@@ -1223,7 +1244,6 @@ public abstract void sendStickyOrderedBroadcast(Intent intent,
12231244
Handler scheduler, int initialCode, String initialData,
12241245
Bundle initialExtras);
12251246

1226-
12271247
/**
12281248
* Remove the data previously sent with {@link #sendStickyBroadcast},
12291249
* so that it is as if the sticky broadcast had never happened.
@@ -1238,6 +1258,73 @@ public abstract void sendStickyOrderedBroadcast(Intent intent,
12381258
*/
12391259
public abstract void removeStickyBroadcast(Intent intent);
12401260

1261+
/**
1262+
* Same as {@link #sendStickyBroadcast(Intent)},
1263+
* but for a specific user. This broadcast
1264+
* can only be sent to receivers that are part of the calling application. It
1265+
* requires holding the {@link android.Manifest.permission#INTERACT_ACROSS_USERS}
1266+
* permission.
1267+
*
1268+
* @param intent The Intent to broadcast; all receivers matching this
1269+
* Intent will receive the broadcast, and the Intent will be held to
1270+
* be re-broadcast to future receivers.
1271+
* @param user UserHandle to send the intent to.
1272+
*
1273+
* @see #sendBroadcast(Intent)
1274+
*/
1275+
public abstract void sendStickyBroadcastAsUser(Intent intent, UserHandle user);
1276+
1277+
/**
1278+
* Same as
1279+
* {@link #sendStickyOrderedBroadcast(Intent, BroadcastReceiver, Handler, int, String, Bundle)
1280+
* but for a specific user. This broadcast
1281+
* can only be sent to receivers that are part of the calling application. It
1282+
* requires holding the {@link android.Manifest.permission#INTERACT_ACROSS_USERS}
1283+
* permission.
1284+
*
1285+
* <p>See {@link BroadcastReceiver} for more information on Intent broadcasts.
1286+
*
1287+
* @param intent The Intent to broadcast; all receivers matching this
1288+
* Intent will receive the broadcast.
1289+
* @param user UserHandle to send the intent to.
1290+
* @param resultReceiver Your own BroadcastReceiver to treat as the final
1291+
* receiver of the broadcast.
1292+
* @param scheduler A custom Handler with which to schedule the
1293+
* resultReceiver callback; if null it will be
1294+
* scheduled in the Context's main thread.
1295+
* @param initialCode An initial value for the result code. Often
1296+
* Activity.RESULT_OK.
1297+
* @param initialData An initial value for the result data. Often
1298+
* null.
1299+
* @param initialExtras An initial value for the result extras. Often
1300+
* null.
1301+
*
1302+
* @see #sendStickyOrderedBroadcast(Intent, BroadcastReceiver, Handler, int, String, Bundle)
1303+
*/
1304+
public abstract void sendStickyOrderedBroadcastAsUser(Intent intent,
1305+
UserHandle user, BroadcastReceiver resultReceiver,
1306+
Handler scheduler, int initialCode, String initialData,
1307+
Bundle initialExtras);
1308+
1309+
/**
1310+
* Same as
1311+
* {@link #sendStickyOrderedBroadcast(Intent, BroadcastReceiver, Handler, int, String, Bundle)
1312+
* but for a specific user. This broadcast
1313+
* can only be sent to receivers that are part of the calling application. It
1314+
* requires holding the {@link android.Manifest.permission#INTERACT_ACROSS_USERS}
1315+
* permission.
1316+
*
1317+
* <p>You must hold the {@link android.Manifest.permission#BROADCAST_STICKY}
1318+
* permission in order to use this API. If you do not hold that
1319+
* permission, {@link SecurityException} will be thrown.
1320+
*
1321+
* @param intent The Intent that was previously broadcast.
1322+
* @param user UserHandle to remove the sticky broadcast from.
1323+
*
1324+
* @see #sendStickyBroadcastAsUser
1325+
*/
1326+
public abstract void removeStickyBroadcastAsUser(Intent intent, UserHandle user);
1327+
12411328
/**
12421329
* Register a BroadcastReceiver to be run in the main activity thread. The
12431330
* <var>receiver</var> will be called with any broadcast Intent that

0 commit comments

Comments
 (0)