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

Commit d38f51a2 authored by Daniel Huang's avatar Daniel Huang Committed by Android (Google) Code Review
Browse files

Merge "Show dialog when user changes the region" into main

parents 8c067344 a1b89a03
Loading
Loading
Loading
Loading
+127 −20
Original line number Diff line number Diff line
@@ -41,7 +41,9 @@ import com.android.internal.app.LocaleStore;
import com.android.settings.R;
import com.android.settings.core.BasePreferenceController;
import com.android.settings.core.SubSettingLauncher;
import com.android.settings.flags.Flags;
import com.android.settings.overlay.FeatureFactory;
import com.android.settings.regionalpreferences.RegionDialogFragment;
import com.android.settingslib.core.instrumentation.Instrumentable;
import com.android.settingslib.core.instrumentation.MetricsFeatureProvider;

@@ -60,6 +62,28 @@ public abstract class LocalePickerBaseListPreferenceController extends
    private static final String PARENT_FRAGMENT_NAME = "localeListEditor";
    private static final String KEY_SUGGESTED = "suggested";
    private static final String KEY_SUPPORTED = "supported";
    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_REPLACED_TARGET_LOCALE = "arg_replaced_target_locale";
    private static final int DISPOSE = -1;
    /**
     * Display a dialog for modifying the system language region, which was previously present in
     * the system locale list.
     */
    private static final int SHOW_DIALOG_FOR_SYSTEM_LANGUAGE = 0;
    /**
     * Display a dialog for modifying the preferred language region, which was previously present in
     * the system locale list.
     */
    private static final int SHOW_DIALOG_FOR_PREFERRED_LANGUAGE = 1;
    private static final String ARG_DIALOG_TYPE = "arg_dialog_type";
    private static final String ARG_TARGET_LOCALE = "arg_target_locale";
    @VisibleForTesting
    protected static final String TAG_DIALOG_CHANGE_REGION_FOR_SYSTEM_LANGUAGE =
            "change_region_for_system_language";
    @VisibleForTesting
    protected static final String TAG_DIALOG_CHANGE_REGION_PREFERRED_LANGUAGE =
            "change_region_for_preferred_language";

    private PreferenceCategory mPreferenceCategory;
    private Set<LocaleStore.LocaleInfo> mLocaleList;
@@ -188,9 +212,7 @@ public abstract class LocalePickerBaseListPreferenceController extends
            pref.setTitle(localeName);
            pref.setKey(locale.toString());
            pref.setOnPreferenceClickListener(clickedPref -> {
                // TODO: b/390347399 - Should pop up a dialog when changes the region.
                switchFragment(locale);
                ((Activity) mContext).finish();
                return true;
            });
            mPreferences.put(locale.getId(), pref);
@@ -259,25 +281,30 @@ public abstract class LocalePickerBaseListPreferenceController extends
    void switchFragment(LocaleStore.LocaleInfo localeInfo) {
        boolean shouldShowLocaleEditor = shouldShowLocaleEditor(localeInfo);
        if (shouldShowLocaleEditor) {
            List<LocaleStore.LocaleInfo> feedItemList = getUserLocaleList();
            feedItemList.add(localeInfo);
            LocaleList localeList = new LocaleList(feedItemList.stream()
                    .map(LocaleStore.LocaleInfo::getLocale)
                    .toArray(Locale[]::new));
            LocaleList.setDefault(localeList);
            LocalePicker.updateLocales(localeList);
            mMetricsFeatureProvider.action(mContext, SettingsEnums.ACTION_ADD_LANGUAGE);
            returnToParentFrame();
            if (Flags.regionalPreferencesApiEnabled()) {
                int index = indexOfSameLanguageAndScript(localeInfo.getLocale());
                switch(getDialogEvent(index)) {
                    case SHOW_DIALOG_FOR_SYSTEM_LANGUAGE:
                        showDialogForRegionChanged(
                                localeInfo,
                                null,
                                DIALOG_CHANGE_SYSTEM_LOCALE_REGION);
                        break;
                    case SHOW_DIALOG_FOR_PREFERRED_LANGUAGE:
                        Locale replacedLocale = LocaleList.getDefault().get(index);
                        showDialogForRegionChanged(
                                localeInfo,
                                replacedLocale,
                                DIALOG_CHANGE_PREFERRED_LOCALE_REGION);
                        break;
                    default:
                        dispose(localeInfo);
                }
            } else {
            final Bundle extra = new Bundle();
            extra.putSerializable(RegionAndNumberingSystemPickerFragment.EXTRA_TARGET_LOCALE,
                    localeInfo);
            extra.putBoolean(EXTRA_IS_NUMBERING_SYSTEM, localeInfo.hasNumberingSystems());
            new SubSettingLauncher(mContext)
                    .setDestination(RegionAndNumberingSystemPickerFragment.class.getCanonicalName())
                    .setSourceMetricsCategory(Instrumentable.METRICS_CATEGORY_UNKNOWN)
                    .setArguments(extra)
                    .launch();
                dispose(localeInfo);
            }
        } else {
            showRegionAndNumberingSystemPickerFragment(localeInfo);
        }
    }

