Merge "[RESTRICT AUTOMERGE] Send DA's config directly when attaching to DA" into sc-qpr1-dev

This commit is contained in:
Charles Chen
2021-09-15 13:29:40 +00:00
committed by Android (Google) Code Review
8 changed files with 54 additions and 26 deletions

View File

@@ -2721,10 +2721,13 @@ class ContextImpl extends Context {
// need to override their display in ResourcesManager.
baseContext.mForceDisplayOverrideInResources = false;
baseContext.mContextType = CONTEXT_TYPE_WINDOW_CONTEXT;
baseContext.mDisplay = display;
final Resources windowContextResources = createWindowContextResources(baseContext);
baseContext.setResources(windowContextResources);
// Associate the display with window context resources so that configuration update from
// the server side will also apply to the display's metrics.
baseContext.mDisplay = ResourcesManager.getInstance()
.getAdjustedDisplay(display.getDisplayId(), windowContextResources);
return baseContext;
}

View File

@@ -814,9 +814,10 @@ interface IWindowManager
* @param displayId The display associated with the window context
* @param options A bundle used to pass window-related options and choose the right DisplayArea
*
* @return {@code true} if the WindowContext is attached to the DisplayArea successfully.
* @return the DisplayArea's {@link android.app.res.Configuration} if the WindowContext is
* attached to the DisplayArea successfully. {@code null}, otherwise.
*/
boolean attachWindowContextToDisplayArea(IBinder clientToken, int type, int displayId,
Configuration attachWindowContextToDisplayArea(IBinder clientToken, int type, int displayId,
in Bundle options);
/**

View File

@@ -26,7 +26,6 @@ import android.content.Context;
import android.content.ContextWrapper;
import android.content.res.Configuration;
import android.os.Bundle;
import android.os.IBinder;
import android.view.WindowManager;
import com.android.internal.annotations.VisibleForTesting;
@@ -67,7 +66,7 @@ public class WindowContext extends ContextWrapper {
mType = type;
mOptions = options;
mWindowManager = createWindowContextWindowManager(this);
IBinder token = getWindowContextToken();
WindowTokenClient token = (WindowTokenClient) getWindowContextToken();
mController = new WindowContextController(token);
Reference.reachabilityFence(this);

View File

@@ -19,6 +19,7 @@ package android.window;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.content.Context;
import android.content.res.Configuration;
import android.os.Bundle;
import android.os.IBinder;
import android.os.RemoteException;
@@ -46,7 +47,7 @@ public class WindowContextController {
@VisibleForTesting
public boolean mAttachedToDisplayArea;
@NonNull
private final IBinder mToken;
private final WindowTokenClient mToken;
/**
* Window Context Controller constructor
@@ -54,14 +55,13 @@ public class WindowContextController {
* @param token The token used to attach to a window manager node. It is usually from
* {@link Context#getWindowContextToken()}.
*/
public WindowContextController(@NonNull IBinder token) {
mToken = token;
mWms = WindowManagerGlobal.getWindowManagerService();
public WindowContextController(@NonNull WindowTokenClient token) {
this(token, WindowManagerGlobal.getWindowManagerService());
}
/** Used for test only. DO NOT USE it in production code. */
@VisibleForTesting
public WindowContextController(@NonNull IBinder token, IWindowManager mockWms) {
public WindowContextController(@NonNull WindowTokenClient token, IWindowManager mockWms) {
mToken = token;
mWms = mockWms;
}
@@ -81,8 +81,14 @@ public class WindowContextController {
+ "a DisplayArea once.");
}
try {
mAttachedToDisplayArea = mWms.attachWindowContextToDisplayArea(mToken, type, displayId,
options);
final Configuration configuration = mWms.attachWindowContextToDisplayArea(mToken, type,
displayId, options);
if (configuration != null) {
mAttachedToDisplayArea = true;
// Send the DisplayArea's configuration to WindowContext directly instead of
// waiting for dispatching from WMS.
mToken.onConfigurationChanged(configuration, displayId);
}
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}

View File

@@ -24,6 +24,8 @@ import android.content.res.Configuration;
import android.os.Bundle;
import android.os.IBinder;
import com.android.internal.annotations.VisibleForTesting;
import java.lang.ref.WeakReference;
/**
@@ -33,7 +35,7 @@ import java.lang.ref.WeakReference;
* {@link Context#getWindowContextToken() the token of non-Activity UI Contexts}.
*
* @see WindowContext
* @see android.view.IWindowManager#registerWindowContextListener(IBinder, int, int, Bundle)
* @see android.view.IWindowManager#attachWindowContextToDisplayArea(IBinder, int, int, Bundle)
*
* @hide
*/
@@ -50,8 +52,8 @@ public class WindowTokenClient extends IWindowToken.Stub {
* Attaches {@code context} to this {@link WindowTokenClient}. Each {@link WindowTokenClient}
* can only attach one {@link Context}.
* <p>This method must be called before invoking
* {@link android.view.IWindowManager#registerWindowContextListener(IBinder, int, int,
* Bundle, boolean)}.<p/>
* {@link android.view.IWindowManager#attachWindowContextToDisplayArea(IBinder, int, int,
* Bundle)}.<p/>
*
* @param context context to be attached
* @throws IllegalStateException if attached context has already existed.
@@ -63,6 +65,13 @@ public class WindowTokenClient extends IWindowToken.Stub {
mContextRef = new WeakReference<>(context);
}
/**
* Called when {@link Configuration} updates from the server side receive.
*
* @param newConfig the updated {@link Configuration}
* @param newDisplayId the updated {@link android.view.Display} ID
*/
@VisibleForTesting
@Override
public void onConfigurationChanged(Configuration newConfig, int newDisplayId) {
final Context context = mContextRef.get();

View File

@@ -23,11 +23,13 @@ import static com.google.common.truth.Truth.assertThat;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.doNothing;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.verify;
import android.content.res.Configuration;
import android.os.Binder;
import android.platform.test.annotations.Presubmit;
import android.view.IWindowManager;
@@ -38,6 +40,8 @@ import androidx.test.runner.AndroidJUnit4;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
/**
* Tests for {@link WindowContextController}
@@ -53,15 +57,18 @@ import org.junit.runner.RunWith;
@Presubmit
public class WindowContextControllerTest {
private WindowContextController mController;
@Mock
private IWindowManager mMockWms;
@Mock
private WindowTokenClient mMockToken;
@Before
public void setUp() throws Exception {
mMockWms = mock(IWindowManager.class);
mController = new WindowContextController(new Binder(), mMockWms);
doReturn(true).when(mMockWms).attachWindowContextToDisplayArea(any(), anyInt(),
anyInt(), any());
MockitoAnnotations.initMocks(this);
mController = new WindowContextController(mMockToken, mMockWms);
doNothing().when(mMockToken).onConfigurationChanged(any(), anyInt());
doReturn(new Configuration()).when(mMockWms).attachWindowContextToDisplayArea(any(),
anyInt(), anyInt(), any());
}
@Test(expected = IllegalStateException.class)
@@ -85,6 +92,7 @@ public class WindowContextControllerTest {
null /* options */);
assertThat(mController.mAttachedToDisplayArea).isTrue();
verify(mMockToken).onConfigurationChanged(any(), eq(DEFAULT_DISPLAY));
mController.detachIfNeeded();

View File

@@ -2717,8 +2717,8 @@ public class WindowManagerService extends IWindowManager.Stub
}
@Override
public boolean attachWindowContextToDisplayArea(IBinder clientToken, int type, int displayId,
Bundle options) {
public Configuration attachWindowContextToDisplayArea(IBinder clientToken, int
type, int displayId, Bundle options) {
final boolean callerCanManageAppTokens = checkCallingPermission(MANAGE_APP_TOKENS,
"attachWindowContextToDisplayArea", false /* printLog */);
final int callingUid = Binder.getCallingUid();
@@ -2729,15 +2729,17 @@ public class WindowManagerService extends IWindowManager.Stub
if (dc == null) {
ProtoLog.w(WM_ERROR, "attachWindowContextToDisplayArea: trying to attach"
+ " to a non-existing display:%d", displayId);
return false;
return null;
}
// TODO(b/155340867): Investigate if we still need roundedCornerOverlay after
// the feature b/155340867 is completed.
final DisplayArea da = dc.findAreaForWindowType(type, options,
callerCanManageAppTokens, false /* roundedCornerOverlay */);
// TODO(b/190019118): Avoid to send onConfigurationChanged because it has been done
// in return value of attachWindowContextToDisplayArea.
mWindowContextListenerController.registerWindowContainerListener(clientToken, da,
callingUid, type, options);
return true;
return da.getConfiguration();
}
} finally {
Binder.restoreCallingIdentity(origId);

View File

@@ -82,7 +82,7 @@ public class InputMethodMenuControllerTest extends WindowTestsBase {
mWm.mWindowContextListenerController.registerWindowContainerListener(clientToken,
dc.getImeContainer(), 1000 /* ownerUid */, TYPE_INPUT_METHOD_DIALOG,
null /* options */);
return true;
return dc.getImeContainer().getConfiguration();
}).when(wms).attachWindowContextToDisplayArea(any(), eq(TYPE_INPUT_METHOD_DIALOG),
anyInt(), any());