summaryrefslogtreecommitdiffstats
path: root/mobile/android/base/java/org/mozilla/gecko/Locales.java
blob: e030b95e9e75c8f36abff63918522b4cd449f2c2 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
/* 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
 * <code>onCreate</code> method, or inherit from
 * <code>LocaleAwareFragmentActivity</code> or <code>LocaleAwareActivity</code>.
 */
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
     * <code>Locale#toLanguageTag()</code>.
     *
     * @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);
    }
}