Merge "Migrate WindowContext#onConfigurationChanged to ClientTransaction (5/n)" into main

This commit is contained in:
Chris Li
2023-07-24 01:13:28 +00:00
committed by Android (Google) Code Review
8 changed files with 117 additions and 57 deletions

View File

@@ -427,12 +427,6 @@
"group": "WM_DEBUG_BACK_PREVIEW",
"at": "com\/android\/server\/wm\/BackNavigationController.java"
},
"-1715268616": {
"message": "Last window, removing starting window %s",
"level": "VERBOSE",
"group": "WM_DEBUG_STARTING_WINDOW",
"at": "com\/android\/server\/wm\/ActivityRecord.java"
},
"-1710206702": {
"message": "Display id=%d is frozen while keyguard locked, return %d",
"level": "VERBOSE",
@@ -463,6 +457,12 @@
"group": "WM_DEBUG_TASKS",
"at": "com\/android\/server\/wm\/ActivityTaskManagerService.java"
},
"-1671601441": {
"message": "attachWindowContextToDisplayContent: calling from non-existing process pid=%d uid=%d",
"level": "WARN",
"group": "WM_ERROR",
"at": "com\/android\/server\/wm\/WindowManagerService.java"
},
"-1670695197": {
"message": "Attempted to add presentation window to a non-suitable display. Aborting.",
"level": "WARN",
@@ -1225,6 +1225,12 @@
"group": "WM_DEBUG_STARTING_WINDOW",
"at": "com\/android\/server\/wm\/WindowState.java"
},
"-961053385": {
"message": "attachWindowContextToDisplayArea: calling from non-existing process pid=%d uid=%d",
"level": "WARN",
"group": "WM_ERROR",
"at": "com\/android\/server\/wm\/WindowManagerService.java"
},
"-957060823": {
"message": "Moving to PAUSING: %s",
"level": "VERBOSE",
@@ -4057,12 +4063,6 @@
"group": "WM_DEBUG_WINDOW_TRANSITIONS",
"at": "com\/android\/server\/wm\/Transition.java"
},
"1671994402": {
"message": "Nulling last startingData",
"level": "VERBOSE",
"group": "WM_DEBUG_STARTING_WINDOW",
"at": "com\/android\/server\/wm\/ActivityRecord.java"
},
"1674747211": {
"message": "%s forcing orientation to %d for display id=%d",
"level": "VERBOSE",
@@ -4243,12 +4243,6 @@
"group": "WM_DEBUG_ORIENTATION",
"at": "com\/android\/server\/wm\/ActivityRecord.java"
},
"1853793312": {
"message": "Notify removed startingWindow %s",
"level": "VERBOSE",
"group": "WM_DEBUG_STARTING_WINDOW",
"at": "com\/android\/server\/wm\/ActivityRecord.java"
},
"1856783490": {
"message": "resumeTopActivity: Restarting %s",
"level": "DEBUG",
@@ -4279,6 +4273,12 @@
"group": "WM_DEBUG_ORIENTATION",
"at": "com\/android\/server\/wm\/DisplayContent.java"
},
"1879463933": {
"message": "attachWindowContextToWindowToken: calling from non-existing process pid=%d uid=%d",
"level": "WARN",
"group": "WM_ERROR",
"at": "com\/android\/server\/wm\/WindowManagerService.java"
},
"1891501279": {
"message": "cancelAnimation(): reason=%s",
"level": "DEBUG",

View File

@@ -5422,8 +5422,10 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp
// Attach the SystemUiContext to this DisplayContent the get latest configuration.
// Note that the SystemUiContext will be removed automatically if this DisplayContent
// is detached.
final WindowProcessController wpc = mAtmService.getProcessController(
getDisplayUiContext().getIApplicationThread());
mWmService.mWindowContextListenerController.registerWindowContainerListener(
getDisplayUiContext().getWindowContextToken(), this, SYSTEM_UID,
wpc, getDisplayUiContext().getWindowContextToken(), this, SYSTEM_UID,
INVALID_WINDOW_TYPE, null /* options */);
}
}

View File