@@ -318,4 +345,84 @@ public abstract class LocalePickerBaseListPreferenceController extends
        }
        return result;
    }

    private void showRegionAndNumberingSystemPickerFragment(LocaleStore.LocaleInfo localeInfo) {
        final Bundle extra = new Bundle();
        extra.putSerializable(
                RegionAndNumberingSystemPickerFragment.EXTRA_TARGET_LOCALE, localeInfo);
        extra.putBoolean(EXTRA_IS_NUMBERING_SYSTEM, localeInfo.hasNumberingSystems());
        new SubSettingLauncher(mContext)
                .setDestination(RegionAndNumberingSystemPickerFragment.class.getCanonicalName())
                .setSourceMetricsCategory(Instrumentable.METRICS_CATEGORY_UNKNOWN)
                .setArguments(extra)
                .launch();
        ((Activity) mContext).finish();
    }

    private void dispose(LocaleStore.LocaleInfo localeInfo) {
        List<LocaleStore.LocaleInfo> feedItemList = getUserLocaleList();
        feedItemList.add(localeInfo);
        LocaleList localeList = new LocaleList(feedItemList.stream()
                .map(LocaleStore.LocaleInfo::getLocale)
                .toArray(Locale[]::new));
        LocaleList.setDefault(localeList);
        LocalePicker.updateLocales(localeList);
        mMetricsFeatureProvider.action(mContext, SettingsEnums.ACTION_ADD_LANGUAGE);
        returnToParentFrame();
        ((Activity) mContext).finish();
    }

    private void showDialogForRegionChanged(@NonNull LocaleStore.LocaleInfo locale,
            @Nullable Locale replacedLocale, int dialogType) {
        Bundle args = new Bundle();
        args.putInt(ARG_DIALOG_TYPE, dialogType);
        args.putSerializable(ARG_TARGET_LOCALE, locale);
        if (replacedLocale != null) {
            args.putSerializable(ARG_REPLACED_TARGET_LOCALE, replacedLocale);
        }
        RegionDialogFragment regionDialogFragment = RegionDialogFragment.newInstance();
        regionDialogFragment.setArguments(args);
        regionDialogFragment.show(
                mFragmentManager,
                replacedLocale == null
                    ? TAG_DIALOG_CHANGE_REGION_FOR_SYSTEM_LANGUAGE
                    : TAG_DIALOG_CHANGE_REGION_PREFERRED_LANGUAGE);
    }

    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;
                break;
            }
        }
        return index;
    }

    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;
        }
        return false;
    }
}
+2 −1
Original line number Diff line number Diff line
@@ -33,7 +33,6 @@ import android.widget.SearchView;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.core.view.ViewCompat;
import androidx.preference.PreferenceCategory;
import androidx.preference.PreferenceScreen;
import androidx.recyclerview.widget.RecyclerView;

