1a43b74a4ef3735e52d3fda348271b8e495d685a8Daisuke Miyakawa/*
2a43b74a4ef3735e52d3fda348271b8e495d685a8Daisuke Miyakawa * Copyright (C) 2010 The Android Open Source Project
3a43b74a4ef3735e52d3fda348271b8e495d685a8Daisuke Miyakawa *
4a43b74a4ef3735e52d3fda348271b8e495d685a8Daisuke Miyakawa * Licensed under the Apache License, Version 2.0 (the "License");
5a43b74a4ef3735e52d3fda348271b8e495d685a8Daisuke Miyakawa * you may not use this file except in compliance with the License.
6a43b74a4ef3735e52d3fda348271b8e495d685a8Daisuke Miyakawa * You may obtain a copy of the License at
7a43b74a4ef3735e52d3fda348271b8e495d685a8Daisuke Miyakawa *
8a43b74a4ef3735e52d3fda348271b8e495d685a8Daisuke Miyakawa *      http://www.apache.org/licenses/LICENSE-2.0
9a43b74a4ef3735e52d3fda348271b8e495d685a8Daisuke Miyakawa *
10a43b74a4ef3735e52d3fda348271b8e495d685a8Daisuke Miyakawa * Unless required by applicable law or agreed to in writing, software
11a43b74a4ef3735e52d3fda348271b8e495d685a8Daisuke Miyakawa * distributed under the License is distributed on an "AS IS" BASIS,
12a43b74a4ef3735e52d3fda348271b8e495d685a8Daisuke Miyakawa * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13a43b74a4ef3735e52d3fda348271b8e495d685a8Daisuke Miyakawa * See the License for the specific language governing permissions and
14a43b74a4ef3735e52d3fda348271b8e495d685a8Daisuke Miyakawa * limitations under the License.
15a43b74a4ef3735e52d3fda348271b8e495d685a8Daisuke Miyakawa */
16a43b74a4ef3735e52d3fda348271b8e495d685a8Daisuke Miyakawa
17a43b74a4ef3735e52d3fda348271b8e495d685a8Daisuke Miyakawapackage com.android.internal.app;
18a43b74a4ef3735e52d3fda348271b8e495d685a8Daisuke Miyakawa
1988b7349125d26200c5b4ef3c143e2e1cceda5703Daisuke Miyakawaimport com.android.internal.R;
2088b7349125d26200c5b4ef3c143e2e1cceda5703Daisuke Miyakawa
21dc589ac82b5fe2063f4cfd94c8ae26d43d5420a0Sudheer Shankaimport android.app.ActivityManager;
22a43b74a4ef3735e52d3fda348271b8e495d685a8Daisuke Miyakawaimport android.app.IActivityManager;
23a43b74a4ef3735e52d3fda348271b8e495d685a8Daisuke Miyakawaimport android.app.ListFragment;
24a43b74a4ef3735e52d3fda348271b8e495d685a8Daisuke Miyakawaimport android.app.backup.BackupManager;
2553daead5718a95953fc009782299bd5e544bf4e5Daisuke Miyakawaimport android.content.Context;
26a43b74a4ef3735e52d3fda348271b8e495d685a8Daisuke Miyakawaimport android.content.res.Configuration;
27a43b74a4ef3735e52d3fda348271b8e495d685a8Daisuke Miyakawaimport android.content.res.Resources;
28a43b74a4ef3735e52d3fda348271b8e495d685a8Daisuke Miyakawaimport android.os.Bundle;
2923cbe85610f780134cc77dd4a54732a22ed6e86eYohei Yukawaimport android.os.LocaleList;
30a43b74a4ef3735e52d3fda348271b8e495d685a8Daisuke Miyakawaimport android.os.RemoteException;
31dee5cde1ec3cca5235c397acdb217ddadaa7994fElliott Hughesimport android.provider.Settings;
32a43b74a4ef3735e52d3fda348271b8e495d685a8Daisuke Miyakawaimport android.util.Log;
330203341a0bbfefb97a91d54613a556f524c94a5cVictoria Leaseimport android.view.LayoutInflater;
34a43b74a4ef3735e52d3fda348271b8e495d685a8Daisuke Miyakawaimport android.view.View;
350203341a0bbfefb97a91d54613a556f524c94a5cVictoria Leaseimport android.view.ViewGroup;
36a43b74a4ef3735e52d3fda348271b8e495d685a8Daisuke Miyakawaimport android.widget.ArrayAdapter;
37a43b74a4ef3735e52d3fda348271b8e495d685a8Daisuke Miyakawaimport android.widget.ListView;
380203341a0bbfefb97a91d54613a556f524c94a5cVictoria Leaseimport android.widget.TextView;
39a43b74a4ef3735e52d3fda348271b8e495d685a8Daisuke Miyakawa
40a43b74a4ef3735e52d3fda348271b8e495d685a8Daisuke Miyakawaimport java.text.Collator;
41b27c137087ee926746b43b1abd08fb360ede671bNarayan Kamathimport java.util.Collections;
42b27c137087ee926746b43b1abd08fb360ede671bNarayan Kamathimport java.util.List;
43a43b74a4ef3735e52d3fda348271b8e495d685a8Daisuke Miyakawaimport java.util.Locale;
4439f96f95c3ee5e6c2f2e96f2bdf4ba29d18840feBenjamin Poieszimport java.util.ArrayList;
45a43b74a4ef3735e52d3fda348271b8e495d685a8Daisuke Miyakawa
46a43b74a4ef3735e52d3fda348271b8e495d685a8Daisuke Miyakawapublic class LocalePicker extends ListFragment {
47a43b74a4ef3735e52d3fda348271b8e495d685a8Daisuke Miyakawa    private static final String TAG = "LocalePicker";
48a43b74a4ef3735e52d3fda348271b8e495d685a8Daisuke Miyakawa    private static final boolean DEBUG = false;
49451376062a4cbc63bf1f74cad58863ff0e439e67Mihai Nita    private static final String[] pseudoLocales = { "en-XA", "ar-XB" };
50a43b74a4ef3735e52d3fda348271b8e495d685a8Daisuke Miyakawa
51a43b74a4ef3735e52d3fda348271b8e495d685a8Daisuke Miyakawa    public static interface LocaleSelectionListener {
52a43b74a4ef3735e52d3fda348271b8e495d685a8Daisuke Miyakawa        // You can add any argument if you really need it...
5388b7349125d26200c5b4ef3c143e2e1cceda5703Daisuke Miyakawa        public void onLocaleSelected(Locale locale);
54a43b74a4ef3735e52d3fda348271b8e495d685a8Daisuke Miyakawa    }
55a43b74a4ef3735e52d3fda348271b8e495d685a8Daisuke Miyakawa
56a43b74a4ef3735e52d3fda348271b8e495d685a8Daisuke Miyakawa    LocaleSelectionListener mListener;  // default to null
57a43b74a4ef3735e52d3fda348271b8e495d685a8Daisuke Miyakawa
5853daead5718a95953fc009782299bd5e544bf4e5Daisuke Miyakawa    public static class LocaleInfo implements Comparable<LocaleInfo> {
5953daead5718a95953fc009782299bd5e544bf4e5Daisuke Miyakawa        static final Collator sCollator = Collator.getInstance();
60a43b74a4ef3735e52d3fda348271b8e495d685a8Daisuke Miyakawa
61a43b74a4ef3735e52d3fda348271b8e495d685a8Daisuke Miyakawa        String label;
62451376062a4cbc63bf1f74cad58863ff0e439e67Mihai Nita        final Locale locale;
63a43b74a4ef3735e52d3fda348271b8e495d685a8Daisuke Miyakawa
6453daead5718a95953fc009782299bd5e544bf4e5Daisuke Miyakawa        public LocaleInfo(String label, Locale locale) {
65a43b74a4ef3735e52d3fda348271b8e495d685a8Daisuke Miyakawa            this.label = label;
66a43b74a4ef3735e52d3fda348271b8e495d685a8Daisuke Miyakawa            this.locale = locale;
67a43b74a4ef3735e52d3fda348271b8e495d685a8Daisuke Miyakawa        }
68a43b74a4ef3735e52d3fda348271b8e495d685a8Daisuke Miyakawa
6953daead5718a95953fc009782299bd5e544bf4e5Daisuke Miyakawa        public String getLabel() {
7053daead5718a95953fc009782299bd5e544bf4e5Daisuke Miyakawa            return label;
7153daead5718a95953fc009782299bd5e544bf4e5Daisuke Miyakawa        }
7253daead5718a95953fc009782299bd5e544bf4e5Daisuke Miyakawa
7353daead5718a95953fc009782299bd5e544bf4e5Daisuke Miyakawa        public Locale getLocale() {
7453daead5718a95953fc009782299bd5e544bf4e5Daisuke Miyakawa            return locale;
7553daead5718a95953fc009782299bd5e544bf4e5Daisuke Miyakawa        }
7653daead5718a95953fc009782299bd5e544bf4e5Daisuke Miyakawa
77a43b74a4ef3735e52d3fda348271b8e495d685a8Daisuke Miyakawa        @Override
78a43b74a4ef3735e52d3fda348271b8e495d685a8Daisuke Miyakawa        public String toString() {
79a43b74a4ef3735e52d3fda348271b8e495d685a8Daisuke Miyakawa            return this.label;
80a43b74a4ef3735e52d3fda348271b8e495d685a8Daisuke Miyakawa        }
81a43b74a4ef3735e52d3fda348271b8e495d685a8Daisuke Miyakawa
82a43b74a4ef3735e52d3fda348271b8e495d685a8Daisuke Miyakawa        @Override
8353daead5718a95953fc009782299bd5e544bf4e5Daisuke Miyakawa        public int compareTo(LocaleInfo another) {
84a43b74a4ef3735e52d3fda348271b8e495d685a8Daisuke Miyakawa            return sCollator.compare(this.label, another.label);
85a43b74a4ef3735e52d3fda348271b8e495d685a8Daisuke Miyakawa        }
86a43b74a4ef3735e52d3fda348271b8e495d685a8Daisuke Miyakawa    }
87a43b74a4ef3735e52d3fda348271b8e495d685a8Daisuke Miyakawa
88451376062a4cbc63bf1f74cad58863ff0e439e67Mihai Nita    public static String[] getSystemAssetLocales() {
89451376062a4cbc63bf1f74cad58863ff0e439e67Mihai Nita        return Resources.getSystem().getAssets().getLocales();
90451376062a4cbc63bf1f74cad58863ff0e439e67Mihai Nita    }
91451376062a4cbc63bf1f74cad58863ff0e439e67Mihai Nita
92451376062a4cbc63bf1f74cad58863ff0e439e67Mihai Nita    public static String[] getSupportedLocales(Context context) {
93451376062a4cbc63bf1f74cad58863ff0e439e67Mihai Nita        return context.getResources().getStringArray(R.array.supported_locales);
94451376062a4cbc63bf1f74cad58863ff0e439e67Mihai Nita    }
95451376062a4cbc63bf1f74cad58863ff0e439e67Mihai Nita
96451376062a4cbc63bf1f74cad58863ff0e439e67Mihai Nita    public static String[] getPseudoLocales() {
97451376062a4cbc63bf1f74cad58863ff0e439e67Mihai Nita        return pseudoLocales;
98451376062a4cbc63bf1f74cad58863ff0e439e67Mihai Nita    }
99451376062a4cbc63bf1f74cad58863ff0e439e67Mihai Nita
10037197df4791da690d18aefb1f24c54748515b6a0Narayan Kamath    public static List<LocaleInfo> getAllAssetLocales(Context context, boolean isInDeveloperMode) {
10153daead5718a95953fc009782299bd5e544bf4e5Daisuke Miyakawa        final Resources resources = context.getResources();
10239f96f95c3ee5e6c2f2e96f2bdf4ba29d18840feBenjamin Poiesz
103451376062a4cbc63bf1f74cad58863ff0e439e67Mihai Nita        final String[] locales = getSystemAssetLocales();
104b27c137087ee926746b43b1abd08fb360ede671bNarayan Kamath        List<String> localeList = new ArrayList<String>(locales.length);
105b27c137087ee926746b43b1abd08fb360ede671bNarayan Kamath        Collections.addAll(localeList, locales);
106dee5cde1ec3cca5235c397acdb217ddadaa7994fElliott Hughes
107dee5cde1ec3cca5235c397acdb217ddadaa7994fElliott Hughes        // Don't show the pseudolocales unless we're in developer mode. http://b/17190407.
108dee5cde1ec3cca5235c397acdb217ddadaa7994fElliott Hughes        if (!isInDeveloperMode) {
109451376062a4cbc63bf1f74cad58863ff0e439e67Mihai Nita            for (String locale : pseudoLocales) {
110451376062a4cbc63bf1f74cad58863ff0e439e67Mihai Nita                localeList.remove(locale);
111451376062a4cbc63bf1f74cad58863ff0e439e67Mihai Nita            }
11239f96f95c3ee5e6c2f2e96f2bdf4ba29d18840feBenjamin Poiesz        }
11339f96f95c3ee5e6c2f2e96f2bdf4ba29d18840feBenjamin Poiesz
114b27c137087ee926746b43b1abd08fb360ede671bNarayan Kamath        Collections.sort(localeList);
11553daead5718a95953fc009782299bd5e544bf4e5Daisuke Miyakawa        final String[] specialLocaleCodes = resources.getStringArray(R.array.special_locale_codes);
11653daead5718a95953fc009782299bd5e544bf4e5Daisuke Miyakawa        final String[] specialLocaleNames = resources.getStringArray(R.array.special_locale_names);
117b27c137087ee926746b43b1abd08fb360ede671bNarayan Kamath
118b27c137087ee926746b43b1abd08fb360ede671bNarayan Kamath        final ArrayList<LocaleInfo> localeInfos = new ArrayList<LocaleInfo>(localeList.size());
119b27c137087ee926746b43b1abd08fb360ede671bNarayan Kamath        for (String locale : localeList) {
120b27c137087ee926746b43b1abd08fb360ede671bNarayan Kamath            final Locale l = Locale.forLanguageTag(locale.replace('_', '-'));
12180b574199c5d06132acbcf640ec81f45f0d76ce3Narayan Kamath            if (l == null || "und".equals(l.getLanguage())
12280b574199c5d06132acbcf640ec81f45f0d76ce3Narayan Kamath                    || l.getLanguage().isEmpty() || l.getCountry().isEmpty()) {
123b27c137087ee926746b43b1abd08fb360ede671bNarayan Kamath                continue;
124b27c137087ee926746b43b1abd08fb360ede671bNarayan Kamath            }
125b27c137087ee926746b43b1abd08fb360ede671bNarayan Kamath
126b27c137087ee926746b43b1abd08fb360ede671bNarayan Kamath            if (localeInfos.isEmpty()) {
127b27c137087ee926746b43b1abd08fb360ede671bNarayan Kamath                if (DEBUG) {
128b27c137087ee926746b43b1abd08fb360ede671bNarayan Kamath                    Log.v(TAG, "adding initial "+ toTitleCase(l.getDisplayLanguage(l)));
129b27c137087ee926746b43b1abd08fb360ede671bNarayan Kamath                }
130b27c137087ee926746b43b1abd08fb360ede671bNarayan Kamath                localeInfos.add(new LocaleInfo(toTitleCase(l.getDisplayLanguage(l)), l));
131b27c137087ee926746b43b1abd08fb360ede671bNarayan Kamath            } else {
132b27c137087ee926746b43b1abd08fb360ede671bNarayan Kamath                // check previous entry:
133b27c137087ee926746b43b1abd08fb360ede671bNarayan Kamath                //  same lang and a country -> upgrade to full name and
134b27c137087ee926746b43b1abd08fb360ede671bNarayan Kamath                //    insert ours with full name
135b27c137087ee926746b43b1abd08fb360ede671bNarayan Kamath                //  diff lang -> insert ours with lang-only name
136b27c137087ee926746b43b1abd08fb360ede671bNarayan Kamath                final LocaleInfo previous = localeInfos.get(localeInfos.size() - 1);
137b27c137087ee926746b43b1abd08fb360ede671bNarayan Kamath                if (previous.locale.getLanguage().equals(l.getLanguage()) &&
138b27c137087ee926746b43b1abd08fb360ede671bNarayan Kamath                        !previous.locale.getLanguage().equals("zz")) {
139b27c137087ee926746b43b1abd08fb360ede671bNarayan Kamath                    if (DEBUG) {
140b27c137087ee926746b43b1abd08fb360ede671bNarayan Kamath                        Log.v(TAG, "backing up and fixing " + previous.label + " to " +
141b27c137087ee926746b43b1abd08fb360ede671bNarayan Kamath                                getDisplayName(previous.locale, specialLocaleCodes, specialLocaleNames));
142b27c137087ee926746b43b1abd08fb360ede671bNarayan Kamath                    }
143b27c137087ee926746b43b1abd08fb360ede671bNarayan Kamath                    previous.label = toTitleCase(getDisplayName(
144b27c137087ee926746b43b1abd08fb360ede671bNarayan Kamath                            previous.locale, specialLocaleCodes, specialLocaleNames));
145a43b74a4ef3735e52d3fda348271b8e495d685a8Daisuke Miyakawa                    if (DEBUG) {
146b27c137087ee926746b43b1abd08fb360ede671bNarayan Kamath                        Log.v(TAG, "  and adding "+ toTitleCase(
147b27c137087ee926746b43b1abd08fb360ede671bNarayan Kamath                                getDisplayName(l, specialLocaleCodes, specialLocaleNames)));
148a43b74a4ef3735e52d3fda348271b8e495d685a8Daisuke Miyakawa                    }
149b27c137087ee926746b43b1abd08fb360ede671bNarayan Kamath                    localeInfos.add(new LocaleInfo(toTitleCase(
150b27c137087ee926746b43b1abd08fb360ede671bNarayan Kamath                            getDisplayName(l, specialLocaleCodes, specialLocaleNames)), l));
151a43b74a4ef3735e52d3fda348271b8e495d685a8Daisuke Miyakawa                } else {
152dee5cde1ec3cca5235c397acdb217ddadaa7994fElliott Hughes                    String displayName = toTitleCase(l.getDisplayLanguage(l));
153b27c137087ee926746b43b1abd08fb360ede671bNarayan Kamath                    if (DEBUG) {
154b27c137087ee926746b43b1abd08fb360ede671bNarayan Kamath                        Log.v(TAG, "adding "+displayName);
155a43b74a4ef3735e52d3fda348271b8e495d685a8Daisuke Miyakawa                    }
156b27c137087ee926746b43b1abd08fb360ede671bNarayan Kamath                    localeInfos.add(new LocaleInfo(displayName, l));
157a43b74a4ef3735e52d3fda348271b8e495d685a8Daisuke Miyakawa                }
158a43b74a4ef3735e52d3fda348271b8e495d685a8Daisuke Miyakawa            }
159a43b74a4ef3735e52d3fda348271b8e495d685a8Daisuke Miyakawa        }
16053daead5718a95953fc009782299bd5e544bf4e5Daisuke Miyakawa
161b27c137087ee926746b43b1abd08fb360ede671bNarayan Kamath        Collections.sort(localeInfos);
16237197df4791da690d18aefb1f24c54748515b6a0Narayan Kamath        return localeInfos;
16337197df4791da690d18aefb1f24c54748515b6a0Narayan Kamath    }
16437197df4791da690d18aefb1f24c54748515b6a0Narayan Kamath
165dee5cde1ec3cca5235c397acdb217ddadaa7994fElliott Hughes    /**
166dee5cde1ec3cca5235c397acdb217ddadaa7994fElliott Hughes     * Constructs an Adapter object containing Locale information. Content is sorted by
167dee5cde1ec3cca5235c397acdb217ddadaa7994fElliott Hughes     * {@link LocaleInfo#label}.
168dee5cde1ec3cca5235c397acdb217ddadaa7994fElliott Hughes     */
169dee5cde1ec3cca5235c397acdb217ddadaa7994fElliott Hughes    public static ArrayAdapter<LocaleInfo> constructAdapter(Context context) {
170dee5cde1ec3cca5235c397acdb217ddadaa7994fElliott Hughes        return constructAdapter(context, R.layout.locale_picker_item, R.id.locale);
171dee5cde1ec3cca5235c397acdb217ddadaa7994fElliott Hughes    }
172dee5cde1ec3cca5235c397acdb217ddadaa7994fElliott Hughes
17337197df4791da690d18aefb1f24c54748515b6a0Narayan Kamath    public static ArrayAdapter<LocaleInfo> constructAdapter(Context context,
174dee5cde1ec3cca5235c397acdb217ddadaa7994fElliott Hughes            final int layoutId, final int fieldId) {
175dee5cde1ec3cca5235c397acdb217ddadaa7994fElliott Hughes        boolean isInDeveloperMode = Settings.Global.getInt(context.getContentResolver(),
176dee5cde1ec3cca5235c397acdb217ddadaa7994fElliott Hughes                Settings.Global.DEVELOPMENT_SETTINGS_ENABLED, 0) != 0;
17737197df4791da690d18aefb1f24c54748515b6a0Narayan Kamath        final List<LocaleInfo> localeInfos = getAllAssetLocales(context, isInDeveloperMode);
17837197df4791da690d18aefb1f24c54748515b6a0Narayan Kamath
1790203341a0bbfefb97a91d54613a556f524c94a5cVictoria Lease        final LayoutInflater inflater =
1800203341a0bbfefb97a91d54613a556f524c94a5cVictoria Lease                (LayoutInflater)context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
1810203341a0bbfefb97a91d54613a556f524c94a5cVictoria Lease        return new ArrayAdapter<LocaleInfo>(context, layoutId, fieldId, localeInfos) {
1820203341a0bbfefb97a91d54613a556f524c94a5cVictoria Lease            @Override
1830203341a0bbfefb97a91d54613a556f524c94a5cVictoria Lease            public View getView(int position, View convertView, ViewGroup parent) {
1840203341a0bbfefb97a91d54613a556f524c94a5cVictoria Lease                View view;
1850203341a0bbfefb97a91d54613a556f524c94a5cVictoria Lease                TextView text;
1860203341a0bbfefb97a91d54613a556f524c94a5cVictoria Lease                if (convertView == null) {
1870203341a0bbfefb97a91d54613a556f524c94a5cVictoria Lease                    view = inflater.inflate(layoutId, parent, false);
1880203341a0bbfefb97a91d54613a556f524c94a5cVictoria Lease                    text = (TextView) view.findViewById(fieldId);
1890203341a0bbfefb97a91d54613a556f524c94a5cVictoria Lease                    view.setTag(text);
1900203341a0bbfefb97a91d54613a556f524c94a5cVictoria Lease                } else {
1910203341a0bbfefb97a91d54613a556f524c94a5cVictoria Lease                    view = convertView;
1920203341a0bbfefb97a91d54613a556f524c94a5cVictoria Lease                    text = (TextView) view.getTag();
1930203341a0bbfefb97a91d54613a556f524c94a5cVictoria Lease                }
1940203341a0bbfefb97a91d54613a556f524c94a5cVictoria Lease                LocaleInfo item = getItem(position);
1950203341a0bbfefb97a91d54613a556f524c94a5cVictoria Lease                text.setText(item.toString());
1960203341a0bbfefb97a91d54613a556f524c94a5cVictoria Lease                text.setTextLocale(item.getLocale());
1970203341a0bbfefb97a91d54613a556f524c94a5cVictoria Lease
1980203341a0bbfefb97a91d54613a556f524c94a5cVictoria Lease                return view;
1990203341a0bbfefb97a91d54613a556f524c94a5cVictoria Lease            }
2000203341a0bbfefb97a91d54613a556f524c94a5cVictoria Lease        };
201a43b74a4ef3735e52d3fda348271b8e495d685a8Daisuke Miyakawa    }
202a43b74a4ef3735e52d3fda348271b8e495d685a8Daisuke Miyakawa
203a43b74a4ef3735e52d3fda348271b8e495d685a8Daisuke Miyakawa    private static String toTitleCase(String s) {
204a43b74a4ef3735e52d3fda348271b8e495d685a8Daisuke Miyakawa        if (s.length() == 0) {
205a43b74a4ef3735e52d3fda348271b8e495d685a8Daisuke Miyakawa            return s;
206a43b74a4ef3735e52d3fda348271b8e495d685a8Daisuke Miyakawa        }
207a43b74a4ef3735e52d3fda348271b8e495d685a8Daisuke Miyakawa
208a43b74a4ef3735e52d3fda348271b8e495d685a8Daisuke Miyakawa        return Character.toUpperCase(s.charAt(0)) + s.substring(1);
209a43b74a4ef3735e52d3fda348271b8e495d685a8Daisuke Miyakawa    }
210a43b74a4ef3735e52d3fda348271b8e495d685a8Daisuke Miyakawa
21153daead5718a95953fc009782299bd5e544bf4e5Daisuke Miyakawa    private static String getDisplayName(
21253daead5718a95953fc009782299bd5e544bf4e5Daisuke Miyakawa            Locale l, String[] specialLocaleCodes, String[] specialLocaleNames) {
213a43b74a4ef3735e52d3fda348271b8e495d685a8Daisuke Miyakawa        String code = l.toString();
214a43b74a4ef3735e52d3fda348271b8e495d685a8Daisuke Miyakawa
21553daead5718a95953fc009782299bd5e544bf4e5Daisuke Miyakawa        for (int i = 0; i < specialLocaleCodes.length; i++) {
21653daead5718a95953fc009782299bd5e544bf4e5Daisuke Miyakawa            if (specialLocaleCodes[i].equals(code)) {
21753daead5718a95953fc009782299bd5e544bf4e5Daisuke Miyakawa                return specialLocaleNames[i];
218a43b74a4ef3735e52d3fda348271b8e495d685a8Daisuke Miyakawa            }
219a43b74a4ef3735e52d3fda348271b8e495d685a8Daisuke Miyakawa        }
220a43b74a4ef3735e52d3fda348271b8e495d685a8Daisuke Miyakawa
221a43b74a4ef3735e52d3fda348271b8e495d685a8Daisuke Miyakawa        return l.getDisplayName(l);
222a43b74a4ef3735e52d3fda348271b8e495d685a8Daisuke Miyakawa    }
223a43b74a4ef3735e52d3fda348271b8e495d685a8Daisuke Miyakawa
224a43b74a4ef3735e52d3fda348271b8e495d685a8Daisuke Miyakawa    @Override
22553daead5718a95953fc009782299bd5e544bf4e5Daisuke Miyakawa    public void onActivityCreated(final Bundle savedInstanceState) {
22653daead5718a95953fc009782299bd5e544bf4e5Daisuke Miyakawa        super.onActivityCreated(savedInstanceState);
227dee5cde1ec3cca5235c397acdb217ddadaa7994fElliott Hughes        final ArrayAdapter<LocaleInfo> adapter = constructAdapter(getActivity());
22853daead5718a95953fc009782299bd5e544bf4e5Daisuke Miyakawa        setListAdapter(adapter);
22953daead5718a95953fc009782299bd5e544bf4e5Daisuke Miyakawa    }
23053daead5718a95953fc009782299bd5e544bf4e5Daisuke Miyakawa
23153daead5718a95953fc009782299bd5e544bf4e5Daisuke Miyakawa    public void setLocaleSelectionListener(LocaleSelectionListener listener) {
23253daead5718a95953fc009782299bd5e544bf4e5Daisuke Miyakawa        mListener = listener;
23353daead5718a95953fc009782299bd5e544bf4e5Daisuke Miyakawa    }
23453daead5718a95953fc009782299bd5e544bf4e5Daisuke Miyakawa
23553daead5718a95953fc009782299bd5e544bf4e5Daisuke Miyakawa    @Override
236a43b74a4ef3735e52d3fda348271b8e495d685a8Daisuke Miyakawa    public void onResume() {
237a43b74a4ef3735e52d3fda348271b8e495d685a8Daisuke Miyakawa        super.onResume();
238a43b74a4ef3735e52d3fda348271b8e495d685a8Daisuke Miyakawa        getListView().requestFocus();
239a43b74a4ef3735e52d3fda348271b8e495d685a8Daisuke Miyakawa    }
240a43b74a4ef3735e52d3fda348271b8e495d685a8Daisuke Miyakawa
24188b7349125d26200c5b4ef3c143e2e1cceda5703Daisuke Miyakawa    /**
24288b7349125d26200c5b4ef3c143e2e1cceda5703Daisuke Miyakawa     * Each listener needs to call {@link #updateLocale(Locale)} to actually change the locale.
24388b7349125d26200c5b4ef3c143e2e1cceda5703Daisuke Miyakawa     *
24488b7349125d26200c5b4ef3c143e2e1cceda5703Daisuke Miyakawa     * We don't call {@link #updateLocale(Locale)} automatically, as it halt the system for
24588b7349125d26200c5b4ef3c143e2e1cceda5703Daisuke Miyakawa     * a moment and some callers won't want it.
24688b7349125d26200c5b4ef3c143e2e1cceda5703Daisuke Miyakawa     */
247a43b74a4ef3735e52d3fda348271b8e495d685a8Daisuke Miyakawa    @Override
248a43b74a4ef3735e52d3fda348271b8e495d685a8Daisuke Miyakawa    public void onListItemClick(ListView l, View v, int position, long id) {
24988b7349125d26200c5b4ef3c143e2e1cceda5703Daisuke Miyakawa        if (mListener != null) {
25053daead5718a95953fc009782299bd5e544bf4e5Daisuke Miyakawa            final Locale locale = ((LocaleInfo)getListAdapter().getItem(position)).locale;
25153daead5718a95953fc009782299bd5e544bf4e5Daisuke Miyakawa            mListener.onLocaleSelected(locale);
25288b7349125d26200c5b4ef3c143e2e1cceda5703Daisuke Miyakawa        }
25388b7349125d26200c5b4ef3c143e2e1cceda5703Daisuke Miyakawa    }
25488b7349125d26200c5b4ef3c143e2e1cceda5703Daisuke Miyakawa
25588b7349125d26200c5b4ef3c143e2e1cceda5703Daisuke Miyakawa    /**
25688b7349125d26200c5b4ef3c143e2e1cceda5703Daisuke Miyakawa     * Requests the system to update the system locale. Note that the system looks halted
25788b7349125d26200c5b4ef3c143e2e1cceda5703Daisuke Miyakawa     * for a while during the Locale migration, so the caller need to take care of it.
258451376062a4cbc63bf1f74cad58863ff0e439e67Mihai Nita     *
259451376062a4cbc63bf1f74cad58863ff0e439e67Mihai Nita     * @see #updateLocales(LocaleList)
26088b7349125d26200c5b4ef3c143e2e1cceda5703Daisuke Miyakawa     */
26188b7349125d26200c5b4ef3c143e2e1cceda5703Daisuke Miyakawa    public static void updateLocale(Locale locale) {
262451376062a4cbc63bf1f74cad58863ff0e439e67Mihai Nita        updateLocales(new LocaleList(locale));
263451376062a4cbc63bf1f74cad58863ff0e439e67Mihai Nita    }
264451376062a4cbc63bf1f74cad58863ff0e439e67Mihai Nita
265451376062a4cbc63bf1f74cad58863ff0e439e67Mihai Nita    /**
266451376062a4cbc63bf1f74cad58863ff0e439e67Mihai Nita     * Requests the system to update the list of system locales.
267451376062a4cbc63bf1f74cad58863ff0e439e67Mihai Nita     * Note that the system looks halted for a while during the Locale migration,
268451376062a4cbc63bf1f74cad58863ff0e439e67Mihai Nita     * so the caller need to take care of it.
269451376062a4cbc63bf1f74cad58863ff0e439e67Mihai Nita     */
270451376062a4cbc63bf1f74cad58863ff0e439e67Mihai Nita    public static void updateLocales(LocaleList locales) {
271a43b74a4ef3735e52d3fda348271b8e495d685a8Daisuke Miyakawa        try {
272dc589ac82b5fe2063f4cfd94c8ae26d43d5420a0Sudheer Shanka            final IActivityManager am = ActivityManager.getService();
273451376062a4cbc63bf1f74cad58863ff0e439e67Mihai Nita            final Configuration config = am.getConfiguration();
274a43b74a4ef3735e52d3fda348271b8e495d685a8Daisuke Miyakawa
275451376062a4cbc63bf1f74cad58863ff0e439e67Mihai Nita            config.setLocales(locales);
27670392818f07f175d4914cef13b12c215ff08f1dfNarayan Kamath            config.userSetLocale = true;
277a43b74a4ef3735e52d3fda348271b8e495d685a8Daisuke Miyakawa
278bd5cbdd6389f384873951877c5dffbb0403f01d5Seigo Nonaka            am.updatePersistentConfiguration(config);
279a43b74a4ef3735e52d3fda348271b8e495d685a8Daisuke Miyakawa            // Trigger the dirty bit for the Settings Provider.
280a43b74a4ef3735e52d3fda348271b8e495d685a8Daisuke Miyakawa            BackupManager.dataChanged("com.android.providers.settings");
281a43b74a4ef3735e52d3fda348271b8e495d685a8Daisuke Miyakawa        } catch (RemoteException e) {
282a43b74a4ef3735e52d3fda348271b8e495d685a8Daisuke Miyakawa            // Intentionally left blank
283a43b74a4ef3735e52d3fda348271b8e495d685a8Daisuke Miyakawa        }
284a43b74a4ef3735e52d3fda348271b8e495d685a8Daisuke Miyakawa    }
285451376062a4cbc63bf1f74cad58863ff0e439e67Mihai Nita
286451376062a4cbc63bf1f74cad58863ff0e439e67Mihai Nita    /**
287451376062a4cbc63bf1f74cad58863ff0e439e67Mihai Nita     * Get the locale list.
288451376062a4cbc63bf1f74cad58863ff0e439e67Mihai Nita     *
289451376062a4cbc63bf1f74cad58863ff0e439e67Mihai Nita     * @return The locale list.
290451376062a4cbc63bf1f74cad58863ff0e439e67Mihai Nita     */
291451376062a4cbc63bf1f74cad58863ff0e439e67Mihai Nita    public static LocaleList getLocales() {
292451376062a4cbc63bf1f74cad58863ff0e439e67Mihai Nita        try {
293dc589ac82b5fe2063f4cfd94c8ae26d43d5420a0Sudheer Shanka            return ActivityManager.getService()
294451376062a4cbc63bf1f74cad58863ff0e439e67Mihai Nita                    .getConfiguration().getLocales();
295451376062a4cbc63bf1f74cad58863ff0e439e67Mihai Nita        } catch (RemoteException e) {
296451376062a4cbc63bf1f74cad58863ff0e439e67Mihai Nita            // If something went wrong
297451376062a4cbc63bf1f74cad58863ff0e439e67Mihai Nita            return LocaleList.getDefault();
298451376062a4cbc63bf1f74cad58863ff0e439e67Mihai Nita        }
299451376062a4cbc63bf1f74cad58863ff0e439e67Mihai Nita    }
3000203341a0bbfefb97a91d54613a556f524c94a5cVictoria Lease}
301