@@ -69,22 +69,24 @@ class WindowContextListenerController {
final ArrayMap<IBinder, WindowContextListenerImpl> mListeners = new ArrayMap<>();
/**
* @see #registerWindowContainerListener(IBinder, WindowContainer, int, int, Bundle, boolean)
* @see #registerWindowContainerListener(WindowProcessController, IBinder, WindowContainer, int,
* int, Bundle, boolean)
*/
void registerWindowContainerListener(@NonNull IBinder clientToken,
@NonNull WindowContainer<?> container, int ownerUid, @WindowType int type,
@Nullable Bundle options) {
registerWindowContainerListener(clientToken, container, ownerUid, type, options,
void registerWindowContainerListener(@NonNull WindowProcessController wpc,
@NonNull IBinder clientToken, @NonNull WindowContainer<?> container, int ownerUid,
@WindowType int type, @Nullable Bundle options) {
registerWindowContainerListener(wpc, clientToken, container, ownerUid, type, options,
true /* shouDispatchConfigWhenRegistering */);
}
/**
* Registers the listener to a {@code container} which is associated with
* a {@code clientToken}, which is a {@link android.window.WindowContext} representation. If the
* a {@code clientToken}, which is a {@link WindowContext} representation. If the
* listener associated with {@code clientToken} hasn't been initialized yet, create one
* {@link WindowContextListenerImpl}. Otherwise, the listener associated with
* {@code clientToken} switches to listen to the {@code container}.
*
* @param wpc the process that we should send the window configuration change to
* @param clientToken the token to associate with the listener
* @param container the {@link WindowContainer} which the listener is going to listen to.
* @param ownerUid the caller UID
@@ -94,19 +96,32 @@ class WindowContextListenerController {
* {@code container}'s config will dispatch to the client side when
* registering the {@link WindowContextListenerImpl}
*/
void registerWindowContainerListener(@NonNull IBinder clientToken,
@NonNull WindowContainer<?> container, int ownerUid, @WindowType int type,
@Nullable Bundle options, boolean shouDispatchConfigWhenRegistering) {
void registerWindowContainerListener(@NonNull WindowProcessController wpc,
@NonNull IBinder clientToken, @NonNull WindowContainer<?> container, int ownerUid,
@WindowType int type, @Nullable Bundle options,
boolean shouDispatchConfigWhenRegistering) {
WindowContextListenerImpl listener = mListeners.get(clientToken);
if (listener == null) {
listener = new WindowContextListenerImpl(clientToken, container, ownerUid, type,
listener = new WindowContextListenerImpl(wpc, clientToken, container, ownerUid, type,
options);
listener.register(shouDispatchConfigWhenRegistering);
} else {
listener.updateContainer(container);
updateContainerForWindowContextListener(clientToken, container);
}
}
/**
* Updates the {@link WindowContainer} that an existing {@link WindowContext} is listening to.
*/
void updateContainerForWindowContextListener(@NonNull IBinder clientToken,
@NonNull WindowContainer<?> container) {
final WindowContextListenerImpl listener = mListeners.get(clientToken);
if (listener == null) {
throw new IllegalArgumentException("Can't find listener for " + clientToken);
}
listener.updateContainer(container);
}
void unregisterWindowContainerListener(IBinder clientToken) {
final WindowContextListenerImpl listener = mListeners.get(clientToken);
// Listeners may be removed earlier. An example is the display where the listener is
@@ -189,9 +204,13 @@ class WindowContextListenerController {
@VisibleForTesting
class WindowContextListenerImpl implements WindowContainerListener {
@NonNull private final IWindowToken mClientToken;
@NonNull
private final WindowProcessController mWpc;
@NonNull
private final IWindowToken mClientToken;
private final int mOwnerUid;
@NonNull private WindowContainer<?> mContainer;
@NonNull
private WindowContainer<?> mContainer;
/**
* The options from {@link Context#createWindowContext(int, Bundle)}.
* <p>It can be used for choosing the {@link DisplayArea} where the window context
@@ -207,8 +226,10 @@ class WindowContextListenerController {
private boolean mHasPendingConfiguration;
private WindowContextListenerImpl(IBinder clientToken, WindowContainer<?> container,
private WindowContextListenerImpl(@NonNull WindowProcessController wpc,
@NonNull IBinder clientToken, @NonNull WindowContainer<?> container,
int ownerUid, @WindowType int type, @Nullable Bundle options) {
mWpc = Objects.requireNonNull(wpc);
mClientToken = IWindowToken.Stub.asInterface(clientToken);
mContainer = Objects.requireNonNull(container);
mOwnerUid = ownerUid;
@@ -308,6 +329,7 @@ class WindowContextListenerController {
mLastReportedDisplay = displayId;
try {
// TODO(b/290876897): migrate to dispatch through wpc
mClientToken.onConfigurationChanged(config, displayId);
} catch (RemoteException e) {
ProtoLog.w(WM_ERROR, "Could not report config changes to the window token client.");
@@ -337,6 +359,7 @@ class WindowContextListenerController {
}
mDeathRecipient.unlinkToDeath();
try {
// TODO(b/290876897): migrate to dispatch through wpc
mClientToken.onWindowTokenRemoved();
} catch (RemoteException e) {
ProtoLog.w(WM_ERROR, "Could not report token removal to the window token client.");

View File

@@ -1698,8 +1698,8 @@ public class WindowManagerService extends IWindowManager.Stub
return WindowManagerGlobal.ADD_INVALID_TYPE;
}
} else {
mWindowContextListenerController.registerWindowContainerListener(
windowContextToken, token, callingUid, type, options);
mWindowContextListenerController.updateContainerForWindowContextListener(
windowContextToken, token);
}
}
@@ -2744,10 +2744,17 @@ public class WindowManagerService extends IWindowManager.Stub
Objects.requireNonNull(clientToken);
final boolean callerCanManageAppTokens = checkCallingPermission(MANAGE_APP_TOKENS,
"attachWindowContextToDisplayArea", false /* printLog */);
final int callingPid = Binder.getCallingPid();
final int callingUid = Binder.getCallingUid();
final long origId = Binder.clearCallingIdentity();
try {
synchronized (mGlobalLock) {
final WindowProcessController wpc = mAtmService.getProcessController(appThread);
if (wpc == null) {
ProtoLog.w(WM_ERROR, "attachWindowContextToDisplayArea: calling from"
+ " non-existing process pid=%d uid=%d", callingPid, callingUid);
return null;
}
final DisplayContent dc = mRoot.getDisplayContentOrCreate(displayId);
if (dc == null) {
ProtoLog.w(WM_ERROR, "attachWindowContextToDisplayArea: trying to attach"
@@ -2758,8 +2765,9 @@ public class WindowManagerService extends IWindowManager.Stub
// the feature b/155340867 is completed.
final DisplayArea<?> da = dc.findAreaForWindowType(type, options,
callerCanManageAppTokens, false /* roundedCornerOverlay */);
mWindowContextListenerController.registerWindowContainerListener(clientToken, da,
callingUid, type, options, false /* shouDispatchConfigWhenRegistering */);
mWindowContextListenerController.registerWindowContainerListener(wpc, clientToken,
da, callingUid, type, options,
false /* shouDispatchConfigWhenRegistering */);
return da.getConfiguration();
}
} finally {
@@ -2773,10 +2781,17 @@ public class WindowManagerService extends IWindowManager.Stub
@NonNull IBinder clientToken, int displayId) {
Objects.requireNonNull(appThread);
Objects.requireNonNull(clientToken);
final int callingPid = Binder.getCallingPid();
final int callingUid = Binder.getCallingUid();
final long origId = Binder.clearCallingIdentity();
try {
synchronized (mGlobalLock) {
final WindowProcessController wpc = mAtmService.getProcessController(appThread);
if (wpc == null) {
ProtoLog.w(WM_ERROR, "attachWindowContextToDisplayContent: calling from"
+ " non-existing process pid=%d uid=%d", callingPid, callingUid);
return null;
}
// We use "getDisplayContent" instead of "getDisplayContentOrCreate" because
// this method may be called in DisplayPolicy's constructor and may cause
// infinite loop. In this scenario, we early return here and switch to do the
@@ -2793,8 +2808,8 @@ public class WindowManagerService extends IWindowManager.Stub
return null;
}
mWindowContextListenerController.registerWindowContainerListener(clientToken, dc,
callingUid, INVALID_WINDOW_TYPE, null /* options */,
mWindowContextListenerController.registerWindowContainerListener(wpc, clientToken,
dc, callingUid, INVALID_WINDOW_TYPE, null /* options */,
false /* shouDispatchConfigWhenRegistering */);
return dc.getConfiguration();
}
@@ -2811,10 +2826,17 @@ public class WindowManagerService extends IWindowManager.Stub
Objects.requireNonNull(token);
final boolean callerCanManageAppTokens = checkCallingPermission(MANAGE_APP_TOKENS,
"attachWindowContextToWindowToken", false /* printLog */);
final int callingPid = Binder.getCallingPid();
final int callingUid = Binder.getCallingUid();
final long origId = Binder.clearCallingIdentity();
try {
synchronized (mGlobalLock) {
final WindowProcessController wpc = mAtmService.getProcessController(appThread);
if (wpc == null) {
ProtoLog.w(WM_ERROR, "attachWindowContextToWindowToken: calling from"
+ " non-existing process pid=%d uid=%d", callingPid, callingUid);
return;
}
final WindowToken windowToken = mRoot.getWindowToken(token);
if (windowToken == null) {
ProtoLog.w(WM_ERROR, "Then token:%s is invalid. It might be "
@@ -2835,7 +2857,7 @@ public class WindowManagerService extends IWindowManager.Stub
callerCanManageAppTokens, callingUid)) {
return;
}
mWindowContextListenerController.registerWindowContainerListener(clientToken,
mWindowContextListenerController.registerWindowContainerListener(wpc, clientToken,
windowToken, callingUid, windowToken.windowType, windowToken.mOptions);
}
} finally {

View File

@@ -36,6 +36,7 @@ import static org.mockito.Mockito.timeout;
import static org.mockito.Mockito.verify;
import android.app.ActivityThread;
import android.app.IApplicationThread;
import android.content.Context;
import android.content.res.Resources;
import android.graphics.Rect;
@@ -91,10 +92,12 @@ public class InputMethodDialogWindowContextTest extends WindowTestsBase {
spyOn(mIWindowManager);
doAnswer(invocation -> {
Object[] args = invocation.getArguments();
IApplicationThread appThread = (IApplicationThread) args[0];
IBinder clientToken = (IBinder) args[1];
int displayId = (int) args[3];
DisplayContent dc = mWm.mRoot.getDisplayContent(displayId);
mWm.mWindowContextListenerController.registerWindowContainerListener(clientToken,
final WindowProcessController wpc = mAtm.getProcessController(appThread);
mWm.mWindowContextListenerController.registerWindowContainerListener(wpc, clientToken,
dc.getImeContainer(), 1000 /* ownerUid */, TYPE_INPUT_METHOD_DIALOG,
null /* options */);
return dc.getImeContainer().getConfiguration();

View File

@@ -43,6 +43,7 @@ import static org.mockito.Mockito.when;
import static org.mockito.Mockito.withSettings;
import android.app.ActivityManagerInternal;
import android.app.ActivityThread;
import android.app.AppOpsManager;
import android.app.IApplicationThread;
import android.app.usage.UsageStatsManagerInternal;
@@ -321,6 +322,10 @@ public class SystemServicesTestRule implements TestRule {
mock(ActivityManagerService.class, withSettings().stubOnly());
mAtmService = new TestActivityTaskManagerService(mContext, amService);
LocalServices.addService(ActivityTaskManagerInternal.class, mAtmService.getAtmInternal());
// Create a fake WindowProcessController for the system process.
final WindowProcessController wpc =
addProcess("android", "system", 1485 /* pid */, 1000 /* uid */);
wpc.setThread(ActivityThread.currentActivityThread().getApplicationThread());
}
private void setUpWindowManagerService() {

View File

@@ -37,6 +37,7 @@ import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.verify;
import static org.mockito.MockitoAnnotations.initMocks;
import android.app.IWindowToken;
import android.content.res.Configuration;
@@ -53,6 +54,7 @@ import androidx.test.filters.SmallTest;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.Mockito;
/**
@@ -68,11 +70,14 @@ public class WindowContextListenerControllerTests extends WindowTestsBase {
private static final int TEST_UID = 12345;
private static final int ANOTHER_UID = 1000;
@Mock
private WindowProcessController mWpc;
private final IBinder mClientToken = new Binder();
private WindowContainer<?> mContainer;
@Before
public void setUp() {
initMocks(this);
mController = new WindowContextListenerController();
mContainer = createTestWindowToken(TYPE_APPLICATION_OVERLAY, mDisplayContent);
// Make display on to verify configuration propagation.
@@ -82,20 +87,20 @@ public class WindowContextListenerControllerTests extends WindowTestsBase {
@Test
public void testRegisterWindowContextListener() {
mController.registerWindowContainerListener(mClientToken, mContainer, -1,
mController.registerWindowContainerListener(mWpc, mClientToken, mContainer, -1,
TYPE_APPLICATION_OVERLAY, null /* options */);
assertEquals(1, mController.mListeners.size());
final IBinder clientToken = mock(IBinder.class);
mController.registerWindowContainerListener(clientToken, mContainer, -1,
mController.registerWindowContainerListener(mWpc, clientToken, mContainer, -1,
TYPE_APPLICATION_OVERLAY, null /* options */);
assertEquals(2, mController.mListeners.size());
final WindowContainer<?> container = createTestWindowToken(TYPE_APPLICATION_OVERLAY,
mDefaultDisplay);
mController.registerWindowContainerListener(mClientToken, container, -1,
mController.registerWindowContainerListener(mWpc, mClientToken, container, -1,
TYPE_APPLICATION_OVERLAY, null /* options */);
// The number of listeners doesn't increase since the listener just gets updated.
@@ -121,7 +126,7 @@ public class WindowContextListenerControllerTests extends WindowTestsBase {
config1.densityDpi = 100;
mContainer.onRequestedOverrideConfigurationChanged(config1);
mController.registerWindowContainerListener(clientToken, mContainer, -1,
mController.registerWindowContainerListener(mWpc, clientToken, mContainer, -1,
TYPE_APPLICATION_OVERLAY, null /* options */);
assertEquals(bounds1, clientToken.mConfiguration.windowConfiguration.getBounds());
@@ -137,7 +142,7 @@ public class WindowContextListenerControllerTests extends WindowTestsBase {
config2.densityDpi = 200;
container.onRequestedOverrideConfigurationChanged(config2);
mController.registerWindowContainerListener(clientToken, container, -1,
mController.registerWindowContainerListener(mWpc, clientToken, container, -1,
TYPE_APPLICATION_OVERLAY, null /* options */);
assertEquals(bounds2, clientToken.mConfiguration.windowConfiguration.getBounds());
@@ -164,7 +169,7 @@ public class WindowContextListenerControllerTests extends WindowTestsBase {
@Test
public void testAssertCallerCanModifyListener_CanManageAppTokens_ReturnTrue() {
mController.registerWindowContainerListener(mClientToken, mContainer, TEST_UID,
mController.registerWindowContainerListener(mWpc, mClientToken, mContainer, TEST_UID,
TYPE_APPLICATION_OVERLAY, null /* options */);
assertTrue(mController.assertCallerCanModifyListener(mClientToken,
@@ -173,7 +178,7 @@ public class WindowContextListenerControllerTests extends WindowTestsBase {
@Test
public void testAssertCallerCanModifyListener_SameUid_ReturnTrue() {
mController.registerWindowContainerListener(mClientToken, mContainer, TEST_UID,
mController.registerWindowContainerListener(mWpc, mClientToken, mContainer, TEST_UID,
TYPE_APPLICATION_OVERLAY, null /* options */);
assertTrue(mController.assertCallerCanModifyListener(mClientToken,
@@ -182,7 +187,7 @@ public class WindowContextListenerControllerTests extends WindowTestsBase {
@Test(expected = UnsupportedOperationException.class)
public void testAssertCallerCanModifyListener_DifferentUid_ThrowException() {
mController.registerWindowContainerListener(mClientToken, mContainer, TEST_UID,
mController.registerWindowContainerListener(mWpc, mClientToken, mContainer, TEST_UID,
TYPE_APPLICATION_OVERLAY, null /* options */);
mController.assertCallerCanModifyListener(mClientToken,
@@ -198,7 +203,7 @@ public class WindowContextListenerControllerTests extends WindowTestsBase {
.build();
final DisplayArea<?> da = windowContextCreatedToken.getDisplayArea();
mController.registerWindowContainerListener(mClientToken, windowContextCreatedToken,
mController.registerWindowContainerListener(mWpc, mClientToken, windowContextCreatedToken,
TEST_UID, TYPE_ACCESSIBILITY_MAGNIFICATION_OVERLAY, null /* options */);
assertThat(mController.getContainer(mClientToken)).isEqualTo(windowContextCreatedToken);
@@ -233,7 +238,7 @@ public class WindowContextListenerControllerTests extends WindowTestsBase {
.setDisplayContent(dualDisplayContent)
.setFromClientToken(true)
.build();
mController.registerWindowContainerListener(mClientToken, windowContextCreatedToken,
mController.registerWindowContainerListener(mWpc, mClientToken, windowContextCreatedToken,
TEST_UID, TYPE_INPUT_METHOD_DIALOG, null /* options */);
assertThat(mController.getContainer(mClientToken)).isEqualTo(windowContextCreatedToken);
@@ -258,7 +263,7 @@ public class WindowContextListenerControllerTests extends WindowTestsBase {
config1.densityDpi = 100;
mContainer.onRequestedOverrideConfigurationChanged(config1);
mController.registerWindowContainerListener(mockToken, mContainer, -1,
mController.registerWindowContainerListener(mWpc, mockToken, mContainer, -1,
TYPE_APPLICATION_OVERLAY, null /* options */);
verify(mockToken, never()).onConfigurationChanged(any(), anyInt());
@@ -293,7 +298,7 @@ public class WindowContextListenerControllerTests extends WindowTestsBase {
config1.densityDpi = 100;
mContainer.onRequestedOverrideConfigurationChanged(config1);
mController.registerWindowContainerListener(clientToken, mContainer, -1,
mController.registerWindowContainerListener(mWpc, clientToken, mContainer, -1,
TYPE_APPLICATION_OVERLAY, options);
assertThat(clientToken.mConfiguration).isEqualTo(config1);

View File

@@ -473,7 +473,7 @@ public class WindowManagerServiceTests extends WindowTestsBase {
mWm.attachWindowContextToWindowToken(mAppThread, new Binder(), windowToken.token);
verify(mWm.mWindowContextListenerController, never()).registerWindowContainerListener(
any(), any(), anyInt(), anyInt(), any());
any(), any(), any(), anyInt(), anyInt(), any());
}
@Test
@@ -488,8 +488,8 @@ public class WindowManagerServiceTests extends WindowTestsBase {
final IBinder clientToken = new Binder();
mWm.attachWindowContextToWindowToken(mAppThread, clientToken, windowToken.token);
verify(mWm.mWindowContextListenerController).registerWindowContainerListener(
final WindowProcessController wpc = mAtm.getProcessController(mAppThread);
verify(mWm.mWindowContextListenerController).registerWindowContainerListener(eq(wpc),
eq(clientToken), eq(windowToken), anyInt(), eq(TYPE_INPUT_METHOD),
eq(windowToken.mOptions));
}
@@ -519,7 +519,7 @@ public class WindowManagerServiceTests extends WindowTestsBase {
new InsetsSourceControl.Array(), new Rect(), new float[1]);
verify(mWm.mWindowContextListenerController, never()).registerWindowContainerListener(any(),
any(), anyInt(), anyInt(), any());
any(), any(), anyInt(), anyInt(), any());
}
@Test