Java程序  |  224行  |  7.15 KB

/*
 * Copyright (C) 2017 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.android.dialer.dialpadview;

import android.content.Context;
import android.support.annotation.NonNull;
import android.support.v4.util.SimpleArrayMap;
import com.android.dialer.common.Assert;
import com.android.dialer.i18n.LocaleUtils;

/** A class containing character mappings for the dialpad. */
public class DialpadCharMappings {

  /** The character mapping for the Latin alphabet (the default mapping) */
  private static class Latin {
    private static final String[] KEY_TO_CHARS = {
      "+" /* 0 */,
      "" /* 1 */,
      "ABC" /* 2 */,
      "DEF" /* 3 */,
      "GHI" /* 4 */,
      "JKL" /* 5 */,
      "MNO" /* 6 */,
      "PQRS" /* 7 */,
      "TUV" /* 8 */,
      "WXYZ" /* 9 */,
      "" /* * */,
      "" /* # */,
    };

    private static final SimpleArrayMap<Character, Character> CHAR_TO_KEY =
        getCharToKeyMap(KEY_TO_CHARS);
  }

  /** The character mapping for the Bulgarian alphabet */
  private static class Bul {
    private static final String[] KEY_TO_CHARS = {
      "" /* 0 */,
      "" /* 1 */,
      "АБВГ" /* 2 */,
      "ДЕЖЗ" /* 3 */,
      "ИЙКЛ" /* 4 */,
      "МНО" /* 5 */,
      "ПРС" /* 6 */,
      "ТУФХ" /* 7 */,
      "ЦЧШЩ" /* 8 */,
      "ЪЬЮЯ" /* 9 */,
      "" /* * */,
      "" /* # */,
    };

    private static final SimpleArrayMap<Character, Character> CHAR_TO_KEY =
        getCharToKeyMap(KEY_TO_CHARS);
  }

  /** The character mapping for the Russian alphabet */
  private static class Rus {
    private static final String[] KEY_TO_CHARS = {
      "" /* 0 */,
      "" /* 1 */,
      "АБВГ" /* 2 */,
      "ДЕЁЖЗ" /* 3 */,
      "ИЙКЛ" /* 4 */,
      "МНОП" /* 5 */,
      "РСТУ" /* 6 */,
      "ФХЦЧ" /* 7 */,
      "ШЩЪЫ" /* 8 */,
      "ЬЭЮЯ" /* 9 */,
      "" /* * */,
      "" /* # */,
    };

    private static final SimpleArrayMap<Character, Character> CHAR_TO_KEY =
        getCharToKeyMap(KEY_TO_CHARS);
  }

  /** The character mapping for the Ukrainian alphabet */
  private static class Ukr {
    private static final String[] KEY_TO_CHARS = {
      "" /* 0 */,
      "" /* 1 */,
      "АБВГҐ" /* 2 */,
      "ДЕЄЖЗ" /* 3 */,
      "ИІЇЙКЛ" /* 4 */,
      "МНОП" /* 5 */,
      "РСТУ" /* 6 */,
      "ФХЦЧ" /* 7 */,
      "ШЩ" /* 8 */,
      "ЬЮЯ" /* 9 */,
      "" /* * */,
      "" /* # */,
    };

    private static final SimpleArrayMap<Character, Character> CHAR_TO_KEY =
        getCharToKeyMap(KEY_TO_CHARS);
  }

  // A map in which each key is an ISO 639-2 language code and the corresponding value is a
  // character-key map.
  private static final SimpleArrayMap<String, SimpleArrayMap<Character, Character>>
      CHAR_TO_KEY_MAPS = new SimpleArrayMap<>();

  // A map in which each key is an ISO 639-2 language code and the corresponding value is an array
  // defining a key-characters map.
  private static final SimpleArrayMap<String, String[]> KEY_TO_CHAR_MAPS = new SimpleArrayMap<>();

