summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDianne Hackborn <hackbod@google.com>2013-02-04 18:23:34 -0800
committerDianne Hackborn <hackbod@google.com>2013-02-05 11:56:12 -0800
commitf51f61269aacdfcf737b2c32b6b216c48ab61e65 (patch)
tree33839b315b97323df81f9638c8bb085241f017cc
parentb86147910877f1aae0733f05a9a93b91101e67e2 (diff)
downloadframeworks_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.java4
-rw-r--r--core/java/android/app/ActivityManagerNative.java8
-rw-r--r--core/java/android/app/AppOpsManager.java39
-rw-r--r--core/java/android/app/ContextImpl.java49
-rw-r--r--core/java/android/app/IActivityManager.java2
-rw-r--r--core/java/android/content/Context.java19
-rw-r--r--core/java/android/content/ContextWrapper.java17
-rw-r--r--services/java/com/android/server/am/ActivityManagerService.java61
-rw-r--r--services/java/com/android/server/am/BroadcastQueue.java22
-rw-r--r--services/java/com/android/server/am/BroadcastRecord.java10
-rw-r--r--services/java/com/android/server/pm/PackageManagerService.java7
-rw-r--r--test-runner/src/android/test/mock/MockContext.java14
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();