Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 0c2ef7d7 authored by Treehugger Robot's avatar Treehugger Robot Committed by Android (Google) Code Review
Browse files

Merge "Ensure there is at least one locale in the Configuration object" into main

parents 4e290dcc a1d1e800
Loading
Loading
Loading
Loading
+108 −104
Original line number Diff line number Diff line
@@ -2629,12 +2629,16 @@ public class Resources {
    }

    /**
     * Called by ConfigurationBoundResourceCacheTest.
     * Called by ConfigurationBoundResourceCacheTest. Applies the new configuration, returning a
     * bitmask of the changes between the old and new configurations.
     *
     * @param config the new configuration
     * @return bitmask of config changes
     * @hide
     */
    @VisibleForTesting
    public int calcConfigChanges(Configuration config) {
        return mResourcesImpl.calcConfigChanges(config);
    public int applyConfigChanges(Configuration config) {
        return mResourcesImpl.applyConfigChanges(config);
    }

    /**
+68 −29
Original line number Diff line number Diff line
@@ -500,34 +500,55 @@ public class ResourcesImpl {
                // the framework.
                mDisplayAdjustments.getCompatibilityInfo().applyToDisplayMetrics(mMetrics);

                final @Config int configChanges = calcConfigChanges(config);
                final @Config int configChanges = applyConfigChanges(config);

                // If even after the update there are no Locales set, grab the default locales.
                LocaleList locales = mConfiguration.getLocales();
                if (locales.isEmpty()) {
                    locales = LocaleList.getDefault();
                    mConfiguration.setLocales(locales);
                LocaleList configLocales = mConfiguration.getLocales();
                if (configLocales.isEmpty()) {
                    configLocales = LocaleList.getDefault();
                    mConfiguration.setLocales(configLocales);
                }

                // Note: `locales` should be a list in the following order:
                // 1. App-specific locales (typically at most one, set by the user in settings)
                // 2. One or more system locales

                String[] selectedLocales = null;
                String defaultLocale = null;
                if ((configChanges & ActivityInfo.CONFIG_LOCALE) != 0) {
                    if (locales.size() > 1) {
                    if (configLocales.size() > 1) {
                        // There is more than one locale in the configuration. We need to update
                        // the locales in the configuration based on what is supported by the app
                        // so that we will use the same locales on other non-locale config changes.

                        Locale[] intersection = null;
                        if (Flags.defaultLocale() && (mLocaleConfig.getDefaultLocale() != null)) {
                            Locale[] intersection =
                                    locales.getIntersection(mLocaleConfig.getSupportedLocales());
                            // Note: getIntersection() returns a list of locales in the same order
                            // currently in `configLocales`, which is desired (i.e., app-specific
                            // locales first before system locales).
                            defaultLocale = adjustLanguageTag(
                                    mLocaleConfig.getDefaultLocale().toLanguageTag());
                            intersection =
                                    configLocales.getIntersection(
                                            mLocaleConfig.getSupportedLocales());
                            if (intersection.length > 0) {
                                mConfiguration.setLocales(new LocaleList(intersection));
                                selectedLocales = new String[intersection.length];
                                for (int i = 0; i < intersection.length; i++) {
                                    selectedLocales[i] =
                                            adjustLanguageTag(intersection[i].toLanguageTag());
                                }
                            defaultLocale = adjustLanguageTag(
                                    mLocaleConfig.getDefaultLocale().toLanguageTag());
                                Slog.v(TAG, "Updating configuration, with default locale "
                                        + defaultLocale + " and selected locales "
                                        + Arrays.toString(selectedLocales));
                        } else {
                            }
                        }

                        if (intersection == null || intersection.length == 0) {
                            // This is the fallback behavior when multi-locale is not enabled,
                            // or when there was no intersection between the app's supported
                            // locales and the locales in the configuration.

                            String[] availableLocales;
                            // The LocaleList has changed. We must query the AssetManager's
                            // available Locales and figure out the best matching Locale in the new
@@ -542,31 +563,46 @@ public class ResourcesImpl {
                            }

                            if (availableLocales != null) {
                                final Locale bestLocale = locales.getFirstMatchWithEnglishSupported(
                                final Locale bestLocale =
                                        configLocales.getFirstMatchWithEnglishSupported(
                                                availableLocales);
                                if (bestLocale != null) {
                                    selectedLocales = new String[]{
                                            adjustLanguageTag(bestLocale.toLanguageTag())};
                                    if (!bestLocale.equals(locales.get(0))) {
                                    if (!bestLocale.equals(configLocales.get(0))) {
                                        // There was an locale available in the app that matched.
                                        // Update the configuration so that it goes first.
                                        mConfiguration.setLocales(
                                                new LocaleList(bestLocale, locales));
                                                new LocaleList(bestLocale, configLocales));
                                        Slog.v(TAG, "Updating configuration with selected locales "
                                                + Arrays.toString(selectedLocales));
                                    }
                                }
                            }
                        }
                    }
                }
                if (selectedLocales == null) {

                if (selectedLocales == null || selectedLocales.length == 0) {
                    // Either:
                    // 1. The locales were not changed in the configuration, in which case we
                    //    use whatever was last set in the configuration.
                    // 2. Locales changed, but there was only one locale in the configuration, in
                    //    which case we simply use that locale.
                    // 3. Locales changed, and there were multiple locales in the configuration,
                    //    but the app does not support any of them, so we use whatever locales are
                    //    currently in the configuration.
                    if (Flags.defaultLocale() && (mLocaleConfig.getDefaultLocale() != null)) {
                        selectedLocales = new String[locales.size()];
                        for (int i = 0; i < locales.size(); i++) {
                            selectedLocales[i] = adjustLanguageTag(locales.get(i).toLanguageTag());
                        selectedLocales = new String[configLocales.size()];
                        for (int i = 0; i < configLocales.size(); i++) {
                            selectedLocales[i] =
                                    adjustLanguageTag(configLocales.get(i).toLanguageTag());
                        }
                        defaultLocale = adjustLanguageTag(
                                mLocaleConfig.getDefaultLocale().toLanguageTag());
                    } else {
                        selectedLocales = new String[]{
                                adjustLanguageTag(locales.get(0).toLanguageTag())};
                                adjustLanguageTag(configLocales.get(0).toLanguageTag())};
                    }
                }

@@ -646,7 +682,7 @@ public class ResourcesImpl {
     * @param config the new configuration
     * @return bitmask of config changes
     */
    public @Config int calcConfigChanges(@Nullable Configuration config) {
    public @Config int applyConfigChanges(@Nullable Configuration config) {
        if (config == null) {
            // If there is no configuration, assume all flags have changed.
            return 0xFFFFFFFF;
@@ -892,7 +928,10 @@ public class ResourcesImpl {
                }
            } else {
                if (verifyPreloadConfig(
                        changingConfigs, ActivityInfo.CONFIG_LAYOUT_DIRECTION, value.resourceId, "drawable")) {
                        changingConfigs,
                        ActivityInfo.CONFIG_LAYOUT_DIRECTION,
                        value.resourceId,
                        "drawable")) {
                    if ((changingConfigs & ActivityInfo.CONFIG_LAYOUT_DIRECTION) == 0) {
                        // If this resource does not vary based on layout direction,
                        // we can put it in all of the preload maps.
+6 −6
Original line number Diff line number Diff line
@@ -111,7 +111,7 @@ public class ConfigurationBoundResourceCacheTest {
        newCnf.orientation = cfg.orientation == Configuration.ORIENTATION_LANDSCAPE ?
                Configuration.ORIENTATION_PORTRAIT
                : Configuration.ORIENTATION_LANDSCAPE;
        int changes = calcConfigChanges(res, newCnf);
        int changes = applyConfigChanges(res, newCnf);
        assertEquals(staticDim, mCache.getInstance(key, res, mContext.getTheme()));
        mCache.onConfigurationChange(changes);
        assertEquals(staticDim, mCache.getInstance(key, res, mContext.getTheme()));
@@ -134,7 +134,7 @@ public class ConfigurationBoundResourceCacheTest {
        newCnf.orientation = cfg.orientation == Configuration.ORIENTATION_LANDSCAPE ?
                Configuration.ORIENTATION_PORTRAIT
                : Configuration.ORIENTATION_LANDSCAPE;
        int changes = calcConfigChanges(res, newCnf);
        int changes = applyConfigChanges(res, newCnf);
        assertEquals(changingDim,
                mCache.getInstance(key, res, mContext.getTheme()));
        mCache.onConfigurationChange(changes);
@@ -162,7 +162,7 @@ public class ConfigurationBoundResourceCacheTest {
        newCnf.orientation = cfg.orientation == Configuration.ORIENTATION_LANDSCAPE ?
                Configuration.ORIENTATION_PORTRAIT
                : Configuration.ORIENTATION_LANDSCAPE;
        int changes = calcConfigChanges(res, newCnf);
        int changes = applyConfigChanges(res, newCnf);
        assertEquals(staticDim, mCache.getInstance(R.dimen.resource_cache_test_generic, res,
                mContext.getTheme()));
        assertEquals(changingDim,
@@ -205,7 +205,7 @@ public class ConfigurationBoundResourceCacheTest {
        newCnf.orientation = cfg.orientation == Configuration.ORIENTATION_LANDSCAPE ?
                Configuration.ORIENTATION_PORTRAIT
                : Configuration.ORIENTATION_LANDSCAPE;
        int changes = calcConfigChanges(res, newCnf);
        int changes = applyConfigChanges(res, newCnf);
        for (int i = 0; i < 2; i++) {
            final Resources.Theme theme = i == 0 ? mContext.getTheme() : null;
            assertEquals(staticDim,
@@ -224,8 +224,8 @@ public class ConfigurationBoundResourceCacheTest {
        }
    }

    private static int calcConfigChanges(Resources resources, Configuration configuration) {
        return resources.calcConfigChanges(configuration);
    private static int applyConfigChanges(Resources resources, Configuration configuration) {
        return resources.applyConfigChanges(configuration);
    }

    static class DummyFloatConstantState extends ConstantState<Float> {