Remove LocalePickerWithRegion class in Settings.

This class is too complex, we can't afford maintaining this long term.
We need a new Activity that wraps the framework version of LocalePickerWithRegion.

Bug: 111373939
Test: manual test & make RunSettingsRoboTests -j56

Change-Id: I93c719246b84350d2eee4e8ce1ffd97cd168925b
diff --git a/AndroidManifest.xml b/AndroidManifest.xml
index d3acd13..303dea1 100644
--- a/AndroidManifest.xml
+++ b/AndroidManifest.xml
@@ -574,6 +574,12 @@
                 android:value="true" />
         </activity>
 
+        <activity android:name=".localepicker.LocalePickerWithRegionActivity"
+                  android:excludeFromRecents="true"
+                  android:configChanges="orientation|keyboardHidden|screenSize"
+                  android:exported="false">
+        </activity>
+
         <activity
             android:name=".Settings$LanguageAndInputSettingsActivity"
             android:label="@string/language_settings"
diff --git a/src/com/android/settings/localepicker/LocaleListEditor.java b/src/com/android/settings/localepicker/LocaleListEditor.java
index 87c19dd..cbcb1eb 100644
--- a/src/com/android/settings/localepicker/LocaleListEditor.java
+++ b/src/com/android/settings/localepicker/LocaleListEditor.java
@@ -18,8 +18,10 @@
 
 import static android.os.UserManager.DISALLOW_CONFIG_LOCALE;
 
+import android.app.Activity;
 import android.app.AlertDialog;
 import android.content.DialogInterface;
+import android.content.Intent;
 import android.os.Bundle;
 import android.os.LocaleList;
 import android.view.LayoutInflater;
@@ -40,18 +42,18 @@
 import java.util.List;
 import java.util.Locale;
 
-import androidx.fragment.app.FragmentTransaction;
 import androidx.recyclerview.widget.RecyclerView;
 
 /**
  * Drag-and-drop editor for the user-ordered locale lists.
  */
