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

Commit 4d917d99 authored by Zoey Chen's avatar Zoey Chen Committed by Android (Google) Code Review
Browse files

Merge "[Panlingual] Do not show dialog in recycle. Set LocaleEditor as the...

Merge "[Panlingual] Do not show dialog in recycle. Set LocaleEditor as the parent fragment and control the dialog." into udc-dev
parents f0e44010 fb6b6b0b
Loading
Loading
Loading
Loading
+53 −54
Original line number Diff line number Diff line
@@ -21,8 +21,8 @@ import android.app.Dialog;
import android.app.settings.SettingsEnums;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.os.Bundle;
import android.os.ResultReceiver;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
@@ -35,7 +35,6 @@ import androidx.fragment.app.FragmentManager;

import com.android.internal.app.LocaleStore;
import com.android.settings.R;
import com.android.settings.RestrictedSettingsFragment;
import com.android.settings.core.instrumentation.InstrumentedDialogFragment;
import com.android.settings.overlay.FeatureFactory;
import com.android.settingslib.core.instrumentation.MetricsFeatureProvider;
@@ -46,49 +45,19 @@ import com.android.settingslib.core.instrumentation.MetricsFeatureProvider;
public class LocaleDialogFragment extends InstrumentedDialogFragment {
    private static final String TAG = LocaleDialogFragment.class.getSimpleName();

    static final int DIALOG_CONFIRM_SYSTEM_DEFAULT = 0;
    static final int DIALOG_NOT_AVAILABLE_LOCALE = 1;
    static final int DIALOG_CONFIRM_SYSTEM_DEFAULT = 1;
    static final int DIALOG_NOT_AVAILABLE_LOCALE = 2;

    static final String ARG_DIALOG_TYPE = "arg_dialog_type";
    static final String ARG_TARGET_LOCALE = "arg_target_locale";
    static final String ARG_RESULT_RECEIVER = "arg_result_receiver";
    static final String ARG_SHOW_DIALOG = "arg_show_dialog";

    private boolean mShouldKeepDialog;

    public static LocaleDialogFragment newInstance() {
        return new LocaleDialogFragment();
    }

    /**
     * Show dialog
     */
    public void show(
            @NonNull RestrictedSettingsFragment fragment,
            int dialogType,
            LocaleStore.LocaleInfo localeInfo) {
        if (!isAdded()) {
            return;
        }
        show(fragment, dialogType, localeInfo, null);
    }

    /**
     * Show dialog
     */
    public void show(
            @NonNull RestrictedSettingsFragment fragment,
            int dialogType,
            LocaleStore.LocaleInfo localeInfo,
            ResultReceiver resultReceiver) {
        FragmentManager manager = fragment.getChildFragmentManager();
        Bundle args = new Bundle();
        args.putInt(ARG_DIALOG_TYPE, dialogType);
        args.putSerializable(ARG_TARGET_LOCALE, localeInfo);
        args.putParcelable(ARG_RESULT_RECEIVER, resultReceiver);

        LocaleDialogFragment localeDialogFragment = new LocaleDialogFragment();
        localeDialogFragment.setArguments(args);
        localeDialogFragment.show(manager, TAG);
    }

    @Override
    public int getMetricsCategory() {
        int dialogType = getArguments().getInt(ARG_DIALOG_TYPE);
@@ -102,9 +71,29 @@ public class LocaleDialogFragment extends InstrumentedDialogFragment {
        }
    }

    @Override
    public void onSaveInstanceState(Bundle outState) {
        super.onSaveInstanceState(outState);
        outState.putBoolean(ARG_SHOW_DIALOG, mShouldKeepDialog);
    }

