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
21a43b74a4ef3735e52d3fda348271b8e495d685a8Daisuke Miyakawaimport android.app.ActivityManagerNative;
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;
29a43b74a4ef3735e52d3fda348271b8e495d685a8Daisuke Miyakawaimport android.os.RemoteException;
30dee5cde1ec3cca5235c397acdb217ddadaa7994fElliott Hughesimport android.provider.Settings;
31a43b74a4ef3735e52d3fda348271b8e495d685a8Daisuke Miyakawaimport android.util.Log;
320203341a0bbfefb97a91d54613a556f524c94a5cVictoria Leaseimport android.view.LayoutInflater;
33a43b74a4ef3735e52d3fda348271b8e495d685a8Daisuke Miyakawaimport android.view.View;
340203341a0bbfefb97a91d54613a556f524c94a5cVictoria Leaseimport android.view.ViewGroup;
35a43b74a4ef3735e52d3fda348271b8e495d685a8Daisuke Miyakawaimport android.widget.ArrayAdapter;
36a43b74a4ef3735e52d3fda348271b8e495d685a8Daisuke Miyakawaimport android.widget.ListView;
370203341a0bbfefb97a91d54613a556f524c94a5cVictoria Leaseimport android.widget.TextView;
38a43b74a4ef3735e52d3fda348271b8e495d685a8Daisuke Miyakawa
39a43b74a4ef3735e52d3fda348271b8e495d685a8Daisuke Miyakawaimport java.text.Collator;
40b27c137087ee926746b43b1abd08fb360ede671bNarayan Kamathimport java.util.Collections;
41b27c137087ee926746b43b1abd08fb360ede671bNarayan Kamathimport java.util.List;
42a43b74a4ef3735e52d3fda348271b8e495d685a8Daisuke Miyakawaimport java.util.Locale;
4339f96f95c3ee5e6c2f2e96f2bdf4ba29d18840feBenjamin Poieszimport java.util.ArrayList;
44a43b74a4ef3735e52d3fda348271b8e495d685a8Daisuke Miyakawa
45a43b74a4ef3735e52d3fda348271b8e495d685a8Daisuke Miyakawapublic class LocalePicker extends ListFragment {
46a43b74a4ef3735e52d3fda348271b8e495d685a8Daisuke Miyakawa    private static final String TAG = "LocalePicker";
47a43b74a4ef3735e52d3fda348271b8e495d685a8Daisuke Miyakawa    private static final boolean DEBUG = false;
48a43b74a4ef3735e52d3fda348271b8e495d685a8Daisuke Miyakawa
49a43b74a4ef3735e52d3fda348271b8e495d685a8Daisuke Miyakawa    public static interface LocaleSelectionListener {
50a43b74a4ef3735e52d3fda348271b8e495d685a8Daisuke Miyakawa        // You can add any argument if you really need it...
5188b7349125d26200c5b4ef3c143e2e1cceda5703Daisuke Miyakawa        public void onLocaleSelected(Locale locale);
52a43b74a4ef3735e52d3fda348271b8e495d685a8Daisuke Miyakawa    }
53a43b74a4ef3735e52d3fda348271b8e495d685a8Daisuke Miyakawa
54a43b74a4ef3735e52d3fda348271b8e495d685a8Daisuke Miyakawa    LocaleSelectionListener mListener;  // default to null
55a43b74a4ef3735e52d3fda348271b8e495d685a8Daisuke Miyakawa
5653daead5718a95953fc009782299bd5e544bf4e5Daisuke Miyakawa    public static class LocaleInfo implements Comparable<LocaleInfo> {
5753daead5718a95953fc009782299bd5e544bf4e5Daisuke Miyakawa        static final Collator sCollator = Collator.getInstance();
58a43b74a4ef3735e52d3fda348271b8e495d685a8Daisuke Miyakawa
59a43b74a4ef3735e52d3fda348271b8e495d685a8Daisuke Miyakawa        String label;
60a43b74a4ef3735e52d3fda348271b8e495d685a8Daisuke Miyakawa        Locale locale;
61a43b74a4ef3735e52d3fda348271b8e495d685a8Daisuke Miyakawa
6253daead5718a95953fc009782299bd5e544bf4e5Daisuke Miyakawa        public LocaleInfo(String label, Locale locale) {
63a43b74a4ef3735e52d3fda348271b8e495d685a8Daisuke Miyakawa            this.label = label;
64a43b74a4ef3735e52d3fda348271b8e495d685a8Daisuke Miyakawa            this.locale = locale;
65a43b74a4ef3735e52d3fda348271b8e495d685a8Daisuke Miyakawa        }
66a43b74a4ef3735e52d3fda348271b8e495d685a8Daisuke Miyakawa
6753daead5718a95953fc009782299bd5e544bf4e5Daisuke Miyakawa        public String getLabel() {
6853daead5718a95953fc009782299bd5e544bf4e5Daisuke Miyakawa            return label;
6953daead5718a95953fc009782299bd5e544bf4e5Daisuke Miyakawa        }
7053daead5718a95953fc009782299bd5e544bf4e5Daisuke Miyakawa
7153daead5718a95953fc009782299bd5e544bf4e5Daisuke Miyakawa        public Locale getLocale() {
7253daead5718a95953fc009782299bd5e544bf4e5Daisuke Miyakawa            return locale;
7353daead5718a95953fc009782299bd5e544bf4e5Daisuke Miyakawa        }
7453daead5718a95953fc009782299bd5e544bf4e5Daisuke Miyakawa
75a43b74a4ef3735e52d3fda348271b8e495d685a8Daisuke Miyakawa        @Override
76a43b74a4ef3735e52d3fda348271b8e495d685a8Daisuke Miyakawa        public String toString() {
77a43b74a4ef3735e52d3fda348271b8e495d685a8Daisuke Miyakawa            return this.label;
78a43b74a4ef3735e52d3fda348271b8e495d685a8Daisuke Miyakawa        }
79a43b74a4ef3735e52d3fda348271b8e495d685a8Daisuke Miyakawa
80a43b74a4ef3735e52d3fda348271b8e495d685a8Daisuke Miyakawa        @Override
8153daead5718a95953fc009782299bd5e544bf4e5Daisuke Miyakawa        public int compareTo(LocaleInfo another) {
82a43b74a4ef3735e52d3fda348271b8e495d685a8Daisuke Miyakawa            return sCollator.compare(this.label, another.label);
83a43b74a4ef3735e52d3fda348271b8e495d685a8Daisuke Miyakawa        }
84a43b74a4ef3735e52d3fda348271b8e495d685a8Daisuke Miyakawa    }
85a43b74a4ef3735e52d3fda348271b8e495d685a8Daisuke Miyakawa
8637197df4791da690d18aefb1f24c54748515b6a0Narayan Kamath    public static List<LocaleInfo> getAllAssetLocales(Context context, boolean isInDeveloperMode) {
8753daead5718a95953fc009782299bd5e544bf4e5Daisuke Miyakawa        final Resources resources = context.getResources();
8839f96f95c3ee5e6c2f2e96f2bdf4ba29d18840feBenjamin Poiesz
8937197df4791da690d18aefb1f24c54748515b6a0Narayan Kamath        final String[] locales = Resources.getSystem().getAssets().getLocales();
90b27c137087ee926746b43b1abd08fb360ede671bNarayan Kamath        List<String> localeList = new ArrayList<String>(locales.length);
91b27c137087ee926746b43b1abd08fb360ede671bNarayan Kamath        Collections.addAll(localeList, locales);
92dee5cde1ec3cca5235c397acdb217ddadaa7994fElliott Hughes
93dee5cde1ec3cca5235c397acdb217ddadaa7994fElliott Hughes        // Don't show the pseudolocales unless we're in developer mode. http://b/17190407.
94dee5cde1ec3cca5235c397acdb217ddadaa7994fElliott Hughes        if (!isInDeveloperMode) {
95dee5cde1ec3cca5235c397acdb217ddadaa7994fElliott Hughes            localeList.remove("ar-XB");
96dee5cde1ec3cca5235c397acdb217ddadaa7994fElliott Hughes            localeList.remove("en-XA");
9739f96f95c3ee5e6c2f2e96f2bdf4ba29d18840feBenjamin Poiesz        }
9839f96f95c3ee5e6c2f2e96f2bdf4ba29d18840feBenjamin Poiesz
99b27c137087ee926746b43b1abd08fb360ede671bNarayan Kamath        Collections.sort(localeList);
10053daead5718a95953fc009782299bd5e544bf4e5Daisuke Miyakawa        final String[] specialLocaleCodes = resources.getStringArray(R.array.special_locale_codes);
10153daead5718a95953fc009782299bd5e544bf4e5Daisuke Miyakawa        final String[] specialLocaleNames = resources.getStringArray(R.array.special_locale_names);
102b27c137087ee926746b43b1abd08fb360ede671bNarayan Kamath
103b27c137087ee926746b43b1abd08fb360ede671bNarayan Kamath        final ArrayList<LocaleInfo> localeInfos = new ArrayList<LocaleInfo>(localeList.size());
104b27c137087ee926746b43b1abd08fb360ede671bNarayan Kamath        for (String locale : localeList) {
105b27c137087ee926746b43b1abd08fb360ede671bNarayan Kamath            final Locale l = Locale.forLanguageTag(locale.replace('_', '-'));
10680b574199c5d06132acbcf640ec81f45f0d76ce3Narayan Kamath            if (l == null || "und".equals(l.getLanguage())
10780b574199c5d06132acbcf640ec81f45f0d76ce3Narayan Kamath                    || l.getLanguage().isEmpty() || l.getCountry().isEmpty()) {
108b27c137087ee926746b43b1abd08fb360ede671bNarayan Kamath                continue;
109b27c137087ee926746b43b1abd08fb360ede671bNarayan Kamath            }
110b27c137087ee926746b43b1abd08fb360ede671bNarayan Kamath
111b27c137087ee926746b43b1abd08fb360ede671bNarayan Kamath            if (localeInfos.isEmpty()) {
112b27c137087ee926746b43b1abd08fb360ede671bNarayan Kamath                if (DEBUG) {
113b27c137087ee926746b43b1abd08fb360ede671bNarayan Kamath                    Log.v(TAG, "adding initial "+ toTitleCase(l.getDisplayLanguage(l)));
114b27c137087ee926746b43b1abd08fb360ede671bNarayan Kamath                }
115b27c137087ee926746b43b1abd08fb360ede671bNarayan Kamath                localeInfos.add(new LocaleInfo(toTitleCase(l.getDisplayLanguage(l)), l));
116b27c137087ee926746b43b1abd08fb360ede671bNarayan Kamath            } else {
117b27c137087ee926746b43b1abd08fb360ede671bNarayan Kamath                // check previous entry:
118b27c137087ee926746b43b1abd08fb360ede671bNarayan Kamath                //  same lang and a country -> upgrade to full name and
119b27c137087ee926746b43b1abd08fb360ede671bNarayan Kamath                //    insert ours with full name
120b27c137087ee926746b43b1abd08fb360ede671bNarayan Kamath                //  diff lang -> insert ours with lang-only name
121b27c137087ee926746b43b1abd08fb360ede671bNarayan Kamath                final LocaleInfo previous = localeInfos.get(localeInfos.size() - 1);
122b27c137087ee926746b43b1abd08fb360ede671bNarayan Kamath                if (previous.locale.getLanguage().equals(l.getLanguage()) &&
123b27c137087ee926746b43b1abd08fb360ede671bNarayan Kamath                        !previous.locale.getLanguage().equals("zz")) {
124b27c137087ee926746b43b1abd08fb360ede671bNarayan Kamath                    if (DEBUG) {
125b27c137087ee926746b43b1abd08fb360ede671bNarayan Kamath                        Log.v(TAG, "backing up and fixing " + previous.label + " to " +
126b27c137087ee926746b43b1abd08fb360ede671bNarayan Kamath                                getDisplayName(previous.locale, specialLocaleCodes, specialLocaleNames));
127b27c137087ee926746b43b1abd08fb360ede671bNarayan Kamath                    }
128b27c137087ee926746b43b1abd08fb360ede671bNarayan Kamath                    previous.label = toTitleCase(getDisplayName(
129b27c137087ee926746b43b1abd08fb360ede671bNarayan Kamath                            previous.locale, specialLocaleCodes, specialLocaleNames));
130a43b74a4ef3735e52d3fda348271b8e495d685a8Daisuke Miyakawa                    if (DEBUG) {
131b27c137087ee926746b43b1abd08fb360ede671bNarayan Kamath                        Log.v(TAG, "  and adding "+ toTitleCase(
132b27c137087ee926746b43b1abd08fb360ede671bNarayan Kamath                                getDisplayName(l, specialLocaleCodes, specialLocaleNames)));
133a43b74a4ef3735e52d3fda348271b8e495d685a8Daisuke Miyakawa                    }
134b27c137087ee926746b43b1abd08fb360ede671bNarayan Kamath                    localeInfos.add(new LocaleInfo(toTitleCase(
135b27c137087ee926746b43b1abd08fb360ede671bNarayan Kamath                            getDisplayName(l, specialLocaleCodes, specialLocaleNames)), l));
136a43b74a4ef3735e52d3fda348271b8e495d685a8Daisuke Miyakawa                } else {
137dee5cde1ec3cca5235c397acdb217ddadaa7994fElliott Hughes                    String displayName = toTitleCase(l.getDisplayLanguage(l));
138b27c137087ee926746b43b1abd08fb360ede671bNarayan Kamath                    if (DEBUG) {
139b27c137087ee926746b43b1abd08fb360ede671bNarayan Kamath                        Log.v(TAG, "adding "+displayName);
140a43b74a4ef3735e52d3fda348271b8e495d685a8Daisuke Miyakawa                    }
141b27c137087ee926746b43b1abd08fb360ede671bNarayan Kamath                    localeInfos.add(new LocaleInfo(displayName, l));
142a43b74a4ef3735e52d3fda348271b8e495d685a8Daisuke Miyakawa                }
143a43b74a4ef3735e52d3fda348271b8e495d685a8Daisuke Miyakawa            }
144a43b74a4ef3735e52d3fda348271b8e495d685a8Daisuke Miyakawa        }
14553daead5718a95953fc009782299bd5e544bf4e5Daisuke Miyakawa
146b27c137087ee926746b43b1abd08fb360ede671bNarayan Kamath        Collections.sort(localeInfos);
14737197df4791da690d18aefb1f24c54748515b6a0Narayan Kamath        return localeInfos;
14837197df4791da690d18aefb1f24c54748515b6a0Narayan Kamath    }
14937197df4791da690d18aefb1f24c54748515b6a0Narayan Kamath
150dee5cde1ec3cca5235c397acdb217ddadaa7994fElliott Hughes    /**
151dee5cde1ec3cca5235c397acdb217ddadaa7994fElliott Hughes     * Constructs an Adapter object containing Locale information. Content is sorted by
152dee5cde1ec3cca5235c397acdb217ddadaa7994fElliott Hughes     * {@link LocaleInfo#label}.
153dee5cde1ec3cca5235c397acdb217ddadaa7994fElliott Hughes     */
154dee5cde1ec3cca5235c397acdb217ddadaa7994fElliott Hughes    public static ArrayAdapter<LocaleInfo> constructAdapter(Context context) {
155dee5cde1ec3cca5235c397acdb217ddadaa7994fElliott Hughes        return constructAdapter(context, R.layout.locale_picker_item, R.id.locale);
156dee5cde1ec3cca5235c397acdb217ddadaa7994fElliott Hughes    }
157dee5cde1ec3cca5235c397acdb217ddadaa7994fElliott Hughes
15837197df4791da690d18aefb1f24c54748515b6a0Narayan Kamath    public static ArrayAdapter<LocaleInfo> constructAdapter(Context context,
159dee5cde1ec3cca5235c397acdb217ddadaa7994fElliott Hughes            final int layoutId, final int fieldId) {
160dee5cde1ec3cca5235c397acdb217ddadaa7994fElliott Hughes        boolean isInDeveloperMode = Settings.Global.getInt(context.getContentResolver(),
161dee5cde1ec3cca5235c397acdb217ddadaa7994fElliott Hughes                Settings.Global.DEVELOPMENT_SETTINGS_ENABLED, 0) != 0;
16237197df4791da690d18aefb1f24c54748515b6a0Narayan Kamath        final List<LocaleInfo> localeInfos = getAllAssetLocales(context, isInDeveloperMode);
16337197df4791da690d18aefb1f24c54748515b6a0Narayan Kamath
1640203341a0bbfefb97a91d54613a556f524c94a5cVictoria Lease        final LayoutInflater inflater =
1650203341a0bbfefb97a91d54613a556f524c94a5cVictoria Lease                (LayoutInflater)context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
1660203341a0bbfefb97a91d54613a556f524c94a5cVictoria Lease        return new ArrayAdapter<LocaleInfo>(context, layoutId, fieldId, localeInfos) {
1670203341a0bbfefb97a91d54613a556f524c94a5cVictoria Lease            @Override
1680203341a0bbfefb97a91d54613a556f524c94a5cVictoria Lease            public View getView(int position, View convertView, ViewGroup parent) {
1690203341a0bbfefb97a91d54613a556f524c94a5cVictoria Lease                View view;
1700203341a0bbfefb97a91d54613a556f524c94a5cVictoria Lease                TextView text;
1710203341a0bbfefb97a91d54613a556f524c94a5cVictoria Lease                if (convertView == null) {
1720203341a0bbfefb97a91d54613a556f524c94a5cVictoria Lease                    view = inflater.inflate(layoutId, parent, false);
1730203341a0bbfefb97a91d54613a556f524c94a5cVictoria Lease                    text = (TextView) view.findViewById(fieldId);
1740203341a0bbfefb97a91d54613a556f524c94a5cVictoria Lease                    view.setTag(text);
1750203341a0bbfefb97a91d54613a556f524c94a5cVictoria Lease                } else {
1760203341a0bbfefb97a91d54613a556f524c94a5cVictoria Lease                    view = convertView;
1770203341a0bbfefb97a91d54613a556f524c94a5cVictoria Lease                    text = (TextView) view.getTag();
1780203341a0bbfefb97a91d54613a556f524c94a5cVictoria Lease                }
1790203341a0bbfefb97a91d54613a556f524c94a5cVictoria Lease                LocaleInfo item = getItem(position);
1800203341a0bbfefb97a91d54613a556f524c94a5cVictoria Lease                text.setText(item.toString());
1810203341a0bbfefb97a91d54613a556f524c94a5cVictoria Lease                text.setTextLocale(item.getLocale());
1820203341a0bbfefb97a91d54613a556f524c94a5cVictoria Lease
1830203341a0bbfefb97a91d54613a556f524c94a5cVictoria Lease                return view;
1840203341a0bbfefb97a91d54613a556f524c94a5cVictoria Lease            }
1850203341a0bbfefb97a91d54613a556f524c94a5cVictoria Lease        };
186a43b74a4ef3735e52d3fda348271b8e495d685a8Daisuke Miyakawa    }
187a43b74a4ef3735e52d3fda348271b8e495d685a8Daisuke Miyakawa
188a43b74a4ef3735e52d3fda348271b8e495d685a8Daisuke Miyakawa    private static String toTitleCase(String s) {
189a43b74a4ef3735e52d3fda348271b8e495d685a8Daisuke Miyakawa        if (s.length() == 0) {
190a43b74a4ef3735e52d3fda348271b8e495d685a8Daisuke Miyakawa            return s;
191a43b74a4ef3735e52d3fda348271b8e495d685a8Daisuke Miyakawa        }
192a43b74a4ef3735e52d3fda348271b8e495d685a8Daisuke Miyakawa
193a43b74a4ef3735e52d3fda348271b8e495d685a8Daisuke Miyakawa        return Character.toUpperCase(s.charAt(0)) + s.substring(1);
194a43b74a4ef3735e52d3fda348271b8e495d685a8Daisuke Miyakawa    }
195a43b74a4ef3735e52d3fda348271b8e495d685a8Daisuke Miyakawa
19653daead5718a95953fc009782299bd5e544bf4e5Daisuke Miyakawa    private static String getDisplayName(
19753daead5718a95953fc009782299bd5e544bf4e5Daisuke Miyakawa            Locale l, String[] specialLocaleCodes, String[] specialLocaleNames) {
198a43b74a4ef3735e52d3fda348271b8e495d685a8Daisuke Miyakawa        String code = l.toString();
199a43b74a4ef3735e52d3fda348271b8e495d685a8Daisuke Miyakawa
20053daead5718a95953fc009782299bd5e544bf4e5Daisuke Miyakawa        for (int i = 0; i < specialLocaleCodes.length; i++) {
20153daead5718a95953fc009782299bd5e544bf4e5Daisuke Miyakawa            if (specialLocaleCodes[i].equals(code)) {
20253daead5718a95953fc009782299bd5e544bf4e5Daisuke Miyakawa                return specialLocaleNames[i];
203a43b74a4ef3735e52d3fda348271b8e495d685a8Daisuke Miyakawa            }
204a43b74a4ef3735e52d3fda348271b8e495d685a8Daisuke Miyakawa        }
205a43b74a4ef3735e52d3fda348271b8e495d685a8Daisuke Miyakawa
206a43b74a4ef3735e52d3fda348271b8e495d685a8Daisuke Miyakawa        return l.getDisplayName(l);
207a43b74a4ef3735e52d3fda348271b8e495d685a8Daisuke Miyakawa    }
208a43b74a4ef3735e52d3fda348271b8e495d685a8Daisuke Miyakawa
209a43b74a4ef3735e52d3fda348271b8e495d685a8Daisuke Miyakawa    @Override
21053daead5718a95953fc009782299bd5e544bf4e5Daisuke Miyakawa    public void onActivityCreated(final Bundle savedInstanceState) {
21153daead5718a95953fc009782299bd5e544bf4e5Daisuke Miyakawa        super.onActivityCreated(savedInstanceState);
212dee5cde1ec3cca5235c397acdb217ddadaa7994fElliott Hughes        final ArrayAdapter<LocaleInfo> adapter = constructAdapter(getActivity());
21353daead5718a95953fc009782299bd5e544bf4e5Daisuke Miyakawa        setListAdapter(adapter);
21453daead5718a95953fc009782299bd5e544bf4e5Daisuke Miyakawa    }
21553daead5718a95953fc009782299bd5e544bf4e5Daisuke Miyakawa
21653daead5718a95953fc009782299bd5e544bf4e5Daisuke Miyakawa    public void setLocaleSelectionListener(LocaleSelectionListener listener) {
21753daead5718a95953fc009782299bd5e544bf4e5Daisuke Miyakawa        mListener = listener;
21853daead5718a95953fc009782299bd5e544bf4e5Daisuke Miyakawa    }
21953daead5718a95953fc009782299bd5e544bf4e5Daisuke Miyakawa
22053daead5718a95953fc009782299bd5e544bf4e5Daisuke Miyakawa    @Override
221a43b74a4ef3735e52d3fda348271b8e495d685a8Daisuke Miyakawa    public void onResume() {
222a43b74a4ef3735e52d3fda348271b8e495d685a8Daisuke Miyakawa        super.onResume();
223a43b74a4ef3735e52d3fda348271b8e495d685a8Daisuke Miyakawa        getListView().requestFocus();
224a43b74a4ef3735e52d3fda348271b8e495d685a8Daisuke Miyakawa    }
225a43b74a4ef3735e52d3fda348271b8e495d685a8Daisuke Miyakawa
22688b7349125d26200c5b4ef3c143e2e1cceda5703Daisuke Miyakawa    /**
22788b7349125d26200c5b4ef3c143e2e1cceda5703Daisuke Miyakawa     * Each listener needs to call {@link #updateLocale(Locale)} to actually change the locale.
22888b7349125d26200c5b4ef3c143e2e1cceda5703Daisuke Miyakawa     *
22988b7349125d26200c5b4ef3c143e2e1cceda5703Daisuke Miyakawa     * We don't call {@link #updateLocale(Locale)} automatically, as it halt the system for
23088b7349125d26200c5b4ef3c143e2e1cceda5703Daisuke Miyakawa     * a moment and some callers won't want it.
23188b7349125d26200c5b4ef3c143e2e1cceda5703Daisuke Miyakawa     */
232a43b74a4ef3735e52d3fda348271b8e495d685a8Daisuke Miyakawa    @Override
233a43b74a4ef3735e52d3fda348271b8e495d685a8Daisuke Miyakawa    public void onListItemClick(ListView l, View v, int position, long id) {
23488b7349125d26200c5b4ef3c143e2e1cceda5703Daisuke Miyakawa        if (mListener != null) {
23553daead5718a95953fc009782299bd5e544bf4e5Daisuke Miyakawa            final Locale locale = ((LocaleInfo)getListAdapter().getItem(position)).locale;
23653daead5718a95953fc009782299bd5e544bf4e5Daisuke Miyakawa            mListener.onLocaleSelected(locale);
23788b7349125d26200c5b4ef3c143e2e1cceda5703Daisuke Miyakawa        }
23888b7349125d26200c5b4ef3c143e2e1cceda5703Daisuke Miyakawa    }
23988b7349125d26200c5b4ef3c143e2e1cceda5703Daisuke Miyakawa
24088b7349125d26200c5b4ef3c143e2e1cceda5703Daisuke Miyakawa    /**
24188b7349125d26200c5b4ef3c143e2e1cceda5703Daisuke Miyakawa     * Requests the system to update the system locale. Note that the system looks halted
24288b7349125d26200c5b4ef3c143e2e1cceda5703Daisuke Miyakawa     * for a while during the Locale migration, so the caller need to take care of it.
24388b7349125d26200c5b4ef3c143e2e1cceda5703Daisuke Miyakawa     */
24488b7349125d26200c5b4ef3c143e2e1cceda5703Daisuke Miyakawa    public static void updateLocale(Locale locale) {
245a43b74a4ef3735e52d3fda348271b8e495d685a8Daisuke Miyakawa        try {
246a43b74a4ef3735e52d3fda348271b8e495d685a8Daisuke Miyakawa            IActivityManager am = ActivityManagerNative.getDefault();
247a43b74a4ef3735e52d3fda348271b8e495d685a8Daisuke Miyakawa            Configuration config = am.getConfiguration();
248a43b74a4ef3735e52d3fda348271b8e495d685a8Daisuke Miyakawa
2495f7979993979466c79ab4f38d83c6f2aca361662Fabrice Di Meglio            // Will set userSetLocale to indicate this isn't some passing default - the user
2505f7979993979466c79ab4f38d83c6f2aca361662Fabrice Di Meglio            // wants this remembered
2515f7979993979466c79ab4f38d83c6f2aca361662Fabrice Di Meglio            config.setLocale(locale);
252a43b74a4ef3735e52d3fda348271b8e495d685a8Daisuke Miyakawa
253a43b74a4ef3735e52d3fda348271b8e495d685a8Daisuke Miyakawa            am.updateConfiguration(config);
254a43b74a4ef3735e52d3fda348271b8e495d685a8Daisuke Miyakawa            // Trigger the dirty bit for the Settings Provider.
255a43b74a4ef3735e52d3fda348271b8e495d685a8Daisuke Miyakawa            BackupManager.dataChanged("com.android.providers.settings");
256a43b74a4ef3735e52d3fda348271b8e495d685a8Daisuke Miyakawa        } catch (RemoteException e) {
257a43b74a4ef3735e52d3fda348271b8e495d685a8Daisuke Miyakawa            // Intentionally left blank
258a43b74a4ef3735e52d3fda348271b8e495d685a8Daisuke Miyakawa        }
259a43b74a4ef3735e52d3fda348271b8e495d685a8Daisuke Miyakawa    }
2600203341a0bbfefb97a91d54613a556f524c94a5cVictoria Lease}
261