@@ -351,6 +350,8 @@ public class RegionAndNumberingSystemPickerFragment extends DashboardFragment im
                    mIsNumberingMode);
            mSystemLocaleAllListPreferenceController = new SystemLocaleAllListPreferenceController(
                    context, KEY_PREFERENCE_SYSTEM_LOCALE_LIST, mLocaleInfo, mIsNumberingMode);
            mSuggestedListPreferenceController.setFragmentManager(getFragmentManager());
            mSystemLocaleAllListPreferenceController.setFragmentManager(getFragmentManager());
            controllers.add(mSuggestedListPreferenceController);
            controllers.add(mSystemLocaleAllListPreferenceController);
        } else {
+95 −15
Original line number Diff line number Diff line
@@ -15,55 +15,66 @@
 */
package com.android.settings.localepicker;

import static com.android.settings.SettingsActivity.EXTRA_SHOW_FRAGMENT;
import static com.android.settings.flags.Flags.FLAG_REGIONAL_PREFERENCES_API_ENABLED;
import static com.android.settings.localepicker.LocalePickerBaseListPreferenceController.TAG_DIALOG_CHANGE_REGION_FOR_SYSTEM_LANGUAGE;
import static com.android.settings.localepicker.LocalePickerBaseListPreferenceController.TAG_DIALOG_CHANGE_REGION_PREFERRED_LANGUAGE;

import static com.google.common.truth.Truth.assertThat;

import static org.junit.Assert.assertTrue;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyString;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;

import android.app.Activity;
import android.app.IActivityManager;
import android.content.Context;
import android.content.Intent;
import android.content.res.Configuration;
import android.os.LocaleList;
import android.os.Looper;
import android.platform.test.annotations.DisableFlags;
import android.platform.test.annotations.EnableFlags;
import android.platform.test.flag.junit.SetFlagsRule;
import android.telephony.TelephonyManager;
import android.util.ArrayMap;
import android.util.Log;

import com.android.internal.app.LocaleStore;
import com.android.settings.testutils.shadow.ShadowActivityManager;
import com.android.settings.testutils.shadow.ShadowFragment;

import androidx.fragment.app.FragmentActivity;
import androidx.fragment.app.FragmentManager;
import androidx.fragment.app.FragmentTransaction;
import androidx.preference.Preference;
import androidx.preference.PreferenceCategory;
import androidx.preference.PreferenceFragmentCompat;
import androidx.preference.PreferenceManager;
import androidx.preference.PreferenceScreen;
import androidx.test.core.app.ApplicationProvider;
import androidx.test.ext.junit.runners.AndroidJUnit4;

import com.android.internal.app.LocaleStore;
import com.android.settings.regionalpreferences.RegionDialogFragment;
import com.android.settings.testutils.shadow.ShadowActivityManager;
import com.android.settings.testutils.shadow.ShadowFragment;

import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import org.robolectric.Robolectric;
import org.robolectric.RobolectricTestRunner;
import org.robolectric.Shadows;
import org.robolectric.annotation.Config;
import org.robolectric.shadows.ShadowLocaleList;
import org.robolectric.shadows.ShadowTelephonyManager;
import org.robolectric.util.ReflectionHelpers;

import java.util.ArrayList;
import java.util.List;
import java.util.Locale;
import java.util.Map;

@RunWith(RobolectricTestRunner.class)
@@ -74,6 +85,7 @@ public class SystemLocaleAllListPreferenceControllerTest {
    private static final String KEY_SUPPORTED = "system_locale_list";

    private Context mContext;
    private FragmentActivity mActivity;
    private PreferenceManager mPreferenceManager;
    private PreferenceCategory mPreferenceCategory;
    private PreferenceScreen mPreferenceScreen;
@@ -88,11 +100,16 @@ public class SystemLocaleAllListPreferenceControllerTest {
    private LocaleStore.LocaleInfo mSupportedLocaleInfo_2;
    @Mock
    private FragmentTransaction mFragmentTransaction;
    @Mock
    private FragmentManager mFragmentManager;

    @Rule public final SetFlagsRule mSetFlagsRule = new SetFlagsRule();

    @Before
    public void setUp() throws Exception {
        MockitoAnnotations.initMocks(this);
        mContext = spy(ApplicationProvider.getApplicationContext());
        mContext = spy(Robolectric.setupActivity(Activity.class));
        mActivity = Robolectric.buildActivity(FragmentActivity.class).get();
        if (Looper.myLooper() == null) {
            Looper.prepare();
        }
@@ -115,6 +132,7 @@ public class SystemLocaleAllListPreferenceControllerTest {
        mPreferenceScreen = mPreferenceManager.createPreferenceScreen(mContext);
        mPreferenceCategory.setKey(KEY_CATEGORY_SYSTEM_SUPPORTED_LIST);
        mPreferenceScreen.addPreference(mPreferenceCategory);
        when(mFragmentManager.beginTransaction()).thenReturn(mFragmentTransaction);
        mController = new SystemLocaleAllListPreferenceController(mContext, KEY_SUPPORTED, null);
    }

@@ -152,27 +170,89 @@ public class SystemLocaleAllListPreferenceControllerTest {
    }

    @Test
    @DisableFlags(FLAG_REGIONAL_PREFERENCES_API_ENABLED)
    public void switchFragment_shouldShowLocaleEditor() {
        when(mSupportedLocaleInfo_1.isSuggested()).thenReturn(true);

        mController.setFragmentManager(mFragmentManager);
        mController.shouldShowLocaleEditor(mSupportedLocaleInfo_1);
        mController.switchFragment(mSupportedLocaleInfo_1);

        verify(mFragmentTransaction, never()).add(any(LocaleListEditor.class), anyString());
        verify(mFragmentManager).popBackStack(
                anyString(), eq(FragmentManager.POP_BACK_STACK_INCLUSIVE));
    }

    @Test
    @DisableFlags(FLAG_REGIONAL_PREFERENCES_API_ENABLED)
    public void switchFragment_shouldShowRegionNumberingPicker() {
        mController.displayPreference(mPreferenceScreen);
        Context activityContext = mock(Context.class);
        Context activityContext = spy(Robolectric.setupActivity(Activity.class));
        mController = new SystemLocaleAllListPreferenceController(activityContext, KEY_SUPPORTED,
                null);
        when(mSupportedLocaleInfo_1.isSuggested()).thenReturn(false);
        when(mSupportedLocaleInfo_1.isSystemLocale()).thenReturn(false);
        when(mSupportedLocaleInfo_1.getParent()).thenReturn(null);

        mController.setFragmentManager(mFragmentManager);
        mController.shouldShowLocaleEditor(mSupportedLocaleInfo_1);
        mController.switchFragment(mSupportedLocaleInfo_1);

        Intent intent = Shadows.shadowOf(mActivity.getApplication()).getNextStartedActivity();
        assertThat(intent.getStringExtra(EXTRA_SHOW_FRAGMENT))
                .isEqualTo(RegionAndNumberingSystemPickerFragment.class.getName());
    }

    @Test
    @EnableFlags(FLAG_REGIONAL_PREFERENCES_API_ENABLED)
    public void disposedEvent_switchFragment_shouldShowLocaleEditor() {
        ShadowLocaleList.reset();
        Locale defaultLocale1 = new Locale("de", "DE");
        Locale defaultLocale2 = new Locale("fr", "FR");
        Locale defaultLocale3 = new Locale("ja", "JP");
        LocaleList.setDefault(new LocaleList(defaultLocale1, defaultLocale2, defaultLocale3));
        when(mSupportedLocaleInfo_1.isSuggested()).thenReturn(true);

        mController.setFragmentManager(mFragmentManager);
        mController.shouldShowLocaleEditor(mSupportedLocaleInfo_1);
        mController.switchFragment(mSupportedLocaleInfo_1);

        verify(mFragmentManager).popBackStack(
                anyString(), eq(FragmentManager.POP_BACK_STACK_INCLUSIVE));
    }

    @Test
    @EnableFlags(FLAG_REGIONAL_PREFERENCES_API_ENABLED)
    public void changeSystemLanguageRegion_switchFragment_showDialogForTheEvent() {
        ShadowLocaleList.reset();
        Locale defaultLocale1 = new Locale("en", "IN"); //mSupportedLocaleInfo_1 is en_US
        Locale defaultLocale2 = new Locale("fr", "FR");
        Locale defaultLocale3 = new Locale("ja", "JP");
        LocaleList.setDefault(new LocaleList(defaultLocale1, defaultLocale2, defaultLocale3));
        when(mSupportedLocaleInfo_1.isSuggested()).thenReturn(true);

        mController.setFragmentManager(mFragmentManager);
        mController.shouldShowLocaleEditor(mSupportedLocaleInfo_1);
        mController.switchFragment(mSupportedLocaleInfo_1);

        verify(mFragmentTransaction).add(any(RegionDialogFragment.class),
                eq(TAG_DIALOG_CHANGE_REGION_FOR_SYSTEM_LANGUAGE));
    }

    @Test
    @EnableFlags(FLAG_REGIONAL_PREFERENCES_API_ENABLED)
    public void changePreferredLanguageRegion_switchFragment_showDialogForTheEvent() {
        ShadowLocaleList.reset();
        Locale defaultLocale1 = new Locale("fr", "FR");
        Locale defaultLocale2 = new Locale("en", "IN"); //mSupportedLocaleInfo_1 is en_US
        Locale defaultLocale3 = new Locale("ja", "JP");
        LocaleList.setDefault(new LocaleList(defaultLocale1, defaultLocale2, defaultLocale3));
        when(mSupportedLocaleInfo_1.isSuggested()).thenReturn(true);

        mController.setFragmentManager(mFragmentManager);
        mController.shouldShowLocaleEditor(mSupportedLocaleInfo_1);
        mController.switchFragment(mSupportedLocaleInfo_1);

        verify(mFragmentTransaction, never()).add(any(RegionAndNumberingSystemPickerFragment.class),
                anyString());
        verify(mFragmentTransaction).add(any(RegionDialogFragment.class),
                eq(TAG_DIALOG_CHANGE_REGION_PREFERRED_LANGUAGE));
    }
}
+96 −17

File changed.

Preview size limit exceeded, changes collapsed.