1 /* This Source Code Form is subject to the terms of the Mozilla Public 2 * License, v. 2.0. If a copy of the MPL was not distributed with this 3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 4 5 package org.mozilla.gecko; 6 7 import java.lang.reflect.Method; 8 import java.util.Locale; 9 10 import org.mozilla.gecko.LocaleManager; 11 12 import android.app.Activity; 13 import android.content.Context; 14 import android.os.Bundle; 15 import android.os.StrictMode; 16 import android.support.v4.app.FragmentActivity; 17 import android.support.v7.app.AppCompatActivity; 18 19 /** 20 * This is a helper class to do typical locale switching operations without 21 * hitting StrictMode errors or adding boilerplate to common activity 22 * subclasses. 23 * 24 * Either call {@link Locales#initializeLocale(Context)} in your 25 * <code>onCreate</code> method, or inherit from 26 * <code>LocaleAwareFragmentActivity</code> or <code>LocaleAwareActivity</code>. 27 */ 28 public class Locales { getLocaleManager()29 public static LocaleManager getLocaleManager() { 30 try { 31 final Class<?> clazz = Class.forName("org.mozilla.gecko.BrowserLocaleManager"); 32 final Method getInstance = clazz.getMethod("getInstance"); 33 final LocaleManager localeManager = (LocaleManager) getInstance.invoke(null); 34 return localeManager; 35 } catch (Exception e) { 36 throw new RuntimeException(e); 37 } 38 } 39 initializeLocale(Context context)40 public static void initializeLocale(Context context) { 41 final LocaleManager localeManager = getLocaleManager(); 42 final StrictMode.ThreadPolicy savedPolicy = StrictMode.allowThreadDiskReads(); 43 StrictMode.allowThreadDiskWrites(); 44 try { 45 localeManager.getAndApplyPersistedLocale(context); 46 } finally { 47 StrictMode.setThreadPolicy(savedPolicy); 48 } 49 } 50 51 public static abstract class LocaleAwareAppCompatActivity extends AppCompatActivity { 52 @Override onCreate(Bundle savedInstanceState)53 protected void onCreate(Bundle savedInstanceState) { 54 Locales.initializeLocale(getApplicationContext()); 55 super.onCreate(savedInstanceState); 56 } 57 58 } 59 public static abstract class LocaleAwareFragmentActivity extends FragmentActivity { 60 @Override onCreate(Bundle savedInstanceState)61 protected void onCreate(Bundle savedInstanceState) { 62 Locales.initializeLocale(getApplicationContext()); 63 super.onCreate(savedInstanceState); 64 } 65 } 66 67 public static abstract class LocaleAwareActivity extends Activity { 68 @Override onCreate(Bundle savedInstanceState)69 protected void onCreate(Bundle savedInstanceState) { 70 Locales.initializeLocale(getApplicationContext()); 71 super.onCreate(savedInstanceState); 72 } 73 } 74 75 /** 76 * Sometimes we want just the language for a locale, not the entire language 77 * tag. But Java's .getLanguage method is wrong. 78 * 79 * This method is equivalent to the first part of 80 * {@link Locales#getLanguageTag(Locale)}. 81 * 82 * @return a language string, such as "he" for the Hebrew locales. 83 */ getLanguage(final Locale locale)84 public static String getLanguage(final Locale locale) { 85 // Can, but should never be, an empty string. 86 final String language = locale.getLanguage(); 87 88 // Modernize certain language codes. 89 if (language.equals("iw")) { 90 return "he"; 91 } 92 93 if (language.equals("in")) { 94 return "id"; 95 } 96 97 if (language.equals("ji")) { 98 return "yi"; 99 } 100 101 return language; 102 } 103 104 /** 105 * Gecko uses locale codes like "es-ES", whereas a Java {@link Locale} 106 * stringifies as "es_ES". 107 * 108 * This method approximates the Java 7 method 109 * <code>Locale#toLanguageTag()</code>. 110 * 111 * @return a locale string suitable for passing to Gecko. 112 */ getLanguageTag(final Locale locale)113 public static String getLanguageTag(final Locale locale) { 114 // If this were Java 7: 115 // return locale.toLanguageTag(); 116 117 final String language = getLanguage(locale); 118 final String country = locale.getCountry(); // Can be an empty string. 119 if (country.equals("")) { 120 return language; 121 } 122 return language + "-" + country; 123 } 124 parseLocaleCode(final String localeCode)125 public static Locale parseLocaleCode(final String localeCode) { 126 int index; 127 if ((index = localeCode.indexOf('-')) != -1 || 128 (index = localeCode.indexOf('_')) != -1) { 129 final String langCode = localeCode.substring(0, index); 130 final String countryCode = localeCode.substring(index + 1); 131 return new Locale(langCode, countryCode); 132 } 133 134 return new Locale(localeCode); 135 } 136 } 137