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