/* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ package org.mozilla.gecko; import java.lang.reflect.Method; import java.util.Locale; import org.mozilla.gecko.LocaleManager; import android.app.Activity; import android.content.Context; import android.os.Bundle; import android.os.StrictMode; import android.support.v4.app.FragmentActivity; import android.support.v7.app.AppCompatActivity; /** * This is a helper class to do typical locale switching operations without * hitting StrictMode errors or adding boilerplate to common activity * subclasses. * * Either call {@link Locales#initializeLocale(Context)} in your * onCreate method, or inherit from * LocaleAwareFragmentActivity or LocaleAwareActivity. */ public class Locales { public static LocaleManager getLocaleManager() { try { final Class clazz = Class.forName("org.mozilla.gecko.BrowserLocaleManager"); final Method getInstance = clazz.getMethod("getInstance"); final LocaleManager localeManager = (LocaleManager) getInstance.invoke(null); return localeManager; } catch (Exception e) { throw new RuntimeException(e); } } public static void initializeLocale(Context context) { final LocaleManager localeManager = getLocaleManager(); final StrictMode.ThreadPolicy savedPolicy = StrictMode.allowThreadDiskReads(); StrictMode.allowThreadDiskWrites(); try { localeManager.getAndApplyPersistedLocale(context); } finally { StrictMode.setThreadPolicy(savedPolicy); } } public static abstract class LocaleAwareAppCompatActivity extends AppCompatActivity { @Override protected void onCreate(Bundle savedInstanceState) { Locales.initializeLocale(getApplicationContext()); super.onCreate(savedInstanceState); } } public static abstract class LocaleAwareFragmentActivity extends FragmentActivity { @Override protected void onCreate(Bundle savedInstanceState) { Locales.initializeLocale(getApplicationContext()); super.onCreate(savedInstanceState); } } public static abstract class LocaleAwareActivity extends Activity { @Override protected void onCreate(Bundle savedInstanceState) { Locales.initializeLocale(getApplicationContext()); super.onCreate(savedInstanceState); } } /** * Sometimes we want just the language for a locale, not the entire language * tag. But Java's .getLanguage method is wrong. * * This method is equivalent to the first part of * {@link Locales#getLanguageTag(Locale)}. * * @return a language string, such as "he" for the Hebrew locales. */ public static String getLanguage(final Locale locale) { // Can, but should never be, an empty string. final String language = locale.getLanguage(); // Modernize certain language codes. if (language.equals("iw")) { return "he"; } if (language.equals("in")) { return "id"; } if (language.equals("ji")) { return "yi"; } return language; } /** * Gecko uses locale codes like "es-ES", whereas a Java {@link Locale} * stringifies as "es_ES". * * This method approximates the Java 7 method * Locale#toLanguageTag(). * * @return a locale string suitable for passing to Gecko. */ public static String getLanguageTag(final Locale locale) { // If this were Java 7: // return locale.toLanguageTag(); final String language = getLanguage(locale); final String country = locale.getCountry(); // Can be an empty string. if (country.equals("")) { return language; } return language + "-" + country; } public static Locale parseLocaleCode(final String localeCode) { int index; if ((index = localeCode.indexOf('-')) != -1 || (index = localeCode.indexOf('_')) != -1) { final String langCode = localeCode.substring(0, index); final String countryCode = localeCode.substring(index + 1); return new Locale(langCode, countryCode); } return new Locale(localeCode); } }