diff options
Diffstat (limited to 'core/java/android')
| -rw-r--r-- | core/java/android/app/ActivityManagerNative.java | 4 | ||||
| -rw-r--r-- | core/java/android/app/ContextImpl.java | 78 | ||||
| -rw-r--r-- | core/java/android/content/Context.java | 91 | ||||
| -rw-r--r-- | core/java/android/content/ContextWrapper.java | 33 | ||||
| -rw-r--r-- | core/java/android/os/RecoverySystem.java | 3 | ||||
| -rw-r--r-- | core/java/android/os/UserHandle.java | 16 | ||||
| -rw-r--r-- | core/java/android/server/search/SearchManagerService.java | 4 |
7 files changed, 218 insertions, 11 deletions
diff --git a/core/java/android/app/ActivityManagerNative.java b/core/java/android/app/ActivityManagerNative.java index 05c009f..16b7c2a 100644 --- a/core/java/android/app/ActivityManagerNative.java +++ b/core/java/android/app/ActivityManagerNative.java @@ -89,11 +89,11 @@ public abstract class ActivityManagerNative extends Binder implements IActivityM * Convenience for sending a sticky broadcast. For internal use only. * If you don't care about permission, use null. */ - static public void broadcastStickyIntent(Intent intent, String permission) { + static public void broadcastStickyIntent(Intent intent, String permission, int userId) { try { getDefault().broadcastIntent( null, intent, null, null, Activity.RESULT_OK, null, null, - null /*permission*/, false, true, Binder.getOrigCallingUser()); + null /*permission*/, false, true, userId); } catch (RemoteException ex) { } } diff --git a/core/java/android/app/ContextImpl.java b/core/java/android/app/ContextImpl.java index efe4b7b..1b6f84b 100644 --- a/core/java/android/app/ContextImpl.java +++ b/core/java/android/app/ContextImpl.java @@ -1072,8 +1072,22 @@ class ContextImpl extends Context { } @Override + public void sendBroadcastAsUser(Intent intent, UserHandle user, + String receiverPermission) { + String resolvedType = intent.resolveTypeIfNeeded(getContentResolver()); + try { + intent.setAllowFds(false); + ActivityManagerNative.getDefault().broadcastIntent( + mMainThread.getApplicationThread(), intent, resolvedType, null, + Activity.RESULT_OK, null, null, receiverPermission, false, false, + user.getIdentifier()); + } catch (RemoteException e) { + } + } + + @Override public void sendOrderedBroadcastAsUser(Intent intent, UserHandle user, - BroadcastReceiver resultReceiver, Handler scheduler, + String receiverPermission, BroadcastReceiver resultReceiver, Handler scheduler, int initialCode, String initialData, Bundle initialExtras) { IIntentReceiver rd = null; if (resultReceiver != null) { @@ -1097,7 +1111,7 @@ class ContextImpl extends Context { intent.setAllowFds(false); ActivityManagerNative.getDefault().broadcastIntent( mMainThread.getApplicationThread(), intent, resolvedType, rd, - initialCode, initialData, initialExtras, null, + initialCode, initialData, initialExtras, receiverPermission, true, false, user.getIdentifier()); } catch (RemoteException e) { } @@ -1165,6 +1179,66 @@ class ContextImpl extends Context { } @Override + public void sendStickyBroadcastAsUser(Intent intent, UserHandle user) { + String resolvedType = intent.resolveTypeIfNeeded(getContentResolver()); + try { + intent.setAllowFds(false); + ActivityManagerNative.getDefault().broadcastIntent( + mMainThread.getApplicationThread(), intent, resolvedType, null, + Activity.RESULT_OK, null, null, null, false, true, user.getIdentifier()); + } catch (RemoteException e) { + } + } + + @Override + public void sendStickyOrderedBroadcastAsUser(Intent intent, + UserHandle user, BroadcastReceiver resultReceiver, + Handler scheduler, int initialCode, String initialData, + Bundle initialExtras) { + IIntentReceiver rd = null; + if (resultReceiver != null) { + if (mPackageInfo != null) { + if (scheduler == null) { + scheduler = mMainThread.getHandler(); + } + rd = mPackageInfo.getReceiverDispatcher( + resultReceiver, getOuterContext(), scheduler, + mMainThread.getInstrumentation(), false); + } else { + if (scheduler == null) { + scheduler = mMainThread.getHandler(); + } + rd = new LoadedApk.ReceiverDispatcher( + resultReceiver, getOuterContext(), scheduler, null, false).getIIntentReceiver(); + } + } + String resolvedType = intent.resolveTypeIfNeeded(getContentResolver()); + try { + intent.setAllowFds(false); + ActivityManagerNative.getDefault().broadcastIntent( + mMainThread.getApplicationThread(), intent, resolvedType, rd, + initialCode, initialData, initialExtras, null, + true, true, user.getIdentifier()); + } catch (RemoteException e) { + } + } + + @Override + public void removeStickyBroadcastAsUser(Intent intent, UserHandle user) { + String resolvedType = intent.resolveTypeIfNeeded(getContentResolver()); + if (resolvedType != null) { + intent = new Intent(intent); + intent.setDataAndType(intent.getData(), resolvedType); + } + try { + intent.setAllowFds(false); + ActivityManagerNative.getDefault().unbroadcastIntent( + mMainThread.getApplicationThread(), intent, user.getIdentifier()); + } catch (RemoteException e) { + } + } + + @Override public Intent registerReceiver(BroadcastReceiver receiver, IntentFilter filter) { return registerReceiver(receiver, filter, null, null); } diff --git a/core/java/android/content/Context.java b/core/java/android/content/Context.java index dc6d93f..c2b796a 100644 --- a/core/java/android/content/Context.java +++ b/core/java/android/content/Context.java @@ -1127,6 +1127,24 @@ public abstract class Context { public abstract void sendBroadcastAsUser(Intent intent, UserHandle user); /** + * Same as {@link #sendBroadcast(Intent, String)}, but for a specific user. This broadcast + * can only be sent to receivers that are part of the calling application. It + * requires holding the {@link android.Manifest.permission#INTERACT_ACROSS_USERS} + * permission. + * + * @param intent The Intent to broadcast; all receivers matching this + * Intent will receive the broadcast. + * @param user UserHandle to send the intent to. + * @param receiverPermission (optional) String naming a permission that + * a receiver must hold in order to receive your broadcast. + * If null, no permission is required. + * + * @see #sendBroadcast(Intent, String) + */ + public abstract void sendBroadcastAsUser(Intent intent, UserHandle user, + String receiverPermission); + + /** * Same as * {@link #sendOrderedBroadcast(Intent, String, BroadcastReceiver, Handler, int, String, Bundle)}, * but for a specific user. This broadcast @@ -1139,6 +1157,9 @@ public abstract class Context { * @param intent The Intent to broadcast; all receivers matching this * Intent will receive the broadcast. * @param user UserHandle to send the intent to. + * @param receiverPermission String naming a permissions that + * a receiver must hold in order to receive your broadcast. + * If null, no permission is required. * @param resultReceiver Your own BroadcastReceiver to treat as the final * receiver of the broadcast. * @param scheduler A custom Handler with which to schedule the @@ -1154,7 +1175,7 @@ public abstract class Context { * @see #sendOrderedBroadcast(Intent, String, BroadcastReceiver, Handler, int, String, Bundle) */ public abstract void sendOrderedBroadcastAsUser(Intent intent, UserHandle user, - BroadcastReceiver resultReceiver, Handler scheduler, + String receiverPermission, BroadcastReceiver resultReceiver, Handler scheduler, int initialCode, String initialData, Bundle initialExtras); /** @@ -1223,7 +1244,6 @@ public abstract class Context { Handler scheduler, int initialCode, String initialData, Bundle initialExtras); - /** * Remove the data previously sent with {@link #sendStickyBroadcast}, * so that it is as if the sticky broadcast had never happened. @@ -1239,6 +1259,73 @@ public abstract class Context { public abstract void removeStickyBroadcast(Intent intent); /** + * Same as {@link #sendStickyBroadcast(Intent)}, + * but for a specific user. This broadcast + * can only be sent to receivers that are part of the calling application. It + * requires holding the {@link android.Manifest.permission#INTERACT_ACROSS_USERS} + * permission. + * + * @param intent The Intent to broadcast; all receivers matching this + * Intent will receive the broadcast, and the Intent will be held to + * be re-broadcast to future receivers. + * @param user UserHandle to send the intent to. + * + * @see #sendBroadcast(Intent) + */ + public abstract void sendStickyBroadcastAsUser(Intent intent, UserHandle user); + + /** + * Same as + * {@link #sendStickyOrderedBroadcast(Intent, BroadcastReceiver, Handler, int, String, Bundle) + * but for a specific user. This broadcast + * can only be sent to receivers that are part of the calling application. It + * requires holding the {@link android.Manifest.permission#INTERACT_ACROSS_USERS} + * permission. + * + * <p>See {@link BroadcastReceiver} for more information on Intent broadcasts. + * + * @param intent The Intent to broadcast; all receivers matching this + * Intent will receive the broadcast. + * @param user UserHandle to send the intent to. + * @param resultReceiver Your own BroadcastReceiver to treat as the final + * receiver of the broadcast. + * @param scheduler A custom Handler with which to schedule the + * resultReceiver callback; if null it will be + * scheduled in the Context's main thread. + * @param initialCode An initial value for the result code. Often + * Activity.RESULT_OK. + * @param initialData An initial value for the result data. Often + * null. + * @param initialExtras An initial value for the result extras. Often + * null. + * + * @see #sendStickyOrderedBroadcast(Intent, BroadcastReceiver, Handler, int, String, Bundle) + */ + public abstract void sendStickyOrderedBroadcastAsUser(Intent intent, + UserHandle user, BroadcastReceiver resultReceiver, + Handler scheduler, int initialCode, String initialData, + Bundle initialExtras); + + /** + * Same as + * {@link #sendStickyOrderedBroadcast(Intent, BroadcastReceiver, Handler, int, String, Bundle) + * but for a specific user. This broadcast + * can only be sent to receivers that are part of the calling application. It + * requires holding the {@link android.Manifest.permission#INTERACT_ACROSS_USERS} + * permission. + * + * <p>You must hold the {@link android.Manifest.permission#BROADCAST_STICKY} + * permission in order to use this API. If you do not hold that + * permission, {@link SecurityException} will be thrown. + * + * @param intent The Intent that was previously broadcast. + * @param user UserHandle to remove the sticky broadcast from. + * + * @see #sendStickyBroadcastAsUser + */ + public abstract void removeStickyBroadcastAsUser(Intent intent, UserHandle user); + + /** * Register a BroadcastReceiver to be run in the main activity thread. The * <var>receiver</var> will be called with any broadcast Intent that * matches <var>filter</var>, in the main application thread. diff --git a/core/java/android/content/ContextWrapper.java b/core/java/android/content/ContextWrapper.java index 4bbe44e..e503388 100644 --- a/core/java/android/content/ContextWrapper.java +++ b/core/java/android/content/ContextWrapper.java @@ -16,6 +16,9 @@ package android.content; +import android.app.Activity; +import android.app.ActivityManagerNative; +import android.app.LoadedApk; import android.content.pm.ApplicationInfo; import android.content.pm.PackageManager; import android.content.res.AssetManager; @@ -30,6 +33,7 @@ import android.net.Uri; import android.os.Bundle; import android.os.Handler; import android.os.Looper; +import android.os.RemoteException; import android.os.UserHandle; import android.view.CompatibilityInfoHolder; @@ -354,10 +358,16 @@ public class ContextWrapper extends Context { } @Override + public void sendBroadcastAsUser(Intent intent, UserHandle user, + String receiverPermission) { + mBase.sendBroadcastAsUser(intent, user, receiverPermission); + } + + @Override public void sendOrderedBroadcastAsUser(Intent intent, UserHandle user, - BroadcastReceiver resultReceiver, Handler scheduler, + String receiverPermission, BroadcastReceiver resultReceiver, Handler scheduler, int initialCode, String initialData, Bundle initialExtras) { - mBase.sendOrderedBroadcastAsUser(intent, user, resultReceiver, + mBase.sendOrderedBroadcastAsUser(intent, user, receiverPermission, resultReceiver, scheduler, initialCode, initialData, initialExtras); } @@ -382,6 +392,25 @@ public class ContextWrapper extends Context { } @Override + public void sendStickyBroadcastAsUser(Intent intent, UserHandle user) { + mBase.sendStickyBroadcastAsUser(intent, user); + } + + @Override + public void sendStickyOrderedBroadcastAsUser(Intent intent, + UserHandle user, BroadcastReceiver resultReceiver, + Handler scheduler, int initialCode, String initialData, + Bundle initialExtras) { + mBase.sendStickyOrderedBroadcastAsUser(intent, user, resultReceiver, + scheduler, initialCode, initialData, initialExtras); + } + + @Override + public void removeStickyBroadcastAsUser(Intent intent, UserHandle user) { + mBase.removeStickyBroadcastAsUser(intent, user); + } + + @Override public Intent registerReceiver( BroadcastReceiver receiver, IntentFilter filter) { return mBase.registerReceiver(receiver, filter); diff --git a/core/java/android/os/RecoverySystem.java b/core/java/android/os/RecoverySystem.java index 0d11ab4..480fe7d 100644 --- a/core/java/android/os/RecoverySystem.java +++ b/core/java/android/os/RecoverySystem.java @@ -348,7 +348,8 @@ public class RecoverySystem { final ConditionVariable condition = new ConditionVariable(); Intent intent = new Intent("android.intent.action.MASTER_CLEAR_NOTIFICATION"); - context.sendOrderedBroadcast(intent, android.Manifest.permission.MASTER_CLEAR, + context.sendOrderedBroadcastAsUser(intent, UserHandle.OWNER, + android.Manifest.permission.MASTER_CLEAR, new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { diff --git a/core/java/android/os/UserHandle.java b/core/java/android/os/UserHandle.java index d33bd80..fff7d5f 100644 --- a/core/java/android/os/UserHandle.java +++ b/core/java/android/os/UserHandle.java @@ -34,12 +34,28 @@ public final class UserHandle implements Parcelable { /** @hide A user id to indicate the currently active user */ public static final int USER_CURRENT = -2; + /** @hide A user handle to indicate the current user of the device */ + public static final UserHandle CURRENT = new UserHandle(USER_CURRENT); + + /** @hide A user id to indicate that we would like to send to the current + * user, but if this is calling from a user process then we will send it + * to the caller's user instead of failing wiht a security exception */ + public static final int USER_CURRENT_OR_SELF = -2; + + /** @hide A user handle to indicate that we would like to send to the current + * user, but if this is calling from a user process then we will send it + * to the caller's user instead of failing wiht a security exception */ + public static final UserHandle CURRENT_OR_SELF = new UserHandle(USER_CURRENT_OR_SELF); + /** @hide An undefined user id */ public static final int USER_NULL = -10000; /** @hide A user id constant to indicate the "owner" user of the device */ public static final int USER_OWNER = 0; + /** @hide A user handle to indicate the primary/owner user of the device */ + public static final UserHandle OWNER = new UserHandle(USER_OWNER); + /** * @hide Enable multi-user related side effects. Set this to false if * there are problems with single user use-cases. diff --git a/core/java/android/server/search/SearchManagerService.java b/core/java/android/server/search/SearchManagerService.java index df85b2f..bc3efdd 100644 --- a/core/java/android/server/search/SearchManagerService.java +++ b/core/java/android/server/search/SearchManagerService.java @@ -140,7 +140,7 @@ public class SearchManagerService extends ISearchManager.Stub { // Inform all listeners that the list of searchables has been updated. Intent intent = new Intent(SearchManager.INTENT_ACTION_SEARCHABLES_CHANGED); intent.addFlags(Intent.FLAG_RECEIVER_REPLACE_PENDING); - mContext.sendBroadcast(intent); + mContext.sendBroadcastAsUser(intent, UserHandle.ALL); } } @@ -165,7 +165,7 @@ public class SearchManagerService extends ISearchManager.Stub { } Intent intent = new Intent(SearchManager.INTENT_GLOBAL_SEARCH_ACTIVITY_CHANGED); intent.addFlags(Intent.FLAG_RECEIVER_REPLACE_PENDING); - mContext.sendBroadcast(intent); + mContext.sendBroadcastAsUser(intent, UserHandle.ALL); } } |
