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

Commit 5139f57e authored by danielwbhuang's avatar danielwbhuang
Browse files

Show dialog for changing the region of non-system language

User wants to add the same language (non system language) with a different region. Adding the same language again with a different region will change the region of that language to the new region.

Bug: 388942734
Test: manual verification
Flag: EXEMPT bugfix
Change-Id: Ib124aa795277d5e1d66f3a98a16ab9bf1cfbe08f
parent 2871b8df
Loading
Loading
Loading
Loading
+3 −0
Original line number Diff line number Diff line
@@ -502,6 +502,9 @@
    <!-- The content of a confirmation dialog indicating the impact when the user change the system region. [CHAR LIMIT=NONE]-->
    <string name="desc_notice_device_region_change">Your device will keep %s as a system language</string>
    <!-- The content of a confirmation dialog indicating the impact when the user change the region of the preferred languages. [CHAR LIMIT=NONE]-->
    <string name="desc_notice_device_region_change_for_preferred_language">%1$s will replace %2$s in your preferred languages</string>
    <!-- Title for asking to change system locale or not. [CHAR LIMIT=50]-->
    <string name="title_change_system_locale">Change system language to %s ?</string>
+62 −10
Original line number Diff line number Diff line
@@ -28,6 +28,7 @@ import android.view.MenuItem;
import android.window.OnBackInvokedCallback;

import androidx.core.view.ViewCompat;
import androidx.fragment.app.FragmentManager;

import com.android.internal.app.LocalePickerWithRegion;
import com.android.internal.app.LocaleStore;
@@ -49,10 +50,15 @@ public class LocalePickerWithRegionActivity extends SettingsBaseActivity
    private static final String TAG = LocalePickerWithRegionActivity.class.getSimpleName();
    private static final String PARENT_FRAGMENT_NAME = "localeListEditor";
    private static final String CHILD_FRAGMENT_NAME = "LocalePickerWithRegion";
    private static final int DIALOG_CHANGE_LOCALE_REGION = 1;
    private static final int DIALOG_CHANGE_SYSTEM_LOCALE_REGION = 1;
    private static final int DIALOG_CHANGE_PREFERRED_LOCALE_REGION = 2;
    private static final String ARG_DIALOG_TYPE = "arg_dialog_type";
    private static final String ARG_TARGET_LOCALE = "arg_target_locale";
    private static final String ARG_REPLACED_TARGET_LOCALE = "arg_replaced_target_locale";
    private static final String TAG_DIALOG_CHANGE_REGION = "dialog_change_region";
    private static final int DISPOSE = -1;
    private static final int SHOW_DIALOG_FOR_SYSTEM_LANGUAGE = 0;
    private static final int SHOW_DIALOG_FOR_PREFERRED_LANGUAGE = 1;

    private LocalePickerWithRegion mSelector;

