1 /*
2  * Copyright (C) 2016 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package com.android.settings.localepicker;
18 
19 import static android.os.UserManager.DISALLOW_CONFIG_LOCALE;
20 
21 import static com.android.settings.flags.Flags.localeNotificationEnabled;
22 import static com.android.settings.localepicker.AppLocalePickerActivity.EXTRA_APP_LOCALE;
23 import static com.android.settings.localepicker.LocaleDialogFragment.DIALOG_ADD_SYSTEM_LOCALE;
24 import static com.android.settings.localepicker.LocaleDialogFragment.DIALOG_CONFIRM_SYSTEM_DEFAULT;
25 
26 import android.app.Activity;
27 import android.app.settings.SettingsEnums;
28 import android.content.Context;
29 import android.content.DialogInterface;
30 import android.content.Intent;
31 import android.content.res.Resources;
32 import android.os.Bundle;
33 import android.os.LocaleList;
34 import android.provider.Settings;
35 import android.text.TextUtils;
36 import android.util.Log;
37 import android.view.LayoutInflater;
38 import android.view.Menu;
39 import android.view.MenuInflater;
40 import android.view.MenuItem;
41 import android.view.MotionEvent;
42 import android.view.View;
43 import android.view.ViewGroup;
44 import android.widget.TextView;
45 
46 import androidx.annotation.VisibleForTesting;
47 import androidx.appcompat.app.AlertDialog;
48 import androidx.fragment.app.FragmentManager;
49 import androidx.preference.PreferenceScreen;
50 import androidx.recyclerview.widget.RecyclerView;
51 
52 import com.android.internal.app.LocalePicker;
53 import com.android.internal.app.LocaleStore;
54 import com.android.settings.R;
55 import com.android.settings.RestrictedSettingsFragment;
56 import com.android.settings.overlay.FeatureFactory;
57 import com.android.settings.search.BaseSearchIndexProvider;
58 import com.android.settingslib.search.SearchIndexable;
59 import com.android.settingslib.search.SearchIndexableRaw;
60 import com.android.settingslib.utils.StringUtil;
61 import com.android.settingslib.widget.LayoutPreference;
62 
63 import java.util.ArrayList;
64 import java.util.List;
65 import java.util.Locale;
66 
67 /**
68  * Drag-and-drop editor for the user-ordered locale lists.
69  */
70 @SearchIndexable
71 public class LocaleListEditor extends RestrictedSettingsFragment implements View.OnTouchListener {
72     protected static final String INTENT_LOCALE_KEY = "localeInfo";
73     protected static final String EXTRA_SYSTEM_LOCALE_DIALOG_TYPE = "system_locale_dialog_type";
74     protected static final String LOCALE_SUGGESTION = "locale_suggestion";
75 
76     private static final String TAG = LocaleListEditor.class.getSimpleName();
77     private static final String CFGKEY_REMOVE_MODE = "localeRemoveMode";
78     private static final String CFGKEY_REMOVE_DIALOG = "showingLocaleRemoveDialog";
79     private static final String CFGKEY_ADD_LOCALE = "localeAdded";
80     private static final String INDEX_KEY_ADD_LANGUAGE = "add_language";
81     private static final String KEY_LANGUAGES_PICKER = "languages_picker";
82     private static final String KEY_CATEGORY_TERMS_OF_ADDRESS = "key_category_terms_of_address";
83     private static final String TAG_DIALOG_CONFIRM_SYSTEM_DEFAULT = "dialog_confirm_system_default";
84     private static final String TAG_DIALOG_NOT_AVAILABLE = "dialog_not_available_locale";
85     private static final String TAG_DIALOG_ADD_SYSTEM_LOCALE = "dialog_add_system_locale";
86     private static final int MENU_ID_REMOVE = Menu.FIRST + 1;
87     private static final int REQUEST_LOCALE_PICKER = 0;
88 
89     private LocaleDragAndDropAdapter mAdapter;
90     private Menu mMenu;
91     private View mAddLanguage;
92     private AlertDialog mSuggestionDialog = null;
93     private boolean mRemoveMode;
94     private boolean mShowingRemoveDialog;
95     private boolean mLocaleAdditionMode = false;
96     private boolean mIsUiRestricted;
97 
98     private LayoutPreference mLocalePickerPreference;
99     private LocaleHelperPreferenceController mLocaleHelperPreferenceController;
100     private FragmentManager mFragmentManager;
101     private TermsOfAddressCategoryController mTermsOfAddressCategoryController;
102 
LocaleListEditor()103     public LocaleListEditor() {
104         super(DISALLOW_CONFIG_LOCALE);
105     }
106 
107     @Override
getMetricsCategory()108     public int getMetricsCategory() {
109         return SettingsEnums.USER_LOCALE_LIST;
110     }
111 
112     @Override
onCreate(Bundle savedInstanceState)113     public void onCreate(Bundle savedInstanceState) {
114         super.onCreate(savedInstanceState);
115         setHasOptionsMenu(true);
116 
117         addPreferencesFromResource(R.xml.languages);
118         final Activity activity = getActivity();
119         mLocaleHelperPreferenceController = new LocaleHelperPreferenceController(activity);
120         final PreferenceScreen screen = getPreferenceScreen();
121         mLocalePickerPreference = screen.findPreference(KEY_LANGUAGES_PICKER);
122         mLocaleHelperPreferenceController.displayPreference(screen);
123         mTermsOfAddressCategoryController = new TermsOfAddressCategoryController(activity,
124                 KEY_CATEGORY_TERMS_OF_ADDRESS);
125         mTermsOfAddressCategoryController.displayPreference(screen);
126 
127         LocaleStore.fillCache(this.getContext());
128         final List<LocaleStore.LocaleInfo> feedsList = getUserLocaleList();
129         mAdapter = new LocaleDragAndDropAdapter(this, feedsList);
130         mFragmentManager = getChildFragmentManager();
131     }
132 
133     @Override
onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstState)134     public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstState) {
135         configureDragAndDrop(mLocalePickerPreference);
136         return super.onCreateView(inflater, container, savedInstState);
137     }
138 
139     @Override
onResume()140     public void onResume() {
141         super.onResume();
142 
143         final boolean previouslyRestricted = mIsUiRestricted;
144         mIsUiRestricted = isUiRestricted();
145         final TextView emptyView = getEmptyTextView();
146         if (mIsUiRestricted && !previouslyRestricted) {
147             // Lock it down.
148             emptyView.setText(R.string.language_empty_list_user_restricted);
149             emptyView.setVisibility(View.VISIBLE);
150             updateVisibilityOfRemoveMenu();
151         } else if (!mIsUiRestricted && previouslyRestricted) {
152             // Unlock it.
153             emptyView.setVisibility(View.GONE);
154             updateVisibilityOfRemoveMenu();
155         }
156     }
157 
158     @Override
onViewStateRestored(Bundle savedInstanceState)159     public void onViewStateRestored(Bundle savedInstanceState) {
160         super.onViewStateRestored(savedInstanceState);
161         if (savedInstanceState != null) {
162             mRemoveMode = savedInstanceState.getBoolean(CFGKEY_REMOVE_MODE, false);
163             mShowingRemoveDialog = savedInstanceState.getBoolean(CFGKEY_REMOVE_DIALOG, false);
164             mLocaleAdditionMode = savedInstanceState.getBoolean(CFGKEY_ADD_LOCALE, false);
165         }
166         setRemoveMode(mRemoveMode);
167 
168         final LocaleDialogFragment dialogFragment =
169                 (LocaleDialogFragment) mFragmentManager.findFragmentByTag(
170                         TAG_DIALOG_CONFIRM_SYSTEM_DEFAULT);
171         boolean isDialogShowing = false;
172         if (dialogFragment != null && dialogFragment.isAdded()) {
173             isDialogShowing = true;
174         }
175         mAdapter.restoreState(savedInstanceState, isDialogShowing);
176 
177         if (mShowingRemoveDialog) {
178             showRemoveLocaleWarningDialog();
179         }
180         Log.d(TAG, "LocaleAdditionMode:" + mLocaleAdditionMode);
181         if (!mLocaleAdditionMode && shouldShowConfirmationDialog()) {
182             showDialogForAddedLocale();
183             mLocaleAdditionMode = true;
184         }
185     }
186 
187     @Override
onSaveInstanceState(Bundle outState)188     public void onSaveInstanceState(Bundle outState) {
189         super.onSaveInstanceState(outState);
190         outState.putBoolean(CFGKEY_REMOVE_MODE, mRemoveMode);
191         outState.putBoolean(CFGKEY_REMOVE_DIALOG, mShowingRemoveDialog);
192         outState.putBoolean(CFGKEY_ADD_LOCALE, mLocaleAdditionMode);
193         mAdapter.saveState(outState);
194     }
195 
196     @Override
onOptionsItemSelected(MenuItem menuItem)197     public boolean onOptionsItemSelected(MenuItem menuItem) {
198         switch (menuItem.getItemId()) {
199             case MENU_ID_REMOVE:
200                 if (mRemoveMode) {
201                     showRemoveLocaleWarningDialog();
202                 } else {
203                     setRemoveMode(true);
204                 }
205                 return true;
206             case android.R.id.home:
207                 if (mRemoveMode) {
208                     setRemoveMode(false);
209                     return true;
210                 }
211                 break;
212         }
213         return super.onOptionsItemSelected(menuItem);
214     }
215 
216     @Override
onActivityResult(int requestCode, int resultCode, Intent data)217     public void onActivityResult(int requestCode, int resultCode, Intent data) {
218         LocaleStore.LocaleInfo localeInfo;
219         if (requestCode == REQUEST_LOCALE_PICKER && resultCode == Activity.RESULT_OK
220                 && data != null) {
221             localeInfo = (LocaleStore.LocaleInfo) data.getSerializableExtra(INTENT_LOCALE_KEY);
222             String preferencesTags = Settings.System.getString(
223                     getContext().getContentResolver(), Settings.System.LOCALE_PREFERENCES);
224             localeInfo = mayAppendUnicodeTags(localeInfo, preferencesTags);
225             mAdapter.addLocale(localeInfo);
226             updateVisibilityOfRemoveMenu();
227             mMetricsFeatureProvider.action(getContext(), SettingsEnums.ACTION_ADD_LANGUAGE);
228         } else if (requestCode == DIALOG_CONFIRM_SYSTEM_DEFAULT) {
229             localeInfo = mAdapter.getFeedItemList().get(0);
230             if (resultCode == Activity.RESULT_OK) {
231                 mAdapter.doTheUpdate();
232                 if (!localeInfo.isTranslated()) {
233                     Bundle args = new Bundle();
234                     args.putInt(LocaleDialogFragment.ARG_DIALOG_TYPE,
235                             LocaleDialogFragment.DIALOG_NOT_AVAILABLE_LOCALE);
236                     args.putSerializable(LocaleDialogFragment.ARG_TARGET_LOCALE, localeInfo);
237                     LocaleDialogFragment localeDialogFragment = LocaleDialogFragment.newInstance();
238                     localeDialogFragment.setArguments(args);
239                     localeDialogFragment.show(mFragmentManager, TAG_DIALOG_NOT_AVAILABLE);
240                     mMetricsFeatureProvider.action(getContext(),
241                             SettingsEnums.ACTION_NOT_SUPPORTED_SYSTEM_LANGUAGE);
242                 }
243             } else {
244                 mAdapter.notifyListChanged(localeInfo);
245             }
246             mAdapter.setCacheItemList();
247         } else if (requestCode == DIALOG_ADD_SYSTEM_LOCALE) {
248             int action = SettingsEnums.ACTION_CANCEL_SYSTEM_LOCALE_FROM_RECOMMENDATION;
249             if (resultCode == Activity.RESULT_OK) {
250                 localeInfo = (LocaleStore.LocaleInfo) data.getExtras().getSerializable(
251                         LocaleDialogFragment.ARG_TARGET_LOCALE);
252                 String preferencesTags = Settings.System.getString(
253                         getContext().getContentResolver(),
254                         Settings.System.LOCALE_PREFERENCES);
255                 mAdapter.addLocale(mayAppendUnicodeTags(localeInfo, preferencesTags));
256                 action = SettingsEnums.ACTION_ADD_SYSTEM_LOCALE_FROM_RECOMMENDATION;
257             }
258             mMetricsFeatureProvider.action(getContext(), action);
259         }
260         super.onActivityResult(requestCode, resultCode, data);
261     }
262 
263     @VisibleForTesting
mayAppendUnicodeTags( LocaleStore.LocaleInfo localeInfo, String recordTags)264     static LocaleStore.LocaleInfo mayAppendUnicodeTags(
265             LocaleStore.LocaleInfo localeInfo, String recordTags) {
266         if (TextUtils.isEmpty(recordTags) || TextUtils.equals("und", recordTags)) {
267             // No recorded tag, return inputted LocaleInfo.
268             return localeInfo;
269         }
270         Locale recordLocale = Locale.forLanguageTag(recordTags);
271         Locale.Builder builder = new Locale.Builder()
272                 .setLocale(localeInfo.getLocale());
273         recordLocale.getUnicodeLocaleKeys().forEach(key ->
274                 builder.setUnicodeLocaleKeyword(key, recordLocale.getUnicodeLocaleType(key)));
275         LocaleStore.LocaleInfo newLocaleInfo = LocaleStore.fromLocale(builder.build());
276         newLocaleInfo.setTranslated(localeInfo.isTranslated());
277         return newLocaleInfo;
278     }
279 
setRemoveMode(boolean mRemoveMode)280     private void setRemoveMode(boolean mRemoveMode) {
281         this.mRemoveMode = mRemoveMode;
282         mAdapter.setRemoveMode(mRemoveMode);
283         mAddLanguage.setVisibility(mRemoveMode ? View.INVISIBLE : View.VISIBLE);
284         updateVisibilityOfRemoveMenu();
285     }
286 
shouldShowConfirmationDialog()287     private boolean shouldShowConfirmationDialog() {
288         Intent intent = this.getIntent();
289         String dialogType = intent.getStringExtra(EXTRA_SYSTEM_LOCALE_DIALOG_TYPE);
290         String localeTag = intent.getStringExtra(EXTRA_APP_LOCALE);
291         String callingPackage = getActivity().getCallingPackage();
292         if (!localeNotificationEnabled()
293                 || !getContext().getPackageName().equals(callingPackage)
294                 || !isValidDialogType(dialogType)
295                 || !isValidLocale(localeTag)
296                 || LocaleUtils.isInSystemLocale(localeTag)) {
297             return false;
298         }
299         return true;
300     }
301 
302     @VisibleForTesting
getNotificationController()303     NotificationController getNotificationController() {
304         return NotificationController.getInstance(getContext());
305     }
306 
isValidDialogType(String type)307     private boolean isValidDialogType(String type) {
308         return LOCALE_SUGGESTION.equals(type);
309     }
310 
isValidLocale(String tag)311     private boolean isValidLocale(String tag) {
312         if (TextUtils.isEmpty(tag)) {
313             return false;
314         }
315         String[] systemLocales = getSupportedLocales();
316         for (String systemTag : systemLocales) {
317             if (systemTag.equals(tag)) {
318                 return true;
319             }
320         }
321         return false;
322     }
323 
324     @VisibleForTesting
getSupportedLocales()325     String[] getSupportedLocales() {
326         return LocalePicker.getSupportedLocales(getContext());
327     }
328 
showDialogForAddedLocale()329     private void showDialogForAddedLocale() {
330         Log.d(TAG, "show confirmation dialog");
331         Intent intent = this.getIntent();
332         String dialogType = intent.getStringExtra(EXTRA_SYSTEM_LOCALE_DIALOG_TYPE);
333         String appLocaleTag = intent.getStringExtra(EXTRA_APP_LOCALE);
334 
335         LocaleStore.LocaleInfo localeInfo = LocaleStore.getLocaleInfo(
336                 Locale.forLanguageTag(appLocaleTag));
337         final LocaleDialogFragment localeDialogFragment =
338                 LocaleDialogFragment.newInstance();
339         Bundle args = new Bundle();
340         args.putInt(LocaleDialogFragment.ARG_DIALOG_TYPE, DIALOG_ADD_SYSTEM_LOCALE);
341         args.putSerializable(LocaleDialogFragment.ARG_TARGET_LOCALE, localeInfo);
342         localeDialogFragment.setArguments(args);
343         localeDialogFragment.show(mFragmentManager, TAG_DIALOG_ADD_SYSTEM_LOCALE);
344     }
345 
customizeLayout(AlertDialog.Builder dialogBuilder, String language)346     private void customizeLayout(AlertDialog.Builder dialogBuilder, String language) {
347         View dialogView = getLocaleDialogView();
348         dialogBuilder.setView(dialogView);
349         TextView title = dialogView.findViewById(R.id.dialog_title);
350         title.setText(
351                 String.format(getContext().getResources().getString(
352                         R.string.title_system_locale_addition), language));
353         TextView message = dialogView.findViewById(R.id.dialog_msg);
354         message.setText(R.string.desc_system_locale_addition);
355     }
356 
getLocaleDialogView()357     protected View getLocaleDialogView() {
358         LayoutInflater inflater = this.getLayoutInflater();
359         return inflater.inflate(R.layout.locale_dialog, null);
360     }
361 
362     // Show the appropriate warning when the user tries to remove locales.
363     // Shows no warning if there is no locale checked, shows a warning
364     // about removing all the locales if all of them are checked, and
365     // a "regular" warning otherwise.
366     @VisibleForTesting
showRemoveLocaleWarningDialog()367     void showRemoveLocaleWarningDialog() {
368         int checkedCount = mAdapter.getCheckedCount();
369 
370         // Nothing checked, just exit remove mode without a warning dialog
371         if (checkedCount == 0) {
372             setRemoveMode(!mRemoveMode);
373             return;
374         }
375 
376         // All locales selected, warning dialog, can't remove them all
377         if (checkedCount == mAdapter.getItemCount()) {
378             mShowingRemoveDialog = true;
379             new AlertDialog.Builder(getActivity())
380                     .setTitle(R.string.dlg_remove_locales_error_title)
381                     .setMessage(R.string.dlg_remove_locales_error_message)
382                     .setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() {
383                         @Override
384                         public void onClick(DialogInterface dialog, int which) {
385                         }
386                     })
387                     .setOnDismissListener(new DialogInterface.OnDismissListener() {
388                         @Override
389                         public void onDismiss(DialogInterface dialog) {
390                             mShowingRemoveDialog = false;
391                         }
392                     })
393                     .create()
394                     .show();
395             return;
396         }
397 
398         final String title = StringUtil.getIcuPluralsString(getContext(), checkedCount,
399                 R.string.dlg_remove_locales_title);
400         mShowingRemoveDialog = true;
401 
402         final AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
403         if (mAdapter.isFirstLocaleChecked()) {
404             builder.setMessage(R.string.dlg_remove_locales_message);
405         }
406 
407         builder.setTitle(title)
408                 .setNegativeButton(android.R.string.cancel, new DialogInterface.OnClickListener() {
409                     @Override
410                     public void onClick(DialogInterface dialog, int which) {
411                         setRemoveMode(false);
412                     }
413                 })
414                 .setPositiveButton(R.string.locale_remove_menu,
415                         new DialogInterface.OnClickListener() {
416                             @Override
417                             public void onClick(DialogInterface dialog, int which) {
418                                 // This is a sensitive area to change.
419                                 // removeChecked() triggers a system update and "kills" the frame.
420                                 // This means that saveState + restoreState are called before
421                                 // setRemoveMode is called.
422                                 // So we want that mRemoveMode and dialog status have the right
423                                 // values
424                                 // before that save.
425                                 // We can't just call setRemoveMode(false) before calling
426                                 // removeCheched
427                                 // because that unchecks all items and removeChecked would have
428                                 // nothing
429                                 // to remove.
430                                 mRemoveMode = false;
431                                 mShowingRemoveDialog = false;
432                                 LocaleStore.LocaleInfo firstLocale =
433                                         mAdapter.getFeedItemList().get(0);
434                                 mAdapter.removeChecked();
435                                 boolean isFirstRemoved =
436                                         firstLocale != mAdapter.getFeedItemList().get(0);
437                                 showConfirmDialog(isFirstRemoved, isFirstRemoved ? firstLocale
438                                         : mAdapter.getFeedItemList().get(0));
439                                 setRemoveMode(false);
440                             }
441                         })
442                 .setOnDismissListener(new DialogInterface.OnDismissListener() {
443                     @Override
444                     public void onDismiss(DialogInterface dialog) {
445                         mShowingRemoveDialog = false;
446                     }
447                 })
448                 .create()
449                 .show();
450     }
451 
452     @Override
onCreateOptionsMenu(Menu menu, MenuInflater inflater)453     public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
454         final MenuItem menuItem =
455                 menu.add(Menu.NONE, MENU_ID_REMOVE, 0, R.string.locale_remove_menu);
456         menuItem.setShowAsAction(MenuItem.SHOW_AS_ACTION_WITH_TEXT);
457         menuItem.setIcon(R.drawable.ic_delete);
458         super.onCreateOptionsMenu(menu, inflater);
459         mMenu = menu;
460         updateVisibilityOfRemoveMenu();
461     }
462 
getUserLocaleList()463     private List<LocaleStore.LocaleInfo> getUserLocaleList() {
464         final List<LocaleStore.LocaleInfo> result = new ArrayList<>();
465         final LocaleList localeList = LocalePicker.getLocales();
466         for (int i = 0; i < localeList.size(); i++) {
467             Locale locale = localeList.get(i);
468             result.add(LocaleStore.getLocaleInfo(locale));
469         }
470         return result;
471     }
472 
configureDragAndDrop(LayoutPreference layout)473     private void configureDragAndDrop(LayoutPreference layout) {
474         final RecyclerView list = layout.findViewById(R.id.dragList);
475         final LocaleLinearLayoutManager llm = new LocaleLinearLayoutManager(getContext(), mAdapter);
476         llm.setLocaleListEditor(this);
477         llm.setAutoMeasureEnabled(true);
478         list.setLayoutManager(llm);
479         list.setHasFixedSize(true);
480         list.setNestedScrollingEnabled(false);
481         mAdapter.setRecyclerView(list);
482         list.setAdapter(mAdapter);
483         list.setOnTouchListener(this);
484         list.requestFocus();
485 
486         mAddLanguage = layout.findViewById(R.id.add_language);
487         mAddLanguage.setOnClickListener(new View.OnClickListener() {
488             @Override
489             public void onClick(View v) {
490                 FeatureFactory.getFeatureFactory().getMetricsFeatureProvider()
491                         .logSettingsTileClick(INDEX_KEY_ADD_LANGUAGE, getMetricsCategory());
492 
493                 final Intent intent = new Intent(getActivity(),
494                         LocalePickerWithRegionActivity.class);
495                 intent.putExtras(getActivity().getIntent().getExtras());
496                 startActivityForResult(intent, REQUEST_LOCALE_PICKER);
497             }
498         });
499     }
500 
501     @Override
onTouch(View v, MotionEvent event)502     public boolean onTouch(View v, MotionEvent event) {
503         if (event.getAction() == MotionEvent.ACTION_UP
504                 || event.getAction() == MotionEvent.ACTION_CANCEL) {
505             showConfirmDialog(false, mAdapter.getFeedItemList().get(0));
506         }
507         return false;
508     }
509 
showConfirmDialog(boolean isFirstRemoved, LocaleStore.LocaleInfo localeInfo)510     public void showConfirmDialog(boolean isFirstRemoved, LocaleStore.LocaleInfo localeInfo) {
511         Locale currentSystemLocale = LocalePicker.getLocales().get(0);
512         if (!localeInfo.getLocale().equals(currentSystemLocale)) {
513             final LocaleDialogFragment localeDialogFragment =
514                     LocaleDialogFragment.newInstance();
515             Bundle args = new Bundle();
516             args.putInt(LocaleDialogFragment.ARG_DIALOG_TYPE, DIALOG_CONFIRM_SYSTEM_DEFAULT);
517             args.putSerializable(LocaleDialogFragment.ARG_TARGET_LOCALE,
518                     isFirstRemoved ? LocaleStore.getLocaleInfo(currentSystemLocale) : localeInfo);
519             localeDialogFragment.setArguments(args);
520             localeDialogFragment.show(mFragmentManager, TAG_DIALOG_CONFIRM_SYSTEM_DEFAULT);
521         } else {
522             mAdapter.doTheUpdate();
523         }
524     }
525 
526     // Hide the "Remove" menu if there is only one locale in the list, show it otherwise
527     // This is called when the menu is first created, and then one add / remove locale
updateVisibilityOfRemoveMenu()528     private void updateVisibilityOfRemoveMenu() {
529         if (mMenu == null) {
530             return;
531         }
532 
533         final MenuItem menuItemRemove = mMenu.findItem(MENU_ID_REMOVE);
534         if (menuItemRemove != null) {
535             menuItemRemove.setShowAsAction(
536                     mRemoveMode ? MenuItem.SHOW_AS_ACTION_ALWAYS : MenuItem.SHOW_AS_ACTION_NEVER);
537             final boolean hasMultipleLanguages = mAdapter.getItemCount() > 1;
538             menuItemRemove.setVisible(hasMultipleLanguages && !mIsUiRestricted);
539         }
540     }
541 
542     public static final BaseSearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
543             new BaseSearchIndexProvider() {
544                 @Override
545                 public List<SearchIndexableRaw> getRawDataToIndex(Context context,
546                         boolean enabled) {
547                     final Resources res = context.getResources();
548                     final List<SearchIndexableRaw> indexRaws = new ArrayList<>();
549                     final SearchIndexableRaw raw = new SearchIndexableRaw(context);
550                     raw.key = INDEX_KEY_ADD_LANGUAGE;
551                     raw.title = res.getString(R.string.add_a_language);
552                     raw.keywords = res.getString(R.string.keywords_add_language);
553                     indexRaws.add(raw);
554                     return indexRaws;
555                 }
556             };
557 }
558