diff options
| author | 2021-01-25 17:01:35 +0000 | |
|---|---|---|
| committer | 2021-01-25 17:01:35 +0000 | |
| commit | 0ba71bf30e08f29d6ed4f929638de8fa05dd99ad (patch) | |
| tree | 51579e884edeef2e4033684ce01612ac4becde70 | |
| parent | d9c361bebd30bacec6d6c7ff19e9f5222e19612e (diff) | |
| parent | db8d2bf0a202cd57a14b6bdec46dfcc514da5c04 (diff) | |
Merge "Let modules obtain target component of PendingIntent"
| -rw-r--r-- | core/api/current.txt | 4 | ||||
| -rw-r--r-- | core/api/module-lib-current.txt | 12 | ||||
| -rw-r--r-- | core/java/android/app/IActivityManager.aidl | 6 | ||||
| -rw-r--r-- | core/java/android/app/PendingIntent.java | 52 | ||||
| -rw-r--r-- | core/res/AndroidManifest.xml | 5 | ||||
| -rw-r--r-- | services/core/java/com/android/server/am/ActivityManagerService.java | 42 |
6 files changed, 112 insertions, 9 deletions
diff --git a/core/api/current.txt b/core/api/current.txt index e0e2762cdd56..d5a3e974e0db 100644 --- a/core/api/current.txt +++ b/core/api/current.txt @@ -6189,7 +6189,11 @@ package android.app { method public android.content.IntentSender getIntentSender(); method public static android.app.PendingIntent getService(android.content.Context, int, @NonNull android.content.Intent, int); method @Deprecated public String getTargetPackage(); + method public boolean isActivity(); + method public boolean isBroadcast(); + method public boolean isForegroundService(); method public boolean isImmutable(); + method public boolean isService(); method @Nullable public static android.app.PendingIntent readPendingIntentOrNullFromParcel(@NonNull android.os.Parcel); method public void send() throws android.app.PendingIntent.CanceledException; method public void send(int) throws android.app.PendingIntent.CanceledException; diff --git a/core/api/module-lib-current.txt b/core/api/module-lib-current.txt index 4acbf74aafe4..cb2810c08d91 100644 --- a/core/api/module-lib-current.txt +++ b/core/api/module-lib-current.txt @@ -1,4 +1,12 @@ // Signature format: 2.0 +package android { + + public static final class Manifest.permission { + field public static final String GET_INTENT_SENDER_INTENT = "android.permission.GET_INTENT_SENDER_INTENT"; + } + +} + package android.app { public class ActivityManager { @@ -26,6 +34,10 @@ package android.app { field public static final String ACTION_NOTIFICATION_LISTENER_ENABLED_CHANGED = "android.app.action.NOTIFICATION_LISTENER_ENABLED_CHANGED"; } + public final class PendingIntent implements android.os.Parcelable { + method @Nullable @RequiresPermission(android.Manifest.permission.GET_INTENT_SENDER_INTENT) public java.util.List<android.content.pm.ResolveInfo> queryIntentComponents(int); + } + public class StatusBarManager { method @RequiresPermission(android.Manifest.permission.STATUS_BAR) public void setExpansionDisabledForSimNetworkLock(boolean); } diff --git a/core/java/android/app/IActivityManager.aidl b/core/java/android/app/IActivityManager.aidl index 0019fd1908b3..e73636fe7fd0 100644 --- a/core/java/android/app/IActivityManager.aidl +++ b/core/java/android/app/IActivityManager.aidl @@ -51,6 +51,7 @@ import android.content.pm.ConfigurationInfo; import android.content.pm.IPackageDataObserver; import android.content.pm.ParceledListSlice; import android.content.pm.ProviderInfo; +import android.content.pm.ResolveInfo; import android.content.pm.UserInfo; import android.content.res.Configuration; import android.content.LocusId; @@ -704,4 +705,9 @@ interface IActivityManager { * @throws IllegalArgumentException if the user is not a profile. */ boolean stopProfile(int userId); + + /** Called by PendingIntent.queryIntentComponents() */ + List<ResolveInfo> queryIntentComponentsForIntentSender(in IIntentSender sender, int matchFlags); + + boolean isIntentSenderAService(in IIntentSender sender); } diff --git a/core/java/android/app/PendingIntent.java b/core/java/android/app/PendingIntent.java index 6d75d0fe020a..86352225292e 100644 --- a/core/java/android/app/PendingIntent.java +++ b/core/java/android/app/PendingIntent.java @@ -16,9 +16,13 @@ package android.app; +import android.Manifest.permission; import android.annotation.IntDef; import android.annotation.NonNull; import android.annotation.Nullable; +import android.annotation.RequiresPermission; +import android.annotation.SystemApi; +import android.annotation.SystemApi.Client; import android.annotation.TestApi; import android.compat.Compatibility; import android.compat.annotation.ChangeId; @@ -29,6 +33,8 @@ import android.content.IIntentReceiver; import android.content.IIntentSender; import android.content.Intent; import android.content.IntentSender; +import android.content.pm.PackageManager.ResolveInfoFlags; +import android.content.pm.ResolveInfo; import android.os.Build; import android.os.Bundle; import android.os.Handler; @@ -47,6 +53,7 @@ import com.android.internal.os.IResultReceiver; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; +import java.util.List; /** * A description of an Intent and target action to perform with it. Instances @@ -1181,10 +1188,9 @@ public final class PendingIntent implements Parcelable { } /** - * @hide - * Check whether this PendingIntent will launch an Activity. + * @return TRUE if this {@link PendingIntent} was created with + * {@link #getActivity} or {@link #getActivities}. */ - @UnsupportedAppUsage public boolean isActivity() { try { return ActivityManager.getService() @@ -1195,8 +1201,7 @@ public final class PendingIntent implements Parcelable { } /** - * @hide - * Check whether this PendingIntent will launch a foreground service + * @return TRUE if this {@link PendingIntent} was created with {@link #getForegroundService}. */ public boolean isForegroundService() { try { @@ -1208,8 +1213,19 @@ public final class PendingIntent implements Parcelable { } /** - * @hide - * Check whether this PendingIntent will launch an Activity. + * @return TRUE if this {@link PendingIntent} was created with {@link #getService}. + */ + public boolean isService() { + try { + return ActivityManager.getService() + .isIntentSenderAService(mTarget); + } catch (RemoteException e) { + throw e.rethrowFromSystemServer(); + } + } + + /** + * @return TRUE if this {@link PendingIntent} was created with {@link #getBroadcast}. */ public boolean isBroadcast() { try { @@ -1249,6 +1265,28 @@ public final class PendingIntent implements Parcelable { } /** + * Resolve the intent set in this {@link PendingIntent}. Note if the pending intent is + * generated for another user, the resulting component may not exist on the calling user. + * Use {@link android.content.pm.ApplicationInfo#uid} of the resulting + * {@link android.content.pm.ComponentInfo} with + * {@link android.os.UserHandle#getUserHandleForUid(int)} to see which user will receive + * the intent. + * + * @param flags MATCH_* flags from {@link android.content.pm.PackageManager}. + * @hide + */ + @RequiresPermission(permission.GET_INTENT_SENDER_INTENT) + @SystemApi(client = Client.MODULE_LIBRARIES) + public @Nullable List<ResolveInfo> queryIntentComponents(@ResolveInfoFlags int flags) { + try { + return ActivityManager.getService() + .queryIntentComponentsForIntentSender(mTarget, flags); + } catch (RemoteException e) { + throw e.rethrowFromSystemServer(); + } + } + + /** * Comparison operator on two PendingIntent objects, such that true * is returned then they both represent the same operation from the * same package. This allows you to use {@link #getActivity}, diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml index 79c724d95bf9..910f1607b2d2 100644 --- a/core/res/AndroidManifest.xml +++ b/core/res/AndroidManifest.xml @@ -2666,8 +2666,9 @@ <permission android:name="android.permission.GET_PROCESS_STATE_AND_OOM_SCORE" android:protectionLevel="signature|privileged|development" /> - <!-- Allows use of PendingIntent.getIntent(). - @hide --> + <!-- Allows use of PendingIntent.getIntent(), . + @hide @SystemApi(client=android.annotation.SystemApi.Client.MODULE_LIBRARIES) + --> <permission android:name="android.permission.GET_INTENT_SENDER_INTENT" android:protectionLevel="signature" /> diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java index 6ab82efd4403..780c0267ae52 100644 --- a/services/core/java/com/android/server/am/ActivityManagerService.java +++ b/services/core/java/com/android/server/am/ActivityManagerService.java @@ -4946,6 +4946,15 @@ public class ActivityManagerService extends IActivityManager.Stub } @Override + public boolean isIntentSenderAService(IIntentSender pendingResult) { + if (pendingResult instanceof PendingIntentRecord) { + final PendingIntentRecord res = (PendingIntentRecord) pendingResult; + return res.key.type == ActivityManager.INTENT_SENDER_SERVICE; + } + return false; + } + + @Override public boolean isIntentSenderABroadcast(IIntentSender pendingResult) { if (pendingResult instanceof PendingIntentRecord) { final PendingIntentRecord res = (PendingIntentRecord) pendingResult; @@ -4970,6 +4979,39 @@ public class ActivityManagerService extends IActivityManager.Stub } @Override + public List<ResolveInfo> queryIntentComponentsForIntentSender( + IIntentSender pendingResult, int matchFlags) { + enforceCallingPermission(Manifest.permission.GET_INTENT_SENDER_INTENT, + "queryIntentComponentsForIntentSender()"); + Preconditions.checkNotNull(pendingResult); + final PendingIntentRecord res; + try { + res = (PendingIntentRecord) pendingResult; + } catch (ClassCastException e) { + return null; + } + final Intent intent = res.key.requestIntent; + if (intent == null) { + return null; + } + final int userId = res.key.userId; + switch (res.key.type) { + case ActivityManager.INTENT_SENDER_ACTIVITY: + return mContext.getPackageManager().queryIntentActivitiesAsUser( + intent, matchFlags, userId); + case ActivityManager.INTENT_SENDER_SERVICE: + case ActivityManager.INTENT_SENDER_FOREGROUND_SERVICE: + return mContext.getPackageManager().queryIntentServicesAsUser( + intent, matchFlags, userId); + case ActivityManager.INTENT_SENDER_BROADCAST: + return mContext.getPackageManager().queryBroadcastReceiversAsUser( + intent, matchFlags, userId); + default: // ActivityManager.INTENT_SENDER_ACTIVITY_RESULT + throw new IllegalStateException("Unsupported intent sender type: " + res.key.type); + } + } + + @Override public String getTagForIntentSender(IIntentSender pendingResult, String prefix) { if (!(pendingResult instanceof PendingIntentRecord)) { return null; |