@@ -111,19 +117,65 @@ public class LocalePickerWithRegionActivity extends SettingsBaseActivity
    @Override
    public void onLocaleSelected(LocaleStore.LocaleInfo locale) {
        if (Flags.regionalPreferencesApiEnabled()) {
            if (sameLanguageAndScript(locale.getLocale(), LocaleList.getDefault().get(0))) {
            int index = indexOfSameLanguageAndScript(locale.getLocale());
            switch(getDialogEvent(index)) {
                case SHOW_DIALOG_FOR_SYSTEM_LANGUAGE:
                    showDialogForSystemLanguage(locale, getSupportFragmentManager());
                    break;
                case SHOW_DIALOG_FOR_PREFERRED_LANGUAGE:
                    Locale replacedLocale = LocaleList.getDefault().get(index);
                    showDialogForPreferredLanguage(
                            locale, replacedLocale, getSupportFragmentManager());
                    break;
                default:
                    dispose(locale);
            }
        } else {
            dispose(locale);
        }
    }

    private static void showDialogForSystemLanguage(
            LocaleStore.LocaleInfo locale, FragmentManager fragmentManager) {
        Bundle args = new Bundle();
                args.putInt(ARG_DIALOG_TYPE, DIALOG_CHANGE_LOCALE_REGION);
        args.putInt(ARG_DIALOG_TYPE, DIALOG_CHANGE_SYSTEM_LOCALE_REGION);
        args.putSerializable(ARG_TARGET_LOCALE, locale);
        RegionDialogFragment regionDialogFragment = RegionDialogFragment.newInstance();
        regionDialogFragment.setArguments(args);
                regionDialogFragment.show(getSupportFragmentManager(), TAG_DIALOG_CHANGE_REGION);
            } else {
                dispose(locale);
        regionDialogFragment.show(fragmentManager, TAG_DIALOG_CHANGE_REGION);
    }

    private static void showDialogForPreferredLanguage(
            LocaleStore.LocaleInfo locale, Locale replacedLocale, FragmentManager fragmentManager) {
        Bundle args = new Bundle();
        args.putInt(ARG_DIALOG_TYPE, DIALOG_CHANGE_PREFERRED_LOCALE_REGION);
        args.putSerializable(ARG_TARGET_LOCALE, locale);
        args.putSerializable(ARG_REPLACED_TARGET_LOCALE, replacedLocale);
        RegionDialogFragment regionDialogFragment = RegionDialogFragment.newInstance();
        regionDialogFragment.setArguments(args);
        regionDialogFragment.show(fragmentManager, TAG_DIALOG_CHANGE_REGION);
    }

    private static int getDialogEvent(int index) {
        if (index == -1) {
            return DISPOSE;
        }

        return index == 0
            ? SHOW_DIALOG_FOR_SYSTEM_LANGUAGE
            : SHOW_DIALOG_FOR_PREFERRED_LANGUAGE;
    }

    private static int indexOfSameLanguageAndScript(Locale source) {
        int index = -1;
        LocaleList localeList = LocaleList.getDefault();
        for (int i = 0; i < localeList.size(); i++) {
            Locale target = localeList.get(i);
            if (sameLanguageAndScript(source, target)) {
                index = i;
            }
        } else {
            dispose(locale);
        }
        return index;
    }

    private static boolean sameLanguageAndScript(Locale source, Locale target) {
+55 −12
Original line number Diff line number Diff line
@@ -47,9 +47,11 @@ import java.util.Set;
 */
public class RegionDialogFragment extends InstrumentedDialogFragment {
    private static final String TAG = "RegionDialogFragment";
    static final int DIALOG_CHANGE_LOCALE_REGION = 1;
    static final int DIALOG_CHANGE_SYSTEM_LOCALE_REGION = 1;
    static final int DIALOG_CHANGE_PREFERRED_LOCALE_REGION = 2;
    static final String ARG_DIALOG_TYPE = "arg_dialog_type";
    static final String ARG_TARGET_LOCALE = "arg_target_locale";
    static final String ARG_REPLACED_TARGET_LOCALE = "arg_replaced_target_locale";

    /**
     * Use this factory method to create a new instance of
@@ -113,6 +115,7 @@ public class RegionDialogFragment extends InstrumentedDialogFragment {
        private final Context mContext;
        private final int mDialogType;
        private final LocaleStore.LocaleInfo mLocaleInfo;
        private final Locale mReplacedLocale;
        private final MetricsFeatureProvider mMetricsFeatureProvider;

        RegionDialogController(
@@ -121,23 +124,26 @@ public class RegionDialogFragment extends InstrumentedDialogFragment {
            Bundle arguments = dialogFragment.getArguments();
            mDialogType = arguments.getInt(ARG_DIALOG_TYPE);
            mLocaleInfo = (LocaleStore.LocaleInfo) arguments.getSerializable(ARG_TARGET_LOCALE);
            mReplacedLocale = (Locale) arguments.getSerializable(ARG_REPLACED_TARGET_LOCALE);
            mMetricsFeatureProvider =
                FeatureFactory.getFeatureFactory().getMetricsFeatureProvider();
        }

        @Override
        public void onClick(@NonNull DialogInterface dialog, int which) {
            if (mDialogType == DIALOG_CHANGE_LOCALE_REGION) {
            if (mDialogType == DIALOG_CHANGE_SYSTEM_LOCALE_REGION
                    || mDialogType == DIALOG_CHANGE_PREFERRED_LOCALE_REGION) {
                if (which == DialogInterface.BUTTON_POSITIVE) {
                    updateRegion(mLocaleInfo.getLocale().toLanguageTag());
                    mMetricsFeatureProvider.action(
                            mContext,
                            SettingsEnums.ACTION_CHANGE_REGION_DIALOG_POSITIVE_BTN_CLICKED);
                }
                if (which == DialogInterface.BUTTON_NEGATIVE) {
                    // TODO: add new metrics for DIALOG_CHANGE_PREFERRED_LOCALE_REGION
                } else {
                    mMetricsFeatureProvider.action(
                            mContext,
                            SettingsEnums.ACTION_CHANGE_REGION_DIALOG_NEGATIVE_BTN_CLICKED);
                    // TODO: add new metrics for DIALOG_CHANGE_PREFERRED_LOCALE_REGION
                }
                dismiss();
                if (getActivity() != null) {
@@ -150,7 +156,7 @@ public class RegionDialogFragment extends InstrumentedDialogFragment {
        DialogContent getDialogContent() {
            DialogContent dialogContent = new DialogContent();
            switch (mDialogType) {
                case DIALOG_CHANGE_LOCALE_REGION:
                case DIALOG_CHANGE_SYSTEM_LOCALE_REGION:
                    dialogContent.mTitle = String.format(mContext.getString(
                        R.string.title_change_system_region),
                        mLocaleInfo.getLocale().getDisplayCountry());
@@ -161,6 +167,18 @@ public class RegionDialogFragment extends InstrumentedDialogFragment {
                        R.string.button_label_confirmation_of_system_locale_change);
                    dialogContent.mNegativeButton = mContext.getString(R.string.cancel);
                    break;
                case DIALOG_CHANGE_PREFERRED_LOCALE_REGION:
                    dialogContent.mTitle = String.format(mContext.getString(
                            R.string.title_change_system_region),
                        mLocaleInfo.getLocale().getDisplayCountry());
                    dialogContent.mMessage = mContext.getString(
                        R.string.desc_notice_device_region_change_for_preferred_language,
                        mLocaleInfo.getFullNameNative(),
                        LocaleStore.getLocaleInfo(mReplacedLocale).getFullNameNative());
                    dialogContent.mPositiveButton = mContext.getString(
                        R.string.button_label_confirmation_of_system_locale_change);
                    dialogContent.mNegativeButton = mContext.getString(R.string.cancel);
                    break;
                default:
                    break;
            }
@@ -168,10 +186,27 @@ public class RegionDialogFragment extends InstrumentedDialogFragment {
        }

        private void updateRegion(String selectedLanguageTag) {
            Locale[] newLocales = getUpdatedLocales(Locale.forLanguageTag(selectedLanguageTag));
            LocalePicker.updateLocales(new LocaleList(newLocales));
        }

        private Locale[] getUpdatedLocales(Locale selectedLocale) {
            LocaleList localeList = LocaleList.getDefault();
            Locale[] newLocales = new Locale[localeList.size()];
            for (int i = 0; i < localeList.size(); i++) {
                Locale target = localeList.get(i);
                if (sameLanguageAndScript(selectedLocale, target)) {
                    newLocales[i] = appendLocaleExtension(selectedLocale);
                } else {
                    newLocales[i] = localeList.get(i);
                }
            }
            return newLocales;
        }

        private Locale appendLocaleExtension(Locale selectedLocale) {
            Locale systemLocale = Locale.getDefault();
            Set<Character> extensionKeys = systemLocale.getExtensionKeys();
            Locale selectedLocale = Locale.forLanguageTag(selectedLanguageTag);
            Locale.Builder builder = new Locale.Builder();
            builder.setLocale(selectedLocale);
            if (!extensionKeys.isEmpty()) {
@@ -179,13 +214,21 @@ public class RegionDialogFragment extends InstrumentedDialogFragment {
                    builder.setExtension(extKey, systemLocale.getExtension(extKey));
                }
            }
            Locale newLocale = builder.build();
            Locale[] resultLocales = new Locale[localeList.size()];
            resultLocales[0] = newLocale;
            for (int i = 1; i < localeList.size(); i++) {
                resultLocales[i] = localeList.get(i);
            return builder.build();
        }

        private static boolean sameLanguageAndScript(Locale source, Locale target) {
            String sourceLanguage = source.getLanguage();
            String targetLanguage = target.getLanguage();
            String sourceLocaleScript = source.getScript();
            String targetLocaleScript = target.getScript();
            if (sourceLanguage.equals(targetLanguage)) {
                if (!sourceLocaleScript.isEmpty() && !targetLocaleScript.isEmpty()) {
                    return sourceLocaleScript.equals(targetLocaleScript);
                }
                return true;
            }
            LocalePicker.updateLocales(new LocaleList(resultLocales));
            return false;
        }

        @VisibleForTesting
+1 −1
Original line number Diff line number Diff line
@@ -169,7 +169,7 @@ public abstract class RegionPickerBaseListPreferenceController extends BasePrefe
        mFragmentManager = mParent.getChildFragmentManager();
        Bundle args = new Bundle();
        args.putInt(RegionDialogFragment.ARG_DIALOG_TYPE,
                RegionDialogFragment.DIALOG_CHANGE_LOCALE_REGION);
                RegionDialogFragment.DIALOG_CHANGE_SYSTEM_LOCALE_REGION);
        args.putSerializable(RegionDialogFragment.ARG_TARGET_LOCALE, localeInfo);
        RegionDialogFragment regionDialogFragment = RegionDialogFragment.newInstance();
        regionDialogFragment.setArguments(args);