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