diff options
author | Dianne Hackborn <hackbod@google.com> | 2013-02-04 18:23:34 -0800 |
---|---|---|
committer | Dianne Hackborn <hackbod@google.com> | 2013-02-05 11:56:12 -0800 |
commit | f51f61269aacdfcf737b2c32b6b216c48ab61e65 (patch) | |
tree | 33839b315b97323df81f9638c8bb085241f017cc | |
parent | b86147910877f1aae0733f05a9a93b91101e67e2 (diff) | |
download | frameworks_base-f51f61269aacdfcf737b2c32b6b216c48ab61e65.zip frameworks_base-f51f61269aacdfcf737b2c32b6b216c48ab61e65.tar.gz frameworks_base-f51f61269aacdfcf737b2c32b6b216c48ab61e65.tar.bz2 |
App ops: new operations for SMS.
Implementation required a new framework feature
to associate an app op with a broadcast.
Change-Id: I4ff41a52f7ad4ee8fd80cbf7b394f04d6c4315b3
-rw-r--r-- | cmds/am/src/com/android/commands/am/Am.java | 4 | ||||
-rw-r--r-- | core/java/android/app/ActivityManagerNative.java | 8 | ||||
-rw-r--r-- | core/java/android/app/AppOpsManager.java | 39 | ||||
-rw-r--r-- | core/java/android/app/ContextImpl.java | 49 | ||||
-rw-r--r-- | core/java/android/app/IActivityManager.java | 2 | ||||
-rw-r--r-- | core/java/android/content/Context.java | 19 | ||||
-rw-r--r-- | core/java/android/content/ContextWrapper.java | 17 | ||||
-rw-r--r-- | services/java/com/android/server/am/ActivityManagerService.java | 61 | ||||
-rw-r--r-- | services/java/com/android/server/am/BroadcastQueue.java | 22 | ||||
-rw-r--r-- | services/java/com/android/server/am/BroadcastRecord.java | 10 | ||||
-rw-r--r-- | services/java/com/android/server/pm/PackageManagerService.java | 7 | ||||
-rw-r--r-- | test-runner/src/android/test/mock/MockContext.java | 14 |
12 files changed, 196 insertions, 56 deletions
diff --git a/cmds/am/src/com/android/commands/am/Am.java b/cmds/am/src/com/android/commands/am/Am.java index 1c5f32e..3c1fbfe 100644 --- a/cmds/am/src/com/android/commands/am/Am.java +++ b/cmds/am/src/com/android/commands/am/Am.java @@ -614,8 +614,8 @@ public class Am { Intent intent = makeIntent(UserHandle.USER_ALL); IntentReceiver receiver = new IntentReceiver(); System.out.println("Broadcasting: " + intent); - mAm.broadcastIntent(null, intent, null, receiver, 0, null, null, null, true, false, - mUserId); + mAm.broadcastIntent(null, intent, null, receiver, 0, null, null, null, + android.app.AppOpsManager.OP_NONE, true, false, mUserId); receiver.waitForFinish(); } diff --git a/core/java/android/app/ActivityManagerNative.java b/core/java/android/app/ActivityManagerNative.java index c9930e9..50c508c 100644 --- a/core/java/android/app/ActivityManagerNative.java +++ b/core/java/android/app/ActivityManagerNative.java @@ -92,7 +92,7 @@ public abstract class ActivityManagerNative extends Binder implements IActivityM try { getDefault().broadcastIntent( null, intent, null, null, Activity.RESULT_OK, null, null, - null /*permission*/, false, true, userId); + null /*permission*/, AppOpsManager.OP_NONE, false, true, userId); } catch (RemoteException ex) { } } @@ -344,11 +344,12 @@ public abstract class ActivityManagerNative extends Binder implements IActivityM String resultData = data.readString(); Bundle resultExtras = data.readBundle(); String perm = data.readString(); + int appOp = data.readInt(); boolean serialized = data.readInt() != 0; boolean sticky = data.readInt() != 0; int userId = data.readInt(); int res = broadcastIntent(app, intent, resolvedType, resultTo, - resultCode, resultData, resultExtras, perm, + resultCode, resultData, resultExtras, perm, appOp, serialized, sticky, userId); reply.writeNoException(); reply.writeInt(res); @@ -2174,7 +2175,7 @@ class ActivityManagerProxy implements IActivityManager public int broadcastIntent(IApplicationThread caller, Intent intent, String resolvedType, IIntentReceiver resultTo, int resultCode, String resultData, Bundle map, - String requiredPermission, boolean serialized, + String requiredPermission, int appOp, boolean serialized, boolean sticky, int userId) throws RemoteException { Parcel data = Parcel.obtain(); @@ -2188,6 +2189,7 @@ class ActivityManagerProxy implements IActivityManager data.writeString(resultData); data.writeBundle(map); data.writeString(requiredPermission); + data.writeInt(appOp); data.writeInt(serialized ? 1 : 0); data.writeInt(sticky ? 1 : 0); data.writeInt(userId); diff --git a/core/java/android/app/AppOpsManager.java b/core/java/android/app/AppOpsManager.java index a81b6fe..2a59a1d 100644 --- a/core/java/android/app/AppOpsManager.java +++ b/core/java/android/app/AppOpsManager.java @@ -37,6 +37,7 @@ public class AppOpsManager { public static final int MODE_IGNORED = 1; public static final int MODE_ERRORED = 2; + public static final int OP_NONE = -1; public static final int OP_COARSE_LOCATION = 0; public static final int OP_FINE_LOCATION = 1; public static final int OP_GPS = 2; @@ -51,8 +52,17 @@ public class AppOpsManager { public static final int OP_POST_NOTIFICATION = 11; public static final int OP_NEIGHBORING_CELLS = 12; public static final int OP_CALL_PHONE = 13; + public static final int OP_READ_SMS = 14; + public static final int OP_WRITE_SMS = 15; + public static final int OP_RECEIVE_SMS = 16; + public static final int OP_RECEIVE_EMERGECY_SMS = 17; + public static final int OP_RECEIVE_MMS = 18; + public static final int OP_RECEIVE_WAP_PUSH = 19; + public static final int OP_SEND_SMS = 20; + public static final int OP_READ_ICC_SMS = 21; + public static final int OP_WRITE_ICC_SMS = 22; /** @hide */ - public static final int _NUM_OP = 14; + public static final int _NUM_OP = 23; /** * This maps each operation to the operation that serves as the @@ -77,6 +87,15 @@ public class AppOpsManager { OP_POST_NOTIFICATION, OP_COARSE_LOCATION, OP_CALL_PHONE, + OP_READ_SMS, + OP_WRITE_SMS, + OP_READ_SMS, + OP_READ_SMS, + OP_READ_SMS, + OP_READ_SMS, + OP_WRITE_SMS, + OP_READ_SMS, + OP_WRITE_SMS, }; /** @@ -98,6 +117,15 @@ public class AppOpsManager { "POST_NOTIFICATION", "NEIGHBORING_CELLS", "CALL_PHONE", + "READ_SMS", + "WRITE_SMS", + "RECEIVE_SMS", + "RECEIVE_EMERGECY_SMS", + "RECEIVE_MMS", + "RECEIVE_WAP_PUSH", + "SEND_SMS", + "READ_ICC_SMS", + "WRITE_ICC_SMS", }; /** @@ -119,6 +147,15 @@ public class AppOpsManager { android.Manifest.permission.ACCESS_WIFI_STATE, null, // neighboring cells shares the coarse location perm android.Manifest.permission.CALL_PHONE, + android.Manifest.permission.READ_SMS, + android.Manifest.permission.WRITE_SMS, + android.Manifest.permission.RECEIVE_SMS, + android.Manifest.permission.RECEIVE_EMERGENCY_BROADCAST, + android.Manifest.permission.RECEIVE_MMS, + android.Manifest.permission.RECEIVE_WAP_PUSH, + android.Manifest.permission.SEND_SMS, + android.Manifest.permission.READ_SMS, + android.Manifest.permission.WRITE_SMS, }; public static int opToSwitch(int op) { diff --git a/core/java/android/app/ContextImpl.java b/core/java/android/app/ContextImpl.java index 2cf9f59..a40fe75 100644 --- a/core/java/android/app/ContextImpl.java +++ b/core/java/android/app/ContextImpl.java @@ -1042,7 +1042,7 @@ class ContextImpl extends Context { intent.setAllowFds(false); ActivityManagerNative.getDefault().broadcastIntent( mMainThread.getApplicationThread(), intent, resolvedType, null, - Activity.RESULT_OK, null, null, null, false, false, + Activity.RESULT_OK, null, null, null, AppOpsManager.OP_NONE, false, false, getUserId()); } catch (RemoteException e) { } @@ -1056,7 +1056,21 @@ class ContextImpl extends Context { intent.setAllowFds(false); ActivityManagerNative.getDefault().broadcastIntent( mMainThread.getApplicationThread(), intent, resolvedType, null, - Activity.RESULT_OK, null, null, receiverPermission, false, false, + Activity.RESULT_OK, null, null, receiverPermission, AppOpsManager.OP_NONE, + false, false, getUserId()); + } catch (RemoteException e) { + } + } + + @Override + public void sendBroadcast(Intent intent, String receiverPermission, int appOp) { + warnIfCallingFromSystemProcess(); + String resolvedType = intent.resolveTypeIfNeeded(getContentResolver()); + try { + intent.setAllowFds(false); + ActivityManagerNative.getDefault().broadcastIntent( + mMainThread.getApplicationThread(), intent, resolvedType, null, + Activity.RESULT_OK, null, null, receiverPermission, appOp, false, false, getUserId()); } catch (RemoteException e) { } @@ -1071,7 +1085,7 @@ class ContextImpl extends Context { intent.setAllowFds(false); ActivityManagerNative.getDefault().broadcastIntent( mMainThread.getApplicationThread(), intent, resolvedType, null, - Activity.RESULT_OK, null, null, receiverPermission, true, false, + Activity.RESULT_OK, null, null, receiverPermission, AppOpsManager.OP_NONE, true, false, getUserId()); } catch (RemoteException e) { } @@ -1082,6 +1096,15 @@ class ContextImpl extends Context { String receiverPermission, BroadcastReceiver resultReceiver, Handler scheduler, int initialCode, String initialData, Bundle initialExtras) { + sendOrderedBroadcast(intent, receiverPermission, AppOpsManager.OP_NONE, + resultReceiver, scheduler, initialCode, initialData, initialExtras); + } + + @Override + public void sendOrderedBroadcast(Intent intent, + String receiverPermission, int appOp, BroadcastReceiver resultReceiver, + Handler scheduler, int initialCode, String initialData, + Bundle initialExtras) { warnIfCallingFromSystemProcess(); IIntentReceiver rd = null; if (resultReceiver != null) { @@ -1105,8 +1128,8 @@ class ContextImpl extends Context { intent.setAllowFds(false); ActivityManagerNative.getDefault().broadcastIntent( mMainThread.getApplicationThread(), intent, resolvedType, rd, - initialCode, initialData, initialExtras, receiverPermission, - true, false, getUserId()); + initialCode, initialData, initialExtras, receiverPermission, appOp, + true, false, getUserId()); } catch (RemoteException e) { } } @@ -1117,8 +1140,8 @@ class ContextImpl extends Context { try { intent.setAllowFds(false); ActivityManagerNative.getDefault().broadcastIntent(mMainThread.getApplicationThread(), - intent, resolvedType, null, Activity.RESULT_OK, null, null, null, false, false, - user.getIdentifier()); + intent, resolvedType, null, Activity.RESULT_OK, null, null, null, + AppOpsManager.OP_NONE, false, false, user.getIdentifier()); } catch (RemoteException e) { } } @@ -1131,7 +1154,7 @@ class ContextImpl extends Context { intent.setAllowFds(false); ActivityManagerNative.getDefault().broadcastIntent( mMainThread.getApplicationThread(), intent, resolvedType, null, - Activity.RESULT_OK, null, null, receiverPermission, false, false, + Activity.RESULT_OK, null, null, receiverPermission, AppOpsManager.OP_NONE, false, false, user.getIdentifier()); } catch (RemoteException e) { } @@ -1164,7 +1187,7 @@ class ContextImpl extends Context { ActivityManagerNative.getDefault().broadcastIntent( mMainThread.getApplicationThread(), intent, resolvedType, rd, initialCode, initialData, initialExtras, receiverPermission, - true, false, user.getIdentifier()); + AppOpsManager.OP_NONE, true, false, user.getIdentifier()); } catch (RemoteException e) { } } @@ -1177,7 +1200,7 @@ class ContextImpl extends Context { intent.setAllowFds(false); ActivityManagerNative.getDefault().broadcastIntent( mMainThread.getApplicationThread(), intent, resolvedType, null, - Activity.RESULT_OK, null, null, null, false, true, + Activity.RESULT_OK, null, null, null, AppOpsManager.OP_NONE, false, true, getUserId()); } catch (RemoteException e) { } @@ -1212,7 +1235,7 @@ class ContextImpl extends Context { ActivityManagerNative.getDefault().broadcastIntent( mMainThread.getApplicationThread(), intent, resolvedType, rd, initialCode, initialData, initialExtras, null, - true, true, getUserId()); + AppOpsManager.OP_NONE, true, true, getUserId()); } catch (RemoteException e) { } } @@ -1239,7 +1262,7 @@ class ContextImpl extends Context { intent.setAllowFds(false); ActivityManagerNative.getDefault().broadcastIntent( mMainThread.getApplicationThread(), intent, resolvedType, null, - Activity.RESULT_OK, null, null, null, false, true, user.getIdentifier()); + Activity.RESULT_OK, null, null, null, AppOpsManager.OP_NONE, false, true, user.getIdentifier()); } catch (RemoteException e) { } } @@ -1272,7 +1295,7 @@ class ContextImpl extends Context { ActivityManagerNative.getDefault().broadcastIntent( mMainThread.getApplicationThread(), intent, resolvedType, rd, initialCode, initialData, initialExtras, null, - true, true, user.getIdentifier()); + AppOpsManager.OP_NONE, true, true, user.getIdentifier()); } catch (RemoteException e) { } } diff --git a/core/java/android/app/IActivityManager.java b/core/java/android/app/IActivityManager.java index e58ff62..cf4c729 100644 --- a/core/java/android/app/IActivityManager.java +++ b/core/java/android/app/IActivityManager.java @@ -85,7 +85,7 @@ public interface IActivityManager extends IInterface { public int broadcastIntent(IApplicationThread caller, Intent intent, String resolvedType, IIntentReceiver resultTo, int resultCode, String resultData, Bundle map, String requiredPermission, - boolean serialized, boolean sticky, int userId) throws RemoteException; + int appOp, boolean serialized, boolean sticky, int userId) throws RemoteException; public void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) throws RemoteException; public void finishReceiver(IBinder who, int resultCode, String resultData, Bundle map, boolean abortBroadcast) throws RemoteException; public void attachApplication(IApplicationThread app) throws RemoteException; diff --git a/core/java/android/content/Context.java b/core/java/android/content/Context.java index f7c28b6..c964af4 100644 --- a/core/java/android/content/Context.java +++ b/core/java/android/content/Context.java @@ -1138,6 +1138,14 @@ public abstract class Context { String receiverPermission); /** + * Like {@link #sendBroadcast(Intent, String)}, but also allows specification + * of an assocated app op as per {@link android.app.AppOpsManager}. + * @hide + */ + public abstract void sendBroadcast(Intent intent, + String receiverPermission, int appOp); + + /** * Broadcast the given intent to all interested BroadcastReceivers, delivering * them one at a time to allow more preferred receivers to consume the * broadcast before it is delivered to less preferred receivers. This @@ -1208,6 +1216,17 @@ public abstract class Context { Bundle initialExtras); /** + * Like {@link #sendOrderedBroadcast(Intent, String, BroadcastReceiver, android.os.Handler, + * int, String, android.os.Bundle)}, but also allows specification + * of an assocated app op as per {@link android.app.AppOpsManager}. + * @hide + */ + public abstract void sendOrderedBroadcast(Intent intent, + String receiverPermission, int appOp, BroadcastReceiver resultReceiver, + Handler scheduler, int initialCode, String initialData, + Bundle initialExtras); + + /** * Version of {@link #sendBroadcast(Intent)} that allows you to specify the * user the broadcast will be sent to. This is not available to applications * that are not pre-installed on the system image. Using it requires holding diff --git a/core/java/android/content/ContextWrapper.java b/core/java/android/content/ContextWrapper.java index b63f45e..736dd99 100644 --- a/core/java/android/content/ContextWrapper.java +++ b/core/java/android/content/ContextWrapper.java @@ -349,6 +349,12 @@ public class ContextWrapper extends Context { mBase.sendBroadcast(intent, receiverPermission); } + /** @hide */ + @Override + public void sendBroadcast(Intent intent, String receiverPermission, int appOp) { + mBase.sendBroadcast(intent, receiverPermission, appOp); + } + @Override public void sendOrderedBroadcast(Intent intent, String receiverPermission) { @@ -365,6 +371,17 @@ public class ContextWrapper extends Context { initialData, initialExtras); } + /** @hide */ + @Override + public void sendOrderedBroadcast( + Intent intent, String receiverPermission, int appOp, BroadcastReceiver resultReceiver, + Handler scheduler, int initialCode, String initialData, + Bundle initialExtras) { + mBase.sendOrderedBroadcast(intent, receiverPermission, appOp, + resultReceiver, scheduler, initialCode, + initialData, initialExtras); + } + @Override public void sendBroadcastAsUser(Intent intent, UserHandle user) { mBase.sendBroadcastAsUser(intent, user); diff --git a/services/java/com/android/server/am/ActivityManagerService.java b/services/java/com/android/server/am/ActivityManagerService.java index 252cae2..44f2d12 100644 --- a/services/java/com/android/server/am/ActivityManagerService.java +++ b/services/java/com/android/server/am/ActivityManagerService.java @@ -18,6 +18,7 @@ package com.android.server.am; import static android.content.pm.PackageManager.PERMISSION_GRANTED; +import android.app.AppOpsManager; import com.android.internal.R; import com.android.internal.os.BatteryStatsImpl; import com.android.internal.os.ProcessStats; @@ -992,7 +993,7 @@ public final class ActivityManagerService extends ActivityManagerNative | Intent.FLAG_RECEIVER_FOREGROUND); } broadcastIntentLocked(null, null, intent, - null, null, 0, null, null, null, + null, null, 0, null, null, null, AppOpsManager.OP_NONE, false, false, MY_PID, Process.SYSTEM_UID, 0 /* TODO: Verify */); if (mShowDialogs) { @@ -3725,7 +3726,7 @@ public final class ActivityManagerService extends ActivityManagerNative } broadcastIntentLocked(null, null, intent, null, - null, 0, null, null, null, false, false, -1, + null, 0, null, null, null, AppOpsManager.OP_NONE, false, false, -1, Process.SYSTEM_UID, UserHandle.USER_ALL); } @@ -3788,7 +3789,7 @@ public final class ActivityManagerService extends ActivityManagerNative intent.putExtra(Intent.EXTRA_UID, uid); intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(uid)); broadcastIntentLocked(null, null, intent, - null, null, 0, null, null, null, + null, null, 0, null, null, null, AppOpsManager.OP_NONE, false, false, MY_PID, Process.SYSTEM_UID, UserHandle.getUserId(uid)); } @@ -3800,7 +3801,7 @@ public final class ActivityManagerService extends ActivityManagerNative | Intent.FLAG_RECEIVER_FOREGROUND); intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); broadcastIntentLocked(null, null, intent, - null, null, 0, null, null, null, + null, null, 0, null, null, null, AppOpsManager.OP_NONE, false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); } @@ -4479,7 +4480,8 @@ public final class ActivityManagerService extends ActivityManagerNative broadcastIntentLocked(null, null, intent, null, null, 0, null, null, android.Manifest.permission.RECEIVE_BOOT_COMPLETED, - false, false, MY_PID, Process.SYSTEM_UID, userId); + AppOpsManager.OP_NONE, false, false, MY_PID, Process.SYSTEM_UID, + userId); } } } @@ -7911,7 +7913,8 @@ public final class ActivityManagerService extends ActivityManagerNative Slog.i(TAG, "Sending system update to " + intent.getComponent() + " for user " + users[j]); broadcastIntentLocked(null, null, intent, null, finisher, - 0, null, null, null, true, false, MY_PID, Process.SYSTEM_UID, + 0, null, null, null, AppOpsManager.OP_NONE, + true, false, MY_PID, Process.SYSTEM_UID, users[j]); if (finisher != null) { mWaitingUpdate = true; @@ -8044,7 +8047,7 @@ public final class ActivityManagerService extends ActivityManagerNative | Intent.FLAG_RECEIVER_FOREGROUND); intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId); broadcastIntentLocked(null, null, intent, - null, null, 0, null, null, null, + null, null, 0, null, null, null, AppOpsManager.OP_NONE, false, false, MY_PID, Process.SYSTEM_UID, mCurrentUserId); intent = new Intent(Intent.ACTION_USER_STARTING); intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); @@ -8057,7 +8060,7 @@ public final class ActivityManagerService extends ActivityManagerNative throws RemoteException { } }, 0, null, null, - android.Manifest.permission.INTERACT_ACROSS_USERS, + android.Manifest.permission.INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE, true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); } finally { Binder.restoreCallingIdentity(ident); @@ -11552,8 +11555,8 @@ public final class ActivityManagerService extends ActivityManagerNative Intent intent = (Intent)allSticky.get(i); BroadcastQueue queue = broadcastQueueForIntent(intent); BroadcastRecord r = new BroadcastRecord(queue, intent, null, - null, -1, -1, null, receivers, null, 0, null, null, - false, true, true, -1); + null, -1, -1, null, AppOpsManager.OP_NONE, receivers, null, 0, + null, null, false, true, true, -1); queue.enqueueParallelBroadcastLocked(r); queue.scheduleBroadcastsLocked(); } @@ -11702,7 +11705,7 @@ public final class ActivityManagerService extends ActivityManagerNative private final int broadcastIntentLocked(ProcessRecord callerApp, String callerPackage, Intent intent, String resolvedType, IIntentReceiver resultTo, int resultCode, String resultData, - Bundle map, String requiredPermission, + Bundle map, String requiredPermission, int appOp, boolean ordered, boolean sticky, int callingPid, int callingUid, int userId) { intent = new Intent(intent); @@ -11948,7 +11951,7 @@ public final class ActivityManagerService extends ActivityManagerNative // components to be launched. final BroadcastQueue queue = broadcastQueueForIntent(intent); BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp, - callerPackage, callingPid, callingUid, requiredPermission, + callerPackage, callingPid, callingUid, requiredPermission, appOp, registeredReceivers, resultTo, resultCode, resultData, map, ordered, sticky, false, userId); if (DEBUG_BROADCAST) Slog.v( @@ -12038,7 +12041,7 @@ public final class ActivityManagerService extends ActivityManagerNative || resultTo != null) { BroadcastQueue queue = broadcastQueueForIntent(intent); BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp, - callerPackage, callingPid, callingUid, requiredPermission, + callerPackage, callingPid, callingUid, requiredPermission, appOp, receivers, resultTo, resultCode, resultData, map, ordered, sticky, false, userId); if (DEBUG_BROADCAST) Slog.v( @@ -12090,7 +12093,7 @@ public final class ActivityManagerService extends ActivityManagerNative public final int broadcastIntent(IApplicationThread caller, Intent intent, String resolvedType, IIntentReceiver resultTo, int resultCode, String resultData, Bundle map, - String requiredPermission, boolean serialized, boolean sticky, int userId) { + String requiredPermission, int appOp, boolean serialized, boolean sticky, int userId) { enforceNotIsolatedCaller("broadcastIntent"); synchronized(this) { intent = verifyBroadcastLocked(intent); @@ -12102,7 +12105,7 @@ public final class ActivityManagerService extends ActivityManagerNative int res = broadcastIntentLocked(callerApp, callerApp != null ? callerApp.info.packageName : null, intent, resolvedType, resultTo, - resultCode, resultData, map, requiredPermission, serialized, sticky, + resultCode, resultData, map, requiredPermission, appOp, serialized, sticky, callingPid, callingUid, userId); Binder.restoreCallingIdentity(origId); return res; @@ -12119,7 +12122,7 @@ public final class ActivityManagerService extends ActivityManagerNative final long origId = Binder.clearCallingIdentity(); int res = broadcastIntentLocked(null, packageName, intent, resolvedType, resultTo, resultCode, resultData, map, requiredPermission, - serialized, sticky, -1, uid, userId); + AppOpsManager.OP_NONE, serialized, sticky, -1, uid, userId); Binder.restoreCallingIdentity(origId); return res; } @@ -12505,13 +12508,14 @@ public final class ActivityManagerService extends ActivityManagerNative | Intent.FLAG_RECEIVER_REPLACE_PENDING | Intent.FLAG_RECEIVER_FOREGROUND); broadcastIntentLocked(null, null, intent, null, null, 0, null, null, - null, false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); + null, AppOpsManager.OP_NONE, false, false, MY_PID, + Process.SYSTEM_UID, UserHandle.USER_ALL); if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) { intent = new Intent(Intent.ACTION_LOCALE_CHANGED); intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); broadcastIntentLocked(null, null, intent, - null, null, 0, null, null, - null, false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); + null, null, 0, null, null, null, AppOpsManager.OP_NONE, + false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); } } } @@ -14355,7 +14359,7 @@ public final class ActivityManagerService extends ActivityManagerNative | Intent.FLAG_RECEIVER_FOREGROUND); intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); broadcastIntentLocked(null, null, intent, - null, null, 0, null, null, null, + null, null, 0, null, null, null, AppOpsManager.OP_NONE, false, false, MY_PID, Process.SYSTEM_UID, userId); } @@ -14370,7 +14374,8 @@ public final class ActivityManagerService extends ActivityManagerNative boolean sticky, int sendingUser) { userInitialized(uss, userId); } - }, 0, null, null, null, true, false, MY_PID, Process.SYSTEM_UID, + }, 0, null, null, null, AppOpsManager.OP_NONE, + true, false, MY_PID, Process.SYSTEM_UID, userId); uss.initializing = true; } else { @@ -14398,7 +14403,7 @@ public final class ActivityManagerService extends ActivityManagerNative throws RemoteException { } }, 0, null, null, - android.Manifest.permission.INTERACT_ACROSS_USERS, + android.Manifest.permission.INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE, true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); } } @@ -14419,7 +14424,7 @@ public final class ActivityManagerService extends ActivityManagerNative | Intent.FLAG_RECEIVER_FOREGROUND); intent.putExtra(Intent.EXTRA_USER_HANDLE, oldUserId); broadcastIntentLocked(null, null, intent, - null, null, 0, null, null, null, + null, null, 0, null, null, null, AppOpsManager.OP_NONE, false, false, MY_PID, Process.SYSTEM_UID, oldUserId); } if (newUserId >= 0) { @@ -14428,7 +14433,7 @@ public final class ActivityManagerService extends ActivityManagerNative | Intent.FLAG_RECEIVER_FOREGROUND); intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId); broadcastIntentLocked(null, null, intent, - null, null, 0, null, null, null, + null, null, 0, null, null, null, AppOpsManager.OP_NONE, false, false, MY_PID, Process.SYSTEM_UID, newUserId); intent = new Intent(Intent.ACTION_USER_SWITCHED); intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY @@ -14436,7 +14441,7 @@ public final class ActivityManagerService extends ActivityManagerNative intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId); broadcastIntentLocked(null, null, intent, null, null, 0, null, null, - android.Manifest.permission.MANAGE_USERS, + android.Manifest.permission.MANAGE_USERS, AppOpsManager.OP_NONE, false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); } } finally { @@ -14541,7 +14546,7 @@ public final class ActivityManagerService extends ActivityManagerNative intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); broadcastIntentLocked(null, null, intent, null, null, 0, null, null, - android.Manifest.permission.RECEIVE_BOOT_COMPLETED, + android.Manifest.permission.RECEIVE_BOOT_COMPLETED, AppOpsManager.OP_NONE, false, false, MY_PID, Process.SYSTEM_UID, userId); } int num = mUserLru.size(); @@ -14657,14 +14662,14 @@ public final class ActivityManagerService extends ActivityManagerNative uss.mState = UserStartedState.STATE_SHUTDOWN; } broadcastIntentLocked(null, null, shutdownIntent, - null, shutdownReceiver, 0, null, null, null, + null, shutdownReceiver, 0, null, null, null, AppOpsManager.OP_NONE, true, false, MY_PID, Process.SYSTEM_UID, userId); } }; // Kick things off. broadcastIntentLocked(null, null, stoppingIntent, null, stoppingReceiver, 0, null, null, - android.Manifest.permission.INTERACT_ACROSS_USERS, + android.Manifest.permission.INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE, true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); } finally { Binder.restoreCallingIdentity(ident); diff --git a/services/java/com/android/server/am/BroadcastQueue.java b/services/java/com/android/server/am/BroadcastQueue.java index bada7f0..e8e8f25 100644 --- a/services/java/com/android/server/am/BroadcastQueue.java +++ b/services/java/com/android/server/am/BroadcastQueue.java @@ -22,6 +22,7 @@ import java.util.ArrayList; import android.app.ActivityManager; import android.app.AppGlobals; +import android.app.AppOpsManager; import android.content.ComponentName; import android.content.IIntentReceiver; import android.content.Intent; @@ -409,6 +410,16 @@ public class BroadcastQueue { skip = true; } } + if (r.appOp != AppOpsManager.OP_NONE) { + int mode = mService.mAppOpsService.checkOperation(r.appOp, + filter.receiverList.uid, filter.packageName); + if (mode != AppOpsManager.MODE_ALLOWED) { + if (DEBUG_BROADCAST) Slog.v(TAG, + "App op " + r.appOp + " not allowed for broadcast to uid " + + filter.receiverList.uid + " pkg " + filter.packageName); + skip = true; + } + } if (!skip) { // If this is not being sent as an ordered broadcast, then we @@ -706,6 +717,17 @@ public class BroadcastQueue { skip = true; } } + if (r.appOp != AppOpsManager.OP_NONE) { + int mode = mService.mAppOpsService.checkOperation(r.appOp, + info.activityInfo.applicationInfo.uid, info.activityInfo.packageName); + if (mode != AppOpsManager.MODE_ALLOWED) { + if (DEBUG_BROADCAST) Slog.v(TAG, + "App op " + r.appOp + " not allowed for broadcast to uid " + + info.activityInfo.applicationInfo.uid + " pkg " + + info.activityInfo.packageName); + skip = true; + } + } boolean isSingleton = false; try { isSingleton = mService.isSingleton(info.activityInfo.processName, diff --git a/services/java/com/android/server/am/BroadcastRecord.java b/services/java/com/android/server/am/BroadcastRecord.java index 1cf5b9c..a98afb6 100644 --- a/services/java/com/android/server/am/BroadcastRecord.java +++ b/services/java/com/android/server/am/BroadcastRecord.java @@ -16,6 +16,7 @@ package com.android.server.am; +import android.app.AppOpsManager; import android.content.IIntentReceiver; import android.content.ComponentName; import android.content.Intent; @@ -46,6 +47,7 @@ class BroadcastRecord extends Binder { final boolean initialSticky; // initial broadcast from register to sticky? final int userId; // user id this broadcast was for final String requiredPermission; // a permission the caller has required + final int appOp; // an app op that is associated with this broadcast final List receivers; // contains BroadcastFilter and ResolveInfo IIntentReceiver resultTo; // who receives final result if non-null long dispatchTime; // when dispatch started on this set of receivers @@ -90,8 +92,9 @@ class BroadcastRecord extends Binder { pw.print(callerApp != null ? callerApp.toShortString() : "null"); pw.print(" pid="); pw.print(callingPid); pw.print(" uid="); pw.println(callingUid); - if (requiredPermission != null) { - pw.print(prefix); pw.print("requiredPermission="); pw.println(requiredPermission); + if (requiredPermission != null || appOp != AppOpsManager.OP_NONE) { + pw.print(prefix); pw.print("requiredPermission="); pw.print(requiredPermission); + pw.print(" appOp="); pw.println(appOp); } pw.print(prefix); pw.print("dispatchClockTime="); pw.println(new Date(dispatchClockTime)); @@ -164,7 +167,7 @@ class BroadcastRecord extends Binder { BroadcastRecord(BroadcastQueue _queue, Intent _intent, ProcessRecord _callerApp, String _callerPackage, - int _callingPid, int _callingUid, String _requiredPermission, + int _callingPid, int _callingUid, String _requiredPermission, int _appOp, List _receivers, IIntentReceiver _resultTo, int _resultCode, String _resultData, Bundle _resultExtras, boolean _serialized, boolean _sticky, boolean _initialSticky, @@ -176,6 +179,7 @@ class BroadcastRecord extends Binder { callingPid = _callingPid; callingUid = _callingUid; requiredPermission = _requiredPermission; + appOp = _appOp; receivers = _receivers; resultTo = _resultTo; resultCode = _resultCode; diff --git a/services/java/com/android/server/pm/PackageManagerService.java b/services/java/com/android/server/pm/PackageManagerService.java index 829e67a..46d2cca 100644 --- a/services/java/com/android/server/pm/PackageManagerService.java +++ b/services/java/com/android/server/pm/PackageManagerService.java @@ -25,7 +25,6 @@ import static android.content.pm.PackageManager.COMPONENT_ENABLED_STATE_DISABLED import static android.content.pm.PackageManager.COMPONENT_ENABLED_STATE_ENABLED; import static com.android.internal.util.ArrayUtils.appendInt; import static com.android.internal.util.ArrayUtils.removeInt; -import static libcore.io.OsConstants.S_ISLNK; import static libcore.io.OsConstants.S_IRWXU; import static libcore.io.OsConstants.S_IRGRP; import static libcore.io.OsConstants.S_IXGRP; @@ -112,7 +111,6 @@ import android.os.SystemClock; import android.os.SystemProperties; import android.os.UserHandle; import android.os.Environment.UserEnvironment; -import android.provider.Settings.Secure; import android.security.SystemKeyStore; import android.util.DisplayMetrics; import android.util.EventLog; @@ -149,13 +147,11 @@ import java.util.HashSet; import java.util.Iterator; import java.util.List; import java.util.Map; -import java.util.Map.Entry; import java.util.Set; import libcore.io.ErrnoException; import libcore.io.IoUtils; import libcore.io.Libcore; -import libcore.io.OsConstants; import libcore.io.StructStat; /** @@ -5441,7 +5437,8 @@ public class PackageManagerService extends IPackageManager.Stub { + " " + intent.getExtras(), here); } am.broadcastIntent(null, intent, null, finishedReceiver, - 0, null, null, null, finishedReceiver != null, false, id); + 0, null, null, null, android.app.AppOpsManager.OP_NONE, + finishedReceiver != null, false, id); } } catch (RemoteException ex) { } diff --git a/test-runner/src/android/test/mock/MockContext.java b/test-runner/src/android/test/mock/MockContext.java index 248fbf1..cfc6bd7 100644 --- a/test-runner/src/android/test/mock/MockContext.java +++ b/test-runner/src/android/test/mock/MockContext.java @@ -299,6 +299,12 @@ public class MockContext extends Context { throw new UnsupportedOperationException(); } + /** @hide */ + @Override + public void sendBroadcast(Intent intent, String receiverPermission, int appOp) { + throw new UnsupportedOperationException(); + } + @Override public void sendOrderedBroadcast(Intent intent, String receiverPermission) { @@ -312,6 +318,14 @@ public class MockContext extends Context { throw new UnsupportedOperationException(); } + /** @hide */ + @Override + public void sendOrderedBroadcast(Intent intent, String receiverPermission, int appOp, + BroadcastReceiver resultReceiver, Handler scheduler, int initialCode, String initialData, + Bundle initialExtras) { + throw new UnsupportedOperationException(); + } + @Override public void sendBroadcastAsUser(Intent intent, UserHandle user) { throw new UnsupportedOperationException(); |