Migrate WindowContext#onConfigurationChanged to ClientTransaction (4/n)

Update WMS#attachWindowContextTo* function signature:
1. Be consistent on the naming.
2. Take an IApplicationThread as part of the migration.

Bug: 290876897
Test: Renaming. Pass existing tests.
Change-Id: I23a41d699ec9bca0f42e92c0a5f39409d062e9c4
This commit is contained in:
Chris Li
2023-07-18 14:27:20 +08:00
parent 4367c8ed8c
commit 9c8e645d05
9 changed files with 117 additions and 87 deletions

View File

@@ -21,6 +21,8 @@ import static android.view.WindowManagerGlobal.getWindowManagerService;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.app.ActivityThread;
import android.app.IApplicationThread;
import android.content.Context;
import android.content.res.Configuration;
import android.os.Bundle;
@@ -46,6 +48,8 @@ public class WindowTokenClientController {
private static WindowTokenClientController sController;
private final Object mLock = new Object();
private final IApplicationThread mAppThread = ActivityThread.currentActivityThread()
.getApplicationThread();
/** Mapping from a client defined token to the {@link WindowTokenClient} it represents. */
@GuardedBy("mLock")
@@ -84,8 +88,8 @@ public class WindowTokenClientController {
@WindowType int type, int displayId, @Nullable Bundle options) {
final Configuration configuration;
try {
configuration = getWindowManagerService()
.attachWindowContextToDisplayArea(client, type, displayId, options);
configuration = getWindowManagerService().attachWindowContextToDisplayArea(
mAppThread, client, type, displayId, options);
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
@@ -111,7 +115,7 @@ public class WindowTokenClientController {
}
final Configuration configuration;
try {
configuration = wms.attachToDisplayContent(client, displayId);
configuration = wms.attachWindowContextToDisplayContent(mAppThread, client, displayId);
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
@@ -131,7 +135,8 @@ public class WindowTokenClientController {
public void attachToWindowToken(@NonNull WindowTokenClient client,
@NonNull IBinder windowToken) {
try {
getWindowManagerService().attachWindowContextToWindowToken(client, windowToken);
getWindowManagerService().attachWindowContextToWindowToken(
mAppThread, client, windowToken);
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
@@ -149,7 +154,7 @@ public class WindowTokenClientController {
}
}
try {
getWindowManagerService().detachWindowContextFromWindowContainer(client);
getWindowManagerService().detachWindowContext(client);
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}

View File

@@ -21,6 +21,7 @@ import com.android.internal.policy.IKeyguardDismissCallback;
import com.android.internal.policy.IKeyguardLockedStateListener;
import com.android.internal.policy.IShortcutService;
import android.app.IApplicationThread;
import android.app.IAssistDataReceiver;
import android.content.ComponentName;
import android.content.res.CompatibilityInfo;
@@ -850,6 +851,7 @@ interface IWindowManager
* system server. {@link #attachWindowContextToWindowToken(IBinder, IBinder)} could be used in
* this case to attach the WindowContext to the WindowToken.</p>
*
* @param appThread the process that the window context is on.
* @param clientToken {@link android.window.WindowContext#getWindowContextToken()
* the WindowContext's token}
* @param type Window type of the window context
@@ -859,8 +861,8 @@ interface IWindowManager
* @return the DisplayArea's {@link android.app.res.Configuration} if the WindowContext is
* attached to the DisplayArea successfully. {@code null}, otherwise.
*/
Configuration attachWindowContextToDisplayArea(IBinder clientToken, int type, int displayId,
in Bundle options);
@nullable Configuration attachWindowContextToDisplayArea(in IApplicationThread appThread,
IBinder clientToken, int type, int displayId, in @nullable Bundle options);
/**
* Attaches a {@link android.window.WindowContext} to a {@code WindowToken}.
@@ -872,6 +874,7 @@ interface IWindowManager
* {@link android.window.WindowTokenClient#attachContext(Context)}
* </p>
*
* @param appThread the process that the window context is on.
* @param clientToken {@link android.window.WindowContext#getWindowContextToken()
* the WindowContext's token}
* @param token the WindowToken to attach
@@ -881,7 +884,8 @@ interface IWindowManager
*
* @see #attachWindowContextToDisplayArea(IBinder, int, int, Bundle)
*/
void attachWindowContextToWindowToken(IBinder clientToken, IBinder token);
void attachWindowContextToWindowToken(in IApplicationThread appThread, IBinder clientToken,
IBinder token);
/**
* Attaches a {@code clientToken} to associate with DisplayContent.
@@ -890,6 +894,7 @@ interface IWindowManager
* {@link android.window.WindowTokenClient#attachContext(Context)}
* </p>
*
* @param appThread the process that the window context is on.
* @param clientToken {@link android.window.WindowContext#getWindowContextToken()
* the WindowContext's token}
* @param displayId The display associated with the window context
@@ -898,7 +903,8 @@ interface IWindowManager
* attached to the DisplayContent successfully. {@code null}, otherwise.
* @throws android.view.WindowManager.InvalidDisplayException if the display ID is invalid
*/
Configuration attachToDisplayContent(IBinder clientToken, int displayId);
@nullable Configuration attachWindowContextToDisplayContent(in IApplicationThread appThread,
IBinder clientToken, int displayId);
/**
* Detaches {@link android.window.WindowContext} from the window manager node it's currently
@@ -906,7 +912,7 @@ interface IWindowManager
*
* @param clientToken the window context's token
*/
void detachWindowContextFromWindowContainer(IBinder clientToken);
void detachWindowContext(IBinder clientToken);
/**
* Registers a listener, which is to be called whenever cross-window blur is enabled/disabled.

View File

@@ -135,7 +135,7 @@ public class WindowContextController {
* {@link #attachToDisplayArea(int, int, Bundle)}.
*
* @see WindowProviderService#attachToWindowToken(IBinder))
* @see IWindowManager#attachWindowContextToWindowToken(IBinder, IBinder)
* @see IWindowManager#attachWindowContextToWindowToken
*/
public void attachToWindowToken(IBinder windowToken) {
if (mAttachedToDisplayArea != AttachStatus.STATUS_ATTACHED) {

View File

@@ -49,7 +49,7 @@ import java.lang.ref.WeakReference;
* {@link Context#getWindowContextToken() the token of non-Activity UI Contexts}.
*
* @see WindowContext
* @see android.view.IWindowManager#attachWindowContextToDisplayArea(IBinder, int, int, Bundle)
* @see android.view.IWindowManager#attachWindowContextToDisplayArea
*
* @hide
*/

View File

@@ -29,6 +29,7 @@ import static org.mockito.Mockito.verify;
import static org.testng.Assert.assertFalse;
import static org.testng.Assert.assertTrue;
import android.app.ActivityThread;
import android.content.res.Configuration;
import android.os.IBinder;
import android.os.RemoteException;
@@ -87,16 +88,17 @@ public class WindowTokenClientControllerTest {
@Test
public void testAttachToDisplayArea() throws RemoteException {
doReturn(null).when(mWindowManagerService).attachWindowContextToDisplayArea(
any(), anyInt(), anyInt(), any());
any(), any(), anyInt(), anyInt(), any());
assertFalse(mController.attachToDisplayArea(mWindowTokenClient, TYPE_APPLICATION_OVERLAY,
DEFAULT_DISPLAY, null /* options */));
verify(mWindowManagerService).attachWindowContextToDisplayArea(mWindowTokenClient,
verify(mWindowManagerService).attachWindowContextToDisplayArea(
ActivityThread.currentActivityThread().getApplicationThread(), mWindowTokenClient,
TYPE_APPLICATION_OVERLAY, DEFAULT_DISPLAY, null /* options */);
verify(mWindowTokenClient, never()).onConfigurationChanged(any(), anyInt(), anyBoolean());
doReturn(mConfiguration).when(mWindowManagerService).attachWindowContextToDisplayArea(
any(), anyInt(), anyInt(), any());
any(), any(), anyInt(), anyInt(), any());
assertTrue(mController.attachToDisplayArea(mWindowTokenClient, TYPE_APPLICATION_OVERLAY,
DEFAULT_DISPLAY, null /* options */));
@@ -108,36 +110,38 @@ public class WindowTokenClientControllerTest {
public void testAttachToDisplayArea_detachIfNeeded() throws RemoteException {
mController.detachIfNeeded(mWindowTokenClient);
verify(mWindowManagerService, never()).detachWindowContextFromWindowContainer(any());
verify(mWindowManagerService, never()).detachWindowContext(any());
doReturn(null).when(mWindowManagerService).attachWindowContextToDisplayArea(
any(), anyInt(), anyInt(), any());
any(), any(), anyInt(), anyInt(), any());
mController.attachToDisplayArea(mWindowTokenClient, TYPE_APPLICATION_OVERLAY,
DEFAULT_DISPLAY, null /* options */);
mController.detachIfNeeded(mWindowTokenClient);
verify(mWindowManagerService, never()).detachWindowContextFromWindowContainer(any());
verify(mWindowManagerService, never()).detachWindowContext(any());
doReturn(mConfiguration).when(mWindowManagerService).attachWindowContextToDisplayArea(
any(), anyInt(), anyInt(), any());
any(), any(), anyInt(), anyInt(), any());
mController.attachToDisplayArea(mWindowTokenClient, TYPE_APPLICATION_OVERLAY,
DEFAULT_DISPLAY, null /* options */);
mController.detachIfNeeded(mWindowTokenClient);
verify(mWindowManagerService).detachWindowContextFromWindowContainer(any());
verify(mWindowManagerService).detachWindowContext(any());
}
@Test
public void testAttachToDisplayContent() throws RemoteException {
doReturn(null).when(mWindowManagerService).attachToDisplayContent(
any(), anyInt());
doReturn(null).when(mWindowManagerService).attachWindowContextToDisplayContent(
any(), any(), anyInt());
assertFalse(mController.attachToDisplayContent(mWindowTokenClient, DEFAULT_DISPLAY));
verify(mWindowManagerService).attachToDisplayContent(mWindowTokenClient, DEFAULT_DISPLAY);
verify(mWindowManagerService).attachWindowContextToDisplayContent(
ActivityThread.currentActivityThread().getApplicationThread(), mWindowTokenClient,
DEFAULT_DISPLAY);
verify(mWindowTokenClient, never()).onConfigurationChanged(any(), anyInt(), anyBoolean());
doReturn(mConfiguration).when(mWindowManagerService).attachToDisplayContent(
any(), anyInt());
doReturn(mConfiguration).when(mWindowManagerService).attachWindowContextToDisplayContent(
any(), any(), anyInt());
assertTrue(mController.attachToDisplayContent(mWindowTokenClient, DEFAULT_DISPLAY));
verify(mWindowTokenClient).onConfigurationChanged(mConfiguration, DEFAULT_DISPLAY,
@@ -148,28 +152,29 @@ public class WindowTokenClientControllerTest {
public void testAttachToDisplayContent_detachIfNeeded() throws RemoteException {
mController.detachIfNeeded(mWindowTokenClient);
verify(mWindowManagerService, never()).detachWindowContextFromWindowContainer(any());
verify(mWindowManagerService, never()).detachWindowContext(any());
doReturn(null).when(mWindowManagerService).attachToDisplayContent(
any(), anyInt());
doReturn(null).when(mWindowManagerService).attachWindowContextToDisplayContent(
any(), any(), anyInt());
mController.attachToDisplayContent(mWindowTokenClient, DEFAULT_DISPLAY);
mController.detachIfNeeded(mWindowTokenClient);
verify(mWindowManagerService, never()).detachWindowContextFromWindowContainer(any());
verify(mWindowManagerService, never()).detachWindowContext(any());
doReturn(mConfiguration).when(mWindowManagerService).attachToDisplayContent(
any(), anyInt());
doReturn(mConfiguration).when(mWindowManagerService).attachWindowContextToDisplayContent(
any(), any(), anyInt());
mController.attachToDisplayContent(mWindowTokenClient, DEFAULT_DISPLAY);
mController.detachIfNeeded(mWindowTokenClient);
verify(mWindowManagerService).detachWindowContextFromWindowContainer(any());
verify(mWindowManagerService).detachWindowContext(any());
}
@Test
public void testAttachToWindowToken() throws RemoteException {
mController.attachToWindowToken(mWindowTokenClient, mWindowToken);
verify(mWindowManagerService).attachWindowContextToWindowToken(mWindowTokenClient,
verify(mWindowManagerService).attachWindowContextToWindowToken(
ActivityThread.currentActivityThread().getApplicationThread(), mWindowTokenClient,
mWindowToken);
}
@@ -177,12 +182,12 @@ public class WindowTokenClientControllerTest {
public void testAttachToWindowToken_detachIfNeeded() throws RemoteException {
mController.detachIfNeeded(mWindowTokenClient);
verify(mWindowManagerService, never()).detachWindowContextFromWindowContainer(any());
verify(mWindowManagerService, never()).detachWindowContext(any());
mController.attachToWindowToken(mWindowTokenClient, mWindowToken);
mController.detachIfNeeded(mWindowTokenClient);
verify(mWindowManagerService).detachWindowContextFromWindowContainer(any());
verify(mWindowManagerService).detachWindowContext(any());
}
@Test

View File

@@ -47,7 +47,7 @@ import java.util.Objects;
*
* <ul>
* <li>When a {@link WindowContext} is created, it registers the listener via
* {@link WindowManagerService#attachWindowContextToDisplayArea(IBinder, int, int, Bundle)}
* {@link WindowManagerService#attachWindowContextToDisplayArea
* automatically.</li>
* <li>When the {@link WindowContext} adds the first window to the screen via
* {@link android.view.WindowManager#addView(View, android.view.ViewGroup.LayoutParams)},
@@ -55,7 +55,7 @@ import java.util.Objects;
* to corresponding {@link WindowToken} via this controller.</li>
* <li>When the {@link WindowContext} is GCed, it unregisters the previously
* registered listener via
* {@link WindowManagerService#detachWindowContextFromWindowContainer(IBinder)}.
* {@link WindowManagerService#detachWindowContext(IBinder)}.
* {@link WindowManagerService} is also responsible for removing the
* {@link WindowContext} created {@link WindowToken}.</li>
* </ul>

View File

@@ -167,6 +167,7 @@ import android.app.ActivityManagerInternal;
import android.app.ActivityThread;
import android.app.AppOpsManager;
import android.app.IActivityManager;
import android.app.IApplicationThread;
import android.app.IAssistDataReceiver;
import android.app.WindowConfiguration;
import android.content.BroadcastReceiver;
@@ -2734,12 +2735,13 @@ public class WindowManagerService extends IWindowManager.Stub
}
}
@Nullable
@Override
public Configuration attachWindowContextToDisplayArea(IBinder clientToken, int
type, int displayId, Bundle options) {
if (clientToken == null) {
throw new IllegalArgumentException("clientToken must not be null!");
}
public Configuration attachWindowContextToDisplayArea(@NonNull IApplicationThread appThread,
@NonNull IBinder clientToken, @LayoutParams.WindowType int type, int displayId,
@Nullable Bundle options) {
Objects.requireNonNull(appThread);
Objects.requireNonNull(clientToken);
final boolean callerCanManageAppTokens = checkCallingPermission(MANAGE_APP_TOKENS,
"attachWindowContextToDisplayArea", false /* printLog */);
final int callingUid = Binder.getCallingUid();
@@ -2765,8 +2767,48 @@ public class WindowManagerService extends IWindowManager.Stub
}
}
@Nullable
@Override
public void attachWindowContextToWindowToken(IBinder clientToken, IBinder token) {
public Configuration attachWindowContextToDisplayContent(@NonNull IApplicationThread appThread,
@NonNull IBinder clientToken, int displayId) {
Objects.requireNonNull(appThread);
Objects.requireNonNull(clientToken);
final int callingUid = Binder.getCallingUid();
final long origId = Binder.clearCallingIdentity();
try {
synchronized (mGlobalLock) {
// 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
// registration in DisplayContent#onParentChanged at DisplayContent initialization.
final DisplayContent dc = mRoot.getDisplayContent(displayId);
if (dc == null) {
if (Binder.getCallingPid() != MY_PID) {
throw new WindowManager.InvalidDisplayException(
"attachWindowContextToDisplayContent: trying to attach to a"
+ " non-existing display:" + displayId);
}
// Early return if this method is invoked from system process.
// See above comments for more detail.
return null;
}
mWindowContextListenerController.registerWindowContainerListener(clientToken, dc,
callingUid, INVALID_WINDOW_TYPE, null /* options */,
false /* shouDispatchConfigWhenRegistering */);
return dc.getConfiguration();
}
} finally {
Binder.restoreCallingIdentity(origId);
}
}
@Override
public void attachWindowContextToWindowToken(@NonNull IApplicationThread appThread,
@NonNull IBinder clientToken, @NonNull IBinder token) {
Objects.requireNonNull(appThread);
Objects.requireNonNull(clientToken);
Objects.requireNonNull(token);
final boolean callerCanManageAppTokens = checkCallingPermission(MANAGE_APP_TOKENS,
"attachWindowContextToWindowToken", false /* printLog */);
final int callingUid = Binder.getCallingUid();
@@ -2802,9 +2844,10 @@ public class WindowManagerService extends IWindowManager.Stub
}
@Override
public void detachWindowContextFromWindowContainer(IBinder clientToken) {
public void detachWindowContext(@NonNull IBinder clientToken) {
Objects.requireNonNull(clientToken);
final boolean callerCanManageAppTokens = checkCallingPermission(MANAGE_APP_TOKENS,
"detachWindowContextFromWindowContainer", false /* printLog */);
"detachWindowContext", false /* printLog */);
final int callingUid = Binder.getCallingUid();
final long origId = Binder.clearCallingIdentity();
try {
@@ -2828,40 +2871,6 @@ public class WindowManagerService extends IWindowManager.Stub
}
}
@Override
public Configuration attachToDisplayContent(IBinder clientToken, int displayId) {
if (clientToken == null) {
throw new IllegalArgumentException("clientToken must not be null!");
}
final int callingUid = Binder.getCallingUid();
final long origId = Binder.clearCallingIdentity();
try {
synchronized (mGlobalLock) {
// 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
// registration in DisplayContent#onParentChanged at DisplayContent initialization.
final DisplayContent dc = mRoot.getDisplayContent(displayId);
if (dc == null) {
if (Binder.getCallingPid() != MY_PID) {
throw new WindowManager.InvalidDisplayException("attachToDisplayContent: "
+ "trying to attach to a non-existing display:" + displayId);
}
// Early return if this method is invoked from system process.
// See above comments for more detail.
return null;
}
mWindowContextListenerController.registerWindowContainerListener(clientToken, dc,
callingUid, INVALID_WINDOW_TYPE, null /* options */,
false /* shouDispatchConfigWhenRegistering */);
return dc.getConfiguration();
}
} finally {
Binder.restoreCallingIdentity(origId);
}
}
/** Returns {@code true} if this binder is a registered window token. */
@Override
public boolean isWindowToken(IBinder binder) {

View File

@@ -91,14 +91,14 @@ public class InputMethodDialogWindowContextTest extends WindowTestsBase {
spyOn(mIWindowManager);
doAnswer(invocation -> {
Object[] args = invocation.getArguments();
IBinder clientToken = (IBinder) args[0];
int displayId = (int) args[2];
IBinder clientToken = (IBinder) args[1];
int displayId = (int) args[3];
DisplayContent dc = mWm.mRoot.getDisplayContent(displayId);
mWm.mWindowContextListenerController.registerWindowContainerListener(clientToken,
dc.getImeContainer(), 1000 /* ownerUid */, TYPE_INPUT_METHOD_DIALOG,
null /* options */);
return dc.getImeContainer().getConfiguration();
}).when(mIWindowManager).attachWindowContextToDisplayArea(any(),
}).when(mIWindowManager).attachWindowContextToDisplayArea(any(), any(),
eq(TYPE_INPUT_METHOD_DIALOG), anyInt(), any());
mDisplayManagerGlobal = DisplayManagerGlobal.getInstance();
spyOn(mDisplayManagerGlobal);

View File

@@ -68,6 +68,8 @@ import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import android.app.ActivityThread;
import android.app.IApplicationThread;
import android.content.pm.ActivityInfo;
import android.graphics.Point;
import android.graphics.Rect;
@@ -119,6 +121,9 @@ import org.mockito.ArgumentCaptor;
@RunWith(WindowTestRunner.class)
public class WindowManagerServiceTests extends WindowTestsBase {
private final IApplicationThread mAppThread = ActivityThread.currentActivityThread()
.getApplicationThread();
@Rule
public AdoptShellPermissionsRule mAdoptShellPermissionsRule = new AdoptShellPermissionsRule(
InstrumentationRegistry.getInstrumentation().getUiAutomation(),
@@ -428,7 +433,7 @@ public class WindowManagerServiceTests extends WindowTestsBase {
public void testAttachWindowContextToWindowToken_InvalidToken_EarlyReturn() {
spyOn(mWm.mWindowContextListenerController);
mWm.attachWindowContextToWindowToken(new Binder(), new Binder());
mWm.attachWindowContextToWindowToken(mAppThread, new Binder(), new Binder());
verify(mWm.mWindowContextListenerController, never()).getWindowType(any());
}
@@ -441,7 +446,7 @@ public class WindowManagerServiceTests extends WindowTestsBase {
doReturn(INVALID_WINDOW_TYPE).when(mWm.mWindowContextListenerController)
.getWindowType(any());
mWm.attachWindowContextToWindowToken(new Binder(), windowToken.token);
mWm.attachWindowContextToWindowToken(mAppThread, new Binder(), windowToken.token);
}
@Test(expected = IllegalArgumentException.class)
@@ -452,7 +457,7 @@ public class WindowManagerServiceTests extends WindowTestsBase {
doReturn(TYPE_APPLICATION).when(mWm.mWindowContextListenerController)
.getWindowType(any());
mWm.attachWindowContextToWindowToken(new Binder(), windowToken.token);
mWm.attachWindowContextToWindowToken(mAppThread, new Binder(), windowToken.token);
}
@Test
@@ -465,7 +470,7 @@ public class WindowManagerServiceTests extends WindowTestsBase {
doReturn(false).when(mWm.mWindowContextListenerController)
.assertCallerCanModifyListener(any(), anyBoolean(), anyInt());
mWm.attachWindowContextToWindowToken(new Binder(), windowToken.token);
mWm.attachWindowContextToWindowToken(mAppThread, new Binder(), windowToken.token);
verify(mWm.mWindowContextListenerController, never()).registerWindowContainerListener(
any(), any(), anyInt(), anyInt(), any());
@@ -482,7 +487,7 @@ public class WindowManagerServiceTests extends WindowTestsBase {
.assertCallerCanModifyListener(any(), anyBoolean(), anyInt());
final IBinder clientToken = new Binder();
mWm.attachWindowContextToWindowToken(clientToken, windowToken.token);
mWm.attachWindowContextToWindowToken(mAppThread, clientToken, windowToken.token);
verify(mWm.mWindowContextListenerController).registerWindowContainerListener(
eq(clientToken), eq(windowToken), anyInt(), eq(TYPE_INPUT_METHOD),