Don't count toasts as visible windows
in WMS#isAnyWindowVisibleForUid() (now in RootWindowContainer)
Apps could post a toast (or many in a row for that matter) to
trivially bypass the isUidForeground() check.
Bug: 110956953
Test: atest WmTests:ActivityStarterTests
atest WmTests:RootWindowContainerTests
Test: manual
Change-Id: Ice6571264c35fbf7d4446a5f67a4c44c84d0f9f0
This commit is contained in:
@@ -945,7 +945,7 @@ class ActivityStarter {
|
||||
/** Returns true if uid has a visible window or its process is in a top state. */
|
||||
private boolean isUidForeground(int uid) {
|
||||
return (mService.getUidStateLocked(uid) == ActivityManager.PROCESS_STATE_TOP)
|
||||
|| mService.mWindowManager.isAnyWindowVisibleForUid(uid);
|
||||
|| mService.mWindowManager.mRoot.isAnyNonToastWindowVisibleForUid(uid);
|
||||
}
|
||||
|
||||
/** Returns true if uid is in a persistent state. */
|
||||
@@ -968,18 +968,19 @@ class ActivityStarter {
|
||||
Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "logActivityStart");
|
||||
final int callingUidProcState = mService.getUidStateLocked(callingUid);
|
||||
final boolean callingUidHasAnyVisibleWindow =
|
||||
mService.mWindowManager.isAnyWindowVisibleForUid(callingUid);
|
||||
mService.mWindowManager.mRoot.isAnyNonToastWindowVisibleForUid(callingUid);
|
||||
final int realCallingUidProcState = (callingUid == realCallingUid)
|
||||
? callingUidProcState
|
||||
: mService.getUidStateLocked(realCallingUid);
|
||||
final boolean realCallingUidHasAnyVisibleWindow = (callingUid == realCallingUid)
|
||||
? callingUidHasAnyVisibleWindow
|
||||
: mService.mWindowManager.isAnyWindowVisibleForUid(realCallingUid);
|
||||
: mService.mWindowManager.mRoot.isAnyNonToastWindowVisibleForUid(
|
||||
realCallingUid);
|
||||
final String targetPackage = (r != null) ? r.packageName : null;
|
||||
final int targetUid = (r!= null) ? ((r.appInfo != null) ? r.appInfo.uid : -1) : -1;
|
||||
final int targetUidProcState = mService.getUidStateLocked(targetUid);
|
||||
final boolean targetUidHasAnyVisibleWindow = (targetUid != -1)
|
||||
? mService.mWindowManager.isAnyWindowVisibleForUid(targetUid)
|
||||
? mService.mWindowManager.mRoot.isAnyNonToastWindowVisibleForUid(targetUid)
|
||||
: false;
|
||||
final String targetWhitelistTag = (targetUid != -1)
|
||||
? mService.getPendingTempWhitelistTagForUidLocked(targetUid)
|
||||
|
||||
@@ -23,6 +23,7 @@ import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_KEYGUARD;
|
||||
import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_SUSTAINED_PERFORMANCE_MODE;
|
||||
import static android.view.WindowManager.LayoutParams.TYPE_DREAM;
|
||||
import static android.view.WindowManager.LayoutParams.TYPE_KEYGUARD_DIALOG;
|
||||
import static android.view.WindowManager.LayoutParams.TYPE_TOAST;
|
||||
|
||||
import static com.android.server.policy.WindowManagerPolicy.FINISH_LAYOUT_REDO_LAYOUT;
|
||||
import static com.android.server.policy.WindowManagerPolicy.FINISH_LAYOUT_REDO_WALLPAPER;
|
||||
@@ -279,6 +280,15 @@ class RootWindowContainer extends WindowContainer<DisplayContent>
|
||||
}, true /* traverseTopToBottom */);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if the callingUid has any non-toast window currently visible to the user.
|
||||
*/
|
||||
boolean isAnyNonToastWindowVisibleForUid(int callingUid) {
|
||||
return forAllWindows(w -> {
|
||||
return w.getOwningUid() == callingUid && w.isVisible() && w.mAttrs.type != TYPE_TOAST;
|
||||
}, true /* traverseTopToBottom */);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the app window token for the input binder if it exist in the system.
|
||||
* NOTE: Only one AppWindowToken is allowed to exist in the system for a binder token, since
|
||||
|
||||
@@ -5715,17 +5715,6 @@ public class WindowManagerService extends IWindowManager.Stub
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if the callingUid has any window currently visible to the user.
|
||||
*/
|
||||
public boolean isAnyWindowVisibleForUid(int callingUid) {
|
||||
synchronized (mGlobalLock) {
|
||||
return mRoot.forAllWindows(w -> {
|
||||
return w.getOwningUid() == callingUid && w.isVisible();
|
||||
}, true /* traverseTopToBottom */);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Called when a task has been removed from the recent tasks list.
|
||||
* <p>
|
||||
|
||||
@@ -643,10 +643,10 @@ public class ActivityStarterTests extends ActivityTestsBase {
|
||||
boolean hasForegroundActivities, boolean callerIsRecents,
|
||||
boolean callerIsTempWhitelisted) {
|
||||
// window visibility
|
||||
doReturn(callingUidHasVisibleWindow).when(mService.mWindowManager).isAnyWindowVisibleForUid(
|
||||
callingUid);
|
||||
doReturn(realCallingUidHasVisibleWindow).when(mService.mWindowManager)
|
||||
.isAnyWindowVisibleForUid(realCallingUid);
|
||||
doReturn(callingUidHasVisibleWindow).when(mService.mWindowManager.mRoot)
|
||||
.isAnyNonToastWindowVisibleForUid(callingUid);
|
||||
doReturn(realCallingUidHasVisibleWindow).when(mService.mWindowManager.mRoot)
|
||||
.isAnyNonToastWindowVisibleForUid(realCallingUid);
|
||||
// process importance
|
||||
doReturn(callingUidProcState).when(mService).getUidStateLocked(callingUid);
|
||||
doReturn(realCallingUidProcState).when(mService).getUidStateLocked(realCallingUid);
|
||||
|
||||
@@ -0,0 +1,75 @@
|
||||
/*
|
||||
* Copyright (C) 2019 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 android.view.WindowManager.LayoutParams.TYPE_APPLICATION;
|
||||
import static android.view.WindowManager.LayoutParams.TYPE_STATUS_BAR;
|
||||
import static android.view.WindowManager.LayoutParams.TYPE_TOAST;
|
||||
|
||||
import static org.junit.Assert.assertFalse;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
import android.platform.test.annotations.Presubmit;
|
||||
|
||||
import androidx.test.filters.SmallTest;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
/**
|
||||
* Tests for RootWindowContainer.
|
||||
*
|
||||
* Build/Install/Run:
|
||||
* atest WmTests:RootWindowContainerTests
|
||||
*/
|
||||
@SmallTest
|
||||
@Presubmit
|
||||
public class RootWindowContainerTests extends WindowTestsBase {
|
||||
|
||||
private static final int FAKE_CALLING_UID = 667;
|
||||
|
||||
@Test
|
||||
public void testIsAnyNonToastWindowVisibleForUid_oneToastOneNonToastBothVisible() {
|
||||
final WindowState toastyToast = createWindow(null, TYPE_TOAST, "toast", FAKE_CALLING_UID);
|
||||
final WindowState app = createWindow(null, TYPE_APPLICATION, "app", FAKE_CALLING_UID);
|
||||
toastyToast.mHasSurface = true;
|
||||
app.mHasSurface = true;
|
||||
|
||||
assertTrue(toastyToast.isVisible());
|
||||
assertTrue(app.isVisible());
|
||||
assertTrue(mWm.mRoot.isAnyNonToastWindowVisibleForUid(FAKE_CALLING_UID));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testIsAnyNonToastWindowVisibleForUid_onlyToastVisible() {
|
||||
final WindowState toastyToast = createWindow(null, TYPE_TOAST, "toast", FAKE_CALLING_UID);
|
||||
toastyToast.mHasSurface = true;
|
||||
|
||||
assertTrue(toastyToast.isVisible());
|
||||
assertFalse(mWm.mRoot.isAnyNonToastWindowVisibleForUid(FAKE_CALLING_UID));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testIsAnyNonToastWindowVisibleForUid_aFewNonToastButNoneVisible() {
|
||||
final WindowState topBar = createWindow(null, TYPE_STATUS_BAR, "topBar", FAKE_CALLING_UID);
|
||||
final WindowState app = createWindow(null, TYPE_APPLICATION, "app", FAKE_CALLING_UID);
|
||||
|
||||
assertFalse(topBar.isVisible());
|
||||
assertFalse(app.isVisible());
|
||||
assertFalse(mWm.mRoot.isAnyNonToastWindowVisibleForUid(FAKE_CALLING_UID));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -257,6 +257,14 @@ class WindowTestsBase {
|
||||
}
|
||||
}
|
||||
|
||||
WindowState createWindow(WindowState parent, int type, String name, int ownerId) {
|
||||
synchronized (mWm.mGlobalLock) {
|
||||
return (parent == null)
|
||||
? createWindow(parent, type, mDisplayContent, name, ownerId)
|
||||
: createWindow(parent, type, parent.mToken, name, ownerId);
|
||||
}
|
||||
}
|
||||
|
||||
WindowState createWindowOnStack(WindowState parent, int windowingMode, int activityType,
|
||||
int type, DisplayContent dc, String name) {
|
||||
synchronized (mWm.mGlobalLock) {
|
||||
@@ -277,7 +285,16 @@ class WindowTestsBase {
|
||||
synchronized (mWm.mGlobalLock) {
|
||||
final WindowToken token = createWindowToken(
|
||||
dc, WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, type);
|
||||
return createWindow(parent, type, token, name);
|
||||
return createWindow(parent, type, token, name, 0 /* ownerId */);
|
||||
}
|
||||
}
|
||||
|
||||
WindowState createWindow(WindowState parent, int type, DisplayContent dc, String name,
|
||||
int ownerId) {
|
||||
synchronized (mWm.mGlobalLock) {
|
||||
final WindowToken token = createWindowToken(
|
||||
dc, WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, type);
|
||||
return createWindow(parent, type, token, name, ownerId);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -298,6 +315,14 @@ class WindowTestsBase {
|
||||
}
|
||||
}
|
||||
|
||||
WindowState createWindow(WindowState parent, int type, WindowToken token, String name,
|
||||
int ownerId) {
|
||||
synchronized (mWm.mGlobalLock) {
|
||||
return createWindow(parent, type, token, name, ownerId,
|
||||
false /* ownerCanAddInternalSystemWindow */);
|
||||
}
|
||||
}
|
||||
|
||||
WindowState createWindow(WindowState parent, int type, WindowToken token, String name,
|
||||
int ownerId, boolean ownerCanAddInternalSystemWindow) {
|
||||
return createWindow(parent, type, token, name, ownerId, ownerCanAddInternalSystemWindow,
|
||||
|
||||
Reference in New Issue
Block a user