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

Commit aef1b73e authored by Treehugger Robot's avatar Treehugger Robot Committed by Android (Google) Code Review
Browse files

Merge "RESTRICT AUTOMERGE Ignore pinned Windows" into udc-qpr-dev

parents 4ad9b1ed bfdb4ff6
Loading
Loading
Loading
Loading
+6 −2
Original line number Original line Diff line number Diff line
@@ -239,7 +239,9 @@ public class BackgroundActivityStartController {


        // don't abort if the callingUid has a visible window or is a persistent system process
        // don't abort if the callingUid has a visible window or is a persistent system process
        final int callingUidProcState = mService.mActiveUids.getUidState(callingUid);
        final int callingUidProcState = mService.mActiveUids.getUidState(callingUid);
        final boolean callingUidHasAnyVisibleWindow = mService.hasActiveVisibleWindow(callingUid);
        final boolean callingUidHasAnyVisibleWindow =
                mService.mVisibleActivityProcessTracker.hasVisibleNotPinnedActivity(callingUid)
                        || mService.mActiveUids.hasNonAppVisibleWindow(callingUid);
        final boolean isCallingUidPersistentSystemProcess =
        final boolean isCallingUidPersistentSystemProcess =
                callingUidProcState <= ActivityManager.PROCESS_STATE_PERSISTENT_UI;
                callingUidProcState <= ActivityManager.PROCESS_STATE_PERSISTENT_UI;


@@ -267,7 +269,9 @@ public class BackgroundActivityStartController {
        final boolean realCallingUidHasAnyVisibleWindow =
        final boolean realCallingUidHasAnyVisibleWindow =
                (callingUid == realCallingUid)
                (callingUid == realCallingUid)
                        ? callingUidHasAnyVisibleWindow
                        ? callingUidHasAnyVisibleWindow
                        : mService.hasActiveVisibleWindow(realCallingUid);
                        : (mService.mVisibleActivityProcessTracker.hasVisibleNotPinnedActivity(
                                realCallingUid) || mService.mActiveUids.hasNonAppVisibleWindow(
                                realCallingUid));
        final int realCallingAppId = UserHandle.getAppId(realCallingUid);
        final int realCallingAppId = UserHandle.getAppId(realCallingUid);
        final boolean isRealCallingUidPersistentSystemProcess =
        final boolean isRealCallingUidPersistentSystemProcess =
                (callingUid == realCallingUid)
                (callingUid == realCallingUid)
+7 −5
Original line number Original line Diff line number Diff line
@@ -22,7 +22,7 @@ import static com.android.server.wm.ActivityTaskManagerDebugConfig.TAG_ATM;
import static com.android.server.wm.ActivityTaskManagerDebugConfig.TAG_WITH_CLASS_NAME;
import static com.android.server.wm.ActivityTaskManagerDebugConfig.TAG_WITH_CLASS_NAME;
import static com.android.server.wm.ActivityTaskManagerService.ACTIVITY_BG_START_GRACE_PERIOD_MS;
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_ALLOW;
import static com.android.server.wm.ActivityTaskManagerService.APP_SWITCH_FG_ONLY;
import static com.android.server.wm.ActivityTaskManagerService.APP_SWITCH_DISALLOW;
import static com.android.server.wm.BackgroundActivityStartController.BAL_ALLOW_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_GRACE_PERIOD;
import static com.android.server.wm.BackgroundActivityStartController.BAL_ALLOW_PERMISSION;
import static com.android.server.wm.BackgroundActivityStartController.BAL_ALLOW_PERMISSION;
@@ -99,7 +99,8 @@ class BackgroundLaunchProcessController {
    @BackgroundActivityStartController.BalCode
    @BackgroundActivityStartController.BalCode
    int areBackgroundActivityStartsAllowed(int pid, int uid, String packageName,
    int areBackgroundActivityStartsAllowed(int pid, int uid, String packageName,
            int appSwitchState, boolean isCheckingForFgsStart,
            int appSwitchState, boolean isCheckingForFgsStart,
            boolean hasActivityInVisibleTask, boolean hasBackgroundActivityStartPrivileges,
            boolean hasActivityInVisibleTask, boolean inPinnedWindow,
            boolean hasBackgroundActivityStartPrivileges,
            long lastStopAppSwitchesTime, long lastActivityLaunchTime,
            long lastStopAppSwitchesTime, long lastActivityLaunchTime,
            long lastActivityFinishTime) {
            long lastActivityFinishTime) {
        // Allow if the proc is instrumenting with background activity starts privs.
        // Allow if the proc is instrumenting with background activity starts privs.
@@ -121,9 +122,10 @@ class BackgroundLaunchProcessController {
                    BAL_ALLOW_VISIBLE_WINDOW, /*background*/ false, uid, uid, /*intent*/ null,
                    BAL_ALLOW_VISIBLE_WINDOW, /*background*/ false, uid, uid, /*intent*/ null,
                    pid, "Activity start allowed: process bound by foreground uid");
                    pid, "Activity start allowed: process bound by foreground uid");
        }
        }
        // Allow if the caller has an activity in any foreground task.
        // Allow if the caller has an activity in any foreground task, unless it's a pinned window
        if (hasActivityInVisibleTask
        // and not a foreground service start.
                && (appSwitchState == APP_SWITCH_ALLOW || appSwitchState == APP_SWITCH_FG_ONLY)) {
        if ((isCheckingForFgsStart || !inPinnedWindow)
                && hasActivityInVisibleTask && appSwitchState != APP_SWITCH_DISALLOW) {
            return BackgroundActivityStartController.logStartAllowedAndReturnCode(
            return BackgroundActivityStartController.logStartAllowedAndReturnCode(
                    BAL_ALLOW_FOREGROUND, /*background*/ false, uid, uid, /*intent*/ null,
                    BAL_ALLOW_FOREGROUND, /*background*/ false, uid, uid, /*intent*/ null,
                    pid, "Activity start allowed: process has activity in foreground task");
                    pid, "Activity start allowed: process has activity in foreground task");
+11 −2
Original line number Original line Diff line number Diff line
@@ -30,6 +30,7 @@ import java.util.function.Predicate;
 * host process with foreground (resumed) activity.
 * host process with foreground (resumed) activity.
 */
 */
class VisibleActivityProcessTracker {
class VisibleActivityProcessTracker {
    private static final Predicate<WindowProcessController> ALWAYS_TRUE = wpc -> true;
    @GuardedBy("mProcMap")
    @GuardedBy("mProcMap")
    private final ArrayMap<WindowProcessController, CpuTimeRecord> mProcMap = new ArrayMap<>();
    private final ArrayMap<WindowProcessController, CpuTimeRecord> mProcMap = new ArrayMap<>();
    final Executor mBgExecutor = BackgroundThread.getExecutor();
    final Executor mBgExecutor = BackgroundThread.getExecutor();
@@ -80,14 +81,22 @@ class VisibleActivityProcessTracker {
     * {@link ActivityRecord#mVisibleRequested} or {@link ActivityRecord#isVisible()} is true.
     * {@link ActivityRecord#mVisibleRequested} or {@link ActivityRecord#isVisible()} is true.
     */
     */
    boolean hasVisibleActivity(int uid) {
    boolean hasVisibleActivity(int uid) {
        return match(uid, null /* predicate */);
        return match(uid, ALWAYS_TRUE);
    }

    /**
     * Returns {@code true} if the uid has a process that contains an activity with
     * {@link ActivityRecord#mVisibleRequested} or {@link ActivityRecord#isVisible()} is true.
     */
    boolean hasVisibleNotPinnedActivity(int uid) {
        return match(uid, wpc -> !wpc.inPinnedWindowingMode());
    }
    }


    private boolean match(int uid, Predicate<WindowProcessController> predicate) {
    private boolean match(int uid, Predicate<WindowProcessController> predicate) {
        synchronized (mProcMap) {
        synchronized (mProcMap) {
            for (int i = mProcMap.size() - 1; i >= 0; i--) {
            for (int i = mProcMap.size() - 1; i >= 0; i--) {
                final WindowProcessController wpc = mProcMap.keyAt(i);
                final WindowProcessController wpc = mProcMap.keyAt(i);
                if (wpc.mUid == uid && (predicate == null || predicate.test(wpc))) {
                if (wpc.mUid == uid && predicate.test(wpc)) {
                    return true;
                    return true;
                }
                }
            }
            }
+1 −0
Original line number Original line Diff line number Diff line
@@ -645,6 +645,7 @@ public class WindowProcessController extends ConfigurationContainer<Configuratio
            boolean isCheckingForFgsStart) {
            boolean isCheckingForFgsStart) {
        return mBgLaunchController.areBackgroundActivityStartsAllowed(mPid, mUid, mInfo.packageName,
        return mBgLaunchController.areBackgroundActivityStartsAllowed(mPid, mUid, mInfo.packageName,
                appSwitchState, isCheckingForFgsStart, hasActivityInVisibleTask(),
                appSwitchState, isCheckingForFgsStart, hasActivityInVisibleTask(),
                inPinnedWindowingMode(),
                mInstrumentingWithBackgroundActivityStartPrivileges,
                mInstrumentingWithBackgroundActivityStartPrivileges,
                mAtm.getLastStopAppSwitchesTime(),
                mAtm.getLastStopAppSwitchesTime(),
                mLastActivityLaunchTime, mLastActivityFinishTime);
                mLastActivityLaunchTime, mLastActivityFinishTime);
+95 −0
Original line number Original line Diff line number Diff line
/*
 * Copyright (C) 2022 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.android.server.wm;

import static com.google.common.truth.Truth.assertThat;

import static org.mockito.Mockito.mock;

import android.app.IApplicationThread;
import android.app.WindowConfiguration;
import android.content.pm.ApplicationInfo;
import android.platform.test.annotations.Presubmit;

import androidx.test.filters.SmallTest;

import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;


/**
 * Tests for the {@link com.android.server.wm.VisibleActivityProcessTracker} class.
 *
 * Build/Install/Run:
 * atest WmTests:VisibleActivityProcessTrackerTests
 */
@SmallTest
@Presubmit
@RunWith(WindowTestRunner.class)
public class VisibleActivityProcessTrackerTests extends WindowTestsBase {

    private VisibleActivityProcessTracker mTracker;

    @Before
    public void setup() {
        mTracker = mAtm.mVisibleActivityProcessTracker;
    }

    @Test
    public void testVisibleActivity() {
        WindowProcessController wpc = createWindowProcessController();
        assertThat(mTracker.hasVisibleActivity(wpc.mUid)).isFalse();
        mTracker.onAnyActivityVisible(wpc);
        assertThat(mTracker.hasVisibleActivity(wpc.mUid)).isTrue();
        mTracker.onAllActivitiesInvisible(wpc);
        assertThat(mTracker.hasVisibleActivity(wpc.mUid)).isFalse();
    }

    @Test
    public void testVisibleNotPinnedActivity() {
        WindowProcessController wpc = createWindowProcessController();
        assertThat(mTracker.hasVisibleNotPinnedActivity(wpc.mUid)).isFalse();
        mTracker.onAnyActivityVisible(wpc);
        assertThat(mTracker.hasVisibleNotPinnedActivity(wpc.mUid)).isTrue();
        mTracker.onAllActivitiesInvisible(wpc);
        assertThat(mTracker.hasVisibleNotPinnedActivity(wpc.mUid)).isFalse();
    }

    @Test
    public void testVisiblePinnedActivity() {
        WindowProcessController wpc = createWindowProcessController();
        wpc.getConfiguration().windowConfiguration.setWindowingMode(
                WindowConfiguration.WINDOWING_MODE_PINNED);
        assertThat(mTracker.hasVisibleNotPinnedActivity(wpc.mUid)).isFalse();
        mTracker.onAnyActivityVisible(wpc);
        assertThat(mTracker.hasVisibleActivity(wpc.mUid)).isTrue();
        assertThat(mTracker.hasVisibleNotPinnedActivity(wpc.mUid)).isFalse();
        mTracker.onAllActivitiesInvisible(wpc);
        assertThat(mTracker.hasVisibleNotPinnedActivity(wpc.mUid)).isFalse();
    }

    WindowProcessController createWindowProcessController() {
        WindowProcessListener mMockListener = mock(WindowProcessListener.class);
        ApplicationInfo info = mock(ApplicationInfo.class);
        info.packageName = "test.package.name";
        WindowProcessController mWpc = new WindowProcessController(
                mAtm, info, null, 0, -1, null, mMockListener);
        mWpc.setThread(mock(IApplicationThread.class));
        return mWpc;
    }
}