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

Commit 47de436e authored by Achim Thesmann's avatar Achim Thesmann
Browse files

Separate states for token and foreground bound

Introduces 2 new states for token based exemption and services bound by
foreground activities.

Test: atest BackgroundLaunchProcessControllerTests
Flag: com.android.window.flags.bal_improved_metrics
Bug: 339245692
Change-Id: I256c2bb065f8a88e600d261caae00c2d72e9c8fd
parent 3a1b19d8
Loading
Loading
Loading
Loading
+26 −10
Original line number Diff line number Diff line
@@ -128,17 +128,20 @@ public class BackgroundActivityStartController {

    // TODO(b/263368846) Rename when ASM logic is moved in
    @Retention(SOURCE)
    @IntDef({BAL_BLOCK,
            BAL_ALLOW_DEFAULT,
            BAL_ALLOW_ALLOWLISTED_UID,
    @IntDef({
            BAL_ALLOW_ALLOWLISTED_COMPONENT,
            BAL_ALLOW_VISIBLE_WINDOW,
            BAL_ALLOW_ALLOWLISTED_UID,
            BAL_ALLOW_BOUND_BY_FOREGROUND,
            BAL_ALLOW_DEFAULT,
            BAL_ALLOW_FOREGROUND,
            BAL_ALLOW_GRACE_PERIOD,
            BAL_ALLOW_PENDING_INTENT,
            BAL_ALLOW_PERMISSION,
            BAL_ALLOW_SAW_PERMISSION,
            BAL_ALLOW_GRACE_PERIOD,
            BAL_ALLOW_FOREGROUND,
            BAL_ALLOW_SDK_SANDBOX
            BAL_ALLOW_SDK_SANDBOX,
            BAL_ALLOW_TOKEN,
            BAL_ALLOW_VISIBLE_WINDOW,
            BAL_BLOCK
    })
    public @interface BalCode {}

@@ -195,10 +198,19 @@ public class BackgroundActivityStartController {
    static final int BAL_ALLOW_NON_APP_VISIBLE_WINDOW =
            FrameworkStatsLog.BAL_ALLOWED__ALLOWED_REASON__BAL_ALLOW_NON_APP_VISIBLE_WINDOW;

    /** Process belongs to a SDK sandbox */
    static final int BAL_ALLOW_TOKEN =
            FrameworkStatsLog.BAL_ALLOWED__ALLOWED_REASON__BAL_ALLOW_TOKEN;

    /** Process belongs to a SDK sandbox */
    static final int BAL_ALLOW_BOUND_BY_FOREGROUND =
            FrameworkStatsLog.BAL_ALLOWED__ALLOWED_REASON__BAL_ALLOW_BOUND_BY_FOREGROUND;

    static String balCodeToString(@BalCode int balCode) {
        return switch (balCode) {
            case BAL_ALLOW_ALLOWLISTED_COMPONENT -> "BAL_ALLOW_ALLOWLISTED_COMPONENT";
            case BAL_ALLOW_ALLOWLISTED_UID -> "BAL_ALLOW_ALLOWLISTED_UID";
            case BAL_ALLOW_BOUND_BY_FOREGROUND -> "BAL_ALLOW_BOUND_BY_FOREGROUND";
            case BAL_ALLOW_DEFAULT -> "BAL_ALLOW_DEFAULT";
            case BAL_ALLOW_FOREGROUND -> "BAL_ALLOW_FOREGROUND";
            case BAL_ALLOW_GRACE_PERIOD -> "BAL_ALLOW_GRACE_PERIOD";
@@ -207,6 +219,7 @@ public class BackgroundActivityStartController {
            case BAL_ALLOW_PERMISSION -> "BAL_ALLOW_PERMISSION";
            case BAL_ALLOW_SAW_PERMISSION -> "BAL_ALLOW_SAW_PERMISSION";
            case BAL_ALLOW_SDK_SANDBOX -> "BAL_ALLOW_SDK_SANDBOX";
            case BAL_ALLOW_TOKEN -> "BAL_ALLOW_TOKEN";
            case BAL_ALLOW_VISIBLE_WINDOW -> "BAL_ALLOW_VISIBLE_WINDOW";
            case BAL_BLOCK -> "BAL_BLOCK";
            default -> throw new IllegalArgumentException("Unexpected value: " + balCode);
@@ -1042,7 +1055,9 @@ public class BackgroundActivityStartController {
                    || balCode == BAL_ALLOW_PENDING_INTENT
                    || balCode == BAL_ALLOW_SAW_PERMISSION
                    || balCode == BAL_ALLOW_VISIBLE_WINDOW
                    || balCode == BAL_ALLOW_NON_APP_VISIBLE_WINDOW) {
                    || balCode == BAL_ALLOW_NON_APP_VISIBLE_WINDOW
                    || balCode == BAL_ALLOW_TOKEN
                    || balCode == BAL_ALLOW_BOUND_BY_FOREGROUND) {
                return true;
            }
        }
@@ -1266,7 +1281,8 @@ public class BackgroundActivityStartController {
                || balCode == BAL_ALLOW_PERMISSION
                || balCode == BAL_ALLOW_SAW_PERMISSION
                || balCode == BAL_ALLOW_VISIBLE_WINDOW
                || balCode == BAL_ALLOW_NON_APP_VISIBLE_WINDOW) {
                || balCode == BAL_ALLOW_NON_APP_VISIBLE_WINDOW
                || balCode == BAL_ALLOW_BOUND_BY_FOREGROUND) {
            return;
        }

@@ -1572,7 +1588,7 @@ public class BackgroundActivityStartController {
        }

        if (balCode == BAL_ALLOW_VISIBLE_WINDOW || balCode == BAL_ALLOW_NON_APP_VISIBLE_WINDOW
                || balCode == BAL_ALLOW_FOREGROUND) {
                || balCode == BAL_ALLOW_FOREGROUND || balCode == BAL_ALLOW_BOUND_BY_FOREGROUND) {
            Task task = sourceRecord != null ? sourceRecord.getTask() : targetTask;
            if (task != null && task.getDisplayArea() != null) {
                joiner.add(prefix + "Tasks: ");
+7 −3
Original line number Diff line number Diff line
@@ -23,10 +23,13 @@ import static com.android.server.wm.ActivityTaskManagerDebugConfig.TAG_WITH_CLAS
import static com.android.server.wm.ActivityTaskManagerService.ACTIVITY_BG_START_GRACE_PERIOD_MS;
import static com.android.server.wm.ActivityTaskManagerService.APP_SWITCH_ALLOW;
import static com.android.server.wm.ActivityTaskManagerService.APP_SWITCH_DISALLOW;
import static com.android.server.wm.BackgroundActivityStartController.BAL_ALLOW_BOUND_BY_FOREGROUND;
import static com.android.server.wm.BackgroundActivityStartController.BAL_ALLOW_FOREGROUND;
import static com.android.server.wm.BackgroundActivityStartController.BAL_ALLOW_GRACE_PERIOD;
import static com.android.server.wm.BackgroundActivityStartController.BAL_ALLOW_PERMISSION;
import static com.android.server.wm.BackgroundActivityStartController.BAL_ALLOW_TOKEN;
import static com.android.server.wm.BackgroundActivityStartController.BAL_ALLOW_VISIBLE_WINDOW;
import static com.android.window.flags.Flags.balImprovedMetrics;

import static java.util.Objects.requireNonNull;

@@ -110,8 +113,8 @@ class BackgroundLaunchProcessController {
        }
        // Allow if the flag was explicitly set.
        if (isBackgroundStartAllowedByToken(uid, packageName, isCheckingForFgsStart)) {
            return new BalVerdict(BAL_ALLOW_PERMISSION, /*background*/ true,
                    "process allowed by token");
            return new BalVerdict(balImprovedMetrics() ? BAL_ALLOW_TOKEN : BAL_ALLOW_PERMISSION,
                    /*background*/ true, "process allowed by token");
        }
        // Allow if the caller is bound by a UID that's currently foreground.
        // But still respect the appSwitchState.
@@ -120,7 +123,8 @@ class BackgroundLaunchProcessController {
                ? appSwitchState != APP_SWITCH_DISALLOW && isBoundByForegroundUid()
                : isBoundByForegroundUid();
        if (allowBoundByForegroundUid) {
            return new BalVerdict(BAL_ALLOW_VISIBLE_WINDOW, /*background*/ false,
            return new BalVerdict(balImprovedMetrics() ? BAL_ALLOW_BOUND_BY_FOREGROUND
                    : BAL_ALLOW_VISIBLE_WINDOW, /*background*/ false,
                    "process bound by foreground uid");
        }
        // Allow if the caller has an activity in any foreground task.
+67 −2
Original line number Diff line number Diff line
@@ -18,9 +18,11 @@ package com.android.server.wm;

import static com.android.server.wm.ActivityTaskManagerService.APP_SWITCH_ALLOW;
import static com.android.server.wm.ActivityTaskManagerService.APP_SWITCH_DISALLOW;
import static com.android.server.wm.BackgroundActivityStartController.BAL_ALLOW_BOUND_BY_FOREGROUND;
import static com.android.server.wm.BackgroundActivityStartController.BAL_ALLOW_FOREGROUND;
import static com.android.server.wm.BackgroundActivityStartController.BAL_ALLOW_GRACE_PERIOD;
import static com.android.server.wm.BackgroundActivityStartController.BAL_ALLOW_PERMISSION;
import static com.android.server.wm.BackgroundActivityStartController.BAL_ALLOW_TOKEN;
import static com.android.server.wm.BackgroundActivityStartController.BAL_ALLOW_VISIBLE_WINDOW;
import static com.android.server.wm.BackgroundActivityStartController.BAL_BLOCK;

@@ -30,12 +32,18 @@ import android.app.BackgroundStartPrivileges;
import android.content.Context;
import android.os.Binder;
import android.os.IBinder;
import android.platform.test.annotations.DisableFlags;
import android.platform.test.annotations.EnableFlags;
import android.platform.test.annotations.Presubmit;
import android.platform.test.flag.junit.SetFlagsRule;

import androidx.test.filters.SmallTest;

import com.android.server.wm.BackgroundActivityStartController.BalVerdict;
import com.android.window.flags.Flags;

import org.junit.ClassRule;
import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.JUnit4;
@@ -44,6 +52,7 @@ import java.util.Collection;
import java.util.HashSet;
import java.util.Set;


/**
 * Tests for the {@link BackgroundLaunchProcessController} class.
 *
@@ -55,6 +64,10 @@ import java.util.Set;
@RunWith(JUnit4.class)
public class BackgroundLaunchProcessControllerTests {


    @ClassRule public static final SetFlagsRule.ClassRule mClassRule = new SetFlagsRule.ClassRule();
    @Rule public final SetFlagsRule mSetFlagsRule = mClassRule.createSetFlagsRule();

    Set<IBinder> mActivityStartAllowed = new HashSet<>();
    Set<Integer> mHasActiveVisibleWindow = new HashSet<>();

@@ -113,11 +126,46 @@ public class BackgroundLaunchProcessControllerTests {
    }

    @Test
    @DisableFlags(Flags.FLAG_BAL_IMPROVED_METRICS)
    public void testAllowedByTokenNoCallbackOld() {
        mController = new BackgroundLaunchProcessController(mHasActiveVisibleWindow::contains,
                null);
        Binder token = new Binder();
        mActivityStartAllowed.add(token);
        mController.addOrUpdateAllowBackgroundStartPrivileges(token,
                BackgroundStartPrivileges.ALLOW_BAL);
        BalVerdict balVerdict = mController.areBackgroundActivityStartsAllowed(
                mPid, mUid, mPackageName,
                mAppSwitchState, mIsCheckingForFgsStart,
                mHasActivityInVisibleTask, mHasBackgroundActivityStartPrivileges,
                mLastStopAppSwitchesTime, mLastActivityLaunchTime,
                mLastActivityFinishTime);
        assertThat(balVerdict.getCode()).isEqualTo(BAL_ALLOW_PERMISSION);
    }

    @Test
    @EnableFlags(Flags.FLAG_BAL_IMPROVED_METRICS)
    public void testAllowedByTokenNoCallback() {
        mController = new BackgroundLaunchProcessController(mHasActiveVisibleWindow::contains,
                null);
        Binder token = new Binder();
        mActivityStartAllowed.add(token);
        mController.addOrUpdateAllowBackgroundStartPrivileges(token,
                BackgroundStartPrivileges.ALLOW_BAL);
        BalVerdict balVerdict = mController.areBackgroundActivityStartsAllowed(
                mPid, mUid, mPackageName,
                mAppSwitchState, mIsCheckingForFgsStart,
                mHasActivityInVisibleTask, mHasBackgroundActivityStartPrivileges,
                mLastStopAppSwitchesTime, mLastActivityLaunchTime,
                mLastActivityFinishTime);
        assertThat(balVerdict.getCode()).isEqualTo(BAL_ALLOW_TOKEN);
    }

    @Test
    @DisableFlags(Flags.FLAG_BAL_IMPROVED_METRICS)
    public void testAllowedByTokenOld() {
        Binder token = new Binder();
        mActivityStartAllowed.add(token);
        mController.addOrUpdateAllowBackgroundStartPrivileges(token,
                BackgroundStartPrivileges.ALLOW_BAL);
        BalVerdict balVerdict = mController.areBackgroundActivityStartsAllowed(
@@ -130,6 +178,7 @@ public class BackgroundLaunchProcessControllerTests {
    }

    @Test
    @EnableFlags(Flags.FLAG_BAL_IMPROVED_METRICS)
    public void testAllowedByToken() {
        Binder token = new Binder();
        mActivityStartAllowed.add(token);
@@ -141,11 +190,12 @@ public class BackgroundLaunchProcessControllerTests {
                mHasActivityInVisibleTask, mHasBackgroundActivityStartPrivileges,
                mLastStopAppSwitchesTime, mLastActivityLaunchTime,
                mLastActivityFinishTime);
        assertThat(balVerdict.getCode()).isEqualTo(BAL_ALLOW_PERMISSION);
        assertThat(balVerdict.getCode()).isEqualTo(BAL_ALLOW_TOKEN);
    }

    @Test
    public void testBoundByForeground() {
    @DisableFlags(Flags.FLAG_BAL_IMPROVED_METRICS)
    public void testBoundByForegroundOld() {
        mAppSwitchState = APP_SWITCH_ALLOW;
        mController.addBoundClientUid(999, "visible.package", Context.BIND_ALLOW_ACTIVITY_STARTS);
        mHasActiveVisibleWindow.add(999);
@@ -158,6 +208,21 @@ public class BackgroundLaunchProcessControllerTests {
        assertThat(balVerdict.getCode()).isEqualTo(BAL_ALLOW_VISIBLE_WINDOW);
    }

    @Test
    @EnableFlags(Flags.FLAG_BAL_IMPROVED_METRICS)
    public void testBoundByForeground() {
        mAppSwitchState = APP_SWITCH_ALLOW;
        mController.addBoundClientUid(999, "visible.package", Context.BIND_ALLOW_ACTIVITY_STARTS);
        mHasActiveVisibleWindow.add(999);
        BalVerdict balVerdict = mController.areBackgroundActivityStartsAllowed(
                mPid, mUid, mPackageName,
                mAppSwitchState, mIsCheckingForFgsStart,
                mHasActivityInVisibleTask, mHasBackgroundActivityStartPrivileges,
                mLastStopAppSwitchesTime, mLastActivityLaunchTime,
                mLastActivityFinishTime);
        assertThat(balVerdict.getCode()).isEqualTo(BAL_ALLOW_BOUND_BY_FOREGROUND);
    }

    @Test
    public void testForegroundTask() {
        mAppSwitchState = APP_SWITCH_ALLOW;