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

Commit ec3ceb55 authored by Achim Thesmann's avatar Achim Thesmann
Browse files

Allow granting BAL privileged by opt-in on Broadcast PendingIntent

The current logic assumes that the creator of the PendingIntent is also the target of the PendingIntent, and only creates a BAL token if the creator is different from the sender, while the receiver of the broadcast needs the BAL permission.
The logic to prevent apps from creating their own tokens is moved to `BroadcastQueueImpl'.

Test: atest BackgroundActivityLaunchTest
Flag: com.android.window.flags.bal_check_broadcast_when_dispatched
Bug: 421197489, 422788436
Change-Id: Iec7ca549e2ef7ae889d94625fac83f19c8e7f657
parent a6188aac
Loading
Loading
Loading
Loading
+10 −0
Original line number Diff line number Diff line
@@ -81,3 +81,13 @@ flag {
    description: "Report aborted activity starts in the calling process."
    bug: "427863001"
}

flag {
    name: "bal_check_broadcast_when_dispatched"
    namespace: "responsible_apis"
    description: "Check granting BAL permissions on dispatch instead on send."
    bug: "421197489"
    metadata {
        purpose: PURPOSE_BUGFIX
    }
}
 No newline at end of file
+4 −1
Original line number Diff line number Diff line
@@ -44,6 +44,7 @@ import static com.android.server.am.BroadcastRecord.getReceiverPackageName;
import static com.android.server.am.BroadcastRecord.getReceiverProcessName;
import static com.android.server.am.BroadcastRecord.getReceiverUid;
import static com.android.server.am.BroadcastRecord.isDeliveryStateTerminal;
import static com.android.window.flags.Flags.balCheckBroadcastWhenDispatched;

import android.annotation.CheckResult;
import android.annotation.NonNull;
@@ -1149,7 +1150,9 @@ class BroadcastQueueImpl extends BroadcastQueue {
            queue.setTimeoutScheduled(false);
        }

        if (r.mBackgroundStartPrivileges.allowsAny()) {
        if (r.mBackgroundStartPrivileges.allowsAny()
                && (r.callingUid != app.uid || !balCheckBroadcastWhenDispatched())) {
            // allow the broadcast receiver potential privileges if it is not sent to itself
            app.addOrUpdateBackgroundStartPrivileges(r, r.mBackgroundStartPrivileges);

            final long timeout = r.isForeground() ? mFgConstants.ALLOW_BG_ACTIVITY_START_TIMEOUT
+4 −2
Original line number Diff line number Diff line
@@ -20,10 +20,10 @@ import static android.app.ActivityManager.PROCESS_STATE_TOP;
import static android.app.ActivityManager.START_SUCCESS;
import static android.app.ActivityOptions.MODE_BACKGROUND_ACTIVITY_START_ALLOWED;
import static android.app.ActivityOptions.MODE_BACKGROUND_ACTIVITY_START_ALLOW_ALWAYS;
import static android.app.ActivityOptions.MODE_BACKGROUND_ACTIVITY_START_ALLOW_IF_VISIBLE;
import static android.app.ActivityOptions.MODE_BACKGROUND_ACTIVITY_START_COMPAT;
import static android.app.ActivityOptions.MODE_BACKGROUND_ACTIVITY_START_DENIED;
import static android.app.ActivityOptions.MODE_BACKGROUND_ACTIVITY_START_SYSTEM_DEFINED;
import static android.app.ActivityOptions.MODE_BACKGROUND_ACTIVITY_START_ALLOW_IF_VISIBLE;
import static android.os.PowerWhitelistManager.TEMPORARY_ALLOWLIST_TYPE_FOREGROUND_SERVICE_ALLOWED;
import static android.os.PowerWhitelistManager.TEMPORARY_ALLOWLIST_TYPE_FOREGROUND_SERVICE_NOT_ALLOWED;
import static android.os.Process.ROOT_UID;
@@ -31,6 +31,7 @@ import static android.os.Process.SYSTEM_UID;

import static com.android.server.am.ActivityManagerDebugConfig.TAG_AM;
import static com.android.server.am.ActivityManagerDebugConfig.TAG_WITH_CLASS_NAME;
import static com.android.window.flags.Flags.balCheckBroadcastWhenDispatched;

import android.annotation.IntDef;
import android.annotation.Nullable;
@@ -755,7 +756,8 @@ public final class PendingIntentRecord extends IIntentSender.Stub {
        }
        // temporarily allow receivers and services to open activities from background if the
        // PendingIntent.send() caller was foreground at the time of sendInner() call
        if (uid != callingUid && controller.mAtmInternal.isUidForeground(callingUid)) {
        if ((uid != callingUid || balCheckBroadcastWhenDispatched())
                && controller.mAtmInternal.isUidForeground(callingUid)) {
            return getBackgroundStartPrivilegesAllowedByCaller(options, callingUid, null);
        }
        return BackgroundStartPrivileges.NONE;