summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Chris Li <lihongyu@google.com> 2023-08-21 18:55:20 +0800
committer Chris Li <lihongyu@google.com> 2023-08-25 11:41:35 +0800
commit579d9cd8727e67a2083ab99a8f5034d740a58b79 (patch)
tree148b6f615cc02e25e85efa45e9db23b3bb273555
parent8de14cacfba137ea426e0b48cba10f9eb2af54c7 (diff)
Synchronize window config updates (1/n)
When updating Configuration on the client side, check if this should trigger onDisplayChanged. Bug: 260873529 Test: atest WmTests:WindowConfigurationTests Test: atest FrameworksCoreTests:WindowContextInfoChangeItemTest Change-Id: I8baa0f43d6bd00a93910fed4aec2d53f2044e0c7
-rw-r--r--core/api/test-current.txt8
-rw-r--r--core/java/android/app/ActivityThread.java6
-rw-r--r--core/java/android/app/ClientTransactionHandler.java7
-rw-r--r--core/java/android/app/WindowConfiguration.java25
-rw-r--r--core/java/android/app/servertransaction/ActivityConfigurationChangeItem.java14
-rw-r--r--core/java/android/app/servertransaction/ClientTransactionItem.java15
-rw-r--r--core/java/android/app/servertransaction/ConfigurationChangeItem.java17
-rw-r--r--core/java/android/app/servertransaction/TransactionExecutor.java47
-rw-r--r--core/java/android/app/servertransaction/WindowContextInfoChangeItem.java8
-rw-r--r--core/java/android/window/WindowTokenClient.java10
-rw-r--r--core/java/android/window/WindowTokenClientController.java10
-rw-r--r--core/tests/coretests/src/android/app/servertransaction/ActivityConfigurationChangeItemTest.java73
-rw-r--r--core/tests/coretests/src/android/app/servertransaction/ConfigurationChangeItemTest.java70
-rw-r--r--core/tests/coretests/src/android/app/servertransaction/WindowContextInfoChangeItemTest.java25
-rw-r--r--core/tests/coretests/src/android/app/servertransaction/WindowContextWindowRemovalItemTest.java8
-rw-r--r--services/tests/wmtests/src/com/android/server/wm/WindowConfigurationTests.java40
16 files changed, 366 insertions, 17 deletions
diff --git a/core/api/test-current.txt b/core/api/test-current.txt
index 773d720d73fb..6210715440fb 100644
--- a/core/api/test-current.txt
+++ b/core/api/test-current.txt
@@ -496,15 +496,15 @@ package android.app {
method public int compareTo(android.app.WindowConfiguration);
method public int describeContents();
method public int getActivityType();
- method public android.graphics.Rect getAppBounds();
- method public android.graphics.Rect getBounds();
+ method @Nullable public android.graphics.Rect getAppBounds();
+ method @NonNull public android.graphics.Rect getBounds();
method @NonNull public android.graphics.Rect getMaxBounds();
method public int getRotation();
method public int getWindowingMode();
method public static boolean isFloating(int);
method public void setActivityType(int);
- method public void setAppBounds(android.graphics.Rect);
- method public void setBounds(android.graphics.Rect);
+ method public void setAppBounds(@Nullable android.graphics.Rect);
+ method public void setBounds(@Nullable android.graphics.Rect);
method public void setMaxBounds(@Nullable android.graphics.Rect);
method public void setRotation(int);
method public void setTo(android.app.WindowConfiguration);
diff --git a/core/java/android/app/ActivityThread.java b/core/java/android/app/ActivityThread.java
index cc716ecfdafa..3dd69e46a7d9 100644
--- a/core/java/android/app/ActivityThread.java
+++ b/core/java/android/app/ActivityThread.java
@@ -3580,6 +3580,12 @@ public final class ActivityThread extends ClientTransactionHandler
return mActivities.get(token);
}
+ @Nullable
+ @Override
+ public Context getWindowContext(@NonNull IBinder clientToken) {
+ return WindowTokenClientController.getInstance().getWindowContext(clientToken);
+ }
+
@VisibleForTesting(visibility = PACKAGE)
public Configuration getConfiguration() {
return mConfigurationController.getConfiguration();
diff --git a/core/java/android/app/ClientTransactionHandler.java b/core/java/android/app/ClientTransactionHandler.java
index 6753cb884ea7..98020ff2d173 100644
--- a/core/java/android/app/ClientTransactionHandler.java
+++ b/core/java/android/app/ClientTransactionHandler.java
@@ -16,11 +16,13 @@
package android.app;
import android.annotation.NonNull;
+import android.annotation.Nullable;
import android.app.ActivityThread.ActivityClientRecord;
import android.app.servertransaction.ClientTransaction;
import android.app.servertransaction.ClientTransactionItem;
import android.app.servertransaction.PendingTransactionActions;
import android.app.servertransaction.TransactionExecutor;
+import android.content.Context;
import android.content.Intent;
import android.content.pm.ApplicationInfo;
import android.content.res.Configuration;
@@ -28,6 +30,7 @@ import android.os.IBinder;
import android.util.MergedConfiguration;
import android.view.SurfaceControl;
import android.window.SplashScreenView.SplashScreenViewParcelable;
+import android.window.WindowContext;
import android.window.WindowContextInfo;
import com.android.internal.annotations.VisibleForTesting;
@@ -85,6 +88,10 @@ public abstract class ClientTransactionHandler {
/** Get activity instance for the token. */
public abstract Activity getActivity(IBinder token);
+ /** Gets the {@link WindowContext} instance for the token. */
+ @Nullable
+ public abstract Context getWindowContext(@NonNull IBinder clientToken);
+
// Prepare phase related logic and handlers. Methods that inform about about pending changes or
// do other internal bookkeeping.
diff --git a/core/java/android/app/WindowConfiguration.java b/core/java/android/app/WindowConfiguration.java
index 5b955031a098..e3055e5042c6 100644
--- a/core/java/android/app/WindowConfiguration.java
+++ b/core/java/android/app/WindowConfiguration.java
@@ -36,6 +36,7 @@ import android.os.Parcelable;
import android.util.proto.ProtoInputStream;
import android.util.proto.ProtoOutputStream;
import android.util.proto.WireTypeMismatchException;
+import android.view.Display;
import android.view.DisplayInfo;
import android.view.Surface;
import android.view.WindowManager;
@@ -66,6 +67,7 @@ public class WindowConfiguration implements Parcelable, Comparable<WindowConfigu
* the display level. Lower levels can override these values to provide custom bounds to enforce
* features such as a max aspect ratio.
*/
+ @Nullable
private Rect mAppBounds;
/**
@@ -269,7 +271,7 @@ public class WindowConfiguration implements Parcelable, Comparable<WindowConfigu
* Sets the bounds to the provided {@link Rect}.
* @param rect the new bounds value.
*/
- public void setBounds(Rect rect) {
+ public void setBounds(@Nullable Rect rect) {
if (rect == null) {
mBounds.setEmpty();
return;
@@ -283,7 +285,7 @@ public class WindowConfiguration implements Parcelable, Comparable<WindowConfigu
* @param rect The rect value to set {@link #mAppBounds} to.
* @see #getAppBounds()
*/
- public void setAppBounds(Rect rect) {
+ public void setAppBounds(@Nullable Rect rect) {
if (rect == null) {
mAppBounds = null;
return;
@@ -356,11 +358,13 @@ public class WindowConfiguration implements Parcelable, Comparable<WindowConfigu
}
/** @see #setAppBounds(Rect) */
+ @Nullable
public Rect getAppBounds() {
return mAppBounds;
}
/** @see #setBounds(Rect) */
+ @NonNull
public Rect getBounds() {
return mBounds;
}
@@ -905,6 +909,23 @@ public class WindowConfiguration implements Parcelable, Comparable<WindowConfigu
return activityType != ACTIVITY_TYPE_ASSISTANT && activityType != ACTIVITY_TYPE_DREAM;
}
+ /**
+ * Checks if the two {@link Configuration}s are equal to each other for the fields that are read
+ * by {@link Display}.
+ * @hide
+ */
+ public static boolean areConfigurationsEqualForDisplay(@NonNull Configuration newConfig,
+ @NonNull Configuration oldConfig) {
+ // Only report different if max bounds and display rotation is changed, so that it will not
+ // report on Task resizing.
+ if (!newConfig.windowConfiguration.getMaxBounds().equals(
+ oldConfig.windowConfiguration.getMaxBounds())) {
+ return false;
+ }
+ return newConfig.windowConfiguration.getDisplayRotation()
+ == oldConfig.windowConfiguration.getDisplayRotation();
+ }
+
/** @hide */
public static String windowingModeToString(@WindowingMode int windowingMode) {
switch (windowingMode) {
diff --git a/core/java/android/app/servertransaction/ActivityConfigurationChangeItem.java b/core/java/android/app/servertransaction/ActivityConfigurationChangeItem.java
index 1c490be08381..e40925441f0f 100644
--- a/core/java/android/app/servertransaction/ActivityConfigurationChangeItem.java
+++ b/core/java/android/app/servertransaction/ActivityConfigurationChangeItem.java
@@ -23,6 +23,7 @@ import android.annotation.NonNull;
import android.annotation.Nullable;
import android.app.ActivityThread.ActivityClientRecord;
import android.app.ClientTransactionHandler;
+import android.content.Context;
import android.content.res.CompatibilityInfo;
import android.content.res.Configuration;
import android.os.IBinder;
@@ -40,7 +41,7 @@ public class ActivityConfigurationChangeItem extends ActivityTransactionItem {
private Configuration mConfiguration;
@Override
- public void preExecute(android.app.ClientTransactionHandler client, IBinder token) {
+ public void preExecute(@NonNull ClientTransactionHandler client, @Nullable IBinder token) {
CompatibilityInfo.applyOverrideScaleIfNeeded(mConfiguration);
// Notify the client of an upcoming change in the token configuration. This ensures that
// batches of config change items only process the newest configuration.
@@ -48,14 +49,21 @@ public class ActivityConfigurationChangeItem extends ActivityTransactionItem {
}
@Override
- public void execute(ClientTransactionHandler client, ActivityClientRecord r,
- PendingTransactionActions pendingActions) {
+ public void execute(@NonNull ClientTransactionHandler client, @Nullable ActivityClientRecord r,
+ @NonNull PendingTransactionActions pendingActions) {
// TODO(lifecycler): detect if PIP or multi-window mode changed and report it here.
Trace.traceBegin(TRACE_TAG_ACTIVITY_MANAGER, "activityConfigChanged");
client.handleActivityConfigurationChanged(r, mConfiguration, INVALID_DISPLAY);
Trace.traceEnd(TRACE_TAG_ACTIVITY_MANAGER);
}
+ @Nullable
+ @Override
+ public Context getContextToUpdate(@NonNull ClientTransactionHandler client,
+ @Nullable IBinder token) {
+ // TODO(b/260873529): Update ClientTransaction to bundle multiple activity config updates.
+ return client.getActivity(token);
+ }
// ObjectPoolItem implementation
diff --git a/core/java/android/app/servertransaction/ClientTransactionItem.java b/core/java/android/app/servertransaction/ClientTransactionItem.java
index b159f336cd85..fe75d89e1257 100644
--- a/core/java/android/app/servertransaction/ClientTransactionItem.java
+++ b/core/java/android/app/servertransaction/ClientTransactionItem.java
@@ -19,6 +19,11 @@ package android.app.servertransaction;
import static android.app.servertransaction.ActivityLifecycleItem.LifecycleState;
import static android.app.servertransaction.ActivityLifecycleItem.UNDEFINED;
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.app.ClientTransactionHandler;
+import android.content.Context;
+import android.os.IBinder;
import android.os.Parcelable;
/**
@@ -42,6 +47,16 @@ public abstract class ClientTransactionItem implements BaseClientRequest, Parcel
return true;
}
+ /**
+ * If this {@link ClientTransactionItem} is updating configuration, returns the {@link Context}
+ * it is updating; otherwise, returns {@code null}.
+ */
+ @Nullable
+ public Context getContextToUpdate(@NonNull ClientTransactionHandler client,
+ @NonNull IBinder token) {
+ return null;
+ }
+
// Parcelable
@Override
diff --git a/core/java/android/app/servertransaction/ConfigurationChangeItem.java b/core/java/android/app/servertransaction/ConfigurationChangeItem.java
index a563bbc9c70d..f72e2e04deca 100644
--- a/core/java/android/app/servertransaction/ConfigurationChangeItem.java
+++ b/core/java/android/app/servertransaction/ConfigurationChangeItem.java
@@ -16,8 +16,11 @@
package android.app.servertransaction;
+import android.annotation.NonNull;
import android.annotation.Nullable;
+import android.app.ActivityThread;
import android.app.ClientTransactionHandler;
+import android.content.Context;
import android.content.res.CompatibilityInfo;
import android.content.res.Configuration;
import android.os.IBinder;
@@ -35,24 +38,30 @@ public class ConfigurationChangeItem extends ClientTransactionItem {
private int mDeviceId;
@Override
- public void preExecute(android.app.ClientTransactionHandler client, IBinder token) {
+ public void preExecute(@NonNull ClientTransactionHandler client, @Nullable IBinder token) {
CompatibilityInfo.applyOverrideScaleIfNeeded(mConfiguration);
client.updatePendingConfiguration(mConfiguration);
}
@Override
- public void execute(ClientTransactionHandler client, IBinder token,
- PendingTransactionActions pendingActions) {
+ public void execute(@NonNull ClientTransactionHandler client, @Nullable IBinder token,
+ @NonNull PendingTransactionActions pendingActions) {
client.handleConfigurationChanged(mConfiguration, mDeviceId);
}
+ @Nullable
+ @Override
+ public Context getContextToUpdate(@NonNull ClientTransactionHandler client,
+ @Nullable IBinder token) {
+ return ActivityThread.currentApplication();
+ }
// ObjectPoolItem implementation
private ConfigurationChangeItem() {}
/** Obtain an instance initialized with provided params. */
- public static ConfigurationChangeItem obtain(Configuration config, int deviceId) {
+ public static ConfigurationChangeItem obtain(@NonNull Configuration config, int deviceId) {
ConfigurationChangeItem instance = ObjectPool.obtain(ConfigurationChangeItem.class);
if (instance == null) {
instance = new ConfigurationChangeItem();
diff --git a/core/java/android/app/servertransaction/TransactionExecutor.java b/core/java/android/app/servertransaction/TransactionExecutor.java
index bfab61f3ae90..09a9ab326ef7 100644
--- a/core/java/android/app/servertransaction/TransactionExecutor.java
+++ b/core/java/android/app/servertransaction/TransactionExecutor.java
@@ -16,6 +16,7 @@
package android.app.servertransaction;
+import static android.app.WindowConfiguration.areConfigurationsEqualForDisplay;
import static android.app.servertransaction.ActivityLifecycleItem.ON_CREATE;
import static android.app.servertransaction.ActivityLifecycleItem.ON_DESTROY;
import static android.app.servertransaction.ActivityLifecycleItem.ON_PAUSE;
@@ -30,10 +31,16 @@ import static android.app.servertransaction.TransactionExecutorHelper.lastCallba
import static android.app.servertransaction.TransactionExecutorHelper.tId;
import static android.app.servertransaction.TransactionExecutorHelper.transactionToString;
+import static com.android.window.flags.Flags.syncWindowConfigUpdateFlag;
+
+import android.annotation.NonNull;
import android.app.ActivityThread.ActivityClientRecord;
import android.app.ClientTransactionHandler;
import android.content.Context;
+import android.content.res.Configuration;
import android.os.IBinder;
+import android.os.Process;
+import android.util.ArraySet;
import android.util.IntArray;
import android.util.Slog;
@@ -51,12 +58,12 @@ public class TransactionExecutor {
private static final boolean DEBUG_RESOLVER = false;
private static final String TAG = "TransactionExecutor";
- private ClientTransactionHandler mTransactionHandler;
- private PendingTransactionActions mPendingActions = new PendingTransactionActions();
- private TransactionExecutorHelper mHelper = new TransactionExecutorHelper();
+ private final ClientTransactionHandler mTransactionHandler;
+ private final PendingTransactionActions mPendingActions = new PendingTransactionActions();
+ private final TransactionExecutorHelper mHelper = new TransactionExecutorHelper();
/** Initialize an instance with transaction handler, that will execute all requested actions. */
- public TransactionExecutor(ClientTransactionHandler clientTransactionHandler) {
+ public TransactionExecutor(@NonNull ClientTransactionHandler clientTransactionHandler) {
mTransactionHandler = clientTransactionHandler;
}
@@ -122,6 +129,9 @@ public class TransactionExecutor {
// Index of the last callback that requests some post-execution state.
final int lastCallbackRequestingState = lastCallbackRequestingState(transaction);
+ // Keep track of display ids whose Configuration got updated with this transaction.
+ ArraySet<Integer> configUpdatedDisplays = null;
+
final int size = callbacks.size();
for (int i = 0; i < size; ++i) {
final ClientTransactionItem item = callbacks.get(i);
@@ -136,7 +146,29 @@ public class TransactionExecutor {
}
}
+ // Can't read flag from isolated process.
+ final boolean isSyncWindowConfigUpdateFlagEnabled = !Process.isIsolated()
+ && syncWindowConfigUpdateFlag();
+ final Context configUpdatedContext = isSyncWindowConfigUpdateFlagEnabled
+ ? item.getContextToUpdate(mTransactionHandler, token)
+ : null;
+ final Configuration preExecutedConfig = configUpdatedContext != null
+ ? new Configuration(configUpdatedContext.getResources().getConfiguration())
+ : null;
+
item.execute(mTransactionHandler, token, mPendingActions);
+
+ if (configUpdatedContext != null) {
+ final Configuration postExecutedConfig = configUpdatedContext.getResources()
+ .getConfiguration();
+ if (!areConfigurationsEqualForDisplay(postExecutedConfig, preExecutedConfig)) {
+ if (configUpdatedDisplays == null) {
+ configUpdatedDisplays = new ArraySet<>();
+ }
+ configUpdatedDisplays.add(configUpdatedContext.getDisplayId());
+ }
+ }
+
item.postExecute(mTransactionHandler, token, mPendingActions);
if (r == null) {
// Launch activity request will create an activity record.
@@ -150,6 +182,13 @@ public class TransactionExecutor {
cycleToPath(r, postExecutionState, shouldExcludeLastTransition, transaction);
}
}
+
+ if (configUpdatedDisplays != null) {
+ final int displayCount = configUpdatedDisplays.size();
+ for (int i = 0; i < displayCount; i++) {
+ // TODO(b/260873529): trigger onDisplayChanged.
+ }
+ }
}
/** Transition to the final state if requested by the transaction. */
diff --git a/core/java/android/app/servertransaction/WindowContextInfoChangeItem.java b/core/java/android/app/servertransaction/WindowContextInfoChangeItem.java
index 74721d555081..99824b000b70 100644
--- a/core/java/android/app/servertransaction/WindowContextInfoChangeItem.java
+++ b/core/java/android/app/servertransaction/WindowContextInfoChangeItem.java
@@ -21,6 +21,7 @@ import static java.util.Objects.requireNonNull;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.app.ClientTransactionHandler;
+import android.content.Context;
import android.content.res.Configuration;
import android.os.IBinder;
import android.os.Parcel;
@@ -45,6 +46,13 @@ public class WindowContextInfoChangeItem extends ClientTransactionItem {
client.handleWindowContextInfoChanged(mClientToken, mInfo);
}
+ @Nullable
+ @Override
+ public Context getContextToUpdate(@NonNull ClientTransactionHandler client,
+ @Nullable IBinder token) {
+ return client.getWindowContext(mClientToken);
+ }
+
// ObjectPoolItem implementation
private WindowContextInfoChangeItem() {}
diff --git a/core/java/android/window/WindowTokenClient.java b/core/java/android/window/WindowTokenClient.java
index c1d1b2754895..f4f1b3b9b27b 100644
--- a/core/java/android/window/WindowTokenClient.java
+++ b/core/java/android/window/WindowTokenClient.java
@@ -22,6 +22,7 @@ import static android.window.ConfigurationHelper.shouldUpdateResources;
import android.annotation.AnyThread;
import android.annotation.MainThread;
import android.annotation.NonNull;
+import android.annotation.Nullable;
import android.app.ActivityThread;
import android.app.ResourcesManager;
import android.content.Context;
@@ -91,6 +92,15 @@ public class WindowTokenClient extends Binder {
}
/**
+ * Gets the {@link Context} that this {@link WindowTokenClient} is attached through
+ * {@link #attachContext(Context)}.
+ */
+ @Nullable
+ public Context getContext() {
+ return mContextRef != null ? mContextRef.get() : null;
+ }
+
+ /**
* Called when {@link Configuration} updates from the server side receive.
*
* @param newConfig the updated {@link Configuration}
diff --git a/core/java/android/window/WindowTokenClientController.java b/core/java/android/window/WindowTokenClientController.java
index 10f6d5e7abaa..abf7bb15b3d8 100644
--- a/core/java/android/window/WindowTokenClientController.java
+++ b/core/java/android/window/WindowTokenClientController.java
@@ -82,6 +82,16 @@ public class WindowTokenClientController {
private WindowTokenClientController() {}
+ /** Gets the {@link WindowContext} instance for the token. */
+ @Nullable
+ public Context getWindowContext(@NonNull IBinder clientToken) {
+ final WindowTokenClient windowTokenClient;
+ synchronized (mLock) {
+ windowTokenClient = mWindowTokenClientMap.get(clientToken);
+ }
+ return windowTokenClient != null ? windowTokenClient.getContext() : null;
+ }
+
/**
* Attaches a {@link WindowTokenClient} to a {@link com.android.server.wm.DisplayArea}.
*
diff --git a/core/tests/coretests/src/android/app/servertransaction/ActivityConfigurationChangeItemTest.java b/core/tests/coretests/src/android/app/servertransaction/ActivityConfigurationChangeItemTest.java
new file mode 100644
index 000000000000..1560c0c2c195
--- /dev/null
+++ b/core/tests/coretests/src/android/app/servertransaction/ActivityConfigurationChangeItemTest.java
@@ -0,0 +1,73 @@
+/*
+ * 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.app.servertransaction;
+
+import static org.junit.Assert.assertEquals;
+import static org.mockito.Mockito.doReturn;
+
+import android.app.Activity;
+import android.app.ClientTransactionHandler;
+import android.content.Context;
+import android.content.res.Configuration;
+import android.os.IBinder;
+import android.platform.test.annotations.Presubmit;
+
+import androidx.test.filters.SmallTest;
+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 ActivityConfigurationChangeItem}.
+ *
+ * Build/Install/Run:
+ * atest FrameworksCoreTests:ActivityConfigurationChangeItemTest
+ */
+@RunWith(AndroidJUnit4.class)
+@SmallTest
+@Presubmit
+public class ActivityConfigurationChangeItemTest {
+
+ @Mock
+ private ClientTransactionHandler mHandler;
+ @Mock
+ private IBinder mToken;
+ @Mock
+ private Activity mActivity;
+ // Can't mock final class.
+ private final Configuration mConfiguration = new Configuration();
+
+ @Before
+ public void setup() {
+ MockitoAnnotations.initMocks(this);
+ }
+
+ @Test
+ public void testGetContextToUpdate() {
+ doReturn(mActivity).when(mHandler).getActivity(mToken);
+
+ final ActivityConfigurationChangeItem item = ActivityConfigurationChangeItem
+ .obtain(mConfiguration);
+ final Context context = item.getContextToUpdate(mHandler, mToken);
+
+ assertEquals(mActivity, context);
+ }
+}
diff --git a/core/tests/coretests/src/android/app/servertransaction/ConfigurationChangeItemTest.java b/core/tests/coretests/src/android/app/servertransaction/ConfigurationChangeItemTest.java
new file mode 100644
index 000000000000..3926cfb14194
--- /dev/null
+++ b/core/tests/coretests/src/android/app/servertransaction/ConfigurationChangeItemTest.java
@@ -0,0 +1,70 @@
+/*
+ * 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.app.servertransaction;
+
+import static android.content.Context.DEVICE_ID_DEFAULT;
+
+import static org.junit.Assert.assertEquals;
+
+import android.app.ActivityThread;
+import android.app.ClientTransactionHandler;
+import android.content.Context;
+import android.content.res.Configuration;
+import android.os.IBinder;
+import android.platform.test.annotations.Presubmit;
+
+import androidx.test.filters.SmallTest;
+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 ConfigurationChangeItem}.
+ *
+ * Build/Install/Run:
+ * atest FrameworksCoreTests:ConfigurationChangeItemTest
+ */
+@RunWith(AndroidJUnit4.class)
+@SmallTest
+@Presubmit
+public class ConfigurationChangeItemTest {
+
+ @Mock
+ private ClientTransactionHandler mHandler;
+ @Mock
+ private IBinder mToken;
+ // Can't mock final class.
+ private final Configuration mConfiguration = new Configuration();
+
+ @Before
+ public void setup() {
+ MockitoAnnotations.initMocks(this);
+ }
+
+ @Test
+ public void testGetContextToUpdate() {
+ final ConfigurationChangeItem item = ConfigurationChangeItem
+ .obtain(mConfiguration, DEVICE_ID_DEFAULT);
+ final Context context = item.getContextToUpdate(mHandler, mToken);
+
+ assertEquals(ActivityThread.currentApplication(), context);
+ }
+}
diff --git a/core/tests/coretests/src/android/app/servertransaction/WindowContextInfoChangeItemTest.java b/core/tests/coretests/src/android/app/servertransaction/WindowContextInfoChangeItemTest.java
index 37a517e87c74..db76d26b063e 100644
--- a/core/tests/coretests/src/android/app/servertransaction/WindowContextInfoChangeItemTest.java
+++ b/core/tests/coretests/src/android/app/servertransaction/WindowContextInfoChangeItemTest.java
@@ -18,15 +18,24 @@ package android.app.servertransaction;
import static android.view.Display.DEFAULT_DISPLAY;
+import static org.junit.Assert.assertEquals;
+import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.verify;
import android.app.ClientTransactionHandler;
+import android.content.Context;
import android.content.res.Configuration;
import android.os.IBinder;
+import android.platform.test.annotations.Presubmit;
+import android.window.WindowContext;
import android.window.WindowContextInfo;
+import androidx.test.filters.SmallTest;
+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;
@@ -36,6 +45,9 @@ import org.mockito.MockitoAnnotations;
* Build/Install/Run:
* atest FrameworksCoreTests:WindowContextInfoChangeItemTest
*/
+@RunWith(AndroidJUnit4.class)
+@SmallTest
+@Presubmit
public class WindowContextInfoChangeItemTest {
@Mock
@@ -46,6 +58,8 @@ public class WindowContextInfoChangeItemTest {
private PendingTransactionActions mPendingActions;
@Mock
private IBinder mClientToken;
+ @Mock
+ private WindowContext mWindowContext;
// Can't mock final class.
private final Configuration mConfiguration = new Configuration();
@@ -63,4 +77,15 @@ public class WindowContextInfoChangeItemTest {
verify(mHandler).handleWindowContextInfoChanged(mClientToken,
new WindowContextInfo(mConfiguration, DEFAULT_DISPLAY));
}
+
+ @Test
+ public void testGetContextToUpdate() {
+ doReturn(mWindowContext).when(mHandler).getWindowContext(mClientToken);
+
+ final WindowContextInfoChangeItem item = WindowContextInfoChangeItem
+ .obtain(mClientToken, mConfiguration, DEFAULT_DISPLAY);
+ final Context context = item.getContextToUpdate(mHandler, mToken);
+
+ assertEquals(mWindowContext, context);
+ }
}
diff --git a/core/tests/coretests/src/android/app/servertransaction/WindowContextWindowRemovalItemTest.java b/core/tests/coretests/src/android/app/servertransaction/WindowContextWindowRemovalItemTest.java
index 2c83c70e9ae2..17e0ebc1edbc 100644
--- a/core/tests/coretests/src/android/app/servertransaction/WindowContextWindowRemovalItemTest.java
+++ b/core/tests/coretests/src/android/app/servertransaction/WindowContextWindowRemovalItemTest.java
@@ -20,9 +20,14 @@ import static org.mockito.Mockito.verify;
import android.app.ClientTransactionHandler;
import android.os.IBinder;
+import android.platform.test.annotations.Presubmit;
+
+import androidx.test.filters.SmallTest;
+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;
@@ -32,6 +37,9 @@ import org.mockito.MockitoAnnotations;
* Build/Install/Run:
* atest FrameworksCoreTests:WindowContextWindowRemovalItemTest
*/
+@RunWith(AndroidJUnit4.class)
+@SmallTest
+@Presubmit
public class WindowContextWindowRemovalItemTest {
@Mock
diff --git a/services/tests/wmtests/src/com/android/server/wm/WindowConfigurationTests.java b/services/tests/wmtests/src/com/android/server/wm/WindowConfigurationTests.java
index 45cd6a200d01..38aac7cfee22 100644
--- a/services/tests/wmtests/src/com/android/server/wm/WindowConfigurationTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/WindowConfigurationTests.java
@@ -30,6 +30,7 @@ import static android.app.WindowConfiguration.WINDOW_CONFIG_BOUNDS;
import static android.app.WindowConfiguration.WINDOW_CONFIG_MAX_BOUNDS;
import static android.app.WindowConfiguration.WINDOW_CONFIG_ROTATION;
import static android.app.WindowConfiguration.WINDOW_CONFIG_WINDOWING_MODE;
+import static android.app.WindowConfiguration.areConfigurationsEqualForDisplay;
import static android.content.pm.ActivityInfo.CONFIG_WINDOW_CONFIGURATION;
import static android.view.Surface.ROTATION_270;
@@ -269,4 +270,43 @@ public class WindowConfigurationTests extends WindowTestsBase {
config.setTo(other, justWindowingMode);
assertEquals(WINDOWING_MODE_UNDEFINED, config.getWindowingMode());
}
+
+ @Test
+ public void testAreConfigurationsEqualForDisplay() {
+ final Configuration config0 = new Configuration();
+ final Configuration config1 = new Configuration();
+
+ assertTrue(areConfigurationsEqualForDisplay(config0, config1));
+
+ // Only compare fields read in Display.
+ config0.densityDpi = 1;
+ config1.densityDpi = 2;
+
+ assertTrue(areConfigurationsEqualForDisplay(config0, config1));
+
+ // MaxBounds
+ final Rect bounds0 = new Rect(0, 0, 500, 1000);
+ final Rect bounds1 = new Rect(0, 0, 1000, 500);
+
+ config0.windowConfiguration.setMaxBounds(bounds0);
+ config1.windowConfiguration.setMaxBounds(bounds1);
+
+ assertFalse(areConfigurationsEqualForDisplay(config0, config1));
+
+ config0.windowConfiguration.setMaxBounds(null);
+ config1.windowConfiguration.setMaxBounds(null);
+
+ assertTrue(areConfigurationsEqualForDisplay(config0, config1));
+
+ // DisplayRotation
+ config0.windowConfiguration.setDisplayRotation(0);
+ config1.windowConfiguration.setDisplayRotation(1);
+
+ assertFalse(areConfigurationsEqualForDisplay(config0, config1));
+
+ config0.windowConfiguration.setDisplayRotation(2);
+ config1.windowConfiguration.setDisplayRotation(2);
+
+ assertTrue(areConfigurationsEqualForDisplay(config0, config1));
+ }
}