Add support for broadcast intents
Change-Id: Icf61e7a202f489cb33b9fd95564285e48154b25b
diff --git a/services/java/com/android/server/am/ActivityManagerService.java b/services/java/com/android/server/am/ActivityManagerService.java
index 1d26c2c..6fa1822 100644
--- a/services/java/com/android/server/am/ActivityManagerService.java
+++ b/services/java/com/android/server/am/ActivityManagerService.java
@@ -12371,7 +12371,7 @@
Intent intent = (Intent)allSticky.get(i);
BroadcastQueue queue = broadcastQueueForIntent(intent);
BroadcastRecord r = new BroadcastRecord(queue, intent, null,
- null, -1, -1, null, AppOpsManager.OP_NONE, receivers, null, 0,
+ null, -1, -1, null, null, AppOpsManager.OP_NONE, receivers, null, 0,
null, null, false, true, true, -1);
queue.enqueueParallelBroadcastLocked(r);
queue.scheduleBroadcastsLocked();
@@ -12804,8 +12804,8 @@
// components to be launched.
final BroadcastQueue queue = broadcastQueueForIntent(intent);
BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
- callerPackage, callingPid, callingUid, requiredPermission, appOp,
- registeredReceivers, resultTo, resultCode, resultData, map,
+ callerPackage, callingPid, callingUid, resolvedType, requiredPermission,
+ appOp, registeredReceivers, resultTo, resultCode, resultData, map,
ordered, sticky, false, userId);
if (DEBUG_BROADCAST) Slog.v(
TAG, "Enqueueing parallel broadcast " + r);
@@ -12894,9 +12894,9 @@
|| resultTo != null) {
BroadcastQueue queue = broadcastQueueForIntent(intent);
BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
- callerPackage, callingPid, callingUid, requiredPermission, appOp,
- receivers, resultTo, resultCode, resultData, map, ordered,
- sticky, false, userId);
+ callerPackage, callingPid, callingUid, resolvedType,
+ requiredPermission, appOp, receivers, resultTo, resultCode,
+ resultData, map, ordered, sticky, false, userId);
if (DEBUG_BROADCAST) Slog.v(
TAG, "Enqueueing ordered broadcast " + r
+ ": prev had " + queue.mOrderedBroadcasts.size());
diff --git a/services/java/com/android/server/am/BroadcastQueue.java b/services/java/com/android/server/am/BroadcastQueue.java
index cb4b8ff..254a219 100644
--- a/services/java/com/android/server/am/BroadcastQueue.java
+++ b/services/java/com/android/server/am/BroadcastQueue.java
@@ -421,6 +421,10 @@
skip = true;
}
}
+ if (!skip) {
+ skip = !mService.mIntentFirewall.checkBroadcast(r.intent, r.callingUid,
+ r.callingPid, r.resolvedType, filter.receiverList.uid);
+ }
if (!skip) {
// If this is not being sent as an ordered broadcast, then we
@@ -729,6 +733,10 @@
skip = true;
}
}
+ if (!skip) {
+ skip = !mService.mIntentFirewall.checkBroadcast(r.intent, r.callingUid,
+ r.callingPid, r.resolvedType, info.activityInfo.applicationInfo.uid);
+ }
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 eb1df6e..db61e88 100644
--- a/services/java/com/android/server/am/BroadcastRecord.java
+++ b/services/java/com/android/server/am/BroadcastRecord.java
@@ -47,6 +47,7 @@
final boolean sticky; // originated from existing sticky data?
final boolean initialSticky; // initial broadcast from register to sticky?
final int userId; // user id this broadcast was for
+ final String resolvedType; // the resolved data type
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
@@ -171,8 +172,8 @@
BroadcastRecord(BroadcastQueue _queue,
Intent _intent, ProcessRecord _callerApp, String _callerPackage,
- int _callingPid, int _callingUid, String _requiredPermission, int _appOp,
- List _receivers, IIntentReceiver _resultTo, int _resultCode,
+ int _callingPid, int _callingUid, String _resolvedType, String _requiredPermission,
+ int _appOp, List _receivers, IIntentReceiver _resultTo, int _resultCode,
String _resultData, Bundle _resultExtras, boolean _serialized,
boolean _sticky, boolean _initialSticky,
int _userId) {
@@ -183,6 +184,7 @@
callerPackage = _callerPackage;
callingPid = _callingPid;
callingUid = _callingUid;
+ resolvedType = _resolvedType;
requiredPermission = _requiredPermission;
appOp = _appOp;
receivers = _receivers;
diff --git a/services/java/com/android/server/firewall/AndFilter.java b/services/java/com/android/server/firewall/AndFilter.java
index fa53945..13551de 100644
--- a/services/java/com/android/server/firewall/AndFilter.java
+++ b/services/java/com/android/server/firewall/AndFilter.java
@@ -18,7 +18,6 @@
import android.content.ComponentName;
import android.content.Intent;
-import android.content.pm.ApplicationInfo;
import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParserException;
@@ -27,10 +26,10 @@
class AndFilter extends FilterList {
@Override
public boolean matches(IntentFirewall ifw, ComponentName resolvedComponent, Intent intent,
- int callerUid, int callerPid, String resolvedType, ApplicationInfo resolvedApp) {
+ int callerUid, int callerPid, String resolvedType, int receivingUid) {
for (int i=0; i<children.size(); i++) {
if (!children.get(i).matches(ifw, resolvedComponent, intent, callerUid, callerPid,
- resolvedType, resolvedApp)) {
+ resolvedType, receivingUid)) {
return false;
}
}
diff --git a/services/java/com/android/server/firewall/CategoryFilter.java b/services/java/com/android/server/firewall/CategoryFilter.java
index 022dc9a..246c096 100644
--- a/services/java/com/android/server/firewall/CategoryFilter.java
+++ b/services/java/com/android/server/firewall/CategoryFilter.java
@@ -18,7 +18,6 @@
import android.content.ComponentName;
import android.content.Intent;
-import android.content.pm.ApplicationInfo;
import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParserException;
@@ -36,7 +35,7 @@
@Override
public boolean matches(IntentFirewall ifw, ComponentName resolvedComponent, Intent intent,
- int callerUid, int callerPid, String resolvedType, ApplicationInfo resolvedApp) {
+ int callerUid, int callerPid, String resolvedType, int receivingUid) {
Set<String> categories = intent.getCategories();
if (categories == null) {
return false;
diff --git a/services/java/com/android/server/firewall/Filter.java b/services/java/com/android/server/firewall/Filter.java
index 25105e1..0a124f7 100644
--- a/services/java/com/android/server/firewall/Filter.java
+++ b/services/java/com/android/server/firewall/Filter.java
@@ -18,7 +18,6 @@
import android.content.ComponentName;
import android.content.Intent;
-import android.content.pm.ApplicationInfo;
interface Filter {
/**
@@ -30,8 +29,8 @@
* @param callerUid The uid of the caller
* @param callerPid The pid of the caller
* @param resolvedType The resolved mime type of the intent
- * @param resolvedApp The application that contains the resolved component that the intent is
+ * @param receivingUid The uid of the component receiving the intent
*/
boolean matches(IntentFirewall ifw, ComponentName resolvedComponent, Intent intent,
- int callerUid, int callerPid, String resolvedType, ApplicationInfo resolvedApp);
+ int callerUid, int callerPid, String resolvedType, int receivingUid);
}
diff --git a/services/java/com/android/server/firewall/IntentFirewall.java b/services/java/com/android/server/firewall/IntentFirewall.java
index bd62de7..aaa0b58 100644
--- a/services/java/com/android/server/firewall/IntentFirewall.java
+++ b/services/java/com/android/server/firewall/IntentFirewall.java
@@ -124,18 +124,24 @@
public boolean checkStartActivity(Intent intent, int callerUid, int callerPid,
String resolvedType, ApplicationInfo resolvedApp) {
return checkIntent(mActivityResolver, intent.getComponent(), TYPE_ACTIVITY, intent,
- callerUid, callerPid, resolvedType, resolvedApp);
+ callerUid, callerPid, resolvedType, resolvedApp.uid);
}
public boolean checkService(ComponentName resolvedService, Intent intent, int callerUid,
int callerPid, String resolvedType, ApplicationInfo resolvedApp) {
return checkIntent(mServiceResolver, resolvedService, TYPE_SERVICE, intent, callerUid,
- callerPid, resolvedType, resolvedApp);
+ callerPid, resolvedType, resolvedApp.uid);
+ }
+
+ public boolean checkBroadcast(Intent intent, int callerUid, int callerPid,
+ String resolvedType, int receivingUid) {
+ return checkIntent(mBroadcastResolver, intent.getComponent(), TYPE_BROADCAST, intent,
+ callerUid, callerPid, resolvedType, receivingUid);
}
public boolean checkIntent(FirewallIntentResolver resolver, ComponentName resolvedComponent,
int intentType, Intent intent, int callerUid, int callerPid, String resolvedType,
- ApplicationInfo resolvedApp) {
+ int receivingUid) {
boolean log = false;
boolean block = false;
@@ -153,7 +159,7 @@
for (int i=0; i<candidateRules.size(); i++) {
Rule rule = candidateRules.get(i);
if (rule.matches(this, resolvedComponent, intent, callerUid, callerPid, resolvedType,
- resolvedApp)) {
+ receivingUid)) {
block |= rule.getBlock();
log |= rule.getLog();
diff --git a/services/java/com/android/server/firewall/NotFilter.java b/services/java/com/android/server/firewall/NotFilter.java
index 5f3d516..09bf629 100644
--- a/services/java/com/android/server/firewall/NotFilter.java
+++ b/services/java/com/android/server/firewall/NotFilter.java
@@ -18,7 +18,6 @@
import android.content.ComponentName;
import android.content.Intent;
-import android.content.pm.ApplicationInfo;
import com.android.internal.util.XmlUtils;
import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParserException;
@@ -34,9 +33,9 @@
@Override
public boolean matches(IntentFirewall ifw, ComponentName resolvedComponent, Intent intent,
- int callerUid, int callerPid, String resolvedType, ApplicationInfo resolvedApp) {
+ int callerUid, int callerPid, String resolvedType, int receivingUid) {
return !mChild.matches(ifw, resolvedComponent, intent, callerUid, callerPid, resolvedType,
- resolvedApp);
+ receivingUid);
}
public static final FilterFactory FACTORY = new FilterFactory("not") {
diff --git a/services/java/com/android/server/firewall/OrFilter.java b/services/java/com/android/server/firewall/OrFilter.java
index e3811eb..f6a6f22 100644
--- a/services/java/com/android/server/firewall/OrFilter.java
+++ b/services/java/com/android/server/firewall/OrFilter.java
@@ -18,7 +18,6 @@
import android.content.ComponentName;
import android.content.Intent;
-import android.content.pm.ApplicationInfo;
import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParserException;
@@ -27,10 +26,10 @@
class OrFilter extends FilterList {
@Override
public boolean matches(IntentFirewall ifw, ComponentName resolvedComponent, Intent intent,
- int callerUid, int callerPid, String resolvedType, ApplicationInfo resolvedApp) {
+ int callerUid, int callerPid, String resolvedType, int receivingUid) {
for (int i=0; i<children.size(); i++) {
if (children.get(i).matches(ifw, resolvedComponent, intent, callerUid, callerPid,
- resolvedType, resolvedApp)) {
+ resolvedType, receivingUid)) {
return true;
}
}
diff --git a/services/java/com/android/server/firewall/PortFilter.java b/services/java/com/android/server/firewall/PortFilter.java
index d0cd17f..84ace553 100644
--- a/services/java/com/android/server/firewall/PortFilter.java
+++ b/services/java/com/android/server/firewall/PortFilter.java
@@ -18,7 +18,6 @@
import android.content.ComponentName;
import android.content.Intent;
-import android.content.pm.ApplicationInfo;
import android.net.Uri;
import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParserException;
@@ -43,7 +42,7 @@
@Override
public boolean matches(IntentFirewall ifw, ComponentName resolvedComponent, Intent intent,
- int callerUid, int callerPid, String resolvedType, ApplicationInfo resolvedApp) {
+ int callerUid, int callerPid, String resolvedType, int receivingUid) {
int port = -1;
Uri uri = intent.getData();
if (uri != null) {
diff --git a/services/java/com/android/server/firewall/SenderFilter.java b/services/java/com/android/server/firewall/SenderFilter.java
index 7306dbde..c0eee69 100644
--- a/services/java/com/android/server/firewall/SenderFilter.java
+++ b/services/java/com/android/server/firewall/SenderFilter.java
@@ -79,15 +79,15 @@
private static final Filter SIGNATURE = new Filter() {
@Override
public boolean matches(IntentFirewall ifw, ComponentName resolvedComponent, Intent intent,
- int callerUid, int callerPid, String resolvedType, ApplicationInfo resolvedApp) {
- return ifw.signaturesMatch(callerUid, resolvedApp.uid);
+ int callerUid, int callerPid, String resolvedType, int receivingUid) {
+ return ifw.signaturesMatch(callerUid, receivingUid);
}
};
private static final Filter SYSTEM = new Filter() {
@Override
public boolean matches(IntentFirewall ifw, ComponentName resolvedComponent, Intent intent,
- int callerUid, int callerPid, String resolvedType, ApplicationInfo resolvedApp) {
+ int callerUid, int callerPid, String resolvedType, int receivingUid) {
return isPrivilegedApp(callerUid, callerPid);
}
};
@@ -95,21 +95,21 @@
private static final Filter SYSTEM_OR_SIGNATURE = new Filter() {
@Override
public boolean matches(IntentFirewall ifw, ComponentName resolvedComponent, Intent intent,
- int callerUid, int callerPid, String resolvedType, ApplicationInfo resolvedApp) {
+ int callerUid, int callerPid, String resolvedType, int receivingUid) {
return isPrivilegedApp(callerUid, callerPid) ||
- ifw.signaturesMatch(callerUid, resolvedApp.uid);
+ ifw.signaturesMatch(callerUid, receivingUid);
}
};
private static final Filter USER_ID = new Filter() {
@Override
public boolean matches(IntentFirewall ifw, ComponentName resolvedComponent, Intent intent,
- int callerUid, int callerPid, String resolvedType, ApplicationInfo resolvedApp) {
+ int callerUid, int callerPid, String resolvedType, int receivingUid) {
// This checks whether the caller is either the system process, or has the same user id
// I.e. the same app, or an app that uses the same shared user id.
// This is the same set of applications that would be able to access the component if
// it wasn't exported.
- return ifw.checkComponentPermission(null, callerPid, callerUid, resolvedApp.uid, false);
+ return ifw.checkComponentPermission(null, callerPid, callerUid, receivingUid, false);
}
};
}
diff --git a/services/java/com/android/server/firewall/SenderPermissionFilter.java b/services/java/com/android/server/firewall/SenderPermissionFilter.java
index 60225a3..caa65f3 100644
--- a/services/java/com/android/server/firewall/SenderPermissionFilter.java
+++ b/services/java/com/android/server/firewall/SenderPermissionFilter.java
@@ -18,7 +18,6 @@
import android.content.ComponentName;
import android.content.Intent;
-import android.content.pm.ApplicationInfo;
import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParserException;
@@ -35,11 +34,11 @@
@Override
public boolean matches(IntentFirewall ifw, ComponentName resolvedComponent, Intent intent,
- int callerUid, int callerPid, String resolvedType, ApplicationInfo resolvedApp) {
+ int callerUid, int callerPid, String resolvedType, int receivingUid) {
// We assume the component is exported here. If the component is not exported, then
// ActivityManager would only resolve to this component for callers from the same uid.
// In this case, it doesn't matter whether the component is exported or not.
- return ifw.checkComponentPermission(mPermission, callerPid, callerUid, resolvedApp.uid,
+ return ifw.checkComponentPermission(mPermission, callerPid, callerUid, receivingUid,
true);
}
diff --git a/services/java/com/android/server/firewall/StringFilter.java b/services/java/com/android/server/firewall/StringFilter.java
index fa8105f..28e99b3 100644
--- a/services/java/com/android/server/firewall/StringFilter.java
+++ b/services/java/com/android/server/firewall/StringFilter.java
@@ -18,7 +18,6 @@
import android.content.ComponentName;
import android.content.Intent;
-import android.content.pm.ApplicationInfo;
import android.net.Uri;
import android.os.PatternMatcher;
import org.xmlpull.v1.XmlPullParser;
@@ -120,9 +119,8 @@
@Override
public boolean matches(IntentFirewall ifw, ComponentName resolvedComponent, Intent intent,
- int callerUid, int callerPid, String resolvedType, ApplicationInfo resolvedApp) {
- String value = mValueProvider.getValue(resolvedComponent, intent, resolvedType,
- resolvedApp);
+ int callerUid, int callerPid, String resolvedType, int receivingUid) {
+ String value = mValueProvider.getValue(resolvedComponent, intent, resolvedType);
return matchesValue(value);
}
@@ -137,7 +135,7 @@
}
public abstract String getValue(ComponentName resolvedComponent, Intent intent,
- String resolvedType, ApplicationInfo resolvedApp);
+ String resolvedType);
}
private static class EqualsFilter extends StringFilter {
@@ -231,8 +229,8 @@
public static final ValueProvider COMPONENT = new ValueProvider("component") {
@Override
- public String getValue(ComponentName resolvedComponent, Intent intent, String resolvedType,
- ApplicationInfo resolvedApp) {
+ public String getValue(ComponentName resolvedComponent, Intent intent,
+ String resolvedType) {
if (resolvedComponent != null) {
return resolvedComponent.flattenToString();
}
@@ -242,8 +240,8 @@
public static final ValueProvider COMPONENT_NAME = new ValueProvider("component-name") {
@Override
- public String getValue(ComponentName resolvedComponent, Intent intent, String resolvedType,
- ApplicationInfo resolvedApp) {
+ public String getValue(ComponentName resolvedComponent, Intent intent,
+ String resolvedType) {
if (resolvedComponent != null) {
return resolvedComponent.getClassName();
}
@@ -253,8 +251,8 @@
public static final ValueProvider COMPONENT_PACKAGE = new ValueProvider("component-package") {
@Override
- public String getValue(ComponentName resolvedComponent, Intent intent, String resolvedType,
- ApplicationInfo resolvedApp) {
+ public String getValue(ComponentName resolvedComponent, Intent intent,
+ String resolvedType) {
if (resolvedComponent != null) {
return resolvedComponent.getPackageName();
}
@@ -264,16 +262,16 @@
public static final FilterFactory ACTION = new ValueProvider("action") {
@Override
- public String getValue(ComponentName resolvedComponent, Intent intent, String resolvedType,
- ApplicationInfo resolvedApp) {
+ public String getValue(ComponentName resolvedComponent, Intent intent,
+ String resolvedType) {
return intent.getAction();
}
};
public static final ValueProvider DATA = new ValueProvider("data") {
@Override
- public String getValue(ComponentName resolvedComponent, Intent intent, String resolvedType,
- ApplicationInfo resolvedApp) {
+ public String getValue(ComponentName resolvedComponent, Intent intent,
+ String resolvedType) {
Uri data = intent.getData();
if (data != null) {
return data.toString();
@@ -284,16 +282,16 @@
public static final ValueProvider MIME_TYPE = new ValueProvider("mime-type") {
@Override
- public String getValue(ComponentName resolvedComponent, Intent intent, String resolvedType,
- ApplicationInfo resolvedApp) {
+ public String getValue(ComponentName resolvedComponent, Intent intent,
+ String resolvedType) {
return resolvedType;
}
};
public static final ValueProvider SCHEME = new ValueProvider("scheme") {
@Override
- public String getValue(ComponentName resolvedComponent, Intent intent, String resolvedType,
- ApplicationInfo resolvedApp) {
+ public String getValue(ComponentName resolvedComponent, Intent intent,
+ String resolvedType) {
Uri data = intent.getData();
if (data != null) {
return data.getScheme();
@@ -304,8 +302,8 @@
public static final ValueProvider SSP = new ValueProvider("scheme-specific-part") {
@Override
- public String getValue(ComponentName resolvedComponent, Intent intent, String resolvedType,
- ApplicationInfo resolvedApp) {
+ public String getValue(ComponentName resolvedComponent, Intent intent,
+ String resolvedType) {
Uri data = intent.getData();
if (data != null) {
return data.getSchemeSpecificPart();
@@ -316,8 +314,8 @@
public static final ValueProvider HOST = new ValueProvider("host") {
@Override
- public String getValue(ComponentName resolvedComponent, Intent intent, String resolvedType,
- ApplicationInfo resolvedApp) {
+ public String getValue(ComponentName resolvedComponent, Intent intent,
+ String resolvedType) {
Uri data = intent.getData();
if (data != null) {
return data.getHost();
@@ -328,8 +326,8 @@
public static final ValueProvider PATH = new ValueProvider("path") {
@Override
- public String getValue(ComponentName resolvedComponent, Intent intent, String resolvedType,
- ApplicationInfo resolvedApp) {
+ public String getValue(ComponentName resolvedComponent, Intent intent,
+ String resolvedType) {
Uri data = intent.getData();
if (data != null) {
return data.getPath();