Enforce visibleToInstantApps for receivers

Instant apps can only send broadcasts to receivers that are declared in
the manifest with android:visibleToInstantApps=true or if the app
registers a receiver at runtime using the new methods that take
visibleToInstantApps.

Bug:33350280
Test: Manually sending broadcasts from Instant Apps only goes to
receivers with visibleToInstantApps set to true.
Test: Receiving a broadcast from within the same app does not require
visibleToInstantApps to be set.

Change-Id: I54d79a502ba9c5fd03ede3c09e08afc88fe2775f
diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java
index a957c70..20ee30d 100644
--- a/services/core/java/com/android/server/am/ActivityManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityManagerService.java
@@ -18028,7 +18028,8 @@
     }
 
     public Intent registerReceiver(IApplicationThread caller, String callerPackage,
-            IIntentReceiver receiver, IntentFilter filter, String permission, int userId) {
+            IIntentReceiver receiver, IntentFilter filter, String permission, int userId,
+            boolean visibleToInstantApps) {
         enforceNotIsolatedCaller("registerReceiver");
         ArrayList<Intent> stickyIntents = null;
         ProcessRecord callerApp = null;
@@ -18157,7 +18158,7 @@
                         + " callerPackage is " + callerPackage);
             }
             BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage,
-                    permission, callingUid, userId, instantApp);
+                    permission, callingUid, userId, instantApp, visibleToInstantApps);
             rl.add(bf);
             if (!bf.debugCheck()) {
                 Slog.w(TAG, "==> For Dynamic broadcast");
@@ -18175,7 +18176,7 @@
                     Intent intent = allSticky.get(i);
                     BroadcastQueue queue = broadcastQueueForIntent(intent);
                     BroadcastRecord r = new BroadcastRecord(queue, intent, null,
-                            null, -1, -1, null, null, AppOpsManager.OP_NONE, null, receivers,
+                            null, -1, -1, false, null, null, AppOpsManager.OP_NONE, null, receivers,
                             null, 0, null, null, false, true, true, -1);
                     queue.enqueueParallelBroadcastLocked(r);
                     queue.scheduleBroadcastsLocked();
@@ -18911,9 +18912,9 @@
             }
             final BroadcastQueue queue = broadcastQueueForIntent(intent);
             BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
-                    callerPackage, callingPid, callingUid, resolvedType, requiredPermissions,
-                    appOp, brOptions, registeredReceivers, resultTo, resultCode, resultData,
-                    resultExtras, ordered, sticky, false, userId);
+                    callerPackage, callingPid, callingUid, callerInstantApp, resolvedType,
+                    requiredPermissions, appOp, brOptions, registeredReceivers, resultTo,
+                    resultCode, resultData, resultExtras, ordered, sticky, false, userId);
             if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueueing parallel broadcast " + r);
             final boolean replaced = replacePending
                     && (queue.replaceParallelBroadcastLocked(r) != null);
@@ -19007,7 +19008,7 @@
                 || resultTo != null) {
             BroadcastQueue queue = broadcastQueueForIntent(intent);
             BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
-                    callerPackage, callingPid, callingUid, resolvedType,
+                    callerPackage, callingPid, callingUid, callerInstantApp, resolvedType,
                     requiredPermissions, appOp, brOptions, receivers, resultTo, resultCode,
                     resultData, resultExtras, ordered, sticky, false, userId);
 
diff --git a/services/core/java/com/android/server/am/BroadcastFilter.java b/services/core/java/com/android/server/am/BroadcastFilter.java
index a06a21f..f96b06f 100644
--- a/services/core/java/com/android/server/am/BroadcastFilter.java
+++ b/services/core/java/com/android/server/am/BroadcastFilter.java
@@ -30,10 +30,11 @@
     final int owningUid;
     final int owningUserId;
     final boolean instantApp;
