Merge "Let modules obtain target component of PendingIntent"

This commit is contained in:
Makoto Onuki
2021-01-25 17:01:35 +00:00
committed by Android (Google) Code Review
6 changed files with 112 additions and 9 deletions

View File

@@ -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;

View File

@@ -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);
}

View File

@@ -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);
}

View File

@@ -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 {
@@ -1248,6 +1264,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

View File

@@ -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" />

View File

@@ -4945,6 +4945,15 @@ public class ActivityManagerService extends IActivityManager.Stub
return false;
}
@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) {
@@ -4969,6 +4978,39 @@ public class ActivityManagerService extends IActivityManager.Stub
return null;
}
@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)) {