diff --git a/core/java/android/app/ActivityThread.java b/core/java/android/app/ActivityThread.java index d03b3474d268c..4a4bab55f0540 100644 --- a/core/java/android/app/ActivityThread.java +++ b/core/java/android/app/ActivityThread.java @@ -4893,7 +4893,8 @@ public final class ActivityThread { // 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. - int diff = activity.mCurrentConfig.diff(newConfig); + final int diff = activity.mCurrentConfig.diffPublicOnly(newConfig); + if (diff != 0 || !mResourcesManager.isSameResourcesOverrideConfig(activityToken, amOverrideConfig)) { // Always send the task-level config changes. For system-level configuration, if @@ -4981,6 +4982,14 @@ public final class ActivityThread { int configDiff = 0; + // This flag tracks whether the new configuration is fundamentally equivalent to the + // existing configuration. This is necessary to determine whether non-activity + // callbacks should receive notice when the only changes are related to non-public fields. + // We do not gate calling {@link #performActivityConfigurationChanged} based on this flag + // as that method uses the same check on the activity config override as well. + final boolean equivalent = config != null && mConfiguration != null + && (0 == mConfiguration.diffPublicOnly(config)); + synchronized (mResourcesManager) { if (mPendingConfiguration != null) { if (!mPendingConfiguration.isOtherSeqNewer(config)) { @@ -5037,7 +5046,7 @@ public final class ActivityThread { Activity a = (Activity) cb; performConfigurationChangedForActivity(mActivities.get(a.getActivityToken()), config); - } else { + } else if (!equivalent) { performConfigurationChanged(cb, config); } } diff --git a/core/java/android/app/ResourcesManager.java b/core/java/android/app/ResourcesManager.java index 6f326de76150b..636dea7ddaa11 100644 --- a/core/java/android/app/ResourcesManager.java +++ b/core/java/android/app/ResourcesManager.java @@ -44,8 +44,6 @@ import com.android.internal.util.ArrayUtils; import java.lang.ref.WeakReference; import java.util.ArrayList; -import java.util.Iterator; -import java.util.Map; import java.util.Objects; import java.util.WeakHashMap; import java.util.function.Predicate; @@ -417,7 +415,12 @@ public class ResourcesManager { if (activityResources == null) { return overrideConfig == null; } else { - return Objects.equals(activityResources.overrideConfig, overrideConfig); + // The two configurations must either be equal or publicly equivalent to be + // considered the same. + return Objects.equals(activityResources.overrideConfig, overrideConfig) + || (overrideConfig != null && activityResources.overrideConfig != null + && 0 == overrideConfig.diffPublicOnly( + activityResources.overrideConfig)); } } } diff --git a/core/java/android/content/res/Configuration.java b/core/java/android/content/res/Configuration.java index af2713199950b..f7cccd56f0795 100644 --- a/core/java/android/content/res/Configuration.java +++ b/core/java/android/content/res/Configuration.java @@ -1318,7 +1318,19 @@ public final class Configuration implements Parcelable, Comparable 0) && fontScale != delta.fontScale) { changed |= ActivityInfo.CONFIG_FONT_SCALE; @@ -1424,7 +1436,9 @@ public final class Configuration implements Parcelable, Comparable