From b43be0afff6c7ee4daaeb19058289e0ab66bf807 Mon Sep 17 00:00:00 2001 From: Andrii Kulian Date: Thu, 2 Mar 2017 17:29:40 -0800 Subject: [PATCH] Compute merged configuration changes When we compute configuration changes to decide whether to relaunch an activity or just report a coniguration change, we were calculating task override changes and global changes separately. This results in incorrect set of detected changes if we're moving between the displays. E.g. when moving from secondary display to the primary a lot of override config values change from empty to non-empty. This CL switches to calculating configuration changes for merged task configuration (global + overrides). In this second version switched to not marking change to undefined value as an actual change when comparing configuration, so it will behave similarly to Configuration#updateFrom. If new configuration with undefined value is applied to an old one with corresponding value already set, it won't be overwritten to undefined. Bug: 34164473 Bug: 35911519 Test: android.server.cts.ActivityManagerDisplayTests Test: #testOnMovedToDisplayCallback Change-Id: Ie1b90ccd2181aa5fdab4f57b9856e7de6959a6cb --- .../com/android/server/am/ActivityRecord.java | 45 +++++++------------ 1 file changed, 17 insertions(+), 28 deletions(-) diff --git a/services/core/java/com/android/server/am/ActivityRecord.java b/services/core/java/com/android/server/am/ActivityRecord.java index 10055c8d98f7f..75ea7468be7e6 100644 --- a/services/core/java/com/android/server/am/ActivityRecord.java +++ b/services/core/java/com/android/server/am/ActivityRecord.java @@ -2019,6 +2019,12 @@ final class ActivityRecord implements AppWindowContainerListener { // Okay we now are going to make this activity have the new config. // But then we need to figure out how it needs to deal with that. + + // Find changes between last reported merged configuration and the current one. This is used + // to decide whether to relaunch an activity or just report a configuration change. + final int changes = getTaskConfigurationChanges(mTmpConfig1); + + // Update last reported values. final Configuration newGlobalConfig = service.getGlobalConfiguration(); final Configuration newTaskMergedOverrideConfig = task.getMergedOverrideConfiguration(); mTmpConfig1.setTo(mLastReportedConfiguration); @@ -2026,9 +2032,6 @@ final class ActivityRecord implements AppWindowContainerListener { mLastReportedConfiguration.setTo(newGlobalConfig); mLastReportedOverrideConfiguration.setTo(newTaskMergedOverrideConfig); - int taskChanges = getTaskConfigurationChanges(this, newTaskMergedOverrideConfig, - mTmpConfig2); - final int changes = mTmpConfig1.diff(newGlobalConfig) | taskChanges; if (changes == 0 && !forceNewConfig) { if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION, "Configuration no differences in " + this); @@ -2043,8 +2046,7 @@ final class ActivityRecord implements AppWindowContainerListener { } if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION, - "Configuration changes for " + this + " ; taskChanges=" - + Configuration.configurationDiffToString(taskChanges) + ", allChanges=" + "Configuration changes for " + this + ", allChanges=" + Configuration.configurationDiffToString(changes)); // If the activity isn't currently running, just leave the new configuration and it will @@ -2142,40 +2144,27 @@ final class ActivityRecord implements AppWindowContainerListener { return (changes&(~configChanged)) != 0; } - private static int getTaskConfigurationChanges(ActivityRecord record, Configuration taskConfig, - Configuration oldTaskOverride) { - // If we went from full-screen to non-full-screen, make sure to use the correct - // configuration task diff, so the diff stays as small as possible. - if (Configuration.EMPTY.equals(oldTaskOverride) - && !Configuration.EMPTY.equals(taskConfig)) { - oldTaskOverride = record.task.extractOverrideConfig(record.mLastReportedConfiguration); - } - - // Conversely, do the same when going the other direction. - if (Configuration.EMPTY.equals(taskConfig) - && !Configuration.EMPTY.equals(oldTaskOverride)) { - taskConfig = record.task.extractOverrideConfig(record.mLastReportedConfiguration); - } - + private int getTaskConfigurationChanges(Configuration lastReportedConfig) { // Determine what has changed. May be nothing, if this is a config that has come back from // the app after going idle. In that case we just want to leave the official config object // now in the activity and do nothing else. - int taskChanges = oldTaskOverride.diff(taskConfig, true /* skipUndefined */); + final Configuration currentConfig = task.getConfiguration(); + int taskChanges = lastReportedConfig.diff(currentConfig); // We don't want to use size changes if they don't cross boundaries that are important to // the app. if ((taskChanges & CONFIG_SCREEN_SIZE) != 0) { - final boolean crosses = record.crossesHorizontalSizeThreshold( - oldTaskOverride.screenWidthDp, taskConfig.screenWidthDp) - || record.crossesVerticalSizeThreshold( - oldTaskOverride.screenHeightDp, taskConfig.screenHeightDp); + final boolean crosses = crossesHorizontalSizeThreshold(lastReportedConfig.screenWidthDp, + currentConfig.screenWidthDp) + || crossesVerticalSizeThreshold(lastReportedConfig.screenHeightDp, + currentConfig.screenHeightDp); if (!crosses) { taskChanges &= ~CONFIG_SCREEN_SIZE; } } if ((taskChanges & CONFIG_SMALLEST_SCREEN_SIZE) != 0) { - final int oldSmallest = oldTaskOverride.smallestScreenWidthDp; - final int newSmallest = taskConfig.smallestScreenWidthDp; - if (!record.crossesSmallestSizeThreshold(oldSmallest, newSmallest)) { + final int oldSmallest = lastReportedConfig.smallestScreenWidthDp; + final int newSmallest = currentConfig.smallestScreenWidthDp; + if (!crossesSmallestSizeThreshold(oldSmallest, newSmallest)) { taskChanges &= ~CONFIG_SMALLEST_SCREEN_SIZE; } }