    @Override
    public Dialog onCreateDialog(Bundle savedInstanceState) {
        LocaleDialogController controller = new LocaleDialogController(this);
        if (savedInstanceState != null) {
            Bundle arguments = getArguments();
            int type = arguments.getInt(ARG_DIALOG_TYPE);
            mShouldKeepDialog = savedInstanceState.getBoolean(ARG_SHOW_DIALOG, false);
            // Keep the dialog if user rotates the device, otherwise close the confirm system
            // default dialog only when user changes the locale.
            if (type == DIALOG_CONFIRM_SYSTEM_DEFAULT && !mShouldKeepDialog) {
                dismiss();
            }
        }

        mShouldKeepDialog = true;
        LocaleListEditor parentFragment = (LocaleListEditor) getParentFragment();
        LocaleDialogController controller = getLocaleDialogController(getContext(), this,
                parentFragment);
        LocaleDialogController.DialogContent dialogContent = controller.getDialogContent();
        ViewGroup viewGroup = (ViewGroup) LayoutInflater.from(getContext()).inflate(
                R.layout.locale_dialog, null);
@@ -140,47 +129,57 @@ public class LocaleDialogFragment extends InstrumentedDialogFragment {
        textView.setText(content);
    }

    static class LocaleDialogController implements DialogInterface.OnClickListener {
    @VisibleForTesting
    LocaleDialogController getLocaleDialogController(Context context,
            LocaleDialogFragment dialogFragment, LocaleListEditor parentFragment) {
        return new LocaleDialogController(context, dialogFragment, parentFragment);
    }

    class LocaleDialogController implements DialogInterface.OnClickListener {
        private final Context mContext;
        private final int mDialogType;
        private final LocaleStore.LocaleInfo mLocaleInfo;
        private final ResultReceiver mResultReceiver;
        private final MetricsFeatureProvider mMetricsFeatureProvider;

        private LocaleListEditor mParent;

        LocaleDialogController(
                @NonNull Context context, @NonNull LocaleDialogFragment dialogFragment) {
                @NonNull Context context, @NonNull LocaleDialogFragment dialogFragment,
                LocaleListEditor parentFragment) {
            mContext = context;
            Bundle arguments = dialogFragment.getArguments();
            mDialogType = arguments.getInt(ARG_DIALOG_TYPE);
            mLocaleInfo = (LocaleStore.LocaleInfo) arguments.getSerializable(
                    ARG_TARGET_LOCALE);
            mResultReceiver = (ResultReceiver) arguments.getParcelable(ARG_RESULT_RECEIVER);
            mLocaleInfo = (LocaleStore.LocaleInfo) arguments.getSerializable(ARG_TARGET_LOCALE);
            mMetricsFeatureProvider = FeatureFactory.getFactory(
                    mContext).getMetricsFeatureProvider();
            mParent = parentFragment;
        }

        LocaleDialogController(@NonNull LocaleDialogFragment dialogFragment) {
            this(dialogFragment.getContext(), dialogFragment);
        LocaleDialogController(@NonNull LocaleDialogFragment dialogFragment,
                LocaleListEditor parent) {
            this(dialogFragment.getContext(), dialogFragment, parent);
        }

        @Override
        public void onClick(DialogInterface dialog, int which) {
            if (mResultReceiver != null && mDialogType == DIALOG_CONFIRM_SYSTEM_DEFAULT) {
                Bundle bundle = new Bundle();
                bundle.putInt(ARG_DIALOG_TYPE, DIALOG_CONFIRM_SYSTEM_DEFAULT);
            if (mDialogType == DIALOG_CONFIRM_SYSTEM_DEFAULT) {
                int result = Activity.RESULT_CANCELED;
                if (which == DialogInterface.BUTTON_POSITIVE) {
                    mResultReceiver.send(Activity.RESULT_OK, bundle);
                } else if (which == DialogInterface.BUTTON_NEGATIVE) {
                    mResultReceiver.send(Activity.RESULT_CANCELED, bundle);
                    result = Activity.RESULT_OK;
                }
                Intent intent = new Intent();
                Bundle bundle = new Bundle();
                bundle.putInt(ARG_DIALOG_TYPE, DIALOG_CONFIRM_SYSTEM_DEFAULT);
                intent.putExtras(bundle);
                mParent.onActivityResult(DIALOG_CONFIRM_SYSTEM_DEFAULT, result, intent);
                mMetricsFeatureProvider.action(mContext, SettingsEnums.ACTION_CHANGE_LANGUAGE);
            }
            mShouldKeepDialog = false;
        }

        @VisibleForTesting
        DialogContent getDialogContent() {
            DialogContent
                    dialogContent = new DialogContent();
            DialogContent dialogContent = new DialogContent();
            switch (mDialogType) {
                case DIALOG_CONFIRM_SYSTEM_DEFAULT:
                    dialogContent.mTitle = String.format(mContext.getString(
+44 −51
Original line number Diff line number Diff line
@@ -16,14 +16,11 @@

package com.android.settings.localepicker;

import android.app.Activity;
import android.content.Context;
import android.graphics.Canvas;
import android.os.Bundle;
import android.os.Handler;
import android.os.LocaleList;
import android.os.Looper;
import android.os.ResultReceiver;
import android.text.TextUtils;
import android.util.Log;
import android.util.TypedValue;
import android.view.LayoutInflater;
@@ -52,15 +49,20 @@ class LocaleDragAndDropAdapter

    private static final String TAG = "LocaleDragAndDropAdapter";
    private static final String CFGKEY_SELECTED_LOCALES = "selectedLocales";
    private static final String CFGKEY_DRAG_LOCALE = "dragLocales";
    private static final String CFGKEY_DRAG_LOCALES_TO_POSITION = "dragLocales_end";

    private final Context mContext;
    private final ItemTouchHelper mItemTouchHelper;

    private List<LocaleStore.LocaleInfo> mFeedItemList;
    private List<LocaleStore.LocaleInfo> mCacheItemList;
    private final ItemTouchHelper mItemTouchHelper;
    private RecyclerView mParentView = null;
    private LocaleListEditor mParent;
    private boolean mRemoveMode = false;
    private boolean mDragEnabled = true;
    private NumberFormat mNumberFormatter = NumberFormat.getNumberInstance();
    private LocaleStore.LocaleInfo mDragLocale;

    class CustomViewHolder extends RecyclerView.ViewHolder implements View.OnTouchListener {
        private final LocaleDragCell mLocaleDragCell;
@@ -87,8 +89,7 @@ class LocaleDragAndDropAdapter
        }
    }

    LocaleDragAndDropAdapter(LocaleListEditor parent,
            List<LocaleStore.LocaleInfo> feedItemList) {
    LocaleDragAndDropAdapter(LocaleListEditor parent, List<LocaleStore.LocaleInfo> feedItemList) {
        mFeedItemList = feedItemList;
        mParent = parent;
        mCacheItemList = new ArrayList<>(feedItemList);
@@ -202,6 +203,7 @@ class LocaleDragAndDropAdapter
            final LocaleStore.LocaleInfo saved = mFeedItemList.get(fromPosition);
            mFeedItemList.remove(fromPosition);
            mFeedItemList.add(toPosition, saved);
            mDragLocale = saved;
        } else {
            // TODO: It looks like sometimes the RecycleView tries to swap item -1
            // I did not see it in a while, but if it happens, investigate and file a bug.
@@ -317,43 +319,20 @@ class LocaleDragAndDropAdapter
        });
    }

    public void doTheUpdateWithMovingLocaleItem() {
        LocaleStore.LocaleInfo localeInfo = mFeedItemList.get(0);
        final LocaleDialogFragment fragment = LocaleDialogFragment.newInstance();
        if (!localeInfo.getLocale().equals(LocalePicker.getLocales().get(0))) {
            fragment.show(mParent,
                    LocaleDialogFragment.DIALOG_CONFIRM_SYSTEM_DEFAULT,
                    localeInfo,
                    new ResultReceiver(new Handler(Looper.getMainLooper())) {
                        @Override
                        protected void onReceiveResult(int resultCode, Bundle resultData) {
                            super.onReceiveResult(resultCode, resultData);
                            int type = resultData.getInt(LocaleDialogFragment.ARG_DIALOG_TYPE);
                            if (type == LocaleDialogFragment.DIALOG_CONFIRM_SYSTEM_DEFAULT) {
                                if (resultCode == Activity.RESULT_OK) {
                                    doTheUpdate();
                                    if (!localeInfo.isTranslated()) {
                                        fragment.show(mParent,
                                                        LocaleDialogFragment
                                                                .DIALOG_NOT_AVAILABLE_LOCALE,
                                                        localeInfo);
                                    }
                                } else {
                                    if (!localeInfo.getLocale()
                                            .equals(mCacheItemList.get(0).getLocale())) {
    public void notifyListChanged(LocaleStore.LocaleInfo localeInfo) {
        if (!localeInfo.getLocale().equals(mCacheItemList.get(0).getLocale())) {
            mFeedItemList = new ArrayList<>(mCacheItemList);
            notifyDataSetChanged();
        }
    }

    public void setCacheItemList() {
        mCacheItemList = new ArrayList<>(mFeedItemList);
    }
                        }
                    });
        } else {
            doTheUpdate();
        }
    }

    public List<LocaleStore.LocaleInfo> getFeedItemList() {
        return mFeedItemList;
    }
    private void setDragEnabled(boolean enabled) {
        mDragEnabled = enabled;
    }
@@ -373,6 +352,8 @@ class LocaleDragAndDropAdapter
                }
            }
            outInstanceState.putStringArrayList(CFGKEY_SELECTED_LOCALES, selectedLocales);
            // Save the dragged locale before rotation
            outInstanceState.putSerializable(CFGKEY_DRAG_LOCALE, mDragLocale);
        }
    }

@@ -381,9 +362,11 @@ class LocaleDragAndDropAdapter
     * (for instance when the device is rotated)
     *
     * @param savedInstanceState Bundle with the data saved by {@link #saveState(Bundle)}
     * @param isDialogShowing A flag indicating whether the dialog is showing or not.
     */
    public void restoreState(Bundle savedInstanceState) {
        if (savedInstanceState != null && mRemoveMode) {
    public void restoreState(Bundle savedInstanceState, boolean isDialogShowing) {
        if (savedInstanceState != null) {
            if (mRemoveMode) {
                final ArrayList<String> selectedLocales =
                        savedInstanceState.getStringArrayList(CFGKEY_SELECTED_LOCALES);
                if (selectedLocales == null || selectedLocales.isEmpty()) {
@@ -393,6 +376,16 @@ class LocaleDragAndDropAdapter
                    li.setChecked(selectedLocales.contains(li.getId()));
                }
                notifyItemRangeChanged(0, mFeedItemList.size());
            } else if (isDialogShowing) {
                // After rotation, the dragged position will be restored to original. Restore the
                // drag locale's original position to the top.
                mDragLocale = (LocaleStore.LocaleInfo) savedInstanceState.getSerializable(
                        CFGKEY_DRAG_LOCALE);
                mFeedItemList.removeIf(
                        localeInfo -> TextUtils.equals(localeInfo.getId(), mDragLocale.getId()));
                mFeedItemList.add(0, mDragLocale);
                notifyItemRangeChanged(0, mFeedItemList.size());
            }
        }
    }
}
+58 −6
Original line number Diff line number Diff line
@@ -18,6 +18,8 @@ package com.android.settings.localepicker;

import static android.os.UserManager.DISALLOW_CONFIG_LOCALE;

import static com.android.settings.localepicker.LocaleDialogFragment.DIALOG_CONFIRM_SYSTEM_DEFAULT;

import android.app.Activity;
import android.app.settings.SettingsEnums;
import android.content.Context;
@@ -32,12 +34,14 @@ import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;

import androidx.annotation.VisibleForTesting;
import androidx.appcompat.app.AlertDialog;
import androidx.fragment.app.FragmentManager;
import androidx.preference.PreferenceScreen;
import androidx.recyclerview.widget.RecyclerView;

@@ -60,7 +64,7 @@ import java.util.Locale;
 * Drag-and-drop editor for the user-ordered locale lists.
 */
@SearchIndexable
public class LocaleListEditor extends RestrictedSettingsFragment {
public class LocaleListEditor extends RestrictedSettingsFragment implements View.OnTouchListener {

    protected static final String INTENT_LOCALE_KEY = "localeInfo";
    private static final String CFGKEY_REMOVE_MODE = "localeRemoveMode";
@@ -70,6 +74,8 @@ public class LocaleListEditor extends RestrictedSettingsFragment {

    private static final String INDEX_KEY_ADD_LANGUAGE = "add_language";
    private static final String KEY_LANGUAGES_PICKER = "languages_picker";
    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 LocaleDragAndDropAdapter mAdapter;
    private Menu mMenu;
@@ -80,6 +86,7 @@ public class LocaleListEditor extends RestrictedSettingsFragment {

    private LayoutPreference mLocalePickerPreference;
    private LocaleHelperPreferenceController mLocaleHelperPreferenceController;
    private FragmentManager mFragmentManager;

    public LocaleListEditor() {
        super(DISALLOW_CONFIG_LOCALE);
@@ -106,6 +113,7 @@ public class LocaleListEditor extends RestrictedSettingsFragment {
        LocaleStore.fillCache(this.getContext());
        final List<LocaleStore.LocaleInfo> feedsList = getUserLocaleList();
        mAdapter = new LocaleDragAndDropAdapter(this, feedsList);
        mFragmentManager = getChildFragmentManager();
    }

    @Override
@@ -141,7 +149,15 @@ public class LocaleListEditor extends RestrictedSettingsFragment {
            mShowingRemoveDialog = savedInstanceState.getBoolean(CFGKEY_REMOVE_DIALOG, false);
        }
        setRemoveMode(mRemoveMode);
        mAdapter.restoreState(savedInstanceState);

        final LocaleDialogFragment dialogFragment =
                (LocaleDialogFragment) mFragmentManager.findFragmentByTag(
                        TAG_DIALOG_CONFIRM_SYSTEM_DEFAULT);
        boolean isDialogShowing = false;
        if (dialogFragment != null && dialogFragment.isAdded()) {
            isDialogShowing = true;
        }
        mAdapter.restoreState(savedInstanceState, isDialogShowing);

        if (mShowingRemoveDialog) {
            showRemoveLocaleWarningDialog();
@@ -178,17 +194,32 @@ public class LocaleListEditor extends RestrictedSettingsFragment {

    @Override
    public void onActivityResult(int requestCode, int resultCode, Intent data) {
        LocaleStore.LocaleInfo localeInfo;
        if (requestCode == REQUEST_LOCALE_PICKER && resultCode == Activity.RESULT_OK
                && data != null) {
            final LocaleStore.LocaleInfo localeInfo =
                    (LocaleStore.LocaleInfo) data.getSerializableExtra(
                            INTENT_LOCALE_KEY);

            localeInfo = (LocaleStore.LocaleInfo) data.getSerializableExtra(INTENT_LOCALE_KEY);
            String preferencesTags = Settings.System.getString(
                    getContext().getContentResolver(), Settings.System.LOCALE_PREFERENCES);

            mAdapter.addLocale(mayAppendUnicodeTags(localeInfo, preferencesTags));
            updateVisibilityOfRemoveMenu();
        } else if (requestCode == DIALOG_CONFIRM_SYSTEM_DEFAULT) {
            localeInfo = mAdapter.getFeedItemList().get(0);
            if (resultCode == Activity.RESULT_OK) {
                mAdapter.doTheUpdate();
                if (!localeInfo.isTranslated()) {
                    Bundle args = new Bundle();
                    args.putInt(LocaleDialogFragment.ARG_DIALOG_TYPE,
                            LocaleDialogFragment.DIALOG_NOT_AVAILABLE_LOCALE);
                    args.putSerializable(LocaleDialogFragment.ARG_TARGET_LOCALE, localeInfo);
                    LocaleDialogFragment localeDialogFragment = LocaleDialogFragment.newInstance();
                    localeDialogFragment.setArguments(args);
                    localeDialogFragment.show(mFragmentManager, TAG_DIALOG_NOT_AVAILABLE);
                }
            } else {
                mAdapter.notifyListChanged(localeInfo);
            }
            mAdapter.setCacheItemList();
        }
        super.onActivityResult(requestCode, resultCode, data);
    }
@@ -332,6 +363,7 @@ public class LocaleListEditor extends RestrictedSettingsFragment {
        list.setNestedScrollingEnabled(false);
        mAdapter.setRecyclerView(list);
        list.setAdapter(mAdapter);
        list.setOnTouchListener(this);

        mAddLanguage = layout.findViewById(R.id.add_language);
        mAddLanguage.setOnClickListener(new View.OnClickListener() {
@@ -348,6 +380,26 @@ public class LocaleListEditor extends RestrictedSettingsFragment {
        });
    }

    @Override
    public boolean onTouch(View v, MotionEvent event) {
        if (event.getAction() == MotionEvent.ACTION_UP
                || event.getAction() == MotionEvent.ACTION_CANCEL) {
            LocaleStore.LocaleInfo localeInfo = mAdapter.getFeedItemList().get(0);
            if (!localeInfo.getLocale().equals(LocalePicker.getLocales().get(0))) {
                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, localeInfo);
                localeDialogFragment.setArguments(args);
                localeDialogFragment.show(mFragmentManager, TAG_DIALOG_CONFIRM_SYSTEM_DEFAULT);
            } else {
                mAdapter.doTheUpdate();
            }
        }
        return false;
    }

    // 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
    private void updateVisibilityOfRemoveMenu() {
+0 −11
Original line number Diff line number Diff line
@@ -34,15 +34,4 @@ class LocaleRecyclerView extends RecyclerView {
    public LocaleRecyclerView(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
    }

    @Override
    public boolean onTouchEvent(MotionEvent e) {
        if (e.getAction() == MotionEvent.ACTION_UP || e.getAction() == MotionEvent.ACTION_CANCEL) {
            LocaleDragAndDropAdapter adapter = (LocaleDragAndDropAdapter) this.getAdapter();
            if (adapter != null) {
                adapter.doTheUpdateWithMovingLocaleItem();
            }
        }
        return super.onTouchEvent(e);
    }
}
+98 −2

File changed.

Preview size limit exceeded, changes collapsed.

Loading