1 /* 2 * Copyright (C) 2017 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.dialer.dialpadview; 18 19 import android.content.Context; 20 import android.support.annotation.NonNull; 21 import android.support.v4.util.SimpleArrayMap; 22 import com.android.dialer.common.Assert; 23 import com.android.dialer.compat.CompatUtils; 24 25 /** A class containing character mappings for the dialpad. */ 26 public class DialpadCharMappings { 27 28 /** The character mapping for the Latin alphabet (the default mapping) */ 29 private static class Latin { 30 private static final String[] KEY_TO_CHARS = { 31 "+" /* 0 */, 32 "" /* 1 */, 33 "ABC" /* 2 */, 34 "DEF" /* 3 */, 35 "GHI" /* 4 */, 36 "JKL" /* 5 */, 37 "MNO" /* 6 */, 38 "PQRS" /* 7 */, 39 "TUV" /* 8 */, 40 "WXYZ" /* 9 */, 41 "" /* * */, 42 "" /* # */, 43 }; 44 45 private static final SimpleArrayMap<Character, Character> CHAR_TO_KEY = 46 getCharToKeyMap(KEY_TO_CHARS); 47 } 48 49 /** The character mapping for the Bulgarian alphabet */ 50 private static class Bul { 51 private static final String[] KEY_TO_CHARS = { 52 "" /* 0 */, 53 "" /* 1 */, 54 "" /* 2 */, 55 "" /* 3 */, 56 "" /* 4 */, 57 "" /* 5 */, 58 "" /* 6 */, 59 "" /* 7 */, 60 "" /* 8 */, 61 "" /* 9 */, 62 "" /* * */, 63 "" /* # */, 64 }; 65 66 private static final SimpleArrayMap<Character, Character> CHAR_TO_KEY = 67 getCharToKeyMap(KEY_TO_CHARS); 68 } 69 70 /** The character mapping for the Russian alphabet */ 71 private static class Rus { 72 private static final String[] KEY_TO_CHARS = { 73 "" /* 0 */, 74 "" /* 1 */, 75 "" /* 2 */, 76 "" /* 3 */, 77 "" /* 4 */, 78 "" /* 5 */, 79 "" /* 6 */, 80 "" /* 7 */, 81 "" /* 8 */, 82 "" /* 9 */, 83 "" /* * */, 84 "" /* # */, 85 }; 86 87 private static final SimpleArrayMap<Character, Character> CHAR_TO_KEY = 88 getCharToKeyMap(KEY_TO_CHARS); 89 } 90 91 /** The character mapping for the Ukrainian alphabet */ 92 private static class Ukr { 93 private static final String[] KEY_TO_CHARS = { 94 "" /* 0 */, 95 "" /* 1 */, 96 "" /* 2 */, 97 "" /* 3 */, 98 "" /* 4 */, 99 "" /* 5 */, 100 "" /* 6 */, 101 "" /* 7 */, 102 "" /* 8 */, 103 "" /* 9 */, 104 "" /* * */, 105 "" /* # */, 106 }; 107 108 private static final SimpleArrayMap<Character, Character> CHAR_TO_KEY = 109 getCharToKeyMap(KEY_TO_CHARS); 110 } 111 112 // A map in which each key is an ISO 639-2 language code and the corresponding value is a 113 // character-key map. 114 private static final SimpleArrayMap<String, SimpleArrayMap<Character, Character>> 115 CHAR_TO_KEY_MAPS = new SimpleArrayMap<>(); 116 117 // A map in which each key is an ISO 639-2 language code and the corresponding value is an array 118 // defining a key-characters map. 119 private static final SimpleArrayMap<String, String[]> KEY_TO_CHAR_MAPS = new SimpleArrayMap<>(); 120 121 static { 122 CHAR_TO_KEY_MAPS.put("bul", Bul.CHAR_TO_KEY); 123 CHAR_TO_KEY_MAPS.put("rus", Rus.CHAR_TO_KEY); 124 CHAR_TO_KEY_MAPS.put("ukr", Ukr.CHAR_TO_KEY); 125 126 KEY_TO_CHAR_MAPS.put("bul", Bul.KEY_TO_CHARS); 127 KEY_TO_CHAR_MAPS.put("rus", Rus.KEY_TO_CHARS); 128 KEY_TO_CHAR_MAPS.put("ukr", Ukr.KEY_TO_CHARS); 129 } 130 131 /** 132 * Returns the character-key map of the ISO 639-2 language code of the 1st language preference or 133 * null if no character-key map for the language code is defined. 134 */ 135 public static SimpleArrayMap<Character, Character> getCharToKeyMap(@NonNull Context context) { 136 return CHAR_TO_KEY_MAPS.get(CompatUtils.getLocale(context).getISO3Language()); 137 } 138 139 /** 140 * Returns the character-key map of the provided ISO 639-2 language code. 141 * 142 * <p>Note: this method is for implementations of {@link 143 * com.android.dialer.smartdial.map.SmartDialMap} only. {@link #getCharToKeyMap(Context)} should 144 * be used for all other purposes. 145 * 146 * <p>It is the caller's responsibility to ensure the language code is valid and a character 147 * mapping is defined for that language. Otherwise, an exception will be thrown. 148 */ 149 public static SimpleArrayMap<Character, Character> getCharToKeyMap(String languageCode) { 150 SimpleArrayMap<Character, Character> charToKeyMap = CHAR_TO_KEY_MAPS.get(languageCode); 151 152 return Assert.isNotNull( 153 charToKeyMap, "No character mappings can be found for language code '%s'", languageCode); 154 } 155 156 /** Returns the default character-key map (the one that uses the Latin alphabet). */ 157 public static SimpleArrayMap<Character, Character> getDefaultCharToKeyMap() { 158 return Latin.CHAR_TO_KEY; 159 } 160 161 /** 162 * Returns the key-characters map of the given ISO 639-2 language code of the 1st language 163 * preference or null if no key-characters map for the language code is defined. 164 */ 165 static String[] getKeyToCharsMap(@NonNull Context context) { 166 return KEY_TO_CHAR_MAPS.get(CompatUtils.getLocale(context).getISO3Language()); 167 } 168 169 /** Returns the default key-characters map (the one that uses the Latin alphabet). */ 170 public static String[] getDefaultKeyToCharsMap() { 171 return Latin.KEY_TO_CHARS; 172 } 173 174 /** 175 * Given a array representing a key-characters map, return its reverse map. 176 * 177 * <p>It is the caller's responsibility to ensure that 178 * 179 * <ul> 180 * <li>the array contains only 12 elements, 181 * <li>the 0th element ~ the 9th element are the mappings for keys "0" ~ "9", 182 * <li>the 10th element is for key "*", and 183 * <li>the 11th element is for key "#". 184 * </ul> 185 * 186 * @param keyToChars An array representing a key-characters map. It must satisfy the conditions 187 * above. 188 * @return A character-key map. 189 */ 190 private static SimpleArrayMap<Character, Character> getCharToKeyMap( 191 @NonNull String[] keyToChars) { 192 Assert.checkArgument(keyToChars.length == 12); 193 194 SimpleArrayMap<Character, Character> charToKeyMap = new SimpleArrayMap<>(); 195 196 for (int keyIndex = 0; keyIndex < keyToChars.length; keyIndex++) { 197 String chars = keyToChars[keyIndex]; 198 199 for (int j = 0; j < chars.length(); j++) { 200 char c = chars.charAt(j); 201 if (Character.isAlphabetic(c)) { 202 charToKeyMap.put(Character.toLowerCase(c), getKeyChar(keyIndex)); 203 } 204 } 205 } 206 207 return charToKeyMap; 208 } 209 210 /** Given a key index of the dialpad, returns the corresponding character. */ 211 private static char getKeyChar(int keyIndex) { 212 Assert.checkArgument(0 <= keyIndex && keyIndex <= 11); 213 214 switch (keyIndex) { 215 case 10: 216 return '*'; 217 case 11: 218 return '#'; 219 default: 220 return (char) ('0' + keyIndex); 221 } 222 } 223 } 224