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

Commit ceeadaed authored by Michal Karpinski's avatar Michal Karpinski Committed by Android (Google) Code Review
Browse files

Merge "Temporarily whitelist processes to open activities from background when...

Merge "Temporarily whitelist processes to open activities from background when service-based PendingIntent was whitelisted"
parents 6c6528f6 c8aa91bd
Loading
Loading
Loading
Loading
+2 −2
Original line number Diff line number Diff line
@@ -258,8 +258,8 @@ public abstract class ActivityManagerInternal {
            Bundle resultExtras, String requiredPermission, Bundle bOptions, boolean serialized,
            boolean sticky, int userId, boolean allowBackgroundActivityStarts);
    public abstract ComponentName startServiceInPackage(int uid, Intent service,
            String resolvedType, boolean fgRequired, String callingPackage, int userId)
            throws TransactionTooLargeException;
            String resolvedType, boolean fgRequired, String callingPackage, int userId,
            boolean allowBackgroundActivityStarts) throws TransactionTooLargeException;

    public abstract void disconnectActivityFromServices(Object connectionHolder);
    public abstract void cleanUpServices(int userId, ComponentName component, Intent baseIntent);
+32 −0
Original line number Diff line number Diff line
@@ -130,6 +130,9 @@ public final class ActiveServices {
    // calling startForeground() before we ANR + stop it.
    static final int SERVICE_START_FOREGROUND_TIMEOUT = 10*1000;

    // For how long after a whitelisted service's start its process can start a background activity
    private static final int SERVICE_BG_ACTIVITY_START_TIMEOUT_MS = 10*1000;

    final ActivityManagerService mAm;

    // Maximum number of services that we allow to start in the background
@@ -398,6 +401,14 @@ public final class ActiveServices {
    ComponentName startServiceLocked(IApplicationThread caller, Intent service, String resolvedType,
            int callingPid, int callingUid, boolean fgRequired, String callingPackage, final int userId)
            throws TransactionTooLargeException {
        return startServiceLocked(caller, service, resolvedType, callingPid, callingUid, fgRequired,
                callingPackage, userId, false);
    }

    ComponentName startServiceLocked(IApplicationThread caller, Intent service, String resolvedType,
            int callingPid, int callingUid, boolean fgRequired, String callingPackage,
            final int userId, boolean allowBackgroundActivityStarts)
            throws TransactionTooLargeException {
        if (DEBUG_DELAYED_STARTS) Slog.v(TAG_SERVICE, "startService: " + service
                + " type=" + resolvedType + " args=" + service.getExtras());

@@ -622,10 +633,28 @@ public final class ActiveServices {
            }
        }

        if (allowBackgroundActivityStarts) {
            ProcessRecord proc = mAm.getProcessRecordLocked(r.processName, r.appInfo.uid, false);
            if (proc != null) {
                proc.addAllowBackgroundActivityStartsToken(r);
                // schedule removal of the whitelisting token after the timeout
                removeAllowBackgroundActivityStartsServiceToken(proc, r,
                        SERVICE_BG_ACTIVITY_START_TIMEOUT_MS);
            }
        }
        ComponentName cmp = startServiceInnerLocked(smap, service, r, callerFg, addToStarting);
        return cmp;
    }

    private void removeAllowBackgroundActivityStartsServiceToken(ProcessRecord proc,
            ServiceRecord r, int delayMillis) {
        mAm.mHandler.postDelayed(() -> {
            if (proc != null) {
                proc.removeAllowBackgroundActivityStartsToken(r);
            }
        }, delayMillis);
    }

    private boolean requestStartTargetPermissionsReviewIfNeededLocked(ServiceRecord r,
            String callingPackage, int callingUid, Intent service, boolean callerFg,
            final int userId) {
@@ -752,6 +781,9 @@ public final class ActiveServices {
            if (r.record != null) {
                final long origId = Binder.clearCallingIdentity();
                try {
                    // immediately remove bg activity whitelisting token if there was one
                    removeAllowBackgroundActivityStartsServiceToken(callerApp, r.record,
                            0 /* delayMillis */);
                    stopServiceLocked(r.record);
                } finally {
                    Binder.restoreCallingIdentity(origId);
+4 −3
Original line number Diff line number Diff line
@@ -19495,8 +19495,8 @@ public class ActivityManagerService extends IActivityManager.Stub
        @Override
        public ComponentName startServiceInPackage(int uid, Intent service, String resolvedType,
                boolean fgRequired, String callingPackage, int userId)
                throws TransactionTooLargeException {
                boolean fgRequired, String callingPackage, int userId,
                boolean allowBackgroundActivityStarts) throws TransactionTooLargeException {
            synchronized(ActivityManagerService.this) {
                if (DEBUG_SERVICE) Slog.v(TAG_SERVICE,
                        "startServiceInPackage: " + service + " type=" + resolvedType);
@@ -19504,7 +19504,8 @@ public class ActivityManagerService extends IActivityManager.Stub
                ComponentName res;
                try {
                    res = mServices.startServiceLocked(null, service,
                            resolvedType, -1, uid, fgRequired, callingPackage, userId);
                            resolvedType, -1, uid, fgRequired, callingPackage, userId,
                            allowBackgroundActivityStarts);
                } finally {
                    Binder.restoreCallingIdentity(origId);
                }
+7 −1
Original line number Diff line number Diff line
@@ -51,6 +51,7 @@ public final class PendingIntentRecord extends IIntentSender.Stub {

    public static final int FLAG_ACTIVITY_SENDER = 1 << 0;
    public static final int FLAG_BROADCAST_SENDER = 1 << 1;
    public static final int FLAG_SERVICE_SENDER = 1 << 2;

    final PendingIntentController controller;
    final Key key;
@@ -62,6 +63,7 @@ public final class PendingIntentRecord extends IIntentSender.Stub {
    private RemoteCallbackList<IResultReceiver> mCancelCallbacks;
    private ArraySet<IBinder> mAllowBgActivityStartsForActivitySender = new ArraySet<>();
    private ArraySet<IBinder> mAllowBgActivityStartsForBroadcastSender = new ArraySet<>();
    private ArraySet<IBinder> mAllowBgActivityStartsForServiceSender = new ArraySet<>();

    String stringName;
    String lastTagPrefix;
@@ -228,6 +230,9 @@ public final class PendingIntentRecord extends IIntentSender.Stub {
        if ((flags & FLAG_BROADCAST_SENDER) != 0) {
            mAllowBgActivityStartsForBroadcastSender.add(token);
        }
        if ((flags & FLAG_SERVICE_SENDER) != 0) {
            mAllowBgActivityStartsForServiceSender.add(token);
        }
    }

    public void registerCancelListenerLocked(IResultReceiver receiver) {
@@ -426,7 +431,8 @@ public final class PendingIntentRecord extends IIntentSender.Stub {
                    try {
                        controller.mAmInternal.startServiceInPackage(uid, finalIntent, resolvedType,
                                key.type == ActivityManager.INTENT_SENDER_FOREGROUND_SERVICE,
                                key.packageName, userId);
                                key.packageName, userId,
                                mAllowBgActivityStartsForServiceSender.contains(whitelistToken));
                    } catch (RuntimeException e) {
                        Slog.w(TAG, "Unable to send startService intent", e);
                    } catch (TransactionTooLargeException e) {
+2 −0
Original line number Diff line number Diff line
@@ -1142,11 +1142,13 @@ final class ProcessRecord implements WindowProcessListener {
    }

    void addAllowBackgroundActivityStartsToken(Binder entity) {
        if (entity == null) return;
        mAllowBackgroundActivityStartsTokens.add(entity);
        mWindowProcessController.setAllowBackgroundActivityStarts(true);
    }

    void removeAllowBackgroundActivityStartsToken(Binder entity) {
        if (entity == null) return;
        mAllowBackgroundActivityStartsTokens.remove(entity);
        mWindowProcessController.setAllowBackgroundActivityStarts(
                !mAllowBackgroundActivityStartsTokens.isEmpty());
Loading