-public class LocaleListEditor extends RestrictedSettingsFragment
-        implements LocalePickerWithRegion.LocaleSelectedListener {
+public class LocaleListEditor extends RestrictedSettingsFragment {
 
+    protected static final String INTENT_LOCALE_KEY = "localeInfo";
     private static final String CFGKEY_REMOVE_MODE = "localeRemoveMode";
     private static final String CFGKEY_REMOVE_DIALOG = "showingLocaleRemoveDialog";
     private static final int MENU_ID_REMOVE = Menu.FIRST + 1;
+    private static final int REQUEST_LOCALE_PICKER = 0;
 
     private LocaleDragAndDropAdapter mAdapter;
     private Menu mMenu;
@@ -150,6 +152,19 @@
         return super.onOptionsItemSelected(menuItem);
     }
 
+    @Override
+    public void onActivityResult(int requestCode, int resultCode, Intent data) {
+        if (requestCode == REQUEST_LOCALE_PICKER && resultCode == Activity.RESULT_OK
+                && data != null) {
+            final LocaleStore.LocaleInfo locale =
+                    (LocaleStore.LocaleInfo) data.getSerializableExtra(
+                            INTENT_LOCALE_KEY);
+            mAdapter.addLocale(locale);
+            updateVisibilityOfRemoveMenu();
+        }
+        super.onActivityResult(requestCode, resultCode, data);
+    }
+
     private void setRemoveMode(boolean mRemoveMode) {
         this.mRemoveMode = mRemoveMode;
         mAdapter.setRemoveMode(mRemoveMode);
@@ -267,24 +282,13 @@
         mAddLanguage.setOnClickListener(new View.OnClickListener() {
             @Override
             public void onClick(View v) {
-                final LocalePickerWithRegion selector = LocalePickerWithRegion.createLanguagePicker(
-                        getContext(), LocaleListEditor.this, false /* translate only */);
-                getFragmentManager()
-                        .beginTransaction()
-                        .setTransition(FragmentTransaction.TRANSIT_FRAGMENT_OPEN)
-                        .replace(getId(), selector)
-                        .addToBackStack("localeListEditor")
-                        .commit();
+                final Intent intent = new Intent(getActivity(),
+                        LocalePickerWithRegionActivity.class);
+                startActivityForResult(intent, REQUEST_LOCALE_PICKER);
             }
         });
     }
 
-    @Override
-    public void onLocaleSelected(LocaleStore.LocaleInfo locale) {
-        mAdapter.addLocale(locale);
-        updateVisibilityOfRemoveMenu();
-    }
-
     // 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() {
diff --git a/src/com/android/settings/localepicker/LocalePickerWithRegion.java b/src/com/android/settings/localepicker/LocalePickerWithRegion.java
deleted file mode 100644
index e8a91bc..0000000
--- a/src/com/android/settings/localepicker/LocalePickerWithRegion.java
+++ /dev/null
@@ -1,278 +0,0 @@
-/*
- * Copyright (C) 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.settings.localepicker;
-
-import android.content.Context;
-import android.os.Bundle;
-import android.os.LocaleList;
-import android.text.TextUtils;
-import android.view.Menu;
-import android.view.MenuInflater;
-import android.view.MenuItem;
-import android.view.View;
-import android.widget.ListView;
-import android.widget.SearchView;
-
-import com.android.internal.R;
-import com.android.internal.app.LocaleHelper;
-import com.android.internal.app.LocalePicker;
-import com.android.internal.app.LocaleStore;
-import com.android.internal.app.SuggestedLocaleAdapter;
-
-import java.util.Collections;
-import java.util.HashSet;
-import java.util.Locale;
-import java.util.Set;
-
-import androidx.fragment.app.FragmentManager;
-import androidx.fragment.app.FragmentTransaction;
-import androidx.fragment.app.ListFragment;
-
-/**
- * A two-step locale picker. It shows a language, then a country.
- *
- * <p>It shows suggestions at the top, then the rest of the locales.
- * Allows the user to search for locales using both their native name and their name in the
- * default locale.</p>
- */
-public class LocalePickerWithRegion extends ListFragment implements SearchView.OnQueryTextListener {
-    private static final String PARENT_FRAGMENT_NAME = "localeListEditor";
-
-    private SuggestedLocaleAdapter mAdapter;
-    private LocaleSelectedListener mListener;
-    private Set<LocaleStore.LocaleInfo> mLocaleList;
-    private LocaleStore.LocaleInfo mParentLocale;
-    private boolean mTranslatedOnly = false;
-    private SearchView mSearchView = null;
-    private CharSequence mPreviousSearch = null;
-    private boolean mPreviousSearchHadFocus = false;
-    private int mFirstVisiblePosition = 0;
-    private int mTopDistance = 0;
-
-    /**
-     * Other classes can register to be notified when a locale was selected.
-     *
-     * <p>This is the mechanism to "return" the result of the selection.</p>
-     */
-    public interface LocaleSelectedListener {
-        /**
-         * The classes that want to retrieve the locale picked should implement this method.
-         * @param locale    the locale picked.
-         */
-        void onLocaleSelected(LocaleStore.LocaleInfo locale);
-    }
-
-    private static LocalePickerWithRegion createCountryPicker(Context context,
-            LocaleSelectedListener listener, LocaleStore.LocaleInfo parent,
-            boolean translatedOnly) {
-        LocalePickerWithRegion
-                localePicker = new LocalePickerWithRegion();
-        boolean shouldShowTheList = localePicker.setListener(context, listener, parent,
-                translatedOnly);
-        return shouldShowTheList ? localePicker : null;
-    }
-
-    public static LocalePickerWithRegion createLanguagePicker(Context context,
-            LocaleSelectedListener listener, boolean translatedOnly) {
-        LocalePickerWithRegion
-                localePicker = new LocalePickerWithRegion();
-        localePicker.setListener(context, listener, /* parent */ null, translatedOnly);
-        return localePicker;
-    }
-
-    /**
-     * Sets the listener and initializes the locale list.
-     *
-     * <p>Returns true if we need to show the list, false if not.</p>
-     *
-     * <p>Can return false because of an error, trying to show a list of countries,
-     * but no parent locale was provided.</p>
-     *
-     * <p>It can also return false if the caller tries to show the list in country mode and
-     * there is only one country available (i.e. Japanese => Japan).
-     * In this case we don't even show the list, we call the listener with that locale,
-     * "pretending" it was selected, and return false.</p>
-     */
-    private boolean setListener(Context context, LocaleSelectedListener listener,
-            LocaleStore.LocaleInfo parent, boolean translatedOnly) {
-        this.mParentLocale = parent;
-        this.mListener = listener;
-        this.mTranslatedOnly = translatedOnly;
-        setRetainInstance(true);
-
-        final HashSet<String> langTagsToIgnore = new HashSet<>();
-        if (!translatedOnly) {
-            final LocaleList userLocales = LocalePicker.getLocales();
-            final String[] langTags = userLocales.toLanguageTags().split(",");
-            Collections.addAll(langTagsToIgnore, langTags);
-        }
-
-        if (parent != null) {
-            mLocaleList = LocaleStore.getLevelLocales(context,
-                    langTagsToIgnore, parent, translatedOnly);
-            if (mLocaleList.size() <= 1) {
-                if (listener != null && (mLocaleList.size() == 1)) {
-                    listener.onLocaleSelected(mLocaleList.iterator().next());
-                }
-                return false;
-            }
-        } else {
-            mLocaleList = LocaleStore.getLevelLocales(context, langTagsToIgnore,
-                    null /* no parent */, translatedOnly);
-        }
-
-        return true;
-    }
-
-    private void returnToParentFrame() {
-        getFragmentManager().popBackStack(PARENT_FRAGMENT_NAME,
-                FragmentManager.POP_BACK_STACK_INCLUSIVE);
-    }
-
-    @Override
-    public void onCreate(Bundle savedInstanceState) {
-        super.onCreate(savedInstanceState);
-        setHasOptionsMenu(true);
-
-        if (mLocaleList == null) {
-            // The fragment was killed and restored by the FragmentManager.
-            // At this point we have no data, no listener. Just return, to prevend a NPE.
-            // Fixes b/28748150. Created b/29400003 for a cleaner solution.
-            returnToParentFrame();
-            return;
-        }
-
-        final boolean countryMode = mParentLocale != null;
-        final Locale sortingLocale = countryMode ? mParentLocale.getLocale() : Locale.getDefault();
-        mAdapter = new SuggestedLocaleAdapter(mLocaleList, countryMode);
-        final LocaleHelper.LocaleInfoComparator comp =
-                new LocaleHelper.LocaleInfoComparator(sortingLocale, countryMode);
-        mAdapter.sort(comp);
-        setListAdapter(mAdapter);
-    }
-
-    @Override
-    public boolean onOptionsItemSelected(MenuItem menuItem) {
-        int id = menuItem.getItemId();
-        switch (id) {
-            case android.R.id.home:
-                getFragmentManager().popBackStack();
-                return true;
-        }
-        return super.onOptionsItemSelected(menuItem);
-    }
-
-    @Override
-    public void onResume() {
-        super.onResume();
-
-        if (mParentLocale != null) {
-            getActivity().setTitle(mParentLocale.getFullNameNative());
-        } else {
-            getActivity().setTitle(R.string.language_selection_title);
-        }
-
-        getListView().requestFocus();
-    }
-
-    @Override
-    public void onPause() {
-        super.onPause();
-
-        // Save search status
-        if (mSearchView != null) {
-            mPreviousSearchHadFocus = mSearchView.hasFocus();
-            mPreviousSearch = mSearchView.getQuery();
-        } else {
-            mPreviousSearchHadFocus = false;
-            mPreviousSearch = null;
-        }
-
-        // Save scroll position
-        final ListView list = getListView();
-        final View firstChild = list.getChildAt(0);
-        mFirstVisiblePosition = list.getFirstVisiblePosition();
-        mTopDistance = (firstChild == null) ? 0 : (firstChild.getTop() - list.getPaddingTop());
-    }
-
-    @Override
-    public void onListItemClick(ListView l, View v, int position, long id) {
-        final LocaleStore.LocaleInfo locale =
-                (LocaleStore.LocaleInfo) getListAdapter().getItem(position);
-
-        if (locale.getParent() != null) {
-            if (mListener != null) {
-                mListener.onLocaleSelected(locale);
-            }
-            returnToParentFrame();
-        } else {
-            LocalePickerWithRegion
-                    selector = LocalePickerWithRegion.createCountryPicker(
-                    getContext(), mListener, locale, mTranslatedOnly /* translate only */);
-            if (selector != null) {
-                getFragmentManager().beginTransaction()
-                        .setTransition(FragmentTransaction.TRANSIT_FRAGMENT_OPEN)
-                        .replace(getId(), selector).addToBackStack(null)
-                        .commit();
-            } else {
-                returnToParentFrame();
-            }
-        }
-    }
-
-    @Override
-    public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
-        if (mParentLocale == null) {
-            inflater.inflate(R.menu.language_selection_list, menu);
-
-            final MenuItem searchMenuItem = menu.findItem(R.id.locale_search_menu);
-            mSearchView = (SearchView) searchMenuItem.getActionView();
-
-            mSearchView.setQueryHint(getText(R.string.search_language_hint));
-            mSearchView.setOnQueryTextListener(this);
-
-            // Restore previous search status
-            if (!TextUtils.isEmpty(mPreviousSearch)) {
-                searchMenuItem.expandActionView();
-                mSearchView.setIconified(false);
-                mSearchView.setActivated(true);
-                if (mPreviousSearchHadFocus) {
-                    mSearchView.requestFocus();
-                }
-                mSearchView.setQuery(mPreviousSearch, true /* submit */);
-            } else {
-                mSearchView.setQuery(null, false /* submit */);
-            }
-
-            // Restore previous scroll position
-            getListView().setSelectionFromTop(mFirstVisiblePosition, mTopDistance);
-        }
-    }
-
-    @Override
-    public boolean onQueryTextSubmit(String query) {
-        return false;
-    }
-
-    @Override
-    public boolean onQueryTextChange(String newText) {
-        if (mAdapter != null) {
-            mAdapter.getFilter().filter(newText);
-        }
-        return false;
-    }
-}
diff --git a/src/com/android/settings/localepicker/LocalePickerWithRegionActivity.java b/src/com/android/settings/localepicker/LocalePickerWithRegionActivity.java
new file mode 100644
index 0000000..6ddcf23
--- /dev/null
+++ b/src/com/android/settings/localepicker/LocalePickerWithRegionActivity.java
@@ -0,0 +1,79 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.settings.localepicker;
+
+import android.app.Activity;
+import android.app.FragmentTransaction;
+import android.content.Intent;
+import android.os.Bundle;
+import android.view.MenuItem;
+
+import com.android.internal.app.LocalePickerWithRegion;
+import com.android.internal.app.LocaleStore;
+
+public class LocalePickerWithRegionActivity extends Activity
+        implements LocalePickerWithRegion.LocaleSelectedListener {
+
+    private static final String PARENT_FRAGMENT_NAME = "localeListEditor";
+
+    @Override
+    public void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        getActionBar().setDisplayHomeAsUpEnabled(true);
+
+        final LocalePickerWithRegion selector = LocalePickerWithRegion.createLanguagePicker(
+                this, LocalePickerWithRegionActivity.this, false /* translate only */);
+        getFragmentManager()
+                .beginTransaction()
+                .setTransition(FragmentTransaction.TRANSIT_FRAGMENT_OPEN)
+                .replace(android.R.id.content, selector)
+                .addToBackStack(PARENT_FRAGMENT_NAME)
+                .commit();
+    }
+
+    @Override
+    public boolean onOptionsItemSelected(MenuItem item) {
+        if (item.getItemId() == android.R.id.home) {
+            handleBackPressed();
+            return true;
+        }
+        return super.onOptionsItemSelected(item);
+    }
+
+    @Override
+    public void onLocaleSelected(LocaleStore.LocaleInfo locale) {
+        final Intent intent = new Intent();
+        intent.putExtra(LocaleListEditor.INTENT_LOCALE_KEY, locale);
+        setResult(RESULT_OK, intent);
+        finish();
+    }
+
+    @Override
+    public void onBackPressed() {
+        handleBackPressed();
+    }
+
+    private void handleBackPressed() {
+        if (getFragmentManager().getBackStackEntryCount() > 1) {
+            super.onBackPressed();
+        } else {
+            setResult(RESULT_CANCELED);
+            finish();
+        }
+    }
+}
+
diff --git a/tests/robotests/assets/grandfather_not_implementing_instrumentable b/tests/robotests/assets/grandfather_not_implementing_instrumentable
index 27ab65c..2c8ae5d 100644
--- a/tests/robotests/assets/grandfather_not_implementing_instrumentable
+++ b/tests/robotests/assets/grandfather_not_implementing_instrumentable
@@ -5,5 +5,4 @@
 com.android.settings.password.ChooseLockPattern$SaveAndFinishWorker
 com.android.settings.RestrictedListPreference$RestrictedListPreferenceDialogFragment
 com.android.settings.password.ConfirmDeviceCredentialBaseFragment$LastTryDialog
