Merge "Introduce WindowContextController" into sc-dev
This commit is contained in:
@@ -27,10 +27,7 @@ import android.content.ContextWrapper;
|
||||
import android.content.res.Configuration;
|
||||
import android.os.Bundle;
|
||||
import android.os.IBinder;
|
||||
import android.os.RemoteException;
|
||||
import android.view.IWindowManager;
|
||||
import android.view.WindowManager;
|
||||
import android.view.WindowManagerGlobal;
|
||||
|
||||
import com.android.internal.annotations.VisibleForTesting;
|
||||
|
||||
@@ -48,13 +45,11 @@ import java.lang.ref.Reference;
|
||||
@UiContext
|
||||
public class WindowContext extends ContextWrapper {
|
||||
private final WindowManager mWindowManager;
|
||||
private final IWindowManager mWms;
|
||||
private final @NonNull IBinder mToken;
|
||||
private final @WindowManager.LayoutParams.WindowType int mType;
|
||||
private final @Nullable Bundle mOptions;
|
||||
private boolean mListenerRegistered;
|
||||
private final ComponentCallbacksController mCallbacksController =
|
||||
new ComponentCallbacksController();
|
||||
private final WindowContextController mController;
|
||||
|
||||
/**
|
||||
* Default constructor. Will generate a {@link WindowTokenClient} and attach this context to
|
||||
@@ -69,9 +64,9 @@ public class WindowContext extends ContextWrapper {
|
||||
|
||||
mType = type;
|
||||
mOptions = options;
|
||||
mWms = WindowManagerGlobal.getWindowManagerService();
|
||||
mToken = getWindowContextToken();
|
||||
mWindowManager = createWindowContextWindowManager(this);
|
||||
IBinder token = getWindowContextToken();
|
||||
mController = new WindowContextController(token);
|
||||
|
||||
Reference.reachabilityFence(this);
|
||||
}
|
||||
@@ -81,12 +76,7 @@ public class WindowContext extends ContextWrapper {
|
||||
* to receive configuration changes of the associated {@link WindowManager} node.
|
||||
*/
|
||||
public void registerWithServer() {
|
||||
try {
|
||||
mListenerRegistered = mWms.registerWindowContextListener(mToken, mType, getDisplayId(),
|
||||
mOptions);
|
||||
} catch (RemoteException e) {
|
||||
throw e.rethrowFromSystemServer();
|
||||
}
|
||||
mController.registerListener(mType, getDisplayId(), mOptions);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -106,14 +96,7 @@ public class WindowContext extends ContextWrapper {
|
||||
/** Used for test to invoke because we can't invoke finalize directly. */
|
||||
@VisibleForTesting
|
||||
public void release() {
|
||||
if (mListenerRegistered) {
|
||||
mListenerRegistered = false;
|
||||
try {
|
||||
mWms.unregisterWindowContextListener(mToken);
|
||||
} catch (RemoteException e) {
|
||||
throw e.rethrowFromSystemServer();
|
||||
}
|
||||
}
|
||||
mController.unregisterListenerIfNeeded();
|
||||
destroy();
|
||||
}
|
||||
|
||||
|
||||
96
core/java/android/window/WindowContextController.java
Normal file
96
core/java/android/window/WindowContextController.java
Normal file
@@ -0,0 +1,96 @@
|
||||
/*
|
||||
* Copyright (C) 2021 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 android.window;
|
||||
|
||||
import android.annotation.NonNull;
|
||||
import android.annotation.Nullable;
|
||||
import android.content.Context;
|
||||
import android.os.Bundle;
|
||||
import android.os.IBinder;
|
||||
import android.os.RemoteException;
|
||||
import android.view.IWindowManager;
|
||||
import android.view.WindowManager.LayoutParams.WindowType;
|
||||
import android.view.WindowManagerGlobal;
|
||||
|
||||
import com.android.internal.annotations.VisibleForTesting;
|
||||
|
||||
/**
|
||||
* The controller to manage {@link WindowContext} listener, such as registering and unregistering
|
||||
* the listener.
|
||||
*
|
||||
* @hide
|
||||
*/
|
||||
public class WindowContextController {
|
||||
private final IWindowManager mWms;
|
||||
@VisibleForTesting
|
||||
public boolean mListenerRegistered;
|
||||
@NonNull
|
||||
private final IBinder mToken;
|
||||
|
||||
/**
|
||||
* Window Context Controller constructor
|
||||
*
|
||||
* @param token The token to register to the window context listener. It is usually from
|
||||
* {@link Context#getWindowContextToken()}.
|
||||
*/
|
||||
public WindowContextController(@NonNull IBinder token) {
|
||||
mToken = token;
|
||||
mWms = WindowManagerGlobal.getWindowManagerService();
|
||||
}
|
||||
|
||||
/** Used for test only. DO NOT USE it in production code. */
|
||||
@VisibleForTesting
|
||||
public WindowContextController(@NonNull IBinder token, IWindowManager mockWms) {
|
||||
mToken = token;
|
||||
mWms = mockWms;
|
||||
}
|
||||
|
||||
/**
|
||||
* Registers the {@code mToken} to the window context listener.
|
||||
*
|
||||
* @param type The window type of the {@link WindowContext}
|
||||
* @param displayId The {@link Context#getDisplayId() ID of display} to associate with
|
||||
* @param options The window context launched option
|
||||
*/
|
||||
public void registerListener(@WindowType int type, int displayId, @Nullable Bundle options) {
|
||||
if (mListenerRegistered) {
|
||||
throw new UnsupportedOperationException("A Window Context can only register a listener"
|
||||
+ " once.");
|
||||
}
|
||||
try {
|
||||
mListenerRegistered = mWms.registerWindowContextListener(mToken, type, displayId,
|
||||
options);
|
||||
} catch (RemoteException e) {
|
||||
throw e.rethrowFromSystemServer();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Unregisters the window context listener associated with the {@code mToken} if it has been
|
||||
* registered.
|
||||
*/
|
||||
public void unregisterListenerIfNeeded() {
|
||||
if (mListenerRegistered) {
|
||||
try {
|
||||
mWms.unregisterWindowContextListener(mToken);
|
||||
mListenerRegistered = false;
|
||||
} catch (RemoteException e) {
|
||||
throw e.rethrowFromSystemServer();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,93 @@
|
||||
/*
|
||||
* Copyright (C) 2021 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 android.window;
|
||||
|
||||
import static android.view.Display.DEFAULT_DISPLAY;
|
||||
import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY;
|
||||
|
||||
import static com.google.common.truth.Truth.assertThat;
|
||||
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.ArgumentMatchers.anyInt;
|
||||
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.os.Binder;
|
||||
import android.platform.test.annotations.Presubmit;
|
||||
import android.view.IWindowManager;
|
||||
|
||||
import androidx.test.filters.SmallTest;
|
||||
import androidx.test.runner.AndroidJUnit4;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
|
||||
/**
|
||||
* Tests for {@link WindowContextController}
|
||||
*
|
||||
* <p>Build/Install/Run:
|
||||
* atest FrameworksCoreTests:WindowContextControllerTest
|
||||
*
|
||||
* <p>This test class is a part of Window Manager Service tests and specified in
|
||||
* {@link com.android.server.wm.test.filters.FrameworksTestsFilter}.
|
||||
*/
|
||||
@RunWith(AndroidJUnit4.class)
|
||||
@SmallTest
|
||||
@Presubmit
|
||||
public class WindowContextControllerTest {
|
||||
private WindowContextController mController;
|
||||
private IWindowManager mMockWms;
|
||||
|
||||
@Before
|
||||
public void setUp() throws Exception {
|
||||
mMockWms = mock(IWindowManager.class);
|
||||
mController = new WindowContextController(new Binder(), mMockWms);
|
||||
|
||||
doReturn(true).when(mMockWms).registerWindowContextListener(
|
||||
any(), anyInt(), anyInt(), any());
|
||||
}
|
||||
|
||||
@Test(expected = UnsupportedOperationException.class)
|
||||
public void testRegisterListenerTwiceThrowException() {
|
||||
mController.registerListener(TYPE_APPLICATION_OVERLAY, DEFAULT_DISPLAY,
|
||||
null /* options */);
|
||||
mController.registerListener(TYPE_APPLICATION_OVERLAY, DEFAULT_DISPLAY,
|
||||
null /* options */);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testUnregisterListenerIfNeeded_NotRegisteredYet_DoNothing() throws Exception {
|
||||
mController.unregisterListenerIfNeeded();
|
||||
|
||||
verify(mMockWms, never()).registerWindowContextListener(any(), anyInt(), anyInt(), any());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRegisterAndUnRegisterListener() {
|
||||
mController.registerListener(TYPE_APPLICATION_OVERLAY, DEFAULT_DISPLAY,
|
||||
null /* options */);
|
||||
|
||||
assertThat(mController.mListenerRegistered).isTrue();
|
||||
|
||||
mController.unregisterListenerIfNeeded();
|
||||
|
||||
assertThat(mController.mListenerRegistered).isFalse();
|
||||
}
|
||||
}
|
||||
@@ -61,7 +61,8 @@ public final class FrameworksTestsFilter extends SelectTest {
|
||||
"android.view.PendingInsetsControllerTest",
|
||||
"android.window.WindowContextTest",
|
||||
"android.window.WindowMetricsHelperTest",
|
||||
"android.app.activity.ActivityThreadTest"
|
||||
"android.app.activity.ActivityThreadTest",
|
||||
"android.window.WindowContextControllerTest"
|
||||
};
|
||||
|
||||
public FrameworksTestsFilter(Bundle testArgs) {
|
||||
|
||||
Reference in New Issue
Block a user