summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Chris Li <lihongyu@google.com> 2023-07-20 12:48:21 +0800
committer Chris Li <lihongyu@google.com> 2023-07-31 16:26:05 +0800
commit7ef648e6a353bbae7aab5119f3b7474a36094fac (patch)
tree3b5fe8349a899c9bfef7b840fd3e93af9622f48a
parent6603c87997c2b7bdffd7a134413b7c560f3d0576 (diff)
Migrate WindowContext#onConfigurationChanged to ClientTransaction (7/n)
1. Introdce WindowContextInfo to store info that we want to pass for WindowContext. 2. Update #attachToWindowToken to be consistent with #attachToDisplayArea that it also return the current WindowContext config. Before, when #attachToWindowToken, the server side will trigger an onConfigurationChanged to the WindowContext. Now, this will be done in the client side by post to the main thread so it doesn't change the client side behavior. Bug: 290876897 Test: atest FrameworksCoreTests:WindowTokenClientControllerTest Change-Id: I7655ac454a941a795d519351de4741778c514d82
-rw-r--r--core/java/android/app/ActivityThread.java8
-rw-r--r--core/java/android/app/ClientTransactionHandler.java7
-rw-r--r--core/java/android/app/servertransaction/WindowContextInfoChangeItem.java (renamed from core/java/android/app/servertransaction/WindowContextConfigurationChangeItem.java)57
-rw-r--r--core/java/android/view/IWindowManager.aidl19
-rw-r--r--core/java/android/window/WindowContextController.java6
-rw-r--r--core/java/android/window/WindowContextInfo.aidl20
-rw-r--r--core/java/android/window/WindowContextInfo.java117
-rw-r--r--core/java/android/window/WindowTokenClient.java8
-rw-r--r--core/java/android/window/WindowTokenClientController.java58
-rw-r--r--core/tests/coretests/src/android/app/activity/ActivityThreadTest.java8
-rw-r--r--core/tests/coretests/src/android/app/servertransaction/WindowContextInfoChangeItemTest.java (renamed from core/tests/coretests/src/android/app/servertransaction/WindowContextConfigurationChangeItemTest.java)13
-rw-r--r--core/tests/coretests/src/android/window/WindowTokenClientControllerTest.java65
-rw-r--r--services/core/java/com/android/server/wm/WindowContextListenerController.java8
-rw-r--r--services/core/java/com/android/server/wm/WindowManagerService.java29
-rw-r--r--services/tests/wmtests/src/com/android/server/wm/InputMethodDialogWindowContextTest.java3
-rw-r--r--services/tests/wmtests/src/com/android/server/wm/WindowManagerServiceTests.java10
16 files changed, 315 insertions, 121 deletions
diff --git a/core/java/android/app/ActivityThread.java b/core/java/android/app/ActivityThread.java
index 58c25489431a..a09d7dcfa08d 100644
--- a/core/java/android/app/ActivityThread.java
+++ b/core/java/android/app/ActivityThread.java
@@ -203,6 +203,7 @@ import android.webkit.WebView;
import android.window.SizeConfigurationBuckets;
import android.window.SplashScreen;
import android.window.SplashScreenView;
+import android.window.WindowContextInfo;
import android.window.WindowProviderService;
import android.window.WindowTokenClientController;
@@ -6248,10 +6249,9 @@ public final class ActivityThread extends ClientTransactionHandler
}
@Override
- public void handleWindowContextConfigurationChanged(@NonNull IBinder clientToken,
- @NonNull Configuration configuration, int displayId) {
- WindowTokenClientController.getInstance().onWindowContextConfigurationChanged(clientToken,
- configuration, displayId);
+ public void handleWindowContextInfoChanged(@NonNull IBinder clientToken,
+ @NonNull WindowContextInfo info) {
+ WindowTokenClientController.getInstance().onWindowContextInfoChanged(clientToken, info);
}
@Override
diff --git a/core/java/android/app/ClientTransactionHandler.java b/core/java/android/app/ClientTransactionHandler.java
index f7a43f42f2ef..6753cb884ea7 100644
--- a/core/java/android/app/ClientTransactionHandler.java
+++ b/core/java/android/app/ClientTransactionHandler.java
@@ -28,6 +28,7 @@ import android.os.IBinder;
import android.util.MergedConfiguration;
import android.view.SurfaceControl;
import android.window.SplashScreenView.SplashScreenViewParcelable;
+import android.window.WindowContextInfo;
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.content.ReferrerIntent;
@@ -163,9 +164,9 @@ public abstract class ClientTransactionHandler {
public abstract void handleActivityConfigurationChanged(@NonNull ActivityClientRecord r,
Configuration overrideConfig, int displayId);
- /** Deliver {@link android.window.WindowContext} configuration change. */
- public abstract void handleWindowContextConfigurationChanged(@NonNull IBinder clientToken,
- @NonNull Configuration configuration, int displayId);
+ /** Deliver {@link android.window.WindowContextInfo} change. */
+ public abstract void handleWindowContextInfoChanged(@NonNull IBinder clientToken,
+ @NonNull WindowContextInfo info);
/** Deliver {@link android.window.WindowContext} window removal event. */
public abstract void handleWindowContextWindowRemoval(@NonNull IBinder clientToken);
diff --git a/core/java/android/app/servertransaction/WindowContextConfigurationChangeItem.java b/core/java/android/app/servertransaction/WindowContextInfoChangeItem.java
index 3ac642fd4664..74721d555081 100644
--- a/core/java/android/app/servertransaction/WindowContextConfigurationChangeItem.java
+++ b/core/java/android/app/servertransaction/WindowContextInfoChangeItem.java
@@ -16,8 +16,6 @@
package android.app.servertransaction;
-import static android.view.Display.INVALID_DISPLAY;
-
import static java.util.Objects.requireNonNull;
import android.annotation.NonNull;
@@ -26,6 +24,7 @@ import android.app.ClientTransactionHandler;
import android.content.res.Configuration;
import android.os.IBinder;
import android.os.Parcel;
+import android.window.WindowContextInfo;
import java.util.Objects;
@@ -33,35 +32,33 @@ import java.util.Objects;
* {@link android.window.WindowContext} configuration change message.
* @hide
*/
-public class WindowContextConfigurationChangeItem extends ClientTransactionItem {
+public class WindowContextInfoChangeItem extends ClientTransactionItem {
@Nullable
private IBinder mClientToken;
@Nullable
- private Configuration mConfiguration;
- private int mDisplayId;
+ private WindowContextInfo mInfo;
@Override
public void execute(@NonNull ClientTransactionHandler client, @NonNull IBinder token,
@NonNull PendingTransactionActions pendingActions) {
- client.handleWindowContextConfigurationChanged(mClientToken, mConfiguration, mDisplayId);
+ client.handleWindowContextInfoChanged(mClientToken, mInfo);
}
// ObjectPoolItem implementation
- private WindowContextConfigurationChangeItem() {}
+ private WindowContextInfoChangeItem() {}
/** Obtains an instance initialized with provided params. */
- public static WindowContextConfigurationChangeItem obtain(
+ public static WindowContextInfoChangeItem obtain(
@NonNull IBinder clientToken, @NonNull Configuration config, int displayId) {
- WindowContextConfigurationChangeItem instance =
- ObjectPool.obtain(WindowContextConfigurationChangeItem.class);
+ WindowContextInfoChangeItem instance =
+ ObjectPool.obtain(WindowContextInfoChangeItem.class);
if (instance == null) {
- instance = new WindowContextConfigurationChangeItem();
+ instance = new WindowContextInfoChangeItem();
}
instance.mClientToken = requireNonNull(clientToken);
- instance.mConfiguration = requireNonNull(config);
- instance.mDisplayId = displayId;
+ instance.mInfo = new WindowContextInfo(config, displayId);
return instance;
}
@@ -69,8 +66,7 @@ public class WindowContextConfigurationChangeItem extends ClientTransactionItem
@Override
public void recycle() {
mClientToken = null;
- mConfiguration = null;
- mDisplayId = INVALID_DISPLAY;
+ mInfo = null;
ObjectPool.recycle(this);
}
@@ -80,25 +76,23 @@ public class WindowContextConfigurationChangeItem extends ClientTransactionItem
@Override
public void writeToParcel(@NonNull Parcel dest, int flags) {
dest.writeStrongBinder(mClientToken);
- dest.writeTypedObject(mConfiguration, flags);
- dest.writeInt(mDisplayId);
+ dest.writeTypedObject(mInfo, flags);
}
/** Reads from Parcel. */
- private WindowContextConfigurationChangeItem(@NonNull Parcel in) {
+ private WindowContextInfoChangeItem(@NonNull Parcel in) {
mClientToken = in.readStrongBinder();
- mConfiguration = in.readTypedObject(Configuration.CREATOR);
- mDisplayId = in.readInt();
+ mInfo = in.readTypedObject(WindowContextInfo.CREATOR);
}
- public static final @NonNull Creator<WindowContextConfigurationChangeItem> CREATOR =
+ public static final @NonNull Creator<WindowContextInfoChangeItem> CREATOR =
new Creator<>() {
- public WindowContextConfigurationChangeItem createFromParcel(Parcel in) {
- return new WindowContextConfigurationChangeItem(in);
+ public WindowContextInfoChangeItem createFromParcel(Parcel in) {
+ return new WindowContextInfoChangeItem(in);
}
- public WindowContextConfigurationChangeItem[] newArray(int size) {
- return new WindowContextConfigurationChangeItem[size];
+ public WindowContextInfoChangeItem[] newArray(int size) {
+ return new WindowContextInfoChangeItem[size];
}
};
@@ -110,26 +104,23 @@ public class WindowContextConfigurationChangeItem extends ClientTransactionItem
if (o == null || getClass() != o.getClass()) {
return false;
}
- final WindowContextConfigurationChangeItem other = (WindowContextConfigurationChangeItem) o;
+ final WindowContextInfoChangeItem other = (WindowContextInfoChangeItem) o;
return Objects.equals(mClientToken, other.mClientToken)
- && Objects.equals(mConfiguration, other.mConfiguration)
- && mDisplayId == other.mDisplayId;
+ && Objects.equals(mInfo, other.mInfo);
}
@Override
public int hashCode() {
int result = 17;
result = 31 * result + Objects.hashCode(mClientToken);
- result = 31 * result + Objects.hashCode(mConfiguration);
- result = 31 * result + mDisplayId;
+ result = 31 * result + Objects.hashCode(mInfo);
return result;
}
@Override
public String toString() {
- return "WindowContextConfigurationChangeItem{clientToken=" + mClientToken
- + ", config=" + mConfiguration
- + ", displayId=" + mDisplayId
+ return "WindowContextInfoChangeItem{clientToken=" + mClientToken
+ + ", info=" + mInfo
+ "}";
}
}
diff --git a/core/java/android/view/IWindowManager.aidl b/core/java/android/view/IWindowManager.aidl
index c1474ebad227..d3b7a5be47ba 100644
--- a/core/java/android/view/IWindowManager.aidl
+++ b/core/java/android/view/IWindowManager.aidl
@@ -71,6 +71,7 @@ import android.window.AddToSurfaceSyncGroupResult;
import android.window.ISurfaceSyncGroupCompletedListener;
import android.window.ITaskFpsCallback;
import android.window.ScreenCapture;
+import android.window.WindowContextInfo;
/**
* System private interface to the window manager.
@@ -858,10 +859,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 the DisplayArea's {@link android.app.res.Configuration} if the WindowContext is
- * attached to the DisplayArea successfully. {@code null}, otherwise.
+ * @return the {@link WindowContextInfo} of the DisplayArea if the WindowContext is attached to
+ * the DisplayArea successfully. {@code null}, otherwise.
*/
- @nullable Configuration attachWindowContextToDisplayArea(in IApplicationThread appThread,
+ @nullable WindowContextInfo attachWindowContextToDisplayArea(in IApplicationThread appThread,
IBinder clientToken, int type, int displayId, in @nullable Bundle options);
/**
@@ -879,13 +880,15 @@ interface IWindowManager
* the WindowContext's token}
* @param token the WindowToken to attach
*
+ * @return the {@link WindowContextInfo} of the WindowToken if the WindowContext is attached to
+ * the WindowToken successfully. {@code null}, otherwise.
* @throws IllegalArgumentException if the {@code clientToken} have not been attached to
* the server or the WindowContext's type doesn't match WindowToken {@code token}'s type.
*
* @see #attachWindowContextToDisplayArea(IBinder, int, int, Bundle)
*/
- void attachWindowContextToWindowToken(in IApplicationThread appThread, IBinder clientToken,
- IBinder token);
+ @nullable WindowContextInfo attachWindowContextToWindowToken(in IApplicationThread appThread,
+ IBinder clientToken, IBinder token);
/**
* Attaches a {@code clientToken} to associate with DisplayContent.
@@ -899,11 +902,11 @@ interface IWindowManager
* the WindowContext's token}
* @param displayId The display associated with the window context
*
- * @return the DisplayContent's {@link android.app.res.Configuration} if the Context is
- * attached to the DisplayContent successfully. {@code null}, otherwise.
+ * @return the {@link WindowContextInfo} of the DisplayContent if the WindowContext is attached
+ * to the DisplayContent successfully. {@code null}, otherwise.
* @throws android.view.WindowManager.InvalidDisplayException if the display ID is invalid
*/
- @nullable Configuration attachWindowContextToDisplayContent(in IApplicationThread appThread,
+ @nullable WindowContextInfo attachWindowContextToDisplayContent(in IApplicationThread appThread,
IBinder clientToken, int displayId);
/**
diff --git a/core/java/android/window/WindowContextController.java b/core/java/android/window/WindowContextController.java
index 36eef5375391..c9ac245bc36f 100644
--- a/core/java/android/window/WindowContextController.java
+++ b/core/java/android/window/WindowContextController.java
@@ -137,12 +137,14 @@ public class WindowContextController {
* @see WindowProviderService#attachToWindowToken(IBinder))
* @see IWindowManager#attachWindowContextToWindowToken
*/
- public void attachToWindowToken(IBinder windowToken) {
+ public void attachToWindowToken(@NonNull IBinder windowToken) {
if (mAttachedToDisplayArea != AttachStatus.STATUS_ATTACHED) {
throw new IllegalStateException("The Window Context should have been attached"
+ " to a DisplayArea. AttachToDisplayArea:" + mAttachedToDisplayArea);
}
- getWindowTokenClientController().attachToWindowToken(mToken, windowToken);
+ if (!getWindowTokenClientController().attachToWindowToken(mToken, windowToken)) {
+ Log.e(TAG, "attachToWindowToken fail");
+ }
}
/** Detaches the window context from the node it's currently associated with. */
diff --git a/core/java/android/window/WindowContextInfo.aidl b/core/java/android/window/WindowContextInfo.aidl
new file mode 100644
index 000000000000..360431cf6daa
--- /dev/null
+++ b/core/java/android/window/WindowContextInfo.aidl
@@ -0,0 +1,20 @@
+/*
+ * Copyright 2023 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;
+
+/** @hide */
+parcelable WindowContextInfo; \ No newline at end of file
diff --git a/core/java/android/window/WindowContextInfo.java b/core/java/android/window/WindowContextInfo.java
new file mode 100644
index 000000000000..3c21cd44b10a
--- /dev/null
+++ b/core/java/android/window/WindowContextInfo.java
@@ -0,0 +1,117 @@
+/*
+ * Copyright (C) 2023 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 java.util.Objects.requireNonNull;
+
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.content.res.Configuration;
+import android.os.Parcel;
+import android.os.Parcelable;
+
+import java.util.Objects;
+
+/**
+ * Stores information about a particular window that a {@link WindowContext} is attached to.
+ * @hide
+ */
+public class WindowContextInfo implements Parcelable {
+
+ /**
+ * Configuration of the window.
+ */
+ @NonNull
+ private final Configuration mConfiguration;
+
+ /**
+ * The display id that the window is attached to.
+ */
+ private final int mDisplayId;
+
+ public WindowContextInfo(@NonNull Configuration configuration, int displayId) {
+ mConfiguration = requireNonNull(configuration);
+ mDisplayId = displayId;
+ }
+
+ @NonNull
+ public Configuration getConfiguration() {
+ return mConfiguration;
+ }
+
+ public int getDisplayId() {
+ return mDisplayId;
+ }
+
+ // Parcelable implementation
+
+ /** Writes to Parcel. */
+ @Override
+ public void writeToParcel(@NonNull Parcel dest, int flags) {
+ dest.writeTypedObject(mConfiguration, flags);
+ dest.writeInt(mDisplayId);
+ }
+
+ /** Reads from Parcel. */
+ private WindowContextInfo(@NonNull Parcel in) {
+ mConfiguration = in.readTypedObject(Configuration.CREATOR);
+ mDisplayId = in.readInt();
+ }
+
+ public static final @NonNull Creator<WindowContextInfo> CREATOR = new Creator<>() {
+ public WindowContextInfo createFromParcel(Parcel in) {
+ return new WindowContextInfo(in);
+ }
+
+ public WindowContextInfo[] newArray(int size) {
+ return new WindowContextInfo[size];
+ }
+ };
+
+ @Override
+ public int describeContents() {
+ return 0;
+ }
+
+ @Override
+ public boolean equals(@Nullable Object o) {
+ if (this == o) {
+ return true;
+ }
+ if (o == null || getClass() != o.getClass()) {
+ return false;
+ }
+ final WindowContextInfo other = (WindowContextInfo) o;
+ return Objects.equals(mConfiguration, other.mConfiguration)
+ && mDisplayId == other.mDisplayId;
+ }
+
+ @Override
+ public int hashCode() {
+ int result = 17;
+ result = 31 * result + Objects.hashCode(mConfiguration);
+ result = 31 * result + mDisplayId;
+ return result;
+ }
+
+ @Override
+ public String toString() {
+ return "WindowContextInfo{config=" + mConfiguration
+ + ", displayId=" + mDisplayId
+ + "}";
+ }
+}
diff --git a/core/java/android/window/WindowTokenClient.java b/core/java/android/window/WindowTokenClient.java
index 74585638df6f..6a32529f31c7 100644
--- a/core/java/android/window/WindowTokenClient.java
+++ b/core/java/android/window/WindowTokenClient.java
@@ -99,6 +99,13 @@ public class WindowTokenClient extends IWindowToken.Stub {
@Override
public void onConfigurationChanged(Configuration newConfig, int newDisplayId) {
// TODO(b/290876897): No need to post on mHandler after migrating to ClientTransaction
+ postOnConfigurationChanged(newConfig, newDisplayId);
+ }
+
+ /**
+ * Posts an {@link #onConfigurationChanged} to the main thread.
+ */
+ public void postOnConfigurationChanged(@NonNull Configuration newConfig, int newDisplayId) {
mHandler.post(PooledLambda.obtainRunnable(this::onConfigurationChanged, newConfig,
newDisplayId, true /* shouldReportConfigChange */).recycleOnUse());
}
@@ -162,7 +169,6 @@ public class WindowTokenClient extends IWindowToken.Stub {
windowContext.dispatchConfigurationChanged(newConfig);
}
-
if (shouldReportConfigChange && diff != 0
&& context instanceof WindowProviderService) {
final WindowProviderService windowProviderService = (WindowProviderService) context;
diff --git a/core/java/android/window/WindowTokenClientController.java b/core/java/android/window/WindowTokenClientController.java
index 14b9df65aa69..7a84123c91e1 100644
--- a/core/java/android/window/WindowTokenClientController.java
+++ b/core/java/android/window/WindowTokenClientController.java
@@ -22,10 +22,9 @@ import android.annotation.NonNull;
import android.annotation.Nullable;
import android.app.ActivityThread;
import android.app.IApplicationThread;
-import android.app.servertransaction.WindowContextConfigurationChangeItem;
+import android.app.servertransaction.WindowContextInfoChangeItem;
import android.app.servertransaction.WindowContextWindowRemovalItem;
import android.content.Context;
-import android.content.res.Configuration;
import android.os.Bundle;
import android.os.IBinder;
import android.os.RemoteException;
@@ -94,17 +93,17 @@ public class WindowTokenClientController {
*/
public boolean attachToDisplayArea(@NonNull WindowTokenClient client,
@WindowType int type, int displayId, @Nullable Bundle options) {
- final Configuration configuration;
+ final WindowContextInfo info;
try {
- configuration = getWindowManagerService().attachWindowContextToDisplayArea(
+ info = getWindowManagerService().attachWindowContextToDisplayArea(
mAppThread, client, type, displayId, options);
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
- if (configuration == null) {
+ if (info == null) {
return false;
}
- onWindowContextTokenAttached(client, displayId, configuration);
+ onWindowContextTokenAttached(client, info, false /* shouldReportConfigChange */);
return true;
}
@@ -121,16 +120,16 @@ public class WindowTokenClientController {
if (wms == null) {
return false;
}
- final Configuration configuration;
+ final WindowContextInfo info;
try {
- configuration = wms.attachWindowContextToDisplayContent(mAppThread, client, displayId);
+ info = wms.attachWindowContextToDisplayContent(mAppThread, client, displayId);
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
- if (configuration == null) {
+ if (info == null) {
return false;
}
- onWindowContextTokenAttached(client, displayId, configuration);
+ onWindowContextTokenAttached(client, info, false /* shouldReportConfigChange */);
return true;
}
@@ -139,19 +138,23 @@ public class WindowTokenClientController {
*
* @param client The {@link WindowTokenClient} to attach.
* @param windowToken the window token to associated with
+ * @return {@code true} if attaching successfully.
*/
- public void attachToWindowToken(@NonNull WindowTokenClient client,
+ public boolean attachToWindowToken(@NonNull WindowTokenClient client,
@NonNull IBinder windowToken) {
+ final WindowContextInfo info;
try {
- getWindowManagerService().attachWindowContextToWindowToken(
+ info = getWindowManagerService().attachWindowContextToWindowToken(
mAppThread, client, windowToken);
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
- // We don't report configuration change for now.
- synchronized (mLock) {
- mWindowTokenClientMap.put(client.asBinder(), client);
+ if (info == null) {
+ return false;
}
+ // We currently report configuration for WindowToken after attached.
+ onWindowContextTokenAttached(client, info, true /* shouldReportConfigChange */);
+ return true;
}
/** Detaches a {@link WindowTokenClient} from associated WindowContainer if there's one. */
@@ -168,21 +171,30 @@ public class WindowTokenClientController {
}
}
- private void onWindowContextTokenAttached(@NonNull WindowTokenClient client, int displayId,
- @NonNull Configuration configuration) {
+ private void onWindowContextTokenAttached(@NonNull WindowTokenClient client,
+ @NonNull WindowContextInfo info, boolean shouldReportConfigChange) {
synchronized (mLock) {
mWindowTokenClientMap.put(client.asBinder(), client);
}
- client.onConfigurationChanged(configuration, displayId,
- false /* shouldReportConfigChange */);
+ if (shouldReportConfigChange) {
+ // Should trigger an #onConfigurationChanged callback to the WindowContext. Post the
+ // dispatch in the next loop to prevent the callback from being dispatched before
+ // #onCreate or WindowContext creation..
+ client.postOnConfigurationChanged(info.getConfiguration(), info.getDisplayId());
+ } else {
+ // Apply the config change directly in case users get stale values after WindowContext
+ // creation.
+ client.onConfigurationChanged(info.getConfiguration(), info.getDisplayId(),
+ false /* shouldReportConfigChange */);
+ }
}
- /** Called when receives {@link WindowContextConfigurationChangeItem}. */
- public void onWindowContextConfigurationChanged(@NonNull IBinder clientToken,
- @NonNull Configuration configuration, int displayId) {
+ /** Called when receives {@link WindowContextInfoChangeItem}. */
+ public void onWindowContextInfoChanged(@NonNull IBinder clientToken,
+ @NonNull WindowContextInfo info) {
final WindowTokenClient windowTokenClient = getWindowTokenClient(clientToken);
if (windowTokenClient != null) {
- windowTokenClient.onConfigurationChanged(configuration, displayId);
+ windowTokenClient.onConfigurationChanged(info.getConfiguration(), info.getDisplayId());
}
}
diff --git a/core/tests/coretests/src/android/app/activity/ActivityThreadTest.java b/core/tests/coretests/src/android/app/activity/ActivityThreadTest.java
index 8da6d74de36d..c904d96b6091 100644
--- a/core/tests/coretests/src/android/app/activity/ActivityThreadTest.java
+++ b/core/tests/coretests/src/android/app/activity/ActivityThreadTest.java
@@ -64,6 +64,7 @@ import android.util.DisplayMetrics;
import android.util.MergedConfiguration;
import android.view.Display;
import android.view.View;
+import android.window.WindowContextInfo;
import android.window.WindowTokenClientController;
import androidx.test.filters.MediumTest;
@@ -753,13 +754,12 @@ public class ActivityThreadTest {
WindowTokenClientController.overrideForTesting(windowTokenClientController);
final IBinder clientToken = mock(IBinder.class);
final Configuration configuration = new Configuration();
+ final WindowContextInfo info = new WindowContextInfo(configuration, DEFAULT_DISPLAY);
InstrumentationRegistry.getInstrumentation().runOnMainSync(() -> activityThread
- .handleWindowContextConfigurationChanged(
- clientToken, configuration, DEFAULT_DISPLAY));
+ .handleWindowContextInfoChanged(clientToken, info));
- verify(windowTokenClientController).onWindowContextConfigurationChanged(
- clientToken, configuration, DEFAULT_DISPLAY);
+ verify(windowTokenClientController).onWindowContextInfoChanged(clientToken, info);
}
@Test
diff --git a/core/tests/coretests/src/android/app/servertransaction/WindowContextConfigurationChangeItemTest.java b/core/tests/coretests/src/android/app/servertransaction/WindowContextInfoChangeItemTest.java
index 7811e1a58c22..37a517e87c74 100644
--- a/core/tests/coretests/src/android/app/servertransaction/WindowContextConfigurationChangeItemTest.java
+++ b/core/tests/coretests/src/android/app/servertransaction/WindowContextInfoChangeItemTest.java
@@ -23,6 +23,7 @@ import static org.mockito.Mockito.verify;
import android.app.ClientTransactionHandler;
import android.content.res.Configuration;
import android.os.IBinder;
+import android.window.WindowContextInfo;
import org.junit.Before;
import org.junit.Test;
@@ -30,12 +31,12 @@ import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
/**
- * Tests for {@link WindowContextConfigurationChangeItem}.
+ * Tests for {@link WindowContextInfoChangeItem}.
*
* Build/Install/Run:
- * atest FrameworksCoreTests:WindowContextConfigurationChangeItemTest
+ * atest FrameworksCoreTests:WindowContextInfoChangeItemTest
*/
-public class WindowContextConfigurationChangeItemTest {
+public class WindowContextInfoChangeItemTest {
@Mock
private ClientTransactionHandler mHandler;
@@ -55,11 +56,11 @@ public class WindowContextConfigurationChangeItemTest {
@Test
public void testExecute() {
- final WindowContextConfigurationChangeItem item = WindowContextConfigurationChangeItem
+ final WindowContextInfoChangeItem item = WindowContextInfoChangeItem
.obtain(mClientToken, mConfiguration, DEFAULT_DISPLAY);
item.execute(mHandler, mToken, mPendingActions);
- verify(mHandler).handleWindowContextConfigurationChanged(mClientToken, mConfiguration,
- DEFAULT_DISPLAY);
+ verify(mHandler).handleWindowContextInfoChanged(mClientToken,
+ new WindowContextInfo(mConfiguration, DEFAULT_DISPLAY));
}
}
diff --git a/core/tests/coretests/src/android/window/WindowTokenClientControllerTest.java b/core/tests/coretests/src/android/window/WindowTokenClientControllerTest.java
index c4f7b3b5cd59..7bd6f05d3775 100644
--- a/core/tests/coretests/src/android/window/WindowTokenClientControllerTest.java
+++ b/core/tests/coretests/src/android/window/WindowTokenClientControllerTest.java
@@ -64,6 +64,7 @@ public class WindowTokenClientControllerTest {
// Can't mock final class.
private final Configuration mConfiguration = new Configuration();
+ private WindowContextInfo mWindowContextInfo;
private WindowTokenClientController mController;
@Before
@@ -72,6 +73,7 @@ public class WindowTokenClientControllerTest {
doReturn(mClientToken).when(mWindowTokenClient).asBinder();
mController = spy(WindowTokenClientController.createInstanceForTesting());
doReturn(mWindowManagerService).when(mController).getWindowManagerService();
+ mWindowContextInfo = new WindowContextInfo(mConfiguration, DEFAULT_DISPLAY);
}
@Test
@@ -86,7 +88,7 @@ public class WindowTokenClientControllerTest {
TYPE_APPLICATION_OVERLAY, DEFAULT_DISPLAY, null /* options */);
verify(mWindowTokenClient, never()).onConfigurationChanged(any(), anyInt(), anyBoolean());
- doReturn(mConfiguration).when(mWindowManagerService).attachWindowContextToDisplayArea(
+ doReturn(mWindowContextInfo).when(mWindowManagerService).attachWindowContextToDisplayArea(
any(), any(), anyInt(), anyInt(), any());
assertTrue(mController.attachToDisplayArea(mWindowTokenClient, TYPE_APPLICATION_OVERLAY,
@@ -109,7 +111,7 @@ public class WindowTokenClientControllerTest {
verify(mWindowManagerService, never()).detachWindowContext(any());
- doReturn(mConfiguration).when(mWindowManagerService).attachWindowContextToDisplayArea(
+ doReturn(mWindowContextInfo).when(mWindowManagerService).attachWindowContextToDisplayArea(
any(), any(), anyInt(), anyInt(), any());
mController.attachToDisplayArea(mWindowTokenClient, TYPE_APPLICATION_OVERLAY,
DEFAULT_DISPLAY, null /* options */);
@@ -129,8 +131,8 @@ public class WindowTokenClientControllerTest {
DEFAULT_DISPLAY);
verify(mWindowTokenClient, never()).onConfigurationChanged(any(), anyInt(), anyBoolean());
- doReturn(mConfiguration).when(mWindowManagerService).attachWindowContextToDisplayContent(
- any(), any(), anyInt());
+ doReturn(mWindowContextInfo).when(mWindowManagerService)
+ .attachWindowContextToDisplayContent(any(), any(), anyInt());
assertTrue(mController.attachToDisplayContent(mWindowTokenClient, DEFAULT_DISPLAY));
verify(mWindowTokenClient).onConfigurationChanged(mConfiguration, DEFAULT_DISPLAY,
@@ -150,8 +152,8 @@ public class WindowTokenClientControllerTest {
verify(mWindowManagerService, never()).detachWindowContext(any());
- doReturn(mConfiguration).when(mWindowManagerService).attachWindowContextToDisplayContent(
- any(), any(), anyInt());
+ doReturn(mWindowContextInfo).when(mWindowManagerService)
+ .attachWindowContextToDisplayContent(any(), any(), anyInt());
mController.attachToDisplayContent(mWindowTokenClient, DEFAULT_DISPLAY);
mController.detachIfNeeded(mWindowTokenClient);
@@ -160,11 +162,20 @@ public class WindowTokenClientControllerTest {
@Test
public void testAttachToWindowToken() throws RemoteException {
- mController.attachToWindowToken(mWindowTokenClient, mWindowToken);
+ doReturn(null).when(mWindowManagerService).attachWindowContextToWindowToken(
+ any(), any(), any());
+ assertFalse(mController.attachToWindowToken(mWindowTokenClient, mWindowToken));
verify(mWindowManagerService).attachWindowContextToWindowToken(
ActivityThread.currentActivityThread().getApplicationThread(), mWindowTokenClient,
mWindowToken);
+ verify(mWindowTokenClient, never()).onConfigurationChanged(any(), anyInt(), anyBoolean());
+
+ doReturn(mWindowContextInfo).when(mWindowManagerService)
+ .attachWindowContextToWindowToken(any(), any(), any());
+
+ assertTrue(mController.attachToWindowToken(mWindowTokenClient, mWindowToken));
+ verify(mWindowTokenClient).postOnConfigurationChanged(mConfiguration, DEFAULT_DISPLAY);
}
@Test
@@ -173,6 +184,15 @@ public class WindowTokenClientControllerTest {
verify(mWindowManagerService, never()).detachWindowContext(any());
+ doReturn(null).when(mWindowManagerService).attachWindowContextToWindowToken(
+ any(), any(), any());
+ mController.attachToWindowToken(mWindowTokenClient, mWindowToken);
+ mController.detachIfNeeded(mWindowTokenClient);
+
+ verify(mWindowManagerService, never()).detachWindowContext(any());
+
+ doReturn(mWindowContextInfo).when(mWindowManagerService).attachWindowContextToWindowToken(
+ any(), any(), any());
mController.attachToWindowToken(mWindowTokenClient, mWindowToken);
mController.detachIfNeeded(mWindowTokenClient);
@@ -180,28 +200,43 @@ public class WindowTokenClientControllerTest {
}
@Test
- public void testOnWindowContextConfigurationChanged() {
- mController.onWindowContextConfigurationChanged(
- mClientToken, mConfiguration, DEFAULT_DISPLAY);
+ public void testOnWindowContextInfoChanged() throws RemoteException {
+ doReturn(mWindowContextInfo).when(mWindowManagerService)
+ .attachWindowContextToWindowToken(any(), any(), any());
+
+ // No invoke if not attached.
+ mController.onWindowContextInfoChanged(mClientToken, mWindowContextInfo);
verify(mWindowTokenClient, never()).onConfigurationChanged(any(), anyInt());
- mController.attachToWindowToken(mWindowTokenClient, mWindowToken);
+ // Invoke postOnConfigurationChanged when attached
+ assertTrue(mController.attachToWindowToken(mWindowTokenClient, mWindowToken));
- mController.onWindowContextConfigurationChanged(
- mClientToken, mConfiguration, DEFAULT_DISPLAY);
+ verify(mWindowTokenClient).postOnConfigurationChanged(mConfiguration, DEFAULT_DISPLAY);
- verify(mWindowTokenClient).onConfigurationChanged(mConfiguration, DEFAULT_DISPLAY);
+ // Invoke onConfigurationChanged when onWindowContextInfoChanged
+ mController.onWindowContextInfoChanged(
+ mClientToken, new WindowContextInfo(mConfiguration, DEFAULT_DISPLAY + 1));
+
+ verify(mWindowTokenClient).onConfigurationChanged(mConfiguration, DEFAULT_DISPLAY + 1);
}
@Test
- public void testOnWindowContextWindowRemoved() {
+ public void testOnWindowContextWindowRemoved() throws RemoteException {
+ doReturn(mWindowContextInfo).when(mWindowManagerService)
+ .attachWindowContextToWindowToken(any(), any(), any());
+
+ // No invoke if not attached.
mController.onWindowContextWindowRemoved(mClientToken);
verify(mWindowTokenClient, never()).onWindowTokenRemoved();
+ // No invoke if not onWindowTokenRemoved.
mController.attachToWindowToken(mWindowTokenClient, mWindowToken);
+ verify(mWindowTokenClient, never()).onWindowTokenRemoved();
+
+ // Invoke onWindowTokenRemoved when onWindowContextWindowRemoved
mController.onWindowContextWindowRemoved(mClientToken);
verify(mWindowTokenClient).onWindowTokenRemoved();
diff --git a/services/core/java/com/android/server/wm/WindowContextListenerController.java b/services/core/java/com/android/server/wm/WindowContextListenerController.java
index 26aab07695ca..726ae5c61d56 100644
--- a/services/core/java/com/android/server/wm/WindowContextListenerController.java
+++ b/services/core/java/com/android/server/wm/WindowContextListenerController.java
@@ -76,7 +76,7 @@ class WindowContextListenerController {
@NonNull IBinder clientToken, @NonNull WindowContainer<?> container,
@WindowType int type, @Nullable Bundle options) {
registerWindowContainerListener(wpc, clientToken, container, type, options,
- true /* shouDispatchConfigWhenRegistering */);
+ true /* shouldDispatchConfigWhenRegistering */);
}
/**
@@ -91,19 +91,19 @@ class WindowContextListenerController {
* @param container the {@link WindowContainer} which the listener is going to listen to.
* @param type the window type
* @param options a bundle used to pass window-related options.
- * @param shouDispatchConfigWhenRegistering {@code true} to indicate the current
+ * @param shouldDispatchConfigWhenRegistering {@code true} to indicate the current
* {@code container}'s config will dispatch to the client side when
* registering the {@link WindowContextListenerImpl}
*/
void registerWindowContainerListener(@NonNull WindowProcessController wpc,
@NonNull IBinder clientToken, @NonNull WindowContainer<?> container,
@WindowType int type, @Nullable Bundle options,
- boolean shouDispatchConfigWhenRegistering) {
+ boolean shouldDispatchConfigWhenRegistering) {
WindowContextListenerImpl listener = mListeners.get(clientToken);
if (listener == null) {
listener = new WindowContextListenerImpl(wpc, clientToken, container, type,
options);
- listener.register(shouDispatchConfigWhenRegistering);
+ listener.register(shouldDispatchConfigWhenRegistering);
} else {
updateContainerForWindowContextListener(clientToken, container);
}
diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java
index 210378f79af1..261d6bc489b6 100644
--- a/services/core/java/com/android/server/wm/WindowManagerService.java
+++ b/services/core/java/com/android/server/wm/WindowManagerService.java
@@ -305,6 +305,7 @@ import android.window.ITaskFpsCallback;
import android.window.ScreenCapture;
import android.window.TaskSnapshot;
import android.window.WindowContainerToken;
+import android.window.WindowContextInfo;
import com.android.internal.R;
import com.android.internal.annotations.VisibleForTesting;
@@ -2737,7 +2738,7 @@ public class WindowManagerService extends IWindowManager.Stub
@Nullable
@Override
- public Configuration attachWindowContextToDisplayArea(@NonNull IApplicationThread appThread,
+ public WindowContextInfo attachWindowContextToDisplayArea(@NonNull IApplicationThread appThread,
@NonNull IBinder clientToken, @LayoutParams.WindowType int type, int displayId,
@Nullable Bundle options) {
Objects.requireNonNull(appThread);
@@ -2766,8 +2767,8 @@ public class WindowManagerService extends IWindowManager.Stub
final DisplayArea<?> da = dc.findAreaForWindowType(type, options,
callerCanManageAppTokens, false /* roundedCornerOverlay */);
mWindowContextListenerController.registerWindowContainerListener(wpc, clientToken,
- da, type, options, false /* shouDispatchConfigWhenRegistering */);
- return da.getConfiguration();
+ da, type, options, false /* shouldDispatchConfigWhenRegistering */);
+ return new WindowContextInfo(da.getConfiguration(), displayId);
}
} finally {
Binder.restoreCallingIdentity(origId);
@@ -2776,8 +2777,8 @@ public class WindowManagerService extends IWindowManager.Stub
@Nullable
@Override
- public Configuration attachWindowContextToDisplayContent(@NonNull IApplicationThread appThread,
- @NonNull IBinder clientToken, int displayId) {
+ public WindowContextInfo attachWindowContextToDisplayContent(
+ @NonNull IApplicationThread appThread, @NonNull IBinder clientToken, int displayId) {
Objects.requireNonNull(appThread);
Objects.requireNonNull(clientToken);
final int callingPid = Binder.getCallingPid();
@@ -2809,16 +2810,17 @@ public class WindowManagerService extends IWindowManager.Stub
mWindowContextListenerController.registerWindowContainerListener(wpc, clientToken,
dc, INVALID_WINDOW_TYPE, null /* options */,
- false /* shouDispatchConfigWhenRegistering */);
- return dc.getConfiguration();
+ false /* shouldDispatchConfigWhenRegistering */);
+ return new WindowContextInfo(dc.getConfiguration(), displayId);
}
} finally {
Binder.restoreCallingIdentity(origId);
}
}
+ @Nullable
@Override
- public void attachWindowContextToWindowToken(@NonNull IApplicationThread appThread,
+ public WindowContextInfo attachWindowContextToWindowToken(@NonNull IApplicationThread appThread,
@NonNull IBinder clientToken, @NonNull IBinder token) {
Objects.requireNonNull(appThread);
Objects.requireNonNull(clientToken);
@@ -2834,13 +2836,13 @@ public class WindowManagerService extends IWindowManager.Stub
if (wpc == null) {
ProtoLog.w(WM_ERROR, "attachWindowContextToWindowToken: calling from"
+ " non-existing process pid=%d uid=%d", callingPid, callingUid);
- return;
+ return null;
}
final WindowToken windowToken = mRoot.getWindowToken(token);
if (windowToken == null) {
ProtoLog.w(WM_ERROR, "Then token:%s is invalid. It might be "
+ "removed", token);
- return;
+ return null;
}
final int type = mWindowContextListenerController.getWindowType(clientToken);
if (type == INVALID_WINDOW_TYPE) {
@@ -2854,10 +2856,13 @@ public class WindowManagerService extends IWindowManager.Stub
}
if (!mWindowContextListenerController.assertCallerCanModifyListener(clientToken,
callerCanManageAppTokens, callingUid)) {
- return;
+ return null;
}
mWindowContextListenerController.registerWindowContainerListener(wpc, clientToken,
- windowToken, windowToken.windowType, windowToken.mOptions);
+ windowToken, windowToken.windowType, windowToken.mOptions,
+ false /* shouldDispatchConfigWhenRegistering */);
+ return new WindowContextInfo(windowToken.getConfiguration(),
+ windowToken.getDisplayContent().getDisplayId());
}
} finally {
Binder.restoreCallingIdentity(origId);
diff --git a/services/tests/wmtests/src/com/android/server/wm/InputMethodDialogWindowContextTest.java b/services/tests/wmtests/src/com/android/server/wm/InputMethodDialogWindowContextTest.java
index 1180ebdcaecb..c3db241f28ae 100644
--- a/services/tests/wmtests/src/com/android/server/wm/InputMethodDialogWindowContextTest.java
+++ b/services/tests/wmtests/src/com/android/server/wm/InputMethodDialogWindowContextTest.java
@@ -47,6 +47,7 @@ import android.view.Display;
import android.view.IWindowManager;
import android.view.WindowManager;
import android.view.WindowManagerGlobal;
+import android.window.WindowContextInfo;
import android.window.WindowTokenClient;
import com.android.server.inputmethod.InputMethodDialogWindowContext;
@@ -99,7 +100,7 @@ public class InputMethodDialogWindowContextTest extends WindowTestsBase {
final WindowProcessController wpc = mAtm.getProcessController(appThread);
mWm.mWindowContextListenerController.registerWindowContainerListener(wpc, clientToken,
dc.getImeContainer(), TYPE_INPUT_METHOD_DIALOG, null /* options */);
- return dc.getImeContainer().getConfiguration();
+ return new WindowContextInfo(dc.getImeContainer().getConfiguration(), displayId);
}).when(mIWindowManager).attachWindowContextToDisplayArea(any(), any(),
eq(TYPE_INPUT_METHOD_DIALOG), anyInt(), any());
mDisplayManagerGlobal = DisplayManagerGlobal.getInstance();
diff --git a/services/tests/wmtests/src/com/android/server/wm/WindowManagerServiceTests.java b/services/tests/wmtests/src/com/android/server/wm/WindowManagerServiceTests.java
index 325176fbe7a8..55fda0521e01 100644
--- a/services/tests/wmtests/src/com/android/server/wm/WindowManagerServiceTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/WindowManagerServiceTests.java
@@ -468,7 +468,7 @@ public class WindowManagerServiceTests extends WindowTestsBase {
mWm.attachWindowContextToWindowToken(mAppThread, new Binder(), windowToken.token);
verify(mWm.mWindowContextListenerController, never()).registerWindowContainerListener(
- any(), any(), any(), anyInt(), any());
+ any(), any(), any(), anyInt(), any(), anyBoolean());
}
@Test
@@ -484,9 +484,9 @@ public class WindowManagerServiceTests extends WindowTestsBase {
final IBinder clientToken = new Binder();
mWm.attachWindowContextToWindowToken(mAppThread, clientToken, windowToken.token);
final WindowProcessController wpc = mAtm.getProcessController(mAppThread);
- verify(mWm.mWindowContextListenerController).registerWindowContainerListener(eq(wpc),
- eq(clientToken), eq(windowToken), eq(TYPE_INPUT_METHOD),
- eq(windowToken.mOptions));
+ verify(mWm.mWindowContextListenerController).registerWindowContainerListener(wpc,
+ clientToken, windowToken, TYPE_INPUT_METHOD, windowToken.mOptions,
+ false /* shouldDispatchConfigWhenRegistering */);
}
@Test
@@ -514,7 +514,7 @@ public class WindowManagerServiceTests extends WindowTestsBase {
new InsetsSourceControl.Array(), new Rect(), new float[1]);
verify(mWm.mWindowContextListenerController, never()).registerWindowContainerListener(any(),
- any(), any(), anyInt(), any());
+ any(), any(), anyInt(), any(), anyBoolean());
}
@Test