diff options
author | 2024-10-27 18:48:55 +0000 | |
---|---|---|
committer | 2024-10-29 21:00:42 +0000 | |
commit | abf6e804e0bee6c66b1b77c91038325a0ed30dbd (patch) | |
tree | 96111df411604911768ae57b08c68d4c0fe65003 | |
parent | 705c4de6e0a6866699d24d86adbac1fe573b9ca3 (diff) |
Allow querying the intent-filters receivers were registered for.
Bug: 371313878
Test: atest tests/app/BroadcastsTest/src/android/app/cts/broadcasts/BroadcastReceiverRegistrationTest.java
Flag: EXEMPT testapi
Change-Id: I52a5a4af077a4a1cbf6c604e5a2f92666b41bc77
-rw-r--r-- | core/api/test-current.txt | 1 | ||||
-rw-r--r-- | core/java/android/app/ContextImpl.java | 18 | ||||
-rw-r--r-- | core/java/android/app/IActivityManager.aidl | 1 | ||||
-rw-r--r-- | core/java/android/app/LoadedApk.java | 12 | ||||
-rw-r--r-- | core/java/android/content/Context.java | 21 | ||||
-rw-r--r-- | core/java/android/content/ContextWrapper.java | 7 | ||||
-rw-r--r-- | services/core/java/com/android/server/am/ActivityManagerService.java | 4 | ||||
-rw-r--r-- | services/core/java/com/android/server/am/BroadcastController.java | 15 | ||||
-rw-r--r-- | test-mock/src/android/test/mock/MockContext.java | 7 |
9 files changed, 86 insertions, 0 deletions
diff --git a/core/api/test-current.txt b/core/api/test-current.txt index a0c4fdb90bf1..11ca1b972689 100644 --- a/core/api/test-current.txt +++ b/core/api/test-current.txt @@ -1029,6 +1029,7 @@ package android.content { public abstract class Context { method @NonNull public java.io.File getCrateDir(@NonNull String); method public abstract int getDisplayId(); + method @NonNull public java.util.List<android.content.IntentFilter> getRegisteredIntentFilters(@NonNull android.content.BroadcastReceiver); method @NonNull public android.os.UserHandle getUser(); method public int getUserId(); method public void setAutofillOptions(@Nullable android.content.AutofillOptions); diff --git a/core/java/android/app/ContextImpl.java b/core/java/android/app/ContextImpl.java index ecef0db46bb2..2cf718ef364f 100644 --- a/core/java/android/app/ContextImpl.java +++ b/core/java/android/app/ContextImpl.java @@ -1962,6 +1962,24 @@ class ContextImpl extends Context { } } + @Override + @NonNull + public List<IntentFilter> getRegisteredIntentFilters(@NonNull BroadcastReceiver receiver) { + if (mPackageInfo != null) { + IIntentReceiver rd = mPackageInfo.findRegisteredReceiverDispatcher( + receiver, getOuterContext()); + try { + final List<IntentFilter> filters = ActivityManager.getService() + .getRegisteredIntentFilters(rd); + return filters == null ? new ArrayList<>() : filters; + } catch (RemoteException e) { + throw e.rethrowFromSystemServer(); + } + } else { + throw new RuntimeException("Not supported in system context"); + } + } + private void validateServiceIntent(Intent service) { if (service.getComponent() == null && service.getPackage() == null) { if (getApplicationInfo().targetSdkVersion >= Build.VERSION_CODES.LOLLIPOP) { diff --git a/core/java/android/app/IActivityManager.aidl b/core/java/android/app/IActivityManager.aidl index f880901429f7..34a3ad19b270 100644 --- a/core/java/android/app/IActivityManager.aidl +++ b/core/java/android/app/IActivityManager.aidl @@ -181,6 +181,7 @@ interface IActivityManager { in IntentFilter filter, in String requiredPermission, int userId, int flags); @UnsupportedAppUsage void unregisterReceiver(in IIntentReceiver receiver); + List<IntentFilter> getRegisteredIntentFilters(in IIntentReceiver receiver); /** @deprecated Use {@link #broadcastIntentWithFeature} instead */ @UnsupportedAppUsage(maxTargetSdk=29, publicAlternatives="Use {@link android.content.Context#sendBroadcast(android.content.Intent)} instead") int broadcastIntent(in IApplicationThread caller, in Intent intent, diff --git a/core/java/android/app/LoadedApk.java b/core/java/android/app/LoadedApk.java index 1e45d6fd1674..b8233bc498b8 100644 --- a/core/java/android/app/LoadedApk.java +++ b/core/java/android/app/LoadedApk.java @@ -1627,6 +1627,18 @@ public final class LoadedApk { } } + IIntentReceiver findRegisteredReceiverDispatcher(BroadcastReceiver r, Context context) { + synchronized (mReceivers) { + final ArrayMap<BroadcastReceiver, LoadedApk.ReceiverDispatcher> map = + mReceivers.get(context); + if (map != null) { + final LoadedApk.ReceiverDispatcher rd = map.get(r); + return rd == null ? null : rd.getIIntentReceiver(); + } + return null; + } + } + public IIntentReceiver forgetReceiverDispatcher(Context context, BroadcastReceiver r) { synchronized (mReceivers) { diff --git a/core/java/android/content/Context.java b/core/java/android/content/Context.java index 07106e8359d4..bce88bba3e15 100644 --- a/core/java/android/content/Context.java +++ b/core/java/android/content/Context.java @@ -3658,6 +3658,27 @@ public abstract class Context { public abstract void unregisterReceiver(BroadcastReceiver receiver); /** + * Returns the list of {@link IntentFilter} objects that have been registered for the given + * {@link BroadcastReceiver}. + * + * @param receiver The {@link BroadcastReceiver} whose registered intent filters + * should be retrieved. + * + * @return A list of registered intent filters, or an empty list if the given receiver is not + * registered. + * + * @throws NullPointerException if the {@code receiver} is {@code null}. + * + * @hide + */ + @SuppressLint("UnflaggedApi") // TestApi + @TestApi + @NonNull + public List<IntentFilter> getRegisteredIntentFilters(@NonNull BroadcastReceiver receiver) { + throw new RuntimeException("Not implemented. Must override in a subclass."); + } + + /** * Request that a given application service be started. The Intent * should either contain the complete class name of a specific service * implementation to start, or a specific package name to target. If the diff --git a/core/java/android/content/ContextWrapper.java b/core/java/android/content/ContextWrapper.java index 79fa6ea4d157..23d17cb5ce50 100644 --- a/core/java/android/content/ContextWrapper.java +++ b/core/java/android/content/ContextWrapper.java @@ -843,6 +843,13 @@ public class ContextWrapper extends Context { mBase.unregisterReceiver(receiver); } + /** @hide */ + @Override + @NonNull + public List<IntentFilter> getRegisteredIntentFilters(@NonNull BroadcastReceiver receiver) { + return mBase.getRegisteredIntentFilters(receiver); + } + @Override public @Nullable ComponentName startService(Intent service) { return mBase.startService(service); diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java index 2a9cb435e01d..5494463ee1f2 100644 --- a/services/core/java/com/android/server/am/ActivityManagerService.java +++ b/services/core/java/com/android/server/am/ActivityManagerService.java @@ -14301,6 +14301,10 @@ public class ActivityManagerService extends IActivityManager.Stub mBroadcastController.unregisterReceiver(receiver); } + public List<IntentFilter> getRegisteredIntentFilters(IIntentReceiver receiver) { + return mBroadcastController.getRegisteredIntentFilters(receiver); + } + @GuardedBy("this") final int broadcastIntentLocked(ProcessRecord callerApp, String callerPackage, String callerFeatureId, Intent intent, String resolvedType, diff --git a/services/core/java/com/android/server/am/BroadcastController.java b/services/core/java/com/android/server/am/BroadcastController.java index 71ddf05eb692..b0f880710eb6 100644 --- a/services/core/java/com/android/server/am/BroadcastController.java +++ b/services/core/java/com/android/server/am/BroadcastController.java @@ -679,6 +679,21 @@ class BroadcastController { } } + List<IntentFilter> getRegisteredIntentFilters(IIntentReceiver receiver) { + synchronized (mService) { + final ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder()); + if (rl == null) { + return null; + } + final ArrayList<IntentFilter> filters = new ArrayList<>(); + final int count = rl.size(); + for (int i = 0; i < count; ++i) { + filters.add(rl.get(i)); + } + return filters; + } + } + int broadcastIntentWithFeature(IApplicationThread caller, String callingFeatureId, Intent intent, String resolvedType, IIntentReceiver resultTo, int resultCode, String resultData, Bundle resultExtras, diff --git a/test-mock/src/android/test/mock/MockContext.java b/test-mock/src/android/test/mock/MockContext.java index 6bf7ff501217..3247d1fe5222 100644 --- a/test-mock/src/android/test/mock/MockContext.java +++ b/test-mock/src/android/test/mock/MockContext.java @@ -53,6 +53,7 @@ import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; +import java.util.List; import java.util.concurrent.Executor; /** @@ -607,6 +608,12 @@ public class MockContext extends Context { throw new UnsupportedOperationException(); } + /** @hide */ + @Override + public List<IntentFilter> getRegisteredIntentFilters(BroadcastReceiver receiver) { + throw new UnsupportedOperationException(); + } + @Override public ComponentName startService(Intent service) { throw new UnsupportedOperationException(); |