+    final boolean visibleToInstantApp;
 
     BroadcastFilter(IntentFilter _filter, ReceiverList _receiverList,
             String _packageName, String _requiredPermission, int _owningUid, int _userId,
-            boolean _instantApp) {
+            boolean _instantApp, boolean _visibleToInstantApp) {
         super(_filter);
         receiverList = _receiverList;
         packageName = _packageName;
@@ -41,6 +42,7 @@
         owningUid = _owningUid;
         owningUserId = _userId;
         instantApp = _instantApp;
+        visibleToInstantApp = _visibleToInstantApp;
     }
     
     public void dump(PrintWriter pw, String prefix) {
diff --git a/services/core/java/com/android/server/am/BroadcastQueue.java b/services/core/java/com/android/server/am/BroadcastQueue.java
index 629f80d..2787895 100644
--- a/services/core/java/com/android/server/am/BroadcastQueue.java
+++ b/services/core/java/com/android/server/am/BroadcastQueue.java
@@ -641,6 +641,19 @@
             skip = true;
         }
 
+        if (!skip && !filter.visibleToInstantApp && r.callerInstantApp
+                && filter.receiverList.uid != r.callingUid) {
+            Slog.w(TAG, "Instant App Denial: receiving "
+                    + r.intent.toString()
+                    + " to " + filter.receiverList.app
+                    + " (pid=" + filter.receiverList.pid
+                    + ", uid=" + filter.receiverList.uid + ")"
+                    + " requires receiver be visible to instant apps"
+                    + " due to sender " + r.callerPackage
+                    + " (uid " + r.callingUid + ")");
+            skip = true;
+        }
+
         if (skip) {
             r.delivery[index] = BroadcastRecord.DELIVERY_SKIPPED;
             return;
@@ -1152,6 +1165,17 @@
                         + " not specifying FLAG_RECEIVER_VISIBLE_TO_INSTANT_APPS");
                 skip = true;
             }
+            if (!skip && r.callerInstantApp
+                    && (info.activityInfo.flags & ActivityInfo.FLAG_VISIBLE_TO_EPHEMERAL) == 0
+                    && r.callingUid != info.activityInfo.applicationInfo.uid) {
+                Slog.w(TAG, "Instant App Denial: receiving "
+                        + r.intent
+                        + " to " + component.flattenToShortString()
+                        + " requires receiver have visibleToInstantApps set"
+                        + " due to sender " + r.callerPackage
+                        + " (uid " + r.callingUid + ")");
+                skip = true;
+            }
             if (!skip) {
                 r.manifestCount++;
             } else {
diff --git a/services/core/java/com/android/server/am/BroadcastRecord.java b/services/core/java/com/android/server/am/BroadcastRecord.java
index 1e7911a..7764be7 100644
--- a/services/core/java/com/android/server/am/BroadcastRecord.java
+++ b/services/core/java/com/android/server/am/BroadcastRecord.java
@@ -48,6 +48,7 @@
     final String callerPackage; // who sent this
     final int callingPid;   // the pid of who sent this
     final int callingUid;   // the uid of who sent this
+    final boolean callerInstantApp; // caller is an Instant App?
     final boolean ordered;  // serialize the send to receivers?
     final boolean sticky;   // originated from existing sticky data?
     final boolean initialSticky; // initial broadcast from register to sticky?
@@ -214,11 +215,10 @@
 
     BroadcastRecord(BroadcastQueue _queue,
             Intent _intent, ProcessRecord _callerApp, String _callerPackage,
-            int _callingPid, int _callingUid, String _resolvedType, String[] _requiredPermissions,
-            int _appOp, BroadcastOptions _options, List _receivers, IIntentReceiver _resultTo,
-            int _resultCode, String _resultData, Bundle _resultExtras, boolean _serialized,
-            boolean _sticky, boolean _initialSticky,
-            int _userId) {
+            int _callingPid, int _callingUid, boolean _callerInstantApp, String _resolvedType,
+            String[] _requiredPermissions, int _appOp, BroadcastOptions _options, List _receivers,
+            IIntentReceiver _resultTo, int _resultCode, String _resultData, Bundle _resultExtras,
+            boolean _serialized, boolean _sticky, boolean _initialSticky, int _userId) {
         if (_intent == null) {
             throw new NullPointerException("Can't construct with a null intent");
         }
@@ -229,6 +229,7 @@
         callerPackage = _callerPackage;
         callingPid = _callingPid;
         callingUid = _callingUid;
+        callerInstantApp = _callerInstantApp;
         resolvedType = _resolvedType;
         requiredPermissions = _requiredPermissions;
         appOp = _appOp;