Home | History | Annotate | Download | only in dialpadview
      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