Merge "Add Confirmation Dialog" into main

This commit is contained in:
Daniel Huang
2025-03-05 05:51:36 -08:00
committed by Android (Google) Code Review
5 changed files with 145 additions and 32 deletions

View File

@@ -26,11 +26,6 @@ import android.content.DialogInterface;
import android.content.Intent;
import android.os.Bundle;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.TextView;
import android.window.OnBackInvokedCallback;
import android.window.OnBackInvokedDispatcher;
@@ -57,6 +52,7 @@ public class LocaleDialogFragment extends InstrumentedDialogFragment {
static final String ARG_DIALOG_TYPE = "arg_dialog_type";
static final String ARG_TARGET_LOCALE = "arg_target_locale";
static final String ARG_SHOW_DIALOG = "arg_show_dialog";
static final String ARG_SHOW_DIALOG_FOR_NOT_TRANSLATED = "arg_show_dialog_for_not_translated";
private boolean mShouldKeepDialog;
private OnBackInvokedDispatcher mBackDispatcher;
@@ -185,6 +181,7 @@ public class LocaleDialogFragment extends InstrumentedDialogFragment {
private final int mDialogType;
private final LocaleStore.LocaleInfo mLocaleInfo;
private final MetricsFeatureProvider mMetricsFeatureProvider;
private final boolean mShowDialogForNotTranslated;
private LocaleListEditor mParent;
@@ -194,6 +191,7 @@ public class LocaleDialogFragment extends InstrumentedDialogFragment {
mContext = context;
Bundle arguments = dialogFragment.getArguments();
mDialogType = arguments.getInt(ARG_DIALOG_TYPE);
mShowDialogForNotTranslated = arguments.getBoolean(ARG_SHOW_DIALOG_FOR_NOT_TRANSLATED);
mLocaleInfo = (LocaleStore.LocaleInfo) arguments.getSerializable(ARG_TARGET_LOCALE);
mMetricsFeatureProvider =
FeatureFactory.getFeatureFactory().getMetricsFeatureProvider();
@@ -215,6 +213,7 @@ public class LocaleDialogFragment extends InstrumentedDialogFragment {
bundle.putInt(ARG_DIALOG_TYPE, mDialogType);
bundle.putSerializable(LocaleDialogFragment.ARG_TARGET_LOCALE, mLocaleInfo);
intent.putExtras(bundle);
intent.putExtra(ARG_SHOW_DIALOG_FOR_NOT_TRANSLATED, mShowDialogForNotTranslated);
mParent.onActivityResult(mDialogType, result, intent);
mMetricsFeatureProvider.action(mContext, SettingsEnums.ACTION_CHANGE_LANGUAGE,
changed);

View File

@@ -364,12 +364,25 @@ class LocaleDragAndDropAdapter
}
public void notifyListChanged(LocaleStore.LocaleInfo localeInfo) {
if (!localeInfo.getLocale().equals(mCacheItemList.get(0).getLocale())) {
if (listChanged()) {
mFeedItemList = new ArrayList<>(mCacheItemList);
notifyDataSetChanged();
}
}
private boolean listChanged() {
if (mFeedItemList.size() == mCacheItemList.size()) {
for (int i = 0; i < mFeedItemList.size(); i++) {
if (!mFeedItemList.get(i).getLocale().equals(mCacheItemList.get(i).getLocale())) {
return true;
}
}
return false;
} else {
return true;
}
}
public void setCacheItemList() {
mCacheItemList = new ArrayList<>(mFeedItemList);
}

View File

@@ -151,7 +151,7 @@ public class LocaleLinearLayoutManager extends LinearLayoutManager {
}
if (result) {
mLocaleListEditor.showConfirmDialog(false, mAdapter.getFeedItemList().get(0));
mLocaleListEditor.showConfirmDialog(mAdapter.getFeedItemList().get(0), null);
}
return result;
}

View File

@@ -44,6 +44,7 @@ import android.view.ViewGroup;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.annotation.VisibleForTesting;
import androidx.fragment.app.FragmentManager;
import androidx.preference.Preference;
@@ -235,7 +236,9 @@ public class LocaleListEditor extends RestrictedSettingsFragment implements View
localeInfo = mAdapter.getFeedItemList().get(0);
if (resultCode == Activity.RESULT_OK) {
mAdapter.doTheUpdate();
if (!localeInfo.isTranslated()) {
boolean showNotTranslatedDialog = data.getBooleanExtra(
LocaleDialogFragment.ARG_SHOW_DIALOG_FOR_NOT_TRANSLATED, true);
if (showNotTranslatedDialog && !localeInfo.isTranslated()) {
Bundle args = new Bundle();
args.putInt(LocaleDialogFragment.ARG_DIALOG_TYPE,
LocaleDialogFragment.DIALOG_NOT_AVAILABLE_LOCALE);
@@ -428,13 +431,10 @@ public class LocaleListEditor extends RestrictedSettingsFragment implements View
// to remove.
mRemoveMode = false;
mShowingRemoveDialog = false;
LocaleStore.LocaleInfo firstLocale =
mAdapter.getFeedItemList().get(0);
Locale defaultBeforeRemoval = Locale.getDefault();
mAdapter.removeChecked();
boolean isFirstRemoved =
firstLocale != mAdapter.getFeedItemList().get(0);
showConfirmDialog(isFirstRemoved, isFirstRemoved ? firstLocale
: mAdapter.getFeedItemList().get(0));
showConfirmDialog(mAdapter.getFeedItemList().get(0),
defaultBeforeRemoval);
setRemoveMode(false);
dialogHelper.getDialog().dismiss();
})
@@ -520,26 +520,72 @@ public class LocaleListEditor extends RestrictedSettingsFragment implements View
public boolean onTouch(View v, MotionEvent event) {
if (event.getAction() == MotionEvent.ACTION_UP
|| event.getAction() == MotionEvent.ACTION_CANCEL) {
showConfirmDialog(false, mAdapter.getFeedItemList().get(0));
showConfirmDialog(mAdapter.getFeedItemList().get(0), null);
}
return false;
}
public void showConfirmDialog(boolean isFirstRemoved, LocaleStore.LocaleInfo localeInfo) {
protected void showConfirmDialog(LocaleStore.LocaleInfo localeInfo,
@Nullable Locale defaultLocaleBeforeRemoval) {
Locale currentSystemLocale = LocalePicker.getLocales().get(0);
if (!localeInfo.getLocale().equals(currentSystemLocale)) {
final LocaleDialogFragment localeDialogFragment =
LocaleDialogFragment.newInstance();
Bundle args = new Bundle();
args.putInt(LocaleDialogFragment.ARG_DIALOG_TYPE, DIALOG_CONFIRM_SYSTEM_DEFAULT);
args.putSerializable(LocaleDialogFragment.ARG_TARGET_LOCALE,
isFirstRemoved ? LocaleStore.getLocaleInfo(currentSystemLocale) : localeInfo);
localeDialogFragment.setArguments(args);
localeDialogFragment.show(mFragmentManager, TAG_DIALOG_CONFIRM_SYSTEM_DEFAULT);
displayDialogFragment(localeInfo, true);
} else {
if (!localeInfo.isTranslated()) {
if (defaultLocaleBeforeRemoval == null) {
showDialogDueToDragAndDrop();
} else {
showDialogDueToRemoval(defaultLocaleBeforeRemoval);
}
} else {
mAdapter.doTheUpdate();
}
}
}
private void showDialogDueToDragAndDrop() {
LocaleStore.LocaleInfo newLocale = mAdapter.getFeedItemList().stream().filter(
i -> i.isTranslated()).findFirst().orElse(null);
if (newLocale == null) {
return;
}
LocaleStore.LocaleInfo oldLocale = null;
final LocaleList localeList = LocalePicker.getLocales();
for (int i = 0; i < localeList.size(); i++) {
LocaleStore.LocaleInfo temp = LocaleStore.getLocaleInfo(localeList.get(i));
if (temp.isTranslated()) {
oldLocale = temp;
break;
}
}
if (oldLocale != null && !newLocale.getLocale().equals(
oldLocale.getLocale())) {
displayDialogFragment(newLocale, false);
}
}
private void showDialogDueToRemoval(Locale preDefault) {
if (preDefault == null) {
return;
}
LocaleStore.LocaleInfo currentDefault = mAdapter.getFeedItemList().stream().filter(
i -> i.isTranslated()).findFirst().orElse(null);
if (currentDefault != null && !preDefault.equals(currentDefault.getLocale())) {
displayDialogFragment(currentDefault, false);
}
}
private void displayDialogFragment(LocaleStore.LocaleInfo localeInfo,
boolean showDialogForNotTranslated) {
final LocaleDialogFragment localeDialogFragment = LocaleDialogFragment.newInstance();
Bundle args = new Bundle();
args.putBoolean(LocaleDialogFragment.ARG_SHOW_DIALOG_FOR_NOT_TRANSLATED,
showDialogForNotTranslated);
args.putInt(LocaleDialogFragment.ARG_DIALOG_TYPE, DIALOG_CONFIRM_SYSTEM_DEFAULT);
args.putSerializable(LocaleDialogFragment.ARG_TARGET_LOCALE, localeInfo);
localeDialogFragment.setArguments(args);
localeDialogFragment.show(mFragmentManager, TAG_DIALOG_CONFIRM_SYSTEM_DEFAULT);
}
// Hide the "Remove" menu if there is only one locale in the list, show it otherwise
// This is called when the menu is first created, and then one add / remove locale

View File

@@ -36,7 +36,6 @@ import android.app.Activity;
import android.app.Dialog;
import android.app.IActivityManager;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.res.Configuration;
import android.content.res.Resources;
@@ -100,6 +99,8 @@ public class LocaleListEditorTest {
public final MockitoRule mMockitoRule = MockitoJUnit.rule();
private static final String ARG_DIALOG_TYPE = "arg_dialog_type";
private static final String
ARG_SHOW_DIALOG_FOR_NOT_TRANSLATED = "arg_show_dialog_for_not_translated";
private static final String TAG_DIALOG_CONFIRM_SYSTEM_DEFAULT = "dialog_confirm_system_default";
private static final String TAG_DIALOG_NOT_AVAILABLE = "dialog_not_available_locale";
private static final String TAG_DIALOG_ADD_SYSTEM_LOCALE = "dialog_add_system_locale";
@@ -123,6 +124,10 @@ public class LocaleListEditorTest {
@Mock
private LocaleStore.LocaleInfo mLocaleInfo;
@Mock
private LocaleStore.LocaleInfo mLocaleInfo1;
@Mock
private LocaleStore.LocaleInfo mLocaleInfo2;
@Mock
private FragmentManager mFragmentManager;
@Mock
private FragmentTransaction mFragmentTransaction;
@@ -270,7 +275,7 @@ public class LocaleListEditorTest {
public void showConfirmDialog_systemLocaleSelected_shouldShowLocaleChangeDialog()
throws Exception {
//pre-condition
setUpLocaleConditions();
setUpLocaleConditions(true);
final Configuration config = new Configuration();
config.setLocales((LocaleList.forLanguageTags("zh-TW,en-US")));
when(mActivityService.getConfiguration()).thenReturn(config);
@@ -299,6 +304,41 @@ public class LocaleListEditorTest {
eq(TAG_DIALOG_CONFIRM_SYSTEM_DEFAULT));
}
@Test
public void showConfirmDialog_2ndLocaleSelected_shouldShowLocaleChangeDialog()
throws Exception {
//pre-condition
Locale.setDefault(Locale.forLanguageTag("en-US"));
setUpLocaleConditions2();
final Configuration config = new Configuration();
config.setLocales((LocaleList.forLanguageTags("blo-BJ,en-US,zh-TW")));
when(mActivityService.getConfiguration()).thenReturn(config);
when(mAdapter.getFeedItemList()).thenReturn(mLocaleList);
when(mAdapter.getCheckedCount()).thenReturn(1);
when(mAdapter.getItemCount()).thenReturn(3);
when(mAdapter.isFirstLocaleChecked()).thenReturn(false);
ReflectionHelpers.setField(mLocaleListEditor, "mRemoveMode", true);
ReflectionHelpers.setField(mLocaleListEditor, "mShowingRemoveDialog", true);
//launch the first dialog
mLocaleListEditor.showRemoveLocaleWarningDialog();
final Dialog dialog = ShadowDialog.getLatestDialog();
assertThat(dialog).isNotNull();
// click the remove button
dialog.findViewById(R.id.button_ok).performClick();
ShadowLooper.idleMainLooper();
assertThat(dialog.isShowing()).isFalse();
// check the second dialog is showing
verify(mFragmentTransaction).add(any(LocaleDialogFragment.class),
eq(TAG_DIALOG_CONFIRM_SYSTEM_DEFAULT));
}
@Test
public void mayAppendUnicodeTags_appendUnicodeTags_success() {
LocaleStore.LocaleInfo localeInfo = LocaleStore.fromLocale(Locale.forLanguageTag("en-US"));
@@ -315,7 +355,8 @@ public class LocaleListEditorTest {
Bundle bundle = new Bundle();
bundle.putInt(ARG_DIALOG_TYPE, DIALOG_CONFIRM_SYSTEM_DEFAULT);
mIntent.putExtras(bundle);
setUpLocaleConditions();
mIntent.putExtra(ARG_SHOW_DIALOG_FOR_NOT_TRANSLATED, true);
setUpLocaleConditions(false);
mLocaleListEditor.onActivityResult(REQUEST_CONFIRM_SYSTEM_DEFAULT, Activity.RESULT_OK,
mIntent);
@@ -328,7 +369,7 @@ public class LocaleListEditorTest {
Bundle bundle = new Bundle();
bundle.putInt(ARG_DIALOG_TYPE, DIALOG_CONFIRM_SYSTEM_DEFAULT);
mIntent.putExtras(bundle);
setUpLocaleConditions();
setUpLocaleConditions(true);
mLocaleListEditor.onActivityResult(REQUEST_CONFIRM_SYSTEM_DEFAULT, Activity.RESULT_CANCELED,
mIntent);
@@ -338,7 +379,7 @@ public class LocaleListEditorTest {
@Test
public void onTouch_dragDifferentLocaleToTop_showConfirmDialog() throws Exception {
MotionEvent event = MotionEvent.obtain(0L, 0L, MotionEvent.ACTION_UP, 0.0f, 0.0f, 0);
setUpLocaleConditions();
setUpLocaleConditions(true);
final Configuration config = new Configuration();
config.setLocales((LocaleList.forLanguageTags("zh-TW,en-US")));
when(mActivityService.getConfiguration()).thenReturn(config);
@@ -352,7 +393,7 @@ public class LocaleListEditorTest {
@Test
public void onTouch_dragSameLocaleToTop_updateAdapter() throws Exception {
MotionEvent event = MotionEvent.obtain(0L, 0L, MotionEvent.ACTION_UP, 0.0f, 0.0f, 0);
setUpLocaleConditions();
setUpLocaleConditions(true);
final Configuration config = new Configuration();
config.setLocales((LocaleList.forLanguageTags("en-US,zh-TW")));
when(mActivityService.getConfiguration()).thenReturn(config);
@@ -490,12 +531,26 @@ public class LocaleListEditorTest {
verify(mAdapter).setCheckBoxDescription(any(LocaleDragCell.class), any(), anyBoolean());
}
private void setUpLocaleConditions() {
private void setUpLocaleConditions(boolean isTranslated) {
ShadowActivityManager.setService(mActivityService);
mLocaleList = new ArrayList<>();
mLocaleList.add(mLocaleInfo);
when(mLocaleInfo.getFullNameNative()).thenReturn("English");
when(mLocaleInfo.getLocale()).thenReturn(LocaleList.forLanguageTags("en-US").get(0));
when(mLocaleInfo.isTranslated()).thenReturn(isTranslated);
when(mAdapter.getFeedItemList()).thenReturn(mLocaleList);
}
private void setUpLocaleConditions2() {
ShadowActivityManager.setService(mActivityService);
mLocaleList = new ArrayList<>();
mLocaleList.add(mLocaleInfo);
mLocaleList.add(mLocaleInfo1);
mLocaleList.add(mLocaleInfo2);
when(mLocaleInfo.getLocale()).thenReturn(Locale.forLanguageTag("blo-BJ"));
when(mLocaleInfo.isTranslated()).thenReturn(false);
when(mLocaleInfo2.getLocale()).thenReturn(Locale.forLanguageTag("zh-TW"));
when(mLocaleInfo2.isTranslated()).thenReturn(true);
when(mAdapter.getFeedItemList()).thenReturn(mLocaleList);
}
}