Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit b3853a23 authored by Hui Yu's avatar Hui Yu
Browse files

tempWhitelistForPendingIntent() can specify temp allowlist type.

The supported temp allowlist types are
TEMPORARY_WHITELIST_TYPE_FOREGROUND_SERVICE_ALLOWED and
TEMPORARY_WHITELIST_TYPE_FOREGROUND_SERVICE_NOT_ALLOWED.

Bug: 175244558, 171305836
Test: atest cts/tests/app/src/android/app/cts/ActivityManagerFgsBgStartTest.java

Change-Id: I6b1e7782d54c6934453a0e2b529af96a19a45c4f
parent 5664e559
Loading
Loading
Loading
Loading
+17 −4
Original line number Diff line number Diff line
@@ -99,9 +99,13 @@ public abstract class ActivityManagerInternal {
    /**
     * Sets how long a {@link PendingIntent} can be temporarily whitelist to by bypass restrictions
     * such as Power Save mode.
     * @param target
     * @param whitelistToken
     * @param duration temp allowlist duration in milliseconds.
     * @param type temp allowlist type defined at {@link BroadcastOptions.TempAllowListType}
     */
    public abstract void setPendingIntentWhitelistDuration(IIntentSender target,
            IBinder whitelistToken, long duration);
            IBinder whitelistToken, long duration, int type);

    /**
     * Returns the flags set for a {@link PendingIntent}.
@@ -317,8 +321,17 @@ public abstract class ActivityManagerInternal {
    public abstract boolean isBooted();
    public abstract void finishBooting();

    /**
     * Temp allowlist a UID for PendingIntent.
     * @param callerPid the PID that sent the PendingIntent.
     * @param callerUid the UID that sent the PendingIntent.
     * @param targetUid the UID that is been temp allowlisted.
     * @param duration temp allowlist duration in milliseconds.
     * @param type temp allowlist type defined at {@link BroadcastOptions.TempAllowListType}
     * @param tag
     */
    public abstract void tempWhitelistForPendingIntent(int callerPid, int callerUid, int targetUid,
            long duration, String tag);
            long duration, int type, String tag);

    public abstract int broadcastIntentInPackage(String packageName, @Nullable String featureId,
            int uid, int realCallingUid, int realCallingPid, Intent intent, String resolvedType,
+12 −9
Original line number Diff line number Diff line
@@ -15312,10 +15312,10 @@ public class ActivityManagerService extends IActivityManager.Stub
     */
    @GuardedBy("this")
    void tempWhitelistForPendingIntentLocked(int callerPid, int callerUid, int targetUid,
            long duration, String tag) {
            long duration, int type, String tag) {
        if (DEBUG_WHITELISTS) {
            Slog.d(TAG, "tempWhitelistForPendingIntentLocked(" + callerPid + ", " + callerUid + ", "
                    + targetUid + ", " + duration + ")");
                    + targetUid + ", " + duration + ", " + type + ")");
        }
        synchronized (mPidsSelfLocked) {
@@ -15327,7 +15327,11 @@ public class ActivityManagerService extends IActivityManager.Stub
            }
            if (!pr.whitelistManager) {
                if (checkPermission(CHANGE_DEVICE_IDLE_TEMP_WHITELIST, callerPid, callerUid)
                        != PackageManager.PERMISSION_GRANTED) {
                        != PackageManager.PERMISSION_GRANTED
                        && checkPermission(START_ACTIVITIES_FROM_BACKGROUND, callerPid, callerUid)
                        != PackageManager.PERMISSION_GRANTED
                        && checkPermission(START_FOREGROUND_SERVICES_FROM_BACKGROUND, callerPid,
                        callerUid) != PackageManager.PERMISSION_GRANTED) {
                    if (DEBUG_WHITELISTS) {
                        Slog.d(TAG, "tempWhitelistForPendingIntentLocked() for target " + targetUid
                                + ": pid " + callerPid + " is not allowed");
@@ -15337,8 +15341,7 @@ public class ActivityManagerService extends IActivityManager.Stub
            }
        }
        tempWhitelistUidLocked(targetUid, duration, tag,
                BroadcastOptions.TEMPORARY_WHITELIST_TYPE_FOREGROUND_SERVICE_ALLOWED);
        tempWhitelistUidLocked(targetUid, duration, tag, type);
    }
    /**
@@ -15941,9 +15944,9 @@ public class ActivityManagerService extends IActivityManager.Stub
        @Override
        public void setPendingIntentWhitelistDuration(IIntentSender target, IBinder whitelistToken,
                long duration) {
                long duration, int type) {
            mPendingIntentController.setPendingIntentWhitelistDuration(target, whitelistToken,
                    duration);
                    duration, type);
        }
        @Override
@@ -16359,10 +16362,10 @@ public class ActivityManagerService extends IActivityManager.Stub
        @Override
        public void tempWhitelistForPendingIntent(int callerPid, int callerUid, int targetUid,
                long duration, String tag) {
                long duration, int type, String tag) {
            synchronized (ActivityManagerService.this) {
                ActivityManagerService.this.tempWhitelistForPendingIntentLocked(
                        callerPid, callerUid, targetUid, duration, tag);
                        callerPid, callerUid, targetUid, duration, type, tag);
            }
        }
+3 −2
Original line number Diff line number Diff line
@@ -301,13 +301,14 @@ public class PendingIntentController {
    }

    void setPendingIntentWhitelistDuration(IIntentSender target, IBinder whitelistToken,
            long duration) {
            long duration, int type) {
        if (!(target instanceof PendingIntentRecord)) {
            Slog.w(TAG, "markAsSentFromNotification(): not a PendingIntentRecord: " + target);
            return;
        }
        synchronized (mLock) {
            ((PendingIntentRecord) target).setWhitelistDurationLocked(whitelistToken, duration);
            ((PendingIntentRecord) target).setWhitelistDurationLocked(whitelistToken, duration,
                    type);
        }
    }

+43 −37
Original line number Diff line number Diff line
@@ -24,6 +24,7 @@ import static com.android.server.am.ActivityManagerDebugConfig.TAG_WITH_CLASS_NA
import android.annotation.Nullable;
import android.app.ActivityManager;
import android.app.ActivityOptions;
import android.app.BroadcastOptions;
import android.app.PendingIntent;
import android.content.IIntentReceiver;
import android.content.IIntentSender;
@@ -37,6 +38,7 @@ import android.os.TransactionTooLargeException;
import android.os.UserHandle;
import android.util.ArrayMap;
import android.util.ArraySet;
import android.util.Pair;
import android.util.Slog;
import android.util.TimeUtils;

@@ -61,7 +63,11 @@ public final class PendingIntentRecord extends IIntentSender.Stub {
    public final WeakReference<PendingIntentRecord> ref;
    boolean sent = false;
    boolean canceled = false;
    private ArrayMap<IBinder, Long> whitelistDuration;
    /**
     * Map IBinder to duration specified as Pair<Long, Integer>, Long is allowlist duration in
     * milliseconds, Integer is allowlist type defined at {@link BroadcastOptions.TempAllowListType}
     */
    private ArrayMap<IBinder, Pair<Long, Integer>> mWhitelistDuration;
    private RemoteCallbackList<IResultReceiver> mCancelCallbacks;
    private ArraySet<IBinder> mAllowBgActivityStartsForActivitySender = new ArraySet<>();
    private ArraySet<IBinder> mAllowBgActivityStartsForBroadcastSender = new ArraySet<>();
@@ -215,16 +221,16 @@ public final class PendingIntentRecord extends IIntentSender.Stub {
        ref = new WeakReference<>(this);
    }

    void setWhitelistDurationLocked(IBinder whitelistToken, long duration) {
    void setWhitelistDurationLocked(IBinder whitelistToken, long duration, int type) {
        if (duration > 0) {
            if (whitelistDuration == null) {
                whitelistDuration = new ArrayMap<>();
            if (mWhitelistDuration == null) {
                mWhitelistDuration = new ArrayMap<>();
            }
            whitelistDuration.put(whitelistToken, duration);
        } else if (whitelistDuration != null) {
            whitelistDuration.remove(whitelistToken);
            if (whitelistDuration.size() <= 0) {
                whitelistDuration = null;
            mWhitelistDuration.put(whitelistToken, new Pair(duration, type));
        } else if (mWhitelistDuration != null) {
            mWhitelistDuration.remove(whitelistToken);
            if (mWhitelistDuration.size() <= 0) {
                mWhitelistDuration = null;
            }

        }
@@ -292,7 +298,7 @@ public final class PendingIntentRecord extends IIntentSender.Stub {
        if (intent != null) intent.setDefusable(true);
        if (options != null) options.setDefusable(true);

        Long duration = null;
        Pair<Long, Integer> duration = null;
        Intent finalIntent = null;
        Intent[] allIntents = null;
        String[] allResolvedTypes = null;
@@ -341,8 +347,8 @@ public final class PendingIntentRecord extends IIntentSender.Stub {
                mergedOptions.setCallerOptions(opts);
            }

            if (whitelistDuration != null) {
                duration = whitelistDuration.get(whitelistToken);
            if (mWhitelistDuration != null) {
                duration = mWhitelistDuration.get(whitelistToken);
            }

            if (key.type == ActivityManager.INTENT_SENDER_ACTIVITY
@@ -370,8 +376,6 @@ public final class PendingIntentRecord extends IIntentSender.Stub {
        int res = START_SUCCESS;
        try {
            if (duration != null) {
                int procState = controller.mAmInternal.getUidProcessState(callingUid);
                if (!ActivityManager.isProcStateBackground(procState)) {
                StringBuilder tag = new StringBuilder(64);
                tag.append("pendingintent:");
                UserHandle.formatUid(tag, callingUid);
@@ -384,10 +388,7 @@ public final class PendingIntentRecord extends IIntentSender.Stub {
                    tag.append(finalIntent.getData().toSafeString());
                }
                controller.mAmInternal.tempWhitelistForPendingIntent(callingPid, callingUid,
                            uid, duration, tag.toString());
                } else {
                    Slog.w(TAG, "Not doing whitelist " + this + ": caller state=" + procState);
                }
                        uid, duration.first, duration.second, tag.toString());
            }

            boolean sendFinish = finishedReceiver != null;
@@ -532,16 +533,18 @@ public final class PendingIntentRecord extends IIntentSender.Stub {
            pw.print(prefix); pw.print("sent="); pw.print(sent);
                    pw.print(" canceled="); pw.println(canceled);
        }
        if (whitelistDuration != null) {
        if (mWhitelistDuration != null) {
            pw.print(prefix);
            pw.print("whitelistDuration=");
            for (int i = 0; i < whitelistDuration.size(); i++) {
            for (int i = 0; i < mWhitelistDuration.size(); i++) {
                if (i != 0) {
                    pw.print(", ");
                }
                pw.print(Integer.toHexString(System.identityHashCode(whitelistDuration.keyAt(i))));
                pw.print(Integer.toHexString(System.identityHashCode(mWhitelistDuration.keyAt(i))));
                pw.print(":");
                TimeUtils.formatDuration(whitelistDuration.valueAt(i), pw);
                TimeUtils.formatDuration(mWhitelistDuration.valueAt(i).first, pw);
                pw.print("/");
                pw.print(mWhitelistDuration.valueAt(i).second);
            }
            pw.println();
        }
@@ -569,15 +572,18 @@ public final class PendingIntentRecord extends IIntentSender.Stub {
        }
        sb.append(' ');
        sb.append(key.typeName());
        if (whitelistDuration != null) {
        if (mWhitelistDuration != null) {
            sb.append( " (whitelist: ");
            for (int i = 0; i < whitelistDuration.size(); i++) {
            for (int i = 0; i < mWhitelistDuration.size(); i++) {
                if (i != 0) {
                    sb.append(",");
                }
                sb.append(Integer.toHexString(System.identityHashCode(whitelistDuration.keyAt(i))));
                sb.append(Integer.toHexString(System.identityHashCode(
                        mWhitelistDuration.keyAt(i))));
                sb.append(":");
                TimeUtils.formatDuration(whitelistDuration.valueAt(i), sb);
                TimeUtils.formatDuration(mWhitelistDuration.valueAt(i).first, sb);
                sb.append("/");
                sb.append(mWhitelistDuration.valueAt(i).second);
            }
            sb.append(")");
        }
+4 −1
Original line number Diff line number Diff line
@@ -128,6 +128,7 @@ import android.app.AlarmManager;
import android.app.AppGlobals;
import android.app.AppOpsManager;
import android.app.AutomaticZenRule;
import android.app.BroadcastOptions;
import android.app.IActivityManager;
import android.app.INotificationManager;
import android.app.ITransientNotification;
@@ -5944,7 +5945,9 @@ public class NotificationManagerService extends SystemService {
                    PendingIntent pendingIntent = notification.allPendingIntents.valueAt(i);
                    if (pendingIntent != null) {
                        am.setPendingIntentWhitelistDuration(pendingIntent.getTarget(),
                                ALLOWLIST_TOKEN, duration);
                                ALLOWLIST_TOKEN, duration,
                                BroadcastOptions.TEMPORARY_WHITELIST_TYPE_FOREGROUND_SERVICE_ALLOWED
                        );
                        am.setPendingIntentAllowBgActivityStarts(pendingIntent.getTarget(),
                                ALLOWLIST_TOKEN, (FLAG_ACTIVITY_SENDER | FLAG_BROADCAST_SENDER
                                        | FLAG_SERVICE_SENDER));