• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2014 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package com.android.tv.settings.system;
18 
19 import com.android.tv.settings.R;
20 import com.android.tv.settings.dialog.old.Action;
21 import com.android.tv.settings.dialog.old.ActionAdapter;
22 import com.android.tv.settings.dialog.old.ActionFragment;
23 import com.android.tv.settings.dialog.old.ContentFragment;
24 import com.android.tv.settings.dialog.old.DialogActivity;
25 import com.android.internal.app.LocalePicker;
26 
27 import android.app.ActivityManagerNative;
28 import android.app.Fragment;
29 import android.content.Context;
30 import android.content.res.Configuration;
31 import android.content.res.Resources;
32 import android.net.wifi.WifiManager;
33 import android.os.Bundle;
34 import android.os.RemoteException;
35 import android.text.TextUtils;
36 import android.util.Log;
37 import android.view.KeyEvent;
38 import android.widget.ArrayAdapter;
39 
40 import java.util.ArrayList;
41 import java.util.Comparator;
42 import java.util.Locale;
43 import java.util.MissingResourceException;
44 
45 public class LanguageActivity extends DialogActivity implements ActionAdapter.Listener {
46 
47     private static final String TAG = "LanguageActivity";
48     private static final boolean DEBUG = false;
49 
50     private static final String KEY_LOCALE = "locale";
51     /**
52      * Comparator of LocaleInfo objects that prioritizes US locales above all
53      * others. Between US locales it prioritizes English. All other locales are
54      * sorted alphabetically first by language and then by region. So, Canadian
55      * French is presented before French French.
56      */
57     private static class LocaleComparator implements Comparator<LocalePicker.LocaleInfo> {
58         @Override
compare(LocalePicker.LocaleInfo l, LocalePicker.LocaleInfo r)59         public int compare(LocalePicker.LocaleInfo l, LocalePicker.LocaleInfo r) {
60             Locale lhs = l.getLocale();
61             Locale rhs = r.getLocale();
62 
63             String lhsCountry = "";
64             String rhsCountry = "";
65 
66             try {
67                 lhsCountry = lhs.getISO3Country();
68             } catch (MissingResourceException e) {
69                 Log.e(TAG, "LocaleComparator cuaught exception, country set to empty.");
70             }
71 
72             try {
73                 rhsCountry = rhs.getISO3Country();
74             } catch (MissingResourceException e) {
75                 Log.e(TAG, "LocaleComparator cuaught exception, country set to empty.");
76             }
77 
78             String lhsLang = "";
79             String rhsLang = "";
80 
81             try {
82                 lhsLang = lhs.getISO3Language();
83             } catch (MissingResourceException e) {
84                 Log.e(TAG, "LocaleComparator cuaught exception, language set to empty.");
85             }
86 
87             try {
88                 rhsLang = rhs.getISO3Language();
89             } catch (MissingResourceException e) {
90                 Log.e(TAG, "LocaleComparator cuaught exception, language set to empty.");
91             }
92 
93             // if they're the same locale, return 0
94             if (lhsCountry.equals(rhsCountry) && lhsLang.equals(rhsLang)) {
95                 return 0;
96             }
97 
98             // prioritize US over other countries
99             if ("USA".equals(lhsCountry)) {
100                 // if right hand side is not also USA, left hand side is first
101                 if (!"USA".equals(rhsCountry)) {
102                     return -1;
103                 } else {
104                     // if one of the languages is english we want to prioritize
105                     // it, otherwise we don't care, just alphabetize
106                     if ("ENG".equals(lhsLang) && "ENG".equals(rhsLang)) {
107                         return 0;
108                     } else {
109                         return "ENG".equals(lhsLang) ? -1 : 1;
110                     }
111                 }
112             } else if ("USA".equals(rhsCountry)) {
113                 // right-hand side is the US and the other isn't, return greater than 1
114                 return 1;
115             } else {
116                 // neither side is the US, sort based on display language name
117                 // then country name
118                 int langEquiv = lhs.getDisplayLanguage(lhs).compareTo(rhs.getDisplayLanguage(rhs));
119                 if (langEquiv == 0) {
120                     return lhs.getDisplayCountry(lhs).compareTo(rhs.getDisplayCountry(rhs));
121                 } else {
122                     return langEquiv;
123                 }
124             }
125         }
126     }
127 
128     private Fragment mContentFragment;
129     private ActionFragment mActionFragment;
130     private Resources mResources;
131     private ArrayList<Action> mActions;
132     private ArrayAdapter<LocalePicker.LocaleInfo> mLocales;
133 
134     @Override
onCreate(Bundle savedInstanceState)135     public void onCreate(Bundle savedInstanceState) {
136         super.onCreate(savedInstanceState);
137 
138         mResources = getResources();
139         init();
140         setContentAndActionFragments(mContentFragment, mActionFragment);
141 
142     }
143 
144     @Override
onActionClicked(Action action)145     public void onActionClicked(Action action) {
146         String key = action.getKey();
147         if (key.contains(KEY_LOCALE)) {
148             String s = key.substring(KEY_LOCALE.length());
149             int i = Integer.parseInt(s);
150             setLanguagePreference(i);
151             setWifiCountryCode();
152             finish();
153         }
154     }
155 
156     @Override
onConfigurationChanged(Configuration newConfig)157     public void onConfigurationChanged(Configuration newConfig) {
158         super.onConfigurationChanged(newConfig);
159         mResources = getResources();
160         makeContentFragment();
161         setContentFragment(mContentFragment);
162     }
163 
makeContentFragment()164     private void makeContentFragment() {
165         mContentFragment = ContentFragment.newInstance(
166                 mResources.getString(R.string.system_language), null, null,
167                 R.drawable.ic_settings_language, getResources().getColor(R.color.icon_background));
168     }
169 
init()170     private void init() {
171         mActions = new ArrayList<Action>();
172         makeContentFragment();
173 
174         final String[] specialLocaleCodes = getResources().getStringArray(
175                 com.android.internal.R.array.special_locale_codes);
176         final String[] specialLocaleNames = getResources().getStringArray(
177                 com.android.internal.R.array.special_locale_names);
178         mLocales = LocalePicker.constructAdapter(this);
179         mLocales.sort(new LocaleComparator());
180         final String[] localeNames = new String[mLocales.getCount()];
181         Locale currentLocale;
182         try {
183             currentLocale = ActivityManagerNative.getDefault().getConfiguration().locale;
184         } catch (RemoteException e) {
185             currentLocale = null;
186         }
187         for (int i = 0; i < localeNames.length; i++) {
188             Locale target = mLocales.getItem(i).getLocale();
189             localeNames[i] = getDisplayName(target, specialLocaleCodes, specialLocaleNames);
190 
191             // if this locale's label has a country, use the shortened version
192             // instead
193             if (mLocales.getItem(i).getLabel().contains("(")) {
194                 String country = target.getCountry();
195                 if (!TextUtils.isEmpty(country)) {
196                     localeNames[i] = localeNames[i] + " (" + target.getCountry() + ")";
197                 }
198             }
199 
200             // For some reason locales are not always first letter cased, for example for
201             // in the Spanish locale.
202             if (localeNames[i].length() > 0) {
203                 localeNames[i] = localeNames[i].substring(0, 1).toUpperCase(currentLocale) +
204                         localeNames[i].substring(1);
205             }
206 
207             StringBuilder sb = new StringBuilder();
208             sb.append(KEY_LOCALE).append(i);
209             mActions.add(new Action.Builder()
210                     .key(sb.toString())
211                     .title(localeNames[i])
212                     .checked(target.equals(currentLocale))
213                     .build());
214         }
215 
216         mActionFragment = ActionFragment.newInstance(mActions);
217     }
218 
getDisplayName( Locale l, String[] specialLocaleCodes, String[] specialLocaleNames)219     private static String getDisplayName(
220             Locale l, String[] specialLocaleCodes, String[] specialLocaleNames) {
221         String code = l.toString();
222 
223         for (int i = 0; i < specialLocaleCodes.length; i++) {
224             if (specialLocaleCodes[i].equals(code)) {
225                 return specialLocaleNames[i];
226             }
227         }
228 
229         return l.getDisplayName(l);
230     }
231 
setLanguagePreference(int offset)232     private void setLanguagePreference(int offset) {
233         LocalePicker.updateLocale(mLocales.getItem(offset).getLocale());
234     }
235 
setWifiCountryCode()236     private void setWifiCountryCode() {
237         String countryCode = Locale.getDefault().getCountry();
238         WifiManager wifiMgr = (WifiManager) getSystemService(Context.WIFI_SERVICE);
239 
240         if (wifiMgr != null && !TextUtils.isEmpty(countryCode)) {
241             wifiMgr.setCountryCode(countryCode, true);
242         }
243     }
244 }
245