Don't override activity display adjustments with app config
When process configuration was applied on the client side it accidentally applied an override to display adjustments in resources for all ResourceImpl objects. This resulted in resources of activities having incorrect display adjustments and reporting incorrect display size. This CL fixes the issue by updating the applied config with the activity override. It also removes ResourcesManager#applyNonDefaultDisplayMetricsToConfiguration, which is no longer needed on the client side since the server-side is fully multi-display aware. Bug: 148639826 Test: ActivityThreadTest#testHandleConfigurationChangedDoesntOverrideActivityConfig Test: AppConfigurationTests#testDisplaySizeInSplitScreen Change-Id: Ib3ee007bcccd11451556b66274de4257cba082d4
This commit is contained in:
@@ -250,28 +250,6 @@ public class ResourcesManager {
|
||||
return dm;
|
||||
}
|
||||
|
||||
private static void applyNonDefaultDisplayMetricsToConfiguration(
|
||||
@NonNull DisplayMetrics dm, @NonNull Configuration config) {
|
||||
config.touchscreen = Configuration.TOUCHSCREEN_NOTOUCH;
|
||||
config.densityDpi = dm.densityDpi;
|
||||
config.screenWidthDp = (int) (dm.widthPixels / dm.density);
|
||||
config.screenHeightDp = (int) (dm.heightPixels / dm.density);
|
||||
int sl = Configuration.resetScreenLayout(config.screenLayout);
|
||||
if (dm.widthPixels > dm.heightPixels) {
|
||||
config.orientation = Configuration.ORIENTATION_LANDSCAPE;
|
||||
config.screenLayout = Configuration.reduceScreenLayout(sl,
|
||||
config.screenWidthDp, config.screenHeightDp);
|
||||
} else {
|
||||
config.orientation = Configuration.ORIENTATION_PORTRAIT;
|
||||
config.screenLayout = Configuration.reduceScreenLayout(sl,
|
||||
config.screenHeightDp, config.screenWidthDp);
|
||||
}
|
||||
config.smallestScreenWidthDp = Math.min(config.screenWidthDp, config.screenHeightDp);
|
||||
config.compatScreenWidthDp = config.screenWidthDp;
|
||||
config.compatScreenHeightDp = config.screenHeightDp;
|
||||
config.compatSmallestScreenWidthDp = config.smallestScreenWidthDp;
|
||||
}
|
||||
|
||||
public boolean applyCompatConfigurationLocked(int displayDensity,
|
||||
@NonNull Configuration compatConfiguration) {
|
||||
if (mResCompatibilityInfo != null && !mResCompatibilityInfo.supportsScreen()) {
|
||||
@@ -519,17 +497,11 @@ public class ResourcesManager {
|
||||
|
||||
private Configuration generateConfig(@NonNull ResourcesKey key, @NonNull DisplayMetrics dm) {
|
||||
Configuration config;
|
||||
final boolean isDefaultDisplay = (key.mDisplayId == Display.DEFAULT_DISPLAY);
|
||||
final boolean hasOverrideConfig = key.hasOverrideConfiguration();
|
||||
if (!isDefaultDisplay || hasOverrideConfig) {
|
||||
if (hasOverrideConfig) {
|
||||
config = new Configuration(getConfiguration());
|
||||
if (!isDefaultDisplay) {
|
||||
applyNonDefaultDisplayMetricsToConfiguration(dm, config);
|
||||
}
|
||||
if (hasOverrideConfig) {
|
||||
config.updateFrom(key.mOverrideConfiguration);
|
||||
if (DEBUG) Slog.v(TAG, "Applied overrideConfig=" + key.mOverrideConfiguration);
|
||||
}
|
||||
config.updateFrom(key.mOverrideConfiguration);
|
||||
if (DEBUG) Slog.v(TAG, "Applied overrideConfig=" + key.mOverrideConfiguration);
|
||||
} else {
|
||||
config = getConfiguration();
|
||||
}
|
||||
@@ -1110,8 +1082,6 @@ public class ResourcesManager {
|
||||
+ resourcesImpl + " config to: " + config);
|
||||
}
|
||||
int displayId = key.mDisplayId;
|
||||
final boolean hasOverrideConfiguration = key.hasOverrideConfiguration();
|
||||
tmpConfig.setTo(config);
|
||||
|
||||
// Get new DisplayMetrics based on the DisplayAdjustments given to the ResourcesImpl. Update
|
||||
// a copy if the CompatibilityInfo changed, because the ResourcesImpl object will handle the
|
||||
@@ -1121,15 +1091,12 @@ public class ResourcesManager {
|
||||
daj = new DisplayAdjustments(daj);
|
||||
daj.setCompatibilityInfo(compat);
|
||||
}
|
||||
daj.setConfiguration(config);
|
||||
DisplayMetrics dm = getDisplayMetrics(displayId, daj);
|
||||
if (displayId != Display.DEFAULT_DISPLAY) {
|
||||
applyNonDefaultDisplayMetricsToConfiguration(dm, tmpConfig);
|
||||
}
|
||||
|
||||
if (hasOverrideConfiguration) {
|
||||
tmpConfig.setTo(config);
|
||||
if (key.hasOverrideConfiguration()) {
|
||||
tmpConfig.updateFrom(key.mOverrideConfiguration);
|
||||
}
|
||||
daj.setConfiguration(tmpConfig);
|
||||
DisplayMetrics dm = getDisplayMetrics(displayId, daj);
|
||||
resourcesImpl.updateConfiguration(tmpConfig, dm, compat);
|
||||
}
|
||||
|
||||
|
||||
@@ -40,7 +40,10 @@ import android.app.servertransaction.ResumeActivityItem;
|
||||
import android.app.servertransaction.StopActivityItem;
|
||||
import android.content.Intent;
|
||||
import android.content.res.Configuration;
|
||||
import android.content.res.Resources;
|
||||
import android.graphics.Rect;
|
||||
import android.os.IBinder;
|
||||
import android.util.DisplayMetrics;
|
||||
import android.util.MergedConfiguration;
|
||||
import android.view.Display;
|
||||
import android.view.View;
|
||||
@@ -306,6 +309,58 @@ public class ActivityThreadTest {
|
||||
assertEquals(400, activity.mConfig.smallestScreenWidthDp);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testHandleConfigurationChangedDoesntOverrideActivityConfig() {
|
||||
final TestActivity activity = mActivityTestRule.launchActivity(new Intent());
|
||||
|
||||
InstrumentationRegistry.getInstrumentation().runOnMainSync(() -> {
|
||||
final Configuration oldActivityConfig =
|
||||
new Configuration(activity.getResources().getConfiguration());
|
||||
final DisplayMetrics oldActivityMetrics = new DisplayMetrics();
|
||||
activity.getDisplay().getMetrics(oldActivityMetrics);
|
||||
final Resources oldAppResources = activity.getApplication().getResources();
|
||||
final Configuration oldAppConfig =
|
||||
new Configuration(oldAppResources.getConfiguration());
|
||||
final DisplayMetrics oldApplicationMetrics = new DisplayMetrics();
|
||||
oldApplicationMetrics.setTo(oldAppResources.getDisplayMetrics());
|
||||
assertEquals("Process config must match the top activity config by default",
|
||||
0, oldActivityConfig.diffPublicOnly(oldAppConfig));
|
||||
assertEquals("Process config must match the top activity config by default",
|
||||
oldActivityMetrics, oldApplicationMetrics);
|
||||
|
||||
// Update the application configuration separately from activity config
|
||||
final Configuration newAppConfig = new Configuration(oldAppConfig);
|
||||
newAppConfig.densityDpi += 100;
|
||||
newAppConfig.screenHeightDp += 100;
|
||||
final Rect newBounds = new Rect(newAppConfig.windowConfiguration.getAppBounds());
|
||||
newBounds.bottom += 100;
|
||||
newAppConfig.windowConfiguration.setAppBounds(newBounds);
|
||||
newAppConfig.windowConfiguration.setBounds(newBounds);
|
||||
newAppConfig.seq++;
|
||||
|
||||
final ActivityThread activityThread = activity.getActivityThread();
|
||||
activityThread.handleConfigurationChanged(newAppConfig);
|
||||
|
||||
// Verify that application config update was applied, but didn't change activity config.
|
||||
assertEquals("Activity config must not change if the process config changes",
|
||||
oldActivityConfig, activity.getResources().getConfiguration());
|
||||
|
||||
final DisplayMetrics newActivityMetrics = new DisplayMetrics();
|
||||
activity.getDisplay().getMetrics(newActivityMetrics);
|
||||
assertEquals("Activity display size must not change if the process config changes",
|
||||
oldActivityMetrics, newActivityMetrics);
|
||||
final Resources newAppResources = activity.getApplication().getResources();
|
||||
assertEquals("Application config must be updated",
|
||||
newAppConfig, newAppResources.getConfiguration());
|
||||
final DisplayMetrics newApplicationMetrics = new DisplayMetrics();
|
||||
newApplicationMetrics.setTo(newAppResources.getDisplayMetrics());
|
||||
assertNotEquals("Application display size must be updated after config update",
|
||||
oldApplicationMetrics, newApplicationMetrics);
|
||||
assertNotEquals("Application display size must be updated after config update",
|
||||
newActivityMetrics, newApplicationMetrics);
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testResumeAfterNewIntent() {
|
||||
final Activity activity = mActivityTestRule.launchActivity(new Intent());
|
||||
|
||||
Reference in New Issue
Block a user