-com.android.settings.password.CredentialCheckResultTracker
-com.android.settings.localepicker.LocalePickerWithRegion
+com.android.settings.password.CredentialCheckResultTracker
\ No newline at end of file
diff --git a/tests/robotests/src/com/android/settings/localepicker/LocalePickerWithRegionActivityTest.java b/tests/robotests/src/com/android/settings/localepicker/LocalePickerWithRegionActivityTest.java
new file mode 100644
index 0000000..bad3dbd
--- /dev/null
+++ b/tests/robotests/src/com/android/settings/localepicker/LocalePickerWithRegionActivityTest.java
@@ -0,0 +1,51 @@
+package com.android.settings.localepicker;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.spy;
+
+import android.app.Activity;
+
+import com.android.internal.app.LocaleStore;
+import com.android.settings.testutils.SettingsRobolectricTestRunner;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.MockitoAnnotations;
+import org.robolectric.Robolectric;
+import org.robolectric.Shadows;
+import org.robolectric.android.controller.ActivityController;
+import org.robolectric.shadows.ShadowActivity;
+
+@RunWith(SettingsRobolectricTestRunner.class)
+public class LocalePickerWithRegionActivityTest {
+
+    private LocalePickerWithRegionActivity mActivity;
+
+    @Before
+    public void setUp() {
+        MockitoAnnotations.initMocks(this);
+        final ActivityController<LocalePickerWithRegionActivity> mActivityController =
+                Robolectric.buildActivity(LocalePickerWithRegionActivity.class);
+        mActivity = spy(mActivityController.get());
+    }
+
+    @Test
+    public void onLocaleSelected_resultShouldBeOK() {
+        final ShadowActivity shadowActivity = Shadows.shadowOf(mActivity);
+        mActivity.onLocaleSelected(mock(LocaleStore.LocaleInfo.class));
+
+        assertEquals(Activity.RESULT_OK, shadowActivity.getResultCode());
+    }
+
+    @Test
+    public void onLocaleSelected_localeInfoShouldBeSentBack() {
+        final ShadowActivity shadowActivity = Shadows.shadowOf(mActivity);
+        mActivity.onLocaleSelected(mock(LocaleStore.LocaleInfo.class));
+
+        assertNotNull(shadowActivity.getResultIntent().getSerializableExtra(
+                LocaleListEditor.INTENT_LOCALE_KEY));
+    }
+}