Home | History | Annotate | Download | only in contacts
      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.providers.contacts;
     18 
     19 import android.annotation.NonNull;
     20 import android.annotation.Nullable;
     21 import android.icu.util.ULocale;
     22 import android.os.LocaleList;
     23 import android.text.TextUtils;
     24 
     25 import com.google.common.annotations.VisibleForTesting;
     26 import java.util.Locale;
     27 import java.util.Objects;
     28 
     29 public class LocaleSet {
     30     private static final String SCRIPT_SIMPLIFIED_CHINESE = "Hans";
     31     private static final String SCRIPT_TRADITIONAL_CHINESE = "Hant";
     32 
     33     private final Locale mDefaultLocaleOverrideForTest;
     34     private final LocaleList mLocaleList;
     35 
     36     private LocaleSet(LocaleList localeList, Locale defaultLocaleOverrideForTest) {
     37         mLocaleList = localeList;
     38         mDefaultLocaleOverrideForTest = defaultLocaleOverrideForTest;
     39     }
     40 
     41     public static LocaleSet newDefault() {
     42         return new LocaleSet(LocaleList.getDefault(),
     43                 /*defaultLocaleOverrideForTest= */ null);
     44     }
     45 
     46     @VisibleForTesting
     47     public static LocaleSet newForTest(Locale... locales) {
     48         return new LocaleSet(new LocaleList(locales), locales[0]);
     49     }
     50 
     51     @VisibleForTesting
     52     static boolean isLanguageChinese(@Nullable Locale locale) {
     53         return locale != null && "zh".equals(locale.getLanguage());
     54     }
     55 
     56     @VisibleForTesting
     57     static boolean isLanguageJapanese(@Nullable Locale locale) {
     58         return locale != null && "ja".equals(locale.getLanguage());
     59     }
     60 
     61     @VisibleForTesting
     62     static boolean isLanguageKorean(@Nullable Locale locale) {
     63         return locale != null && "ko".equals(locale.getLanguage());
     64     }
     65 
     66     @VisibleForTesting
     67     static boolean isLocaleCJK(@Nullable Locale locale) {
     68         return isLanguageChinese(locale) ||
     69                 isLanguageJapanese(locale) ||
     70                 isLanguageKorean(locale);
     71     }
     72 
     73     private static String getLikelyScript(Locale locale) {
     74         final String script = locale.getScript();
     75         if (!script.isEmpty()) {
     76             return script;
     77         } else {
     78             return ULocale.addLikelySubtags(ULocale.forLocale(locale)).getScript();
     79         }
     80     }
     81 
     82     /**
     83      * @return the script if the language is Chinese, and otherwise null.
     84      */
     85     @VisibleForTesting
     86     static String getScriptIfChinese(@Nullable Locale locale) {
     87         return isLanguageChinese(locale) ? getLikelyScript(locale) : null;
     88     }
     89 
     90     static boolean isLocaleSimplifiedChinese(@Nullable Locale locale) {
     91         return SCRIPT_SIMPLIFIED_CHINESE.equals(getScriptIfChinese(locale));
     92     }
     93 
     94     @VisibleForTesting
     95     static boolean isLocaleTraditionalChinese(@Nullable Locale locale) {
     96         return SCRIPT_TRADITIONAL_CHINESE.equals(getScriptIfChinese(locale));
     97     }
     98 
     99     /**
    100      * Returns the primary locale, which may not be the first item of {@link #getAllLocales}.
    101      * (See {@link LocaleList})
    102      */
    103     public @NonNull Locale getPrimaryLocale() {
    104         if (mDefaultLocaleOverrideForTest != null) {
    105             return mDefaultLocaleOverrideForTest;
    106         }
    107         return Locale.getDefault();
    108     }
    109 
    110     public @NonNull LocaleList getAllLocales() {
    111         return mLocaleList;
    112     }
    113 
    114     public boolean isPrimaryLocaleCJK() {
    115         return isLocaleCJK(getPrimaryLocale());
    116     }
    117 
    118     /**
    119      * @return true if Japanese is found in the list before simplified Chinese.
    120      */
    121     public boolean shouldPreferJapanese() {
    122         if (isLanguageJapanese(getPrimaryLocale())) {
    123             return true;
    124         }
    125         for (int i = 0; i < mLocaleList.size(); i++) {
    126             final Locale l = mLocaleList.get(i);
    127             if (isLanguageJapanese(l)) {
    128                 return true;
    129             }
    130             if (isLanguageChinese(l)) {
    131                 return false;
    132             }
    133         }
    134         return false;
    135     }
    136 
    137     /**
    138      * @return true if simplified Chinese is found before Japanese or traditional Chinese.
    139      */
    140     public boolean shouldPreferSimplifiedChinese() {
    141         if (isLocaleSimplifiedChinese(getPrimaryLocale())) {
    142             return true;
    143         }
    144         for (int i = 0; i < mLocaleList.size(); i++) {
    145             final Locale l = mLocaleList.get(i);
    146             if (isLocaleSimplifiedChinese(l)) {
    147                 return true;
    148             }
    149             if (isLanguageJapanese(l)) {
    150                 return false;
    151             }
    152             if (isLocaleTraditionalChinese(l)) { // Traditional chinese wins here.
    153                 return false;
    154             }
    155         }
    156         return false;
    157     }
    158 
    159     /**
    160      * @return true if the instance contains the current system locales.
    161      */
    162     public boolean isCurrent() {
    163         return Objects.equals(mLocaleList, LocaleList.getDefault());
    164     }
    165 
    166     @Override
    167     public boolean equals(Object object) {
    168         if (object == this) {
    169             return true;
    170         }
    171         if (object instanceof LocaleSet) {
    172             final LocaleSet other = (LocaleSet) object;
    173             return mLocaleList.equals(other.mLocaleList);
    174         }
    175         return false;
    176     }
    177 
    178     @Override
    179     public final String toString() {
    180         return mLocaleList.toString();
    181     }
    182 }
    183