Merge "Handle WindowProviderService#onConfigurationChanged" into sc-v2-dev

This commit is contained in:
Charles Chen
2021-06-18 06:37:49 +00:00
committed by Android (Google) Code Review
8 changed files with 369 additions and 91 deletions

View File

@@ -18,7 +18,6 @@ package android.app;
import static android.app.ActivityManager.PROCESS_STATE_UNKNOWN;
import static android.app.ConfigurationController.createNewConfigAndUpdateIfNotNull;
import static android.app.ConfigurationController.freeTextLayoutCachesIfNeeded;
import static android.app.WindowConfiguration.WINDOWING_MODE_PINNED;
import static android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED;
import static android.app.servertransaction.ActivityLifecycleItem.ON_CREATE;
@@ -31,6 +30,10 @@ import static android.app.servertransaction.ActivityLifecycleItem.PRE_ON_CREATE;
import static android.content.ContentResolver.DEPRECATE_DATA_COLUMNS;
import static android.content.ContentResolver.DEPRECATE_DATA_PREFIX;
import static android.view.Display.INVALID_DISPLAY;
import static android.window.ConfigurationHelper.diffPublicWithSizeBuckets;
import static android.window.ConfigurationHelper.freeTextLayoutCachesIfNeeded;
import static android.window.ConfigurationHelper.isDifferentDisplay;
import static android.window.ConfigurationHelper.shouldUpdateResources;
import static com.android.internal.annotations.VisibleForTesting.Visibility.PACKAGE;
@@ -91,7 +94,6 @@ import android.database.sqlite.SQLiteDebug.DbStats;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.HardwareRenderer;
import android.graphics.Rect;
import android.graphics.Typeface;
import android.hardware.display.DisplayManagerGlobal;
import android.inputmethodservice.InputMethodService;
@@ -186,6 +188,7 @@ import android.webkit.WebView;
import android.window.SizeConfigurationBuckets;
import android.window.SplashScreen;
import android.window.SplashScreenView;
import android.window.WindowProviderService;
import com.android.internal.annotations.GuardedBy;
import com.android.internal.annotations.VisibleForTesting;
@@ -5756,7 +5759,7 @@ public final class ActivityThread extends ClientTransactionHandler
}
@Override
public ArrayList<ComponentCallbacks2> collectComponentCallbacks(boolean includeActivities) {
public ArrayList<ComponentCallbacks2> collectComponentCallbacks(boolean includeUiContexts) {
ArrayList<ComponentCallbacks2> callbacks
= new ArrayList<ComponentCallbacks2>();
@@ -5765,7 +5768,7 @@ public final class ActivityThread extends ClientTransactionHandler
for (int i=0; i<NAPP; i++) {
callbacks.add(mAllApplications.get(i));
}
if (includeActivities) {
if (includeUiContexts) {
for (int i = mActivities.size() - 1; i >= 0; i--) {
final Activity a = mActivities.valueAt(i).activity;
if (a != null && !a.mFinished) {
@@ -5775,11 +5778,15 @@ public final class ActivityThread extends ClientTransactionHandler
}
final int NSVC = mServices.size();
for (int i=0; i<NSVC; i++) {
final ComponentCallbacks2 serviceComp = mServices.valueAt(i);
if (serviceComp instanceof InputMethodService) {
final Service service = mServices.valueAt(i);
if (service instanceof InputMethodService) {
mHasImeComponent = true;
}
callbacks.add(serviceComp);
// If {@code includeUiContext} is set to false, WindowProviderService should not be
// collected because WindowProviderService is a UI Context.
if (includeUiContexts || !(service instanceof WindowProviderService)) {
callbacks.add(service);
}
}
}
synchronized (mProviderMap) {
@@ -5834,35 +5841,26 @@ public final class ActivityThread extends ClientTransactionHandler
// change callback, see also PinnedStackTests#testConfigurationChangeOrderDuringTransition
handleWindowingModeChangeIfNeeded(activity, newConfig);
final boolean movedToDifferentDisplay = isDifferentDisplay(activity, displayId);
boolean shouldReportChange = false;
if (activity.mCurrentConfig == null) {
shouldReportChange = true;
} else {
// If the new config is the same as the config this Activity is already running with and
// the override config also didn't change, then don't bother calling
// onConfigurationChanged.
// TODO(b/173090263): Use diff instead after the improvement of AssetManager and
// ResourcesImpl constructions.
int diff = activity.mCurrentConfig.diffPublicOnly(newConfig);
final ActivityClientRecord cr = getActivityClient(activityToken);
diff = SizeConfigurationBuckets.filterDiff(diff, activity.mCurrentConfig, newConfig,
cr != null ? cr.mSizeConfigurations : null);
if (diff == 0) {
if (!shouldUpdateWindowMetricsBounds(activity.mCurrentConfig, newConfig)
&& !movedToDifferentDisplay
&& mResourcesManager.isSameResourcesOverrideConfig(
activityToken, amOverrideConfig)) {
// Nothing significant, don't proceed with updating and reporting.
return null;
}
} else if ((~activity.mActivityInfo.getRealConfigChanged() & diff) == 0) {
final boolean movedToDifferentDisplay = isDifferentDisplay(activity.getDisplayId(),
displayId);
final SizeConfigurationBuckets buckets = getActivityClient(activityToken)
.mSizeConfigurations;
final int diff = diffPublicWithSizeBuckets(activity.mCurrentConfig,
newConfig, buckets);
final boolean hasPublicConfigChange = diff != 0;
// TODO(b/173090263): Use diff instead after the improvement of AssetManager and
// ResourcesImpl constructions.
final boolean shouldUpdateResources = hasPublicConfigChange
|| shouldUpdateResources(activityToken, activity.mCurrentConfig, newConfig,
amOverrideConfig, movedToDifferentDisplay, hasPublicConfigChange);
final boolean shouldReportChange = hasPublicConfigChange
// If this activity doesn't handle any of the config changes, then don't bother
// calling onConfigurationChanged. Otherwise, report to the activity for the
// changes.
shouldReportChange = true;
}
&& (~activity.mActivityInfo.getRealConfigChanged() & diff) == 0;
// Nothing significant, don't proceed with updating and reporting.
if (!shouldUpdateResources) {
return null;
}
// Propagate the configuration change to ResourcesManager and Activity.
@@ -5913,26 +5911,6 @@ public final class ActivityThread extends ClientTransactionHandler
return configToReport;
}
// TODO(b/173090263): Remove this method after the improvement of AssetManager and ResourcesImpl
// constructions.
/**
* Returns {@code true} if the metrics reported by {@link android.view.WindowMetrics} APIs
* should be updated.
*
* @see WindowManager#getCurrentWindowMetrics()
* @see WindowManager#getMaximumWindowMetrics()
*/
private static boolean shouldUpdateWindowMetricsBounds(@NonNull Configuration currentConfig,
@NonNull Configuration newConfig) {
final Rect currentBounds = currentConfig.windowConfiguration.getBounds();
final Rect newBounds = newConfig.windowConfiguration.getBounds();
final Rect currentMaxBounds = currentConfig.windowConfiguration.getMaxBounds();
final Rect newMaxBounds = newConfig.windowConfiguration.getMaxBounds();
return !currentBounds.equals(newBounds) || !currentMaxBounds.equals(newMaxBounds);
}
public final void applyConfigurationToResources(Configuration config) {
synchronized (mResourcesManager) {
mResourcesManager.applyConfigurationToResources(config, null);
@@ -6080,7 +6058,8 @@ public final class ActivityThread extends ClientTransactionHandler
// display.
displayId = r.activity.getDisplayId();
}
final boolean movedToDifferentDisplay = isDifferentDisplay(r.activity, displayId);
final boolean movedToDifferentDisplay = isDifferentDisplay(
r.activity.getDisplayId(), displayId);
if (r.overrideConfig != null && !r.overrideConfig.isOtherSeqNewer(overrideConfig)
&& !movedToDifferentDisplay) {
if (DEBUG_CONFIGURATION) {
@@ -6116,14 +6095,6 @@ public final class ActivityThread extends ClientTransactionHandler
mSomeActivitiesChanged = true;
}
/**
* Checks if the display id of activity is different from the given one. Note that
* {@link Display#INVALID_DISPLAY} means no difference.
*/
private static boolean isDifferentDisplay(@NonNull Activity activity, int displayId) {
return displayId != INVALID_DISPLAY && displayId != activity.getDisplayId();
}
final void handleProfilerControl(boolean start, ProfilerInfo profilerInfo, int profileType) {
if (start) {
try {
@@ -6301,7 +6272,7 @@ public final class ActivityThread extends ClientTransactionHandler
final void handleLowMemory() {
final ArrayList<ComponentCallbacks2> callbacks =
collectComponentCallbacks(true /* includeActivities */);
collectComponentCallbacks(true /* includeUiContexts */);
final int N = callbacks.size();
for (int i=0; i<N; i++) {
@@ -6334,7 +6305,7 @@ public final class ActivityThread extends ClientTransactionHandler
}
final ArrayList<ComponentCallbacks2> callbacks =
collectComponentCallbacks(true /* includeActivities */);
collectComponentCallbacks(true /* includeUiContexts */);
final int N = callbacks.size();
for (int i = 0; i < N; i++) {

View File

@@ -38,5 +38,5 @@ interface ActivityThreadInternal {
Application getApplication();
ArrayList<ComponentCallbacks2> collectComponentCallbacks(boolean includeActivities);
ArrayList<ComponentCallbacks2> collectComponentCallbacks(boolean includeUiContexts);
}

View File

@@ -17,17 +17,16 @@
package android.app;
import static android.app.ActivityThread.DEBUG_CONFIGURATION;
import static android.window.ConfigurationHelper.freeTextLayoutCachesIfNeeded;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.content.ComponentCallbacks2;
import android.content.Context;
import android.content.pm.ActivityInfo;
import android.content.res.CompatibilityInfo;
import android.content.res.Configuration;
import android.content.res.Resources;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.HardwareRenderer;
import android.inputmethodservice.InputMethodService;
import android.os.Build;
@@ -228,7 +227,7 @@ class ConfigurationController {
}
final ArrayList<ComponentCallbacks2> callbacks =
mActivityThread.collectComponentCallbacks(false /* includeActivities */);
mActivityThread.collectComponentCallbacks(false /* includeUiContexts */);
freeTextLayoutCachesIfNeeded(configDiff);
@@ -326,16 +325,4 @@ class ConfigurationController {
return newConfig;
}
/** Ask test layout engine to free its caches if there is a locale change. */
static void freeTextLayoutCachesIfNeeded(int configDiff) {
if (configDiff != 0) {
boolean hasLocaleConfigChange = ((configDiff & ActivityInfo.CONFIG_LOCALE) != 0);
if (hasLocaleConfigChange) {
Canvas.freeTextLayoutCaches();
if (DEBUG_CONFIGURATION) {
Slog.v(TAG, "Cleared TextLayout Caches");
}
}
}
}
}

View File

@@ -730,7 +730,7 @@ public class ResourcesManager {
* @return true if activity resources override config matches the provided one or they are both
* null, false otherwise.
*/
boolean isSameResourcesOverrideConfig(@Nullable IBinder activityToken,
public boolean isSameResourcesOverrideConfig(@Nullable IBinder activityToken,
@Nullable Configuration overrideConfig) {
synchronized (mLock) {
final ActivityResources activityResources

View File

@@ -0,0 +1,132 @@
/*
* 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.INVALID_DISPLAY;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.app.ResourcesManager;
import android.content.Context;
import android.content.pm.ActivityInfo;
import android.content.res.Configuration;
import android.graphics.Canvas;
import android.graphics.Rect;
import android.os.IBinder;
import android.view.Display;
import android.view.WindowManager;
/**
* A helper class to maintain {@link android.content.res.Configuration} related methods used both
* in {@link android.app.Activity} and {@link WindowContext}.
*
* @hide
*/
public class ConfigurationHelper {
private ConfigurationHelper() {}
/** Ask text layout engine to free its caches if there is a locale change. */
public static void freeTextLayoutCachesIfNeeded(int configDiff) {
if ((configDiff & ActivityInfo.CONFIG_LOCALE) != 0) {
Canvas.freeTextLayoutCaches();
}
}
/**
* A helper method to filter out {@link ActivityInfo#CONFIG_SCREEN_SIZE} if the
* {@link Configuration#diffPublicOnly(Configuration) diff} of two {@link Configuration}
* doesn't cross the boundary.
*
* @see SizeConfigurationBuckets#filterDiff(int, Configuration, Configuration,
* SizeConfigurationBuckets)
*/
public static int diffPublicWithSizeBuckets(@Nullable Configuration currentConfig,
@NonNull Configuration newConfig, @Nullable SizeConfigurationBuckets buckets) {
// If current configuration is null, it is definitely different from updated Configuration.
if (currentConfig == null) {
return 0xffffffff;
}
int publicDiff = currentConfig.diffPublicOnly(newConfig);
return SizeConfigurationBuckets.filterDiff(publicDiff, currentConfig, newConfig, buckets);
}
/**
* Returns {@code true} if the {@link android.content.res.Resources} associated with
* a {@code token} needs to be updated.
*
* @param token A {@link Context#getActivityToken() activity token} or
* {@link Context#getWindowContextToken() window context token}
* @param config The original {@link Configuration}
* @param newConfig The updated Configuration
* @param displayChanged a flag to indicate there's a display change
* @param configChanged a flag to indicate there's a Configuration change.
*
* @see ResourcesManager#updateResourcesForActivity(IBinder, Configuration, int)
*/
public static boolean shouldUpdateResources(IBinder token, @Nullable Configuration config,
@NonNull Configuration newConfig, @NonNull Configuration overrideConfig,
boolean displayChanged, @Nullable Boolean configChanged) {
// The configuration has not yet been initialized. We should update it.
if (config == null) {
return true;
}
// If the token associated context is moved to another display, we should update the
// ResourcesKey.
if (displayChanged) {
return true;
}
// If the new config is the same as the config this Activity is already running with and
// the override config also didn't change, then don't update the Resources
if (!ResourcesManager.getInstance().isSameResourcesOverrideConfig(token, overrideConfig)) {
return true;
}
// If there's a update on WindowConfiguration#mBounds or maxBounds, we should update the
// Resources to make WindowMetrics API report the updated result.
if (shouldUpdateWindowMetricsBounds(config, newConfig)) {
return true;
}
return configChanged == null ? config.diff(newConfig) != 0 : configChanged;
}
/**
* Returns {@code true} if {@code displayId} is different from {@code newDisplayId}.
* Note that {@link Display#INVALID_DISPLAY} means no difference.
*/
public static boolean isDifferentDisplay(int displayId, int newDisplayId) {
return newDisplayId != INVALID_DISPLAY && displayId != newDisplayId;
}
// TODO(b/173090263): Remove this method after the improvement of AssetManager and ResourcesImpl
// constructions.
/**
* Returns {@code true} if the metrics reported by {@link android.view.WindowMetrics} APIs
* should be updated.
*
* @see WindowManager#getCurrentWindowMetrics()
* @see WindowManager#getMaximumWindowMetrics()
*/
private static boolean shouldUpdateWindowMetricsBounds(@NonNull Configuration currentConfig,
@NonNull Configuration newConfig) {
final Rect currentBounds = currentConfig.windowConfiguration.getBounds();
final Rect newBounds = newConfig.windowConfiguration.getBounds();
final Rect currentMaxBounds = currentConfig.windowConfiguration.getMaxBounds();
final Rect newMaxBounds = newConfig.windowConfiguration.getMaxBounds();
return !currentBounds.equals(newBounds) || !currentMaxBounds.equals(newMaxBounds);
}
}

View File

@@ -15,6 +15,11 @@
*/
package android.window;
import static android.window.ConfigurationHelper.diffPublicWithSizeBuckets;
import static android.window.ConfigurationHelper.freeTextLayoutCachesIfNeeded;
import static android.window.ConfigurationHelper.isDifferentDisplay;
import static android.window.ConfigurationHelper.shouldUpdateResources;
import android.annotation.NonNull;
import android.app.ActivityThread;
import android.app.IWindowToken;
@@ -33,7 +38,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
*/
@@ -46,11 +51,13 @@ public class WindowTokenClient extends IWindowToken.Stub {
private final ResourcesManager mResourcesManager = ResourcesManager.getInstance();
private final Configuration mConfiguration = new Configuration();
/**
* 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,
* {@link android.view.IWindowManager#attachWindowContextToDisplayArea(IBinder, int, int,
* Bundle, boolean)}.<p/>
*
* @param context context to be attached
@@ -61,6 +68,7 @@ public class WindowTokenClient extends IWindowToken.Stub {
throw new IllegalStateException("Context is already attached.");
}
mContextRef = new WeakReference<>(context);
mConfiguration.setTo(context.getResources().getConfiguration());
}
@Override
@@ -69,17 +77,34 @@ public class WindowTokenClient extends IWindowToken.Stub {
if (context == null) {
return;
}
final int currentDisplayId = context.getDisplayId();
final boolean displayChanged = newDisplayId != currentDisplayId;
final Configuration config = context.getResources().getConfiguration();
final boolean configChanged = config.diff(newConfig) != 0;
if (displayChanged || configChanged) {
final boolean displayChanged = isDifferentDisplay(context.getDisplayId(), newDisplayId);
final boolean shouldUpdateResources = shouldUpdateResources(this, mConfiguration,
newConfig, newConfig /* overrideConfig */, displayChanged,
null /* configChanged */);
if (shouldUpdateResources) {
// TODO(ag/9789103): update resource manager logic to track non-activity tokens
mResourcesManager.updateResourcesForActivity(this, newConfig, newDisplayId);
if (context instanceof WindowContext) {
ActivityThread.currentActivityThread().getHandler().post(
() -> ((WindowContext) context).dispatchConfigurationChanged(newConfig));
}
// Dispatch onConfigurationChanged only if there's a significant public change to
// make it compatible with the original behavior.
final Configuration[] sizeConfigurations = context.getResources()
.getSizeConfigurations();
final SizeConfigurationBuckets buckets = sizeConfigurations != null
? new SizeConfigurationBuckets(sizeConfigurations) : null;
final int diff = diffPublicWithSizeBuckets(mConfiguration, newConfig, buckets);
if (context instanceof WindowProviderService && diff != 0) {
ActivityThread.currentActivityThread().getHandler().post(() ->
((WindowProviderService) context).onConfigurationChanged(newConfig));
}
freeTextLayoutCachesIfNeeded(diff);
mConfiguration.setTo(newConfig);
}
if (displayChanged) {
context.updateDisplay(newDisplayId);

View File

@@ -0,0 +1,164 @@
/*
* 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 com.android.dx.mockito.inline.extended.ExtendedMockito.doReturn;
import static com.android.dx.mockito.inline.extended.ExtendedMockito.mockitoSession;
import static com.google.common.truth.Truth.assertThat;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.mock;
import android.app.ResourcesManager;
import android.content.res.Configuration;
import android.graphics.Rect;
import android.os.Binder;
import android.platform.test.annotations.Presubmit;
import androidx.test.ext.junit.runners.AndroidJUnit4;
import androidx.test.filters.SmallTest;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.MockitoSession;
import org.mockito.quality.Strictness;
/**
* Tests for {@link ConfigurationHelper}
*
* <p>Build/Install/Run:
* atest FrameworksMockingCoreTests:ConfigurationHelperTest
*
* <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 ConfigurationHelperTest {
MockitoSession mMockitoSession;
ResourcesManager mResourcesManager;
@Before
public void setUp() {
mMockitoSession = mockitoSession()
.strictness(Strictness.LENIENT)
.spyStatic(ResourcesManager.class)
.startMocking();
doReturn(mock(ResourcesManager.class)).when(ResourcesManager::getInstance);
mResourcesManager = ResourcesManager.getInstance();
}
@After
public void tearDown() {
mMockitoSession.finishMocking();
}
@Test
public void testShouldUpdateResources_NullConfig_ReturnsTrue() {
assertThat(ConfigurationHelper.shouldUpdateResources(new Binder(), null /* config */,
new Configuration(), new Configuration(), false /* displayChanged */,
null /* configChanged */)).isTrue();
}
@Test
public void testShouldUpdateResources_DisplayChanged_ReturnsTrue() {
assertThat(ConfigurationHelper.shouldUpdateResources(new Binder(), new Configuration(),
new Configuration(), new Configuration(), true /* displayChanged */,
null /* configChanged */)).isTrue();
}
@Test
public void testShouldUpdateResources_DifferentResources_ReturnsTrue() {
doReturn(false).when(mResourcesManager).isSameResourcesOverrideConfig(any(), any());
assertThat(ConfigurationHelper.shouldUpdateResources(new Binder(), new Configuration(),
new Configuration(), new Configuration(), false /* displayChanged */,
null /* configChanged */)).isTrue();
}
@Test
public void testShouldUpdateResources_DifferentBounds_ReturnsTrue() {
doReturn(true).when(mResourcesManager).isSameResourcesOverrideConfig(any(), any());
final Configuration config = new Configuration();
config.windowConfiguration.setBounds(new Rect(0, 0, 10, 10));
config.windowConfiguration.setMaxBounds(new Rect(0, 0, 20, 20));
final Configuration newConfig = new Configuration();
newConfig.windowConfiguration.setBounds(new Rect(0, 0, 20, 20));
newConfig.windowConfiguration.setMaxBounds(new Rect(0, 0, 20, 20));
assertThat(ConfigurationHelper.shouldUpdateResources(new Binder(), config, newConfig,
new Configuration(), false /* displayChanged */, null /* configChanged */))
.isTrue();
}
@Test
public void testShouldUpdateResources_SameConfig_ReturnsFalse() {
doReturn(true).when(mResourcesManager).isSameResourcesOverrideConfig(any(), any());
final Configuration config = new Configuration();
final Configuration newConfig = new Configuration();
assertThat(ConfigurationHelper.shouldUpdateResources(new Binder(), config, newConfig,
new Configuration(), false /* displayChanged */, null /* configChanged */))
.isFalse();
}
@Test
public void testShouldUpdateResources_DifferentConfig_ReturnsTrue() {
doReturn(true).when(mResourcesManager).isSameResourcesOverrideConfig(any(), any());
final Configuration config = new Configuration();
final Configuration newConfig = new Configuration();
newConfig.setToDefaults();
assertThat(ConfigurationHelper.shouldUpdateResources(new Binder(), config, newConfig,
new Configuration(), false /* displayChanged */, null /* configChanged */))
.isTrue();
}
@Test
public void testShouldUpdateResources_DifferentNonPublicConfig_ReturnsTrue() {
doReturn(true).when(mResourcesManager).isSameResourcesOverrideConfig(any(), any());
final Configuration config = new Configuration();
final Configuration newConfig = new Configuration();
newConfig.windowConfiguration.setAppBounds(new Rect(0, 0, 10, 10));
assertThat(ConfigurationHelper.shouldUpdateResources(new Binder(), config, newConfig,
new Configuration(), false /* displayChanged */, null /* configChanged */))
.isTrue();
}
@Test
public void testShouldUpdateResources_OverrideConfigChanged_ReturnsFalse() {
doReturn(true).when(mResourcesManager).isSameResourcesOverrideConfig(any(), any());
final Configuration config = new Configuration();
final Configuration newConfig = new Configuration();
final boolean configChanged = true;
assertThat(ConfigurationHelper.shouldUpdateResources(new Binder(), config, newConfig,
new Configuration(), false /* displayChanged */, configChanged))
.isEqualTo(configChanged);
}
}

View File

@@ -45,6 +45,7 @@ public final class FrameworksTestsFilter extends SelectTest {
// Test specifications for FrameworksMockingCoreTests.
"android.app.activity.ActivityThreadClientTest",
"android.view.DisplayTest",
"android.window.ConfigurationHelperTest",
// Test specifications for FrameworksCoreTests.
"android.app.servertransaction.", // all tests under the package.
"android.view.CutoutSpecificationTest",
@@ -59,10 +60,8 @@ public final class FrameworksTestsFilter extends SelectTest {
"android.view.RoundedCornersTest",
"android.view.WindowMetricsTest",
"android.view.PendingInsetsControllerTest",
"android.window.WindowContextTest",
"android.window.WindowMetricsHelperTest",
"android.window.", // all tests under the package.
"android.app.activity.ActivityThreadTest",
"android.window.WindowContextControllerTest"
};
public FrameworksTestsFilter(Bundle testArgs) {