  static {
    CHAR_TO_KEY_MAPS.put("bul", Bul.CHAR_TO_KEY);
    CHAR_TO_KEY_MAPS.put("rus", Rus.CHAR_TO_KEY);
    CHAR_TO_KEY_MAPS.put("ukr", Ukr.CHAR_TO_KEY);

    KEY_TO_CHAR_MAPS.put("bul", Bul.KEY_TO_CHARS);
    KEY_TO_CHAR_MAPS.put("rus", Rus.KEY_TO_CHARS);
    KEY_TO_CHAR_MAPS.put("ukr", Ukr.KEY_TO_CHARS);
  }

  /**
   * Returns the character-key map of the ISO 639-2 language code of the 1st language preference or
   * null if no character-key map for the language code is defined.
   */
  public static SimpleArrayMap<Character, Character> getCharToKeyMap(@NonNull Context context) {
    return CHAR_TO_KEY_MAPS.get(LocaleUtils.getLocale(context).getISO3Language());
  }

  /**
   * Returns the character-key map of the provided ISO 639-2 language code.
   *
   * <p>Note: this method is for implementations of {@link
   * com.android.dialer.smartdial.map.SmartDialMap} only. {@link #getCharToKeyMap(Context)} should
   * be used for all other purposes.
   *
   * <p>It is the caller's responsibility to ensure the language code is valid and a character
   * mapping is defined for that language. Otherwise, an exception will be thrown.
   */
  public static SimpleArrayMap<Character, Character> getCharToKeyMap(String languageCode) {
    SimpleArrayMap<Character, Character> charToKeyMap = CHAR_TO_KEY_MAPS.get(languageCode);

    return Assert.isNotNull(
        charToKeyMap, "No character mappings can be found for language code '%s'", languageCode);
  }

  /** Returns the default character-key map (the one that uses the Latin alphabet). */
  public static SimpleArrayMap<Character, Character> getDefaultCharToKeyMap() {
    return Latin.CHAR_TO_KEY;
  }

  /**
   * Returns the key-characters map of the given ISO 639-2 language code of the 1st language
   * preference or null if no key-characters map for the language code is defined.
   */
  static String[] getKeyToCharsMap(@NonNull Context context) {
    return KEY_TO_CHAR_MAPS.get(LocaleUtils.getLocale(context).getISO3Language());
  }

  /** Returns the default key-characters map (the one that uses the Latin alphabet). */
  public static String[] getDefaultKeyToCharsMap() {
    return Latin.KEY_TO_CHARS;
  }

  /**
   * Given a array representing a key-characters map, return its reverse map.
   *
   * <p>It is the caller's responsibility to ensure that
   *
   * <ul>
   *   <li>the array contains only 12 elements,
   *   <li>the 0th element ~ the 9th element are the mappings for keys "0" ~ "9",
   *   <li>the 10th element is for key "*", and
   *   <li>the 11th element is for key "#".
   * </ul>
   *
   * @param keyToChars An array representing a key-characters map. It must satisfy the conditions
   *     above.
   * @return A character-key map.
   */
  private static SimpleArrayMap<Character, Character> getCharToKeyMap(
      @NonNull String[] keyToChars) {
    Assert.checkArgument(keyToChars.length == 12);

    SimpleArrayMap<Character, Character> charToKeyMap = new SimpleArrayMap<>();

    for (int keyIndex = 0; keyIndex < keyToChars.length; keyIndex++) {
      String chars = keyToChars[keyIndex];

      for (int j = 0; j < chars.length(); j++) {
        char c = chars.charAt(j);
        if (Character.isAlphabetic(c)) {
          charToKeyMap.put(Character.toLowerCase(c), getKeyChar(keyIndex));
        }
      }
    }

    return charToKeyMap;
  }

  /** Given a key index of the dialpad, returns the corresponding character. */
  private static char getKeyChar(int keyIndex) {
    Assert.checkArgument(0 <= keyIndex && keyIndex <= 11);

    switch (keyIndex) {
      case 10:
        return '*';
      case 11:
        return '#';
      default:
        return (char) ('0' + keyIndex);
    }
  }
}