Merge "Handle carrier config changes in TelecomAccountRegistry."
diff --git a/Android.mk b/Android.mk
index c6b0c7d..775d795 100644
--- a/Android.mk
+++ b/Android.mk
@@ -8,12 +8,14 @@
 
 src_dirs := src $(phone_common_dir)/src sip/src
 res_dirs := res $(phone_common_dir)/res sip/res
+asset_dirs := assets ecc/output
 
 LOCAL_JAVA_LIBRARIES := \
         telephony-common \
         voip-common \
         ims-common \
-        org.apache.http.legacy
+        org.apache.http.legacy \
+        libprotobuf-java-lite
 
 LOCAL_STATIC_ANDROID_LIBRARIES := \
         androidx.appcompat_appcompat \
@@ -26,11 +28,13 @@
         volley
 
 LOCAL_SRC_FILES := $(call all-java-files-under, $(src_dirs))
+LOCAL_SRC_FILES += $(call all-proto-files-under, ecc/proto)
 LOCAL_SRC_FILES += \
         src/com/android/phone/EventLogTags.logtags \
         src/com/android/phone/INetworkQueryService.aidl \
         src/com/android/phone/INetworkQueryServiceCallback.aidl
 LOCAL_RESOURCE_DIR := $(addprefix $(LOCAL_PATH)/, $(res_dirs))
+LOCAL_ASSET_DIR := $(addprefix $(LOCAL_PATH)/, $(asset_dirs))
 LOCAL_USE_AAPT2 := true
 
 LOCAL_AAPT_FLAGS := \
@@ -51,3 +55,4 @@
 
 # Build the test package
 include $(call all-makefiles-under,$(LOCAL_PATH))
+
diff --git a/ecc/.gitignore b/ecc/.gitignore
new file mode 100644
index 0000000..fbf10af
--- /dev/null
+++ b/ecc/.gitignore
@@ -0,0 +1 @@
+.intermediate
diff --git a/ecc/README.md b/ecc/README.md
new file mode 100644
index 0000000..ef795d5
--- /dev/null
+++ b/ecc/README.md
@@ -0,0 +1,48 @@
+This directory contains tools and data related to ECC (Emergency Call Codes)
+data and updates.
+
+Directory structure
+===================
+
+gen_eccdata.sh
+  - A script to launch the newest conversion toolset to convert
+    input/eccdata.txt into output/eccdata, and invoke compatibility
+    verification tools of earlier versions of toolsets.
+
+input/eccdata.txt
+  - A text file in ProtoBuf text format which contains all known ECC data.
+    This file shall be compatible with the last version of format toolset,
+    but may not be compatible with all earlier versions.
+
+output/eccdata
+  - The binary file generated from input files, with the last version of
+    format toolset. This file shall be compatible with all earlier versions.
+
+conversion_toolset_v*
+  - Contains format definitions, converting tools and verification tools of
+    one version of ECC data format.
+
+proto
+  - A symbolic link references to protobuf folder of the newest version of
+    conversion toolsets. It's used in Android.mk.
+
+Conversion Toolset
+===================
+
+Every version of conversion toolset shall include at least:
+  - A script to generate eccdata from a known version of input/eccdata.txt.
+  - A script to verify compatibility of output/eccdata generated by any
+    newer version of format toolset.
+
+The output/eccdata generated by a version of conversion toolset shall be
+able to pass compatibility verifications of all previous versions of format
+toolset.
+
+Updating ECC database
+===================
+Steps to update the ECC database:
+1. Edit input/eccdata.txt
+2. Source and launch
+3. Run gen_eccdata.sh
+The database file "output/eccdata" should be updated.
+
diff --git a/ecc/conversion_toolset_v1/env.sh b/ecc/conversion_toolset_v1/env.sh
new file mode 100644
index 0000000..23d9f10
--- /dev/null
+++ b/ecc/conversion_toolset_v1/env.sh
@@ -0,0 +1,38 @@
+#!/bin/bash
+set -o errexit
+
+# Copyright 2018 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.
+
+INPUT_DATA="${INPUT_DIR}/eccdata.txt"
+OUTPUT_DATA="${OUTPUT_DIR}/eccdata"
+PROTOBUF_DIR="${LOCAL_TOOLSET_DIR}/proto"
+PROTOBUF_FILE="${PROTOBUF_DIR}/protobuf_ecc_data.proto"
+RAW_DATA="${INTERMEDIATE_DIR}/eccdata.raw"
+
+read -d "" PYTHON_COMMAND << END || :
+${ANDROID_BUILD_TOP}/prebuilts/python/${KERNEL}-x86/2.7.5/bin/python
+END
+PYTHONPATH="${PYTHONPATH}:${INTERMEDIATE_DIR}"
+PYTHONPATH="${PYTHONPATH}:${ANDROID_BUILD_TOP}/external/nanopb-c/generator/"
+
+if ! [ -x "${PYTHON_COMMAND}" ] ; then
+  echo "Missing ${PYTHON_COMMAND}." 1>&2
+  exit 1
+fi
+
+"${PROTOC_COMMAND}" \
+  --python_out="${INTERMEDIATE_DIR}" \
+  --proto_path="${PROTOBUF_DIR}" \
+  "${PROTOBUF_FILE}"
diff --git a/ecc/conversion_toolset_v1/gen_eccdata.sh b/ecc/conversion_toolset_v1/gen_eccdata.sh
new file mode 100644
index 0000000..8dd751f
--- /dev/null
+++ b/ecc/conversion_toolset_v1/gen_eccdata.sh
@@ -0,0 +1,36 @@
+#!/bin/bash
+set -o errexit
+
+# Copyright 2018 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.
+
+LOCAL_TOOLSET_DIR="${ECC_ROOT}/conversion_toolset_v1"
+source "${LOCAL_TOOLSET_DIR}/env.sh"
+
+${ANDROID_BUILD_TOP}/prebuilts/tools/linux-x86_64/protoc/bin/protoc \
+  --encode=ecc.AllInfo proto/protobuf_ecc_data.proto \
+  < "${INPUT_DATA}" > "${RAW_DATA}"
+
+echo
+echo "Starting strict verification"
+"${PYTHON_COMMAND}" -B \
+  "${LOCAL_TOOLSET_DIR}/verify_protobuf_compatibility.py" \
+  --input="${RAW_DATA}" --strict
+echo "Passed strict verification"
+
+echo
+echo "Compressing and encoding eccdata"
+gzip -c < "${RAW_DATA}" > "${OUTPUT_DATA}"
+echo "Done"
+
diff --git a/ecc/conversion_toolset_v1/proto/protobuf_ecc_data.proto b/ecc/conversion_toolset_v1/proto/protobuf_ecc_data.proto
new file mode 100644
index 0000000..5bd7bc3
--- /dev/null
+++ b/ecc/conversion_toolset_v1/proto/protobuf_ecc_data.proto
@@ -0,0 +1,56 @@
+syntax = "proto2";
+
+package ecc;
+
+option java_package = "com.android.phone.ecc";
+option java_outer_classname = "ProtobufEccData";
+
+// EccInfo represents an Emergency Call Code (i.e. an emergency phone
+// number such as 911, 112, ...)
+message EccInfo {
+    enum Type {
+        TYPE_UNSPECIFIED = 0;
+        POLICE = 1;
+        AMBULANCE = 2;
+        FIRE = 3;
+    }
+
+    // Required: Every EccInfo shall contain a phone number.
+    optional string phone_number = 1;
+
+    // Extra rules: Every Ecc should have at least 1 valid type.
+    repeated Type types = 2 [packed=true];
+}
+
+// CountryInfo represents available ECCs of a country/region, recognized
+// with ISO country code.
+message CountryInfo {
+    // Required: Every CountryInfo shall contain a ISO country code.
+    optional string iso_code = 1;
+
+    // Extra rules: There should be at least one EccInfo in this list.
+    repeated EccInfo eccs = 2;
+
+    // Required: Every CountryInfo shall contain a fallback number, shall
+    // be either 112 or 911.
+    //
+    // If an emergency number in EccInfo is declined by ril.ecclist, this
+    // fallback number may take the place.
+    //
+    // Per http://www.etsi.org/deliver/etsi_ts/122100_122199/122101/09.01.00_60/ts_122101v090100p.pdf,
+    // 112 and 911 shall always be available.
+    optional string ecc_fallback = 3;
+}
+
+message AllInfo {
+    // The revision value in ecc/input/eccdata.json should be increased
+    // before releasing a new content.
+    //
+    // This field is not used to compare data revision for online updating.
+    // It's reserved for identifying ecc info problems.
+    optional int32 revision = 1;
+
+    // Extra rules: There should be at least one CountryInfo in this list.
+    repeated CountryInfo countries = 2;
+}
+
diff --git a/ecc/conversion_toolset_v1/verify_eccdata_compatibility.sh b/ecc/conversion_toolset_v1/verify_eccdata_compatibility.sh
new file mode 100644
index 0000000..8686722
--- /dev/null
+++ b/ecc/conversion_toolset_v1/verify_eccdata_compatibility.sh
@@ -0,0 +1,28 @@
+#!/bin/bash
+set -o errexit
+
+# Copyright 2018 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.
+
+LOCAL_TOOLSET_DIR="${ECC_ROOT}/conversion_toolset_v1"
+source "${LOCAL_TOOLSET_DIR}/env.sh"
+
+echo "Starting compatibility verification v1"
+echo "Decoding and decompressing eccdata"
+gunzip -c < "${OUTPUT_DATA}" > "${RAW_DATA}"
+${PYTHON_COMMAND} -B \
+  "${LOCAL_TOOLSET_DIR}/verify_protobuf_compatibility.py" \
+  --input="${RAW_DATA}"
+echo "Passed compatibility verification v1"
+
diff --git a/ecc/conversion_toolset_v1/verify_protobuf_compatibility.py b/ecc/conversion_toolset_v1/verify_protobuf_compatibility.py
new file mode 100644
index 0000000..bc707eb
--- /dev/null
+++ b/ecc/conversion_toolset_v1/verify_protobuf_compatibility.py
@@ -0,0 +1,85 @@
+#!/usr/bin/python -B
+
+# Copyright 2018 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.
+
+# Notice:
+# - verify_eccdata_strict.py: Verify data which is generated by this
+# version of this toolset.
+# - verify_eccdata_compatibility.py: Verify data which is generated by any
+# newer version of this tool set for ensuring backward compatibility.
+
+import sys
+import argparse
+import protobuf_ecc_data_pb2
+
+parser = argparse.ArgumentParser()
+parser.add_argument("--input", required=True)
+parser.add_argument("--strict", action="store_true")
+args = parser.parse_args()
+
+all_ecc_info = protobuf_ecc_data_pb2.AllInfo()
+
+with open(args.input, "rb") as ecc_data_source_file:
+  all_ecc_info.ParseFromString(ecc_data_source_file.read())
+
+if (args.strict):
+  print("Verify in strict mode")
+
+assert all_ecc_info.HasField("revision")
+assert all_ecc_info.revision > 0
+assert len(all_ecc_info.countries) > 0
+
+loaded_iso = []
+for country_info in all_ecc_info.countries:
+  assert country_info.HasField("iso_code")
+  assert len(country_info.iso_code) > 0
+  assert country_info.iso_code == country_info.iso_code.strip().upper()
+  assert country_info.iso_code not in loaded_iso
+  loaded_iso.append(country_info.iso_code)
+  assert country_info.HasField("ecc_fallback")
+  assert len(country_info.ecc_fallback) > 0
+
+  if len(country_info.eccs) > 0:
+    loaded_phone_number = []
+    for ecc_info in country_info.eccs:
+      assert ecc_info.HasField("phone_number")
+      phone_number = ecc_info.phone_number.strip()
+      assert len(phone_number) > 0
+      assert phone_number not in loaded_phone_number
+      loaded_phone_number.append(phone_number)
+
+      if (args.strict):
+        assert len(ecc_info.types) > 0
+        loaded_types = []
+        for ecc_type in ecc_info.types:
+          assert ecc_type == protobuf_ecc_data_pb2.EccInfo.POLICE or \
+              ecc_type == protobuf_ecc_data_pb2.EccInfo.AMBULANCE or \
+              ecc_type == protobuf_ecc_data_pb2.EccInfo.FIRE
+          assert ecc_type not in loaded_types
+          loaded_types.append(ecc_type)
+      else:
+        # For forward compatibility, ecc_info.types could be null if a phone
+        # number contains only new types which is not defined now. Just leave
+        # a warning message for this case.
+        if len(ecc_info.types) == 0:
+          print("WARNING: No recognizable type for " + \
+              country_info.iso_code + " - " + ecc_info.phone_number)
+        else:
+          loaded_types = []
+          for ecc_type in ecc_info.types:
+            assert ecc_type not in loaded_types
+            loaded_types.append(ecc_type)
+  elif (args.strict):
+    print("Warning: Empty ecc list for country " + country_info.iso_code)
diff --git a/ecc/gen_eccdata.sh b/ecc/gen_eccdata.sh
new file mode 100755
index 0000000..5cf52de
--- /dev/null
+++ b/ecc/gen_eccdata.sh
@@ -0,0 +1,67 @@
+#!/bin/bash
+set -o errexit
+
+# Copyright 2018 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.
+
+if [ -z "${ANDROID_BUILD_TOP}" ] ; then
+  echo "You need to source and lunch before you can use this script" 1>&2
+  exit 1
+fi
+
+case $(uname -s) in
+  Darwin)
+    KERNEL=darwin
+    ;;
+  Linux)
+    KERNEL=linux
+    ;;
+  *)
+    echo "Unknown kernel \"`uname -s`\"" 1>&2
+    exit 1
+    ;;
+esac
+
+read -d "" PROTOC_COMMAND << END || :
+${ANDROID_BUILD_TOP}/prebuilts/tools/${KERNEL}-x86_64/protoc/bin/protoc
+END
+if ! [ -x "${PROTOC_COMMAND}" ] ; then
+  echo "Missing ${PROTOC_COMMAND}." 1>&2
+  exit 1
+fi
+
+ECC_ROOT=`realpath \`dirname $0\``
+TOOLSET_DIR="${ECC_ROOT}/conversion_toolset_v1"
+INPUT_DIR="${ECC_ROOT}/input"
+OUTPUT_DIR="${ECC_ROOT}/output"
+INTERMEDIATE_DIR="${ECC_ROOT}/.intermediate"
+
+rm -rf "${INTERMEDIATE_DIR}" "${OUTPUT_DIR}/*"
+mkdir -p "${INTERMEDIATE_DIR}"
+
+source "${TOOLSET_DIR}/gen_eccdata.sh"
+echo
+
+# Check compatibility with every previous version
+rm -rf "${INTERMEDIATE_DIR}/*"
+source ${ECC_ROOT}/conversion_toolset_v1/verify_eccdata_compatibility.sh
+#rm -rf "${INTERMEDIATE_DIR}/*"
+#source ${ECC_ROOT}/conversion_toolset_v2/verify_eccdata_compatibility.sh
+#rm -rf "${INTERMEDIATE_DIR}/*"
+#source ${ECC_ROOT}/conversion_toolset_v3/verify_eccdata_compatibility.sh
+#...
+
+echo
+echo "Passed all compatibility verification!"
+
diff --git a/ecc/input/eccdata.txt b/ecc/input/eccdata.txt
new file mode 100644
index 0000000..54be16b
--- /dev/null
+++ b/ecc/input/eccdata.txt
@@ -0,0 +1,2856 @@
+revision: 1
+countries {
+  iso_code: "AD"
+  eccs {
+    phone_number: "110"
+    types: POLICE
+  }
+  eccs {
+    phone_number: "116"
+    types: AMBULANCE
+  }
+  eccs {
+    phone_number: "118"
+    types: FIRE
+  }
+  ecc_fallback: "112"
+}
+countries {
+  iso_code: "AE"
+  eccs {
+    phone_number: "999"
+    types: POLICE
+  }
+  eccs {
+    phone_number: "998"
+    types: AMBULANCE
+  }
+  eccs {
+    phone_number: "997"
+    types: FIRE
+  }
+  ecc_fallback: "112"
+}
+countries {
+  iso_code: "AF"
+  eccs {
+    phone_number: "119"
+    types: POLICE
+    types: FIRE
+  }
+  eccs {
+    phone_number: "020112"
+    types: AMBULANCE
+  }
+  ecc_fallback: "112"
+}
+countries {
+  iso_code: "AG"
+  eccs {
+    phone_number: "911"
+    types: POLICE
+    types: AMBULANCE
+    types: FIRE
+  }
+  ecc_fallback: "911"
+}
+countries {
+  iso_code: "AI"
+  eccs {
+    phone_number: "911"
+    types: POLICE
+    types: AMBULANCE
+    types: FIRE
+  }
+  ecc_fallback: "911"
+}
+countries {
+  iso_code: "AL"
+  eccs {
+    phone_number: "129"
+    types: POLICE
+  }
+  eccs {
+    phone_number: "127"
+    types: AMBULANCE
+  }
+  eccs {
+    phone_number: "128"
+    types: FIRE
+  }
+  ecc_fallback: "112"
+}
+countries {
+  iso_code: "AM"
+  eccs {
+    phone_number: "911"
+    types: POLICE
+    types: AMBULANCE
+    types: FIRE
+  }
+  ecc_fallback: "112"
+}
+countries {
+  iso_code: "AO"
+  eccs {
+    phone_number: "113"
+    types: POLICE
+  }
+  eccs {
+    phone_number: "112"
+    types: AMBULANCE
+  }
+  eccs {
+    phone_number: "115"
+    types: FIRE
+  }
+  ecc_fallback: "112"
+}
+countries {
+  iso_code: "AR"
+  eccs {
+    phone_number: "911"
+    types: POLICE
+    types: AMBULANCE
+    types: FIRE
+  }
+  ecc_fallback: "911"
+}
+countries {
+  iso_code: "AS"
+  eccs {
+    phone_number: "911"
+    types: POLICE
+    types: AMBULANCE
+    types: FIRE
+  }
+  ecc_fallback: "911"
+}
+countries {
+  iso_code: "AT"
+  eccs {
+    phone_number: "112"
+    types: POLICE
+    types: AMBULANCE
+    types: FIRE
+  }
+  ecc_fallback: "112"
+}
+countries {
+  iso_code: "AU"
+  eccs {
+    phone_number: "000"
+    types: POLICE
+    types: AMBULANCE
+    types: FIRE
+  }
+  ecc_fallback: "112"
+}
+countries {
+  iso_code: "AW"
+  eccs {
+    phone_number: "911"
+    types: POLICE
+    types: AMBULANCE
+    types: FIRE
+  }
+  ecc_fallback: "911"
+}
+countries {
+  iso_code: "AZ"
+  eccs {
+    phone_number: "112"
+    types: POLICE
+    types: AMBULANCE
+    types: FIRE
+  }
+  ecc_fallback: "112"
+}
+countries {
+  iso_code: "BA"
+  eccs {
+    phone_number: "122"
+    types: POLICE
+  }
+  eccs {
+    phone_number: "124"
+    types: AMBULANCE
+  }
+  eccs {
+    phone_number: "123"
+    types: FIRE
+  }
+  ecc_fallback: "112"
+}
+countries {
+  iso_code: "BB"
+  eccs {
+    phone_number: "211"
+    types: POLICE
+  }
+  eccs {
+    phone_number: "511"
+    types: AMBULANCE
+  }
+  eccs {
+    phone_number: "311"
+    types: FIRE
+  }
+  ecc_fallback: "911"
+}
+countries {
+  iso_code: "BD"
+  eccs {
+    phone_number: "999"
+    types: POLICE
+    types: AMBULANCE
+    types: FIRE
+  }
+  ecc_fallback: "112"
+}
+countries {
+  iso_code: "BE"
+  eccs {
+    phone_number: "112"
+    types: POLICE
+    types: AMBULANCE
+    types: FIRE
+  }
+  ecc_fallback: "112"
+}
+countries {
+  iso_code: "BF"
+  eccs {
+    phone_number: "17"
+    types: POLICE
+  }
+  eccs {
+    phone_number: "18"
+    types: AMBULANCE
+    types: FIRE
+  }
+  ecc_fallback: "112"
+}
+countries {
+  iso_code: "BG"
+  eccs {
+    phone_number: "112"
+    types: POLICE
+    types: AMBULANCE
+    types: FIRE
+  }
+  ecc_fallback: "112"
+}
+countries {
+  iso_code: "BH"
+  eccs {
+    phone_number: "999"
+    types: POLICE
+    types: AMBULANCE
+    types: FIRE
+  }
+  ecc_fallback: "112"
+}
+countries {
+  iso_code: "BI"
+  eccs {
+    phone_number: "112"
+    types: POLICE
+    types: AMBULANCE
+    types: FIRE
+  }
+  ecc_fallback: "112"
+}
+countries {
+  iso_code: "BJ"
+  eccs {
+    phone_number: "117"
+    types: POLICE
+  }
+  eccs {
+    phone_number: "118"
+    types: FIRE
+  }
+  ecc_fallback: "112"
+}
+countries {
+  iso_code: "BM"
+  eccs {
+    phone_number: "911"
+    types: POLICE
+    types: AMBULANCE
+    types: FIRE
+  }
+  ecc_fallback: "911"
+}
+countries {
+  iso_code: "BN"
+  eccs {
+    phone_number: "993"
+    types: POLICE
+  }
+  eccs {
+    phone_number: "991"
+    types: AMBULANCE
+  }
+  eccs {
+    phone_number: "995"
+    types: FIRE
+  }
+  ecc_fallback: "112"
+}
+countries {
+  iso_code: "BO"
+  eccs {
+    phone_number: "110"
+    types: POLICE
+  }
+  eccs {
+    phone_number: "118"
+    types: AMBULANCE
+  }
+  eccs {
+    phone_number: "119"
+    types: FIRE
+  }
+  ecc_fallback: "911"
+}
+countries {
+  iso_code: "BR"
+  eccs {
+    phone_number: "190"
+    types: POLICE
+  }
+  eccs {
+    phone_number: "192"
+    types: AMBULANCE
+  }
+  eccs {
+    phone_number: "193"
+    types: FIRE
+  }
+  ecc_fallback: "911"
+}
+countries {
+  iso_code: "BS"
+  eccs {
+    phone_number: "919"
+    types: POLICE
+    types: AMBULANCE
+    types: FIRE
+  }
+  ecc_fallback: "911"
+}
+countries {
+  iso_code: "BT"
+  eccs {
+    phone_number: "113"
+    types: POLICE
+  }
+  eccs {
+    phone_number: "112"
+    types: AMBULANCE
+  }
+  eccs {
+    phone_number: "110"
+    types: FIRE
+  }
+  ecc_fallback: "112"
+}
+countries {
+  iso_code: "BW"
+  eccs {
+    phone_number: "999"
+    types: POLICE
+  }
+  eccs {
+    phone_number: "997"
+    types: AMBULANCE
+  }
+  eccs {
+    phone_number: "998"
+    types: FIRE
+  }
+  ecc_fallback: "112"
+}
+countries {
+  iso_code: "BY"
+  eccs {
+    phone_number: "102"
+    types: POLICE
+  }
+  eccs {
+    phone_number: "103"
+    types: AMBULANCE
+  }
+  eccs {
+    phone_number: "101"
+    types: FIRE
+  }
+  ecc_fallback: "112"
+}
+countries {
+  iso_code: "BZ"
+  eccs {
+    phone_number: "911"
+    types: POLICE
+    types: AMBULANCE
+    types: FIRE
+  }
+  ecc_fallback: "911"
+}
+countries {
+  iso_code: "CA"
+  eccs {
+    phone_number: "911"
+    types: POLICE
+    types: AMBULANCE
+    types: FIRE
+  }
+  ecc_fallback: "911"
+}
+countries {
+  iso_code: "CD"
+  eccs {
+    phone_number: "118"
+    types: POLICE
+  }
+  ecc_fallback: "112"
+}
+countries {
+  iso_code: "CF"
+  eccs {
+    phone_number: "117"
+    types: POLICE
+    types: AMBULANCE
+    types: FIRE
+  }
+  ecc_fallback: "112"
+}
+countries {
+  iso_code: "CG"
+  eccs {
+    phone_number: "118"
+    types: POLICE
+  }
+  ecc_fallback: "112"
+}
+countries {
+  iso_code: "CH"
+  eccs {
+    phone_number: "117"
+    types: POLICE
+  }
+  eccs {
+    phone_number: "144"
+    types: AMBULANCE
+  }
+  eccs {
+    phone_number: "118"
+    types: FIRE
+  }
+  ecc_fallback: "112"
+}
+countries {
+  iso_code: "CI"
+  eccs {
+    phone_number: "170"
+    types: POLICE
+  }
+  eccs {
+    phone_number: "185"
+    types: AMBULANCE
+  }
+  eccs {
+    phone_number: "180"
+    types: FIRE
+  }
+  ecc_fallback: "112"
+}
+countries {
+  iso_code: "CK"
+  eccs {
+    phone_number: "999"
+    types: POLICE
+    types: AMBULANCE
+    types: FIRE
+  }
+  ecc_fallback: "112"
+}
+countries {
+  iso_code: "CL"
+  eccs {
+    phone_number: "133"
+    types: POLICE
+  }
+  eccs {
+    phone_number: "131"
+    types: AMBULANCE
+  }
+  eccs {
+    phone_number: "132"
+    types: FIRE
+  }
+  ecc_fallback: "112"
+}
+countries {
+  iso_code: "CM"
+  eccs {
+    phone_number: "117"
+    types: POLICE
+  }
+  eccs {
+    phone_number: "119"
+    types: AMBULANCE
+  }
+  eccs {
+    phone_number: "118"
+    types: FIRE
+  }
+  ecc_fallback: "112"
+}
+countries {
+  iso_code: "CN"
+  eccs {
+    phone_number: "110"
+    types: POLICE
+  }
+  eccs {
+    phone_number: "120"
+    types: AMBULANCE
+  }
+  eccs {
+    phone_number: "119"
+    types: FIRE
+  }
+  ecc_fallback: "112"
+}
+countries {
+  iso_code: "CO"
+  eccs {
+    phone_number: "123"
+    types: POLICE
+    types: AMBULANCE
+    types: FIRE
+  }
+  ecc_fallback: "112"
+}
+countries {
+  iso_code: "CR"
+  eccs {
+    phone_number: "911"
+    types: POLICE
+    types: AMBULANCE
+    types: FIRE
+  }
+  ecc_fallback: "911"
+}
+countries {
+  iso_code: "CU"
+  eccs {
+    phone_number: "106"
+    types: POLICE
+  }
+  eccs {
+    phone_number: "104"
+    types: AMBULANCE
+  }
+  eccs {
+    phone_number: "105"
+    types: FIRE
+  }
+  ecc_fallback: "112"
+}
+countries {
+  iso_code: "CV"
+  eccs {
+    phone_number: "132"
+    types: POLICE
+  }
+  eccs {
+    phone_number: "130"
+    types: AMBULANCE
+  }
+  eccs {
+    phone_number: "131"
+    types: FIRE
+  }
+  ecc_fallback: "112"
+}
+countries {
+  iso_code: "CY"
+  eccs {
+    phone_number: "112"
+    types: POLICE
+    types: AMBULANCE
+    types: FIRE
+  }
+  ecc_fallback: "112"
+}
+countries {
+  iso_code: "CZ"
+  eccs {
+    phone_number: "112"
+    types: POLICE
+    types: AMBULANCE
+    types: FIRE
+  }
+  ecc_fallback: "112"
+}
+countries {
+  iso_code: "DE"
+  eccs {
+    phone_number: "112"
+    types: POLICE
+    types: AMBULANCE
+    types: FIRE
+  }
+  ecc_fallback: "112"
+}
+countries {
+  iso_code: "DJ"
+  eccs {
+    phone_number: "17"
+    types: POLICE
+  }
+  eccs {
+    phone_number: "18"
+    types: AMBULANCE
+    types: FIRE
+  }
+  ecc_fallback: "112"
+}
+countries {
+  iso_code: "DK"
+  eccs {
+    phone_number: "112"
+    types: POLICE
+    types: AMBULANCE
+    types: FIRE
+  }
+  ecc_fallback: "112"
+}
+countries {
+  iso_code: "DM"
+  eccs {
+    phone_number: "911"
+    types: POLICE
+    types: AMBULANCE
+    types: FIRE
+  }
+  ecc_fallback: "911"
+}
+countries {
+  iso_code: "DO"
+  eccs {
+    phone_number: "911"
+    types: POLICE
+    types: AMBULANCE
+    types: FIRE
+  }
+  ecc_fallback: "911"
+}
+countries {
+  iso_code: "DZ"
+  eccs {
+    phone_number: "1548"
+    types: POLICE
+    types: AMBULANCE
+    types: FIRE
+  }
+  ecc_fallback: "112"
+}
+countries {
+  iso_code: "EC"
+  eccs {
+    phone_number: "911"
+    types: POLICE
+    types: AMBULANCE
+    types: FIRE
+  }
+  ecc_fallback: "911"
+}
+countries {
+  iso_code: "EE"
+  eccs {
+    phone_number: "112"
+    types: POLICE
+    types: AMBULANCE
+    types: FIRE
+  }
+  ecc_fallback: "112"
+}
+countries {
+  iso_code: "EG"
+  eccs {
+    phone_number: "122"
+    types: POLICE
+  }
+  eccs {
+    phone_number: "123"
+    types: AMBULANCE
+  }
+  eccs {
+    phone_number: "180"
+    types: FIRE
+  }
+  ecc_fallback: "112"
+}
+countries {
+  iso_code: "ER"
+  eccs {
+    phone_number: "127799"
+    types: POLICE
+  }
+  eccs {
+    phone_number: "202914"
+    types: AMBULANCE
+  }
+  eccs {
+    phone_number: "202099"
+    types: FIRE
+  }
+  ecc_fallback: "112"
+}
+countries {
+  iso_code: "ES"
+  eccs {
+    phone_number: "112"
+    types: POLICE
+    types: AMBULANCE
+    types: FIRE
+  }
+  ecc_fallback: "112"
+}
+countries {
+  iso_code: "ET"
+  eccs {
+    phone_number: "991"
+    types: POLICE
+    types: AMBULANCE
+    types: FIRE
+  }
+  ecc_fallback: "112"
+}
+countries {
+  iso_code: "FI"
+  eccs {
+    phone_number: "112"
+    types: POLICE
+    types: AMBULANCE
+    types: FIRE
+  }
+  ecc_fallback: "112"
+}
+countries {
+  iso_code: "FJ"
+  eccs {
+    phone_number: "917"
+    types: POLICE
+  }
+  eccs {
+    phone_number: "911"
+    types: AMBULANCE
+    types: FIRE
+  }
+  ecc_fallback: "911"
+}
+countries {
+  iso_code: "FK"
+  eccs {
+    phone_number: "999"
+    types: POLICE
+    types: AMBULANCE
+    types: FIRE
+  }
+  ecc_fallback: "112"
+}
+countries {
+  iso_code: "FM"
+  eccs {
+    phone_number: "911"
+    types: POLICE
+    types: AMBULANCE
+    types: FIRE
+  }
+  ecc_fallback: "911"
+}
+countries {
+  iso_code: "FO"
+  eccs {
+    phone_number: "112"
+    types: POLICE
+    types: AMBULANCE
+    types: FIRE
+  }
+  ecc_fallback: "112"
+}
+countries {
+  iso_code: "FR"
+  eccs {
+    phone_number: "112"
+    types: POLICE
+    types: AMBULANCE
+    types: FIRE
+  }
+  ecc_fallback: "112"
+}
+countries {
+  iso_code: "GA"
+  eccs {
+    phone_number: "177"
+    types: POLICE
+    types: AMBULANCE
+    types: FIRE
+  }
+  ecc_fallback: "112"
+}
+countries {
+  iso_code: "GB"
+  eccs {
+    phone_number: "112"
+    types: POLICE
+    types: AMBULANCE
+    types: FIRE
+  }
+  ecc_fallback: "112"
+}
+countries {
+  iso_code: "GD"
+  eccs {
+    phone_number: "911"
+    types: POLICE
+    types: AMBULANCE
+    types: FIRE
+  }
+  ecc_fallback: "911"
+}
+countries {
+  iso_code: "GE"
+  eccs {
+    phone_number: "112"
+    types: POLICE
+    types: AMBULANCE
+    types: FIRE
+  }
+  ecc_fallback: "112"
+}
+countries {
+  iso_code: "GF"
+  eccs {
+    phone_number: "17"
+    types: POLICE
+  }
+  eccs {
+    phone_number: "15"
+    types: AMBULANCE
+  }
+  eccs {
+    phone_number: "18"
+    types: FIRE
+  }
+  ecc_fallback: "112"
+}
+countries {
+  iso_code: "GH"
+  eccs {
+    phone_number: "191"
+    types: POLICE
+  }
+  eccs {
+    phone_number: "193"
+    types: AMBULANCE
+  }
+  eccs {
+    phone_number: "192"
+    types: FIRE
+  }
+  ecc_fallback: "112"
+}
+countries {
+  iso_code: "GI"
+  eccs {
+    phone_number: "199"
+    types: POLICE
+  }
+  eccs {
+    phone_number: "190"
+    types: AMBULANCE
+    types: FIRE
+  }
+  ecc_fallback: "112"
+}
+countries {
+  iso_code: "GL"
+  eccs {
+    phone_number: "112"
+    types: POLICE
+    types: AMBULANCE
+    types: FIRE
+  }
+  ecc_fallback: "112"
+}
+countries {
+  iso_code: "GM"
+  eccs {
+    phone_number: "911"
+    types: POLICE
+  }
+  eccs {
+    phone_number: "116"
+    types: AMBULANCE
+  }
+  eccs {
+    phone_number: "118"
+    types: FIRE
+  }
+  ecc_fallback: "112"
+}
+countries {
+  iso_code: "GN"
+  eccs {
+    phone_number: "122"
+    types: POLICE
+  }
+  eccs {
+    phone_number: "442020"
+    types: AMBULANCE
+  }
+  eccs {
+    phone_number: "1717"
+    types: FIRE
+  }
+  ecc_fallback: "112"
+}
+countries {
+  iso_code: "GP"
+  eccs {
+    phone_number: "17"
+    types: POLICE
+  }
+  eccs {
+    phone_number: "15"
+    types: AMBULANCE
+  }
+  eccs {
+    phone_number: "18"
+    types: FIRE
+  }
+  ecc_fallback: "112"
+}
+countries {
+  iso_code: "GQ"
+  eccs {
+    phone_number: "113"
+    types: POLICE
+  }
+  eccs {
+    phone_number: "115"
+    types: FIRE
+  }
+  ecc_fallback: "112"
+}
+countries {
+  iso_code: "GR"
+  eccs {
+    phone_number: "112"
+    types: POLICE
+    types: AMBULANCE
+    types: FIRE
+  }
+  ecc_fallback: "112"
+}
+countries {
+  iso_code: "GT"
+  eccs {
+    phone_number: "120"
+    types: POLICE
+  }
+  eccs {
+    phone_number: "123"
+    types: AMBULANCE
+    types: FIRE
+  }
+  ecc_fallback: "911"
+}
+countries {
+  iso_code: "GU"
+  eccs {
+    phone_number: "911"
+    types: POLICE
+    types: AMBULANCE
+    types: FIRE
+  }
+  ecc_fallback: "911"
+}
+countries {
+  iso_code: "GW"
+  eccs {
+    phone_number: "117"
+    types: POLICE
+  }
+  eccs {
+    phone_number: "113"
+    types: AMBULANCE
+  }
+  eccs {
+    phone_number: "118"
+    types: FIRE
+  }
+  ecc_fallback: "112"
+}
+countries {
+  iso_code: "GY"
+  eccs {
+    phone_number: "911"
+    types: POLICE
+  }
+  eccs {
+    phone_number: "913"
+    types: AMBULANCE
+  }
+  eccs {
+    phone_number: "912"
+    types: FIRE
+  }
+  ecc_fallback: "911"
+}
+countries {
+  iso_code: "HK"
+  eccs {
+    phone_number: "999"
+    types: POLICE
+    types: AMBULANCE
+    types: FIRE
+  }
+  ecc_fallback: "112"
+}
+countries {
+  iso_code: "HN"
+  eccs {
+    phone_number: "911"
+    types: POLICE
+    types: AMBULANCE
+    types: FIRE
+  }
+  ecc_fallback: "911"
+}
+countries {
+  iso_code: "HR"
+  eccs {
+    phone_number: "112"
+    types: POLICE
+    types: AMBULANCE
+    types: FIRE
+  }
+  ecc_fallback: "112"
+}
+countries {
+  iso_code: "HT"
+  eccs {
+    phone_number: "114"
+    types: POLICE
+  }
+  eccs {
+    phone_number: "116"
+    types: AMBULANCE
+  }
+  eccs {
+    phone_number: "115"
+    types: FIRE
+  }
+  ecc_fallback: "112"
+}
+countries {
+  iso_code: "HU"
+  eccs {
+    phone_number: "112"
+    types: POLICE
+    types: AMBULANCE
+    types: FIRE
+  }
+  ecc_fallback: "112"
+}
+countries {
+  iso_code: "ID"
+  eccs {
+    phone_number: "110"
+    types: POLICE
+  }
+  eccs {
+    phone_number: "118"
+    types: AMBULANCE
+  }
+  eccs {
+    phone_number: "113"
+    types: FIRE
+  }
+  ecc_fallback: "112"
+}
+countries {
+  iso_code: "IE"
+  eccs {
+    phone_number: "112"
+    types: POLICE
+    types: AMBULANCE
+    types: FIRE
+  }
+  ecc_fallback: "112"
+}
+countries {
+  iso_code: "IL"
+  eccs {
+    phone_number: "100"
+    types: POLICE
+  }
+  eccs {
+    phone_number: "101"
+    types: AMBULANCE
+  }
+  eccs {
+    phone_number: "102"
+    types: FIRE
+  }
+  ecc_fallback: "112"
+}
+countries {
+  iso_code: "IN"
+  eccs {
+    phone_number: "112"
+    types: POLICE
+    types: AMBULANCE
+    types: FIRE
+  }
+  ecc_fallback: "112"
+}
+countries {
+  iso_code: "IO"
+  eccs {
+    phone_number: "112"
+    types: POLICE
+    types: AMBULANCE
+    types: FIRE
+  }
+  ecc_fallback: "911"
+}
+countries {
+  iso_code: "IQ"
+  eccs {
+    phone_number: "130"
+    types: POLICE
+    types: AMBULANCE
+    types: FIRE
+  }
+  ecc_fallback: "112"
+}
+countries {
+  iso_code: "IR"
+  eccs {
+    phone_number: "110"
+    types: POLICE
+  }
+  eccs {
+    phone_number: "115"
+    types: AMBULANCE
+  }
+  eccs {
+    phone_number: "125"
+    types: FIRE
+  }
+  ecc_fallback: "112"
+}
+countries {
+  iso_code: "IS"
+  eccs {
+    phone_number: "112"
+    types: POLICE
+    types: AMBULANCE
+    types: FIRE
+  }
+  ecc_fallback: "112"
+}
+countries {
+  iso_code: "IT"
+  eccs {
+    phone_number: "112"
+    types: POLICE
+    types: AMBULANCE
+    types: FIRE
+  }
+  ecc_fallback: "112"
+}
+countries {
+  iso_code: "JM"
+  eccs {
+    phone_number: "112"
+    types: POLICE
+    types: AMBULANCE
+    types: FIRE
+  }
+  ecc_fallback: "911"
+}
+countries {
+  iso_code: "JO"
+  eccs {
+    phone_number: "911"
+    types: POLICE
+    types: AMBULANCE
+    types: FIRE
+  }
+  ecc_fallback: "911"
+}
+countries {
+  iso_code: "JP"
+  eccs {
+    phone_number: "110"
+    types: POLICE
+  }
+  eccs {
+    phone_number: "119"
+    types: AMBULANCE
+    types: FIRE
+  }
+  ecc_fallback: "112"
+}
+countries {
+  iso_code: "KE"
+  eccs {
+    phone_number: "999"
+    types: POLICE
+    types: AMBULANCE
+    types: FIRE
+  }
+  ecc_fallback: "112"
+}
+countries {
+  iso_code: "KG"
+  eccs {
+    phone_number: "102"
+    types: POLICE
+  }
+  eccs {
+    phone_number: "103"
+    types: AMBULANCE
+  }
+  eccs {
+    phone_number: "101"
+    types: FIRE
+  }
+  ecc_fallback: "112"
+}
+countries {
+  iso_code: "KH"
+  eccs {
+    phone_number: "117"
+    types: POLICE
+  }
+  eccs {
+    phone_number: "119"
+    types: AMBULANCE
+  }
+  eccs {
+    phone_number: "118"
+    types: FIRE
+  }
+  ecc_fallback: "112"
+}
+countries {
+  iso_code: "KI"
+  eccs {
+    phone_number: "192"
+    types: POLICE
+  }
+  eccs {
+    phone_number: "194"
+    types: AMBULANCE
+  }
+  eccs {
+    phone_number: "193"
+    types: FIRE
+  }
+  ecc_fallback: "911"
+}
+countries {
+  iso_code: "KM"
+  eccs {
+    phone_number: "17"
+    types: POLICE
+  }
+  eccs {
+    phone_number: "18"
+    types: FIRE
+  }
+  ecc_fallback: "112"
+}
+countries {
+  iso_code: "KN"
+  eccs {
+    phone_number: "911"
+    types: POLICE
+    types: AMBULANCE
+  }
+  eccs {
+    phone_number: "333"
+    types: FIRE
+  }
+  ecc_fallback: "911"
+}
+countries {
+  iso_code: "KP"
+  eccs {
+    phone_number: "112"
+    types: POLICE
+    types: AMBULANCE
+    types: FIRE
+  }
+  ecc_fallback: "112"
+}
+countries {
+  iso_code: "KR"
+  eccs {
+    phone_number: "112"
+    types: POLICE
+  }
+  eccs {
+    phone_number: "119"
+    types: AMBULANCE
+    types: FIRE
+  }
+  ecc_fallback: "112"
+}
+countries {
+  iso_code: "KW"
+  eccs {
+    phone_number: "112"
+    types: POLICE
+    types: AMBULANCE
+    types: FIRE
+  }
+  ecc_fallback: "112"
+}
+countries {
+  iso_code: "KY"
+  eccs {
+    phone_number: "911"
+    types: POLICE
+    types: AMBULANCE
+    types: FIRE
+  }
+  ecc_fallback: "911"
+}
+countries {
+  iso_code: "KZ"
+  eccs {
+    phone_number: "102"
+    types: POLICE
+  }
+  eccs {
+    phone_number: "103"
+    types: AMBULANCE
+  }
+  eccs {
+    phone_number: "101"
+    types: FIRE
+  }
+  ecc_fallback: "112"
+}
+countries {
+  iso_code: "LA"
+  eccs {
+    phone_number: "1191"
+    types: POLICE
+  }
+  eccs {
+    phone_number: "1195"
+    types: AMBULANCE
+  }
+  eccs {
+    phone_number: "1190"
+    types: FIRE
+  }
+  ecc_fallback: "112"
+}
+countries {
+  iso_code: "LB"
+  eccs {
+    phone_number: "112"
+    types: POLICE
+    types: AMBULANCE
+    types: FIRE
+  }
+  ecc_fallback: "112"
+}
+countries {
+  iso_code: "LC"
+  eccs {
+    phone_number: "999"
+    types: POLICE
+  }
+  eccs {
+    phone_number: "911"
+    types: AMBULANCE
+    types: FIRE
+  }
+  ecc_fallback: "911"
+}
+countries {
+  iso_code: "LI"
+  eccs {
+    phone_number: "112"
+    types: POLICE
+    types: AMBULANCE
+    types: FIRE
+  }
+  ecc_fallback: "112"
+}
+countries {
+  iso_code: "LK"
+  eccs {
+    phone_number: "119"
+    types: POLICE
+  }
+  eccs {
+    phone_number: "110"
+    types: AMBULANCE
+    types: FIRE
+  }
+  ecc_fallback: "112"
+}
+countries {
+  iso_code: "LR"
+  eccs {
+    phone_number: "911"
+    types: POLICE
+    types: AMBULANCE
+    types: FIRE
+  }
+  ecc_fallback: "911"
+}
+countries {
+  iso_code: "LS"
+  eccs {
+    phone_number: "123"
+    types: POLICE
+  }
+  eccs {
+    phone_number: "121"
+    types: AMBULANCE
+  }
+  eccs {
+    phone_number: "122"
+    types: FIRE
+  }
+  ecc_fallback: "112"
+}
+countries {
+  iso_code: "LT"
+  eccs {
+    phone_number: "112"
+    types: POLICE
+    types: AMBULANCE
+    types: FIRE
+  }
+  ecc_fallback: "112"
+}
+countries {
+  iso_code: "LU"
+  eccs {
+    phone_number: "112"
+    types: POLICE
+    types: AMBULANCE
+    types: FIRE
+  }
+  ecc_fallback: "112"
+}
+countries {
+  iso_code: "LV"
+  eccs {
+    phone_number: "112"
+    types: POLICE
+    types: AMBULANCE
+    types: FIRE
+  }
+  ecc_fallback: "112"
+}
+countries {
+  iso_code: "LY"
+  eccs {
+    phone_number: "1515"
+    types: POLICE
+    types: AMBULANCE
+    types: FIRE
+  }
+  ecc_fallback: "112"
+}
+countries {
+  iso_code: "MA"
+  eccs {
+    phone_number: "190"
+    types: POLICE
+  }
+  eccs {
+    phone_number: "150"
+    types: AMBULANCE
+    types: FIRE
+  }
+  ecc_fallback: "112"
+}
+countries {
+  iso_code: "MC"
+  eccs {
+    phone_number: "112"
+    types: POLICE
+    types: AMBULANCE
+    types: FIRE
+  }
+  ecc_fallback: "112"
+}
+countries {
+  iso_code: "MD"
+  eccs {
+    phone_number: "902"
+    types: POLICE
+  }
+  eccs {
+    phone_number: "903"
+    types: AMBULANCE
+  }
+  eccs {
+    phone_number: "901"
+    types: FIRE
+  }
+  ecc_fallback: "112"
+}
+countries {
+  iso_code: "ME"
+  eccs {
+    phone_number: "122"
+    types: POLICE
+  }
+  eccs {
+    phone_number: "124"
+    types: AMBULANCE
+  }
+  eccs {
+    phone_number: "123"
+    types: FIRE
+  }
+  ecc_fallback: "112"
+}
+countries {
+  iso_code: "MG"
+  eccs {
+    phone_number: "117"
+    types: POLICE
+    types: AMBULANCE
+  }
+  eccs {
+    phone_number: "118"
+    types: FIRE
+  }
+  ecc_fallback: "112"
+}
+countries {
+  iso_code: "MH"
+  eccs {
+    phone_number: "911"
+    types: POLICE
+    types: AMBULANCE
+    types: FIRE
+  }
+  ecc_fallback: "911"
+}
+countries {
+  iso_code: "MK"
+  eccs {
+    phone_number: "192"
+    types: POLICE
+  }
+  eccs {
+    phone_number: "194"
+    types: AMBULANCE
+  }
+  eccs {
+    phone_number: "193"
+    types: FIRE
+  }
+  ecc_fallback: "112"
+}
+countries {
+  iso_code: "ML"
+  eccs {
+    phone_number: "17"
+    types: POLICE
+  }
+  eccs {
+    phone_number: "15"
+    types: AMBULANCE
+  }
+  eccs {
+    phone_number: "18"
+    types: FIRE
+  }
+  ecc_fallback: "112"
+}
+countries {
+  iso_code: "MM"
+  eccs {
+    phone_number: "199"
+    types: POLICE
+  }
+  eccs {
+    phone_number: "192"
+    types: AMBULANCE
+  }
+  eccs {
+    phone_number: "191"
+    types: FIRE
+  }
+  ecc_fallback: "112"
+}
+countries {
+  iso_code: "MN"
+  eccs {
+    phone_number: "102"
+    types: POLICE
+  }
+  eccs {
+    phone_number: "103"
+    types: AMBULANCE
+  }
+  eccs {
+    phone_number: "101"
+    types: FIRE
+  }
+  ecc_fallback: "112"
+}
+countries {
+  iso_code: "MO"
+  eccs {
+    phone_number: "999"
+    types: POLICE
+    types: AMBULANCE
+    types: FIRE
+  }
+  ecc_fallback: "112"
+}
+countries {
+  iso_code: "MP"
+  eccs {
+    phone_number: "911"
+    types: POLICE
+    types: AMBULANCE
+    types: FIRE
+  }
+  ecc_fallback: "911"
+}
+countries {
+  iso_code: "MR"
+  eccs {
+    phone_number: "117"
+    types: POLICE
+  }
+  eccs {
+    phone_number: "118"
+    types: AMBULANCE
+    types: FIRE
+  }
+  ecc_fallback: "112"
+}
+countries {
+  iso_code: "MS"
+  eccs {
+    phone_number: "999"
+    types: POLICE
+  }
+  eccs {
+    phone_number: "6644912802"
+    types: AMBULANCE
+  }
+  eccs {
+    phone_number: "911"
+    types: FIRE
+  }
+  ecc_fallback: "911"
+}
+countries {
+  iso_code: "MT"
+  eccs {
+    phone_number: "112"
+    types: POLICE
+    types: AMBULANCE
+    types: FIRE
+  }
+  ecc_fallback: "112"
+}
+countries {
+  iso_code: "MU"
+  eccs {
+    phone_number: "999"
+    types: POLICE
+  }
+  eccs {
+    phone_number: "114"
+    types: AMBULANCE
+  }
+  eccs {
+    phone_number: "115"
+    types: FIRE
+  }
+  ecc_fallback: "112"
+}
+countries {
+  iso_code: "MV"
+  eccs {
+    phone_number: "119"
+    types: POLICE
+  }
+  eccs {
+    phone_number: "102"
+    types: AMBULANCE
+  }
+  eccs {
+    phone_number: "118"
+    types: FIRE
+  }
+  ecc_fallback: "112"
+}
+countries {
+  iso_code: "MW"
+  eccs {
+    phone_number: "997"
+    types: POLICE
+  }
+  eccs {
+    phone_number: "998"
+    types: AMBULANCE
+  }
+  eccs {
+    phone_number: "999"
+    types: FIRE
+  }
+  ecc_fallback: "112"
+}
+countries {
+  iso_code: "MX"
+  eccs {
+    phone_number: "911"
+    types: POLICE
+    types: AMBULANCE
+    types: FIRE
+  }
+  ecc_fallback: "911"
+}
+countries {
+  iso_code: "MY"
+  eccs {
+    phone_number: "999"
+    types: POLICE
+    types: AMBULANCE
+    types: FIRE
+  }
+  ecc_fallback: "112"
+}
+countries {
+  iso_code: "MZ"
+  eccs {
+    phone_number: "119"
+    types: POLICE
+  }
+  eccs {
+    phone_number: "117"
+    types: AMBULANCE
+  }
+  eccs {
+    phone_number: "198"
+    types: FIRE
+  }
+  ecc_fallback: "112"
+}
+countries {
+  iso_code: "NA"
+  eccs {
+    phone_number: "10111"
+    types: POLICE
+  }
+  eccs {
+    phone_number: "211111"
+    types: AMBULANCE
+    types: FIRE
+  }
+  ecc_fallback: "112"
+}
+countries {
+  iso_code: "NC"
+  eccs {
+    phone_number: "17"
+    types: POLICE
+  }
+  eccs {
+    phone_number: "15"
+    types: AMBULANCE
+  }
+  eccs {
+    phone_number: "18"
+    types: FIRE
+  }
+  ecc_fallback: "112"
+}
+countries {
+  iso_code: "NE"
+  eccs {
+    phone_number: "17"
+    types: POLICE
+  }
+  eccs {
+    phone_number: "15"
+    types: AMBULANCE
+  }
+  eccs {
+    phone_number: "18"
+    types: FIRE
+  }
+  ecc_fallback: "112"
+}
+countries {
+  iso_code: "NG"
+  eccs {
+    phone_number: "199"
+    types: POLICE
+    types: AMBULANCE
+    types: FIRE
+  }
+  ecc_fallback: "112"
+}
+countries {
+  iso_code: "NI"
+  eccs {
+    phone_number: "118"
+    types: POLICE
+  }
+  eccs {
+    phone_number: "128"
+    types: AMBULANCE
+  }
+  eccs {
+    phone_number: "115"
+    types: FIRE
+  }
+  ecc_fallback: "112"
+}
+countries {
+  iso_code: "NL"
+  eccs {
+    phone_number: "112"
+    types: POLICE
+    types: AMBULANCE
+    types: FIRE
+  }
+  ecc_fallback: "112"
+}
+countries {
+  iso_code: "NO"
+  eccs {
+    phone_number: "112"
+    types: POLICE
+    types: AMBULANCE
+    types: FIRE
+  }
+  ecc_fallback: "112"
+}
+countries {
+  iso_code: "NP"
+  eccs {
+    phone_number: "100"
+    types: POLICE
+  }
+  eccs {
+    phone_number: "102"
+    types: AMBULANCE
+  }
+  eccs {
+    phone_number: "101"
+    types: FIRE
+  }
+  ecc_fallback: "112"
+}
+countries {
+  iso_code: "NR"
+  eccs {
+    phone_number: "110"
+    types: POLICE
+  }
+  eccs {
+    phone_number: "111"
+    types: AMBULANCE
+  }
+  eccs {
+    phone_number: "112"
+    types: FIRE
+  }
+  ecc_fallback: "112"
+}
+countries {
+  iso_code: "NU"
+  eccs {
+    phone_number: "999"
+    types: POLICE
+    types: AMBULANCE
+    types: FIRE
+  }
+  ecc_fallback: "112"
+}
+countries {
+  iso_code: "NZ"
+  eccs {
+    phone_number: "111"
+    types: POLICE
+    types: AMBULANCE
+    types: FIRE
+  }
+  ecc_fallback: "112"
+}
+countries {
+  iso_code: "OM"
+  eccs {
+    phone_number: "9999"
+    types: POLICE
+    types: AMBULANCE
+    types: FIRE
+  }
+  ecc_fallback: "112"
+}
+countries {
+  iso_code: "PA"
+  eccs {
+    phone_number: "104"
+    types: POLICE
+  }
+  eccs {
+    phone_number: "911"
+    types: AMBULANCE
+    types: FIRE
+  }
+  ecc_fallback: "911"
+}
+countries {
+  iso_code: "PE"
+  eccs {
+    phone_number: "105"
+    types: POLICE
+  }
+  eccs {
+    phone_number: "110"
+    types: AMBULANCE
+  }
+  eccs {
+    phone_number: "116"
+    types: FIRE
+  }
+  ecc_fallback: "911"
+}
+countries {
+  iso_code: "PF"
+  eccs {
+    phone_number: "17"
+    types: POLICE
+  }
+  eccs {
+    phone_number: "15"
+    types: AMBULANCE
+  }
+  eccs {
+    phone_number: "18"
+    types: FIRE
+  }
+  ecc_fallback: "112"
+}
+countries {
+  iso_code: "PG"
+  eccs {
+    phone_number: "112"
+    types: POLICE
+  }
+  eccs {
+    phone_number: "111"
+    types: AMBULANCE
+  }
+  eccs {
+    phone_number: "110"
+    types: FIRE
+  }
+  ecc_fallback: "112"
+}
+countries {
+  iso_code: "PH"
+  eccs {
+    phone_number: "911"
+    types: POLICE
+    types: AMBULANCE
+    types: FIRE
+  }
+  ecc_fallback: "911"
+}
+countries {
+  iso_code: "PK"
+  eccs {
+    phone_number: "15"
+    types: POLICE
+  }
+  eccs {
+    phone_number: "115"
+    types: AMBULANCE
+  }
+  eccs {
+    phone_number: "16"
+    types: FIRE
+  }
+  ecc_fallback: "112"
+}
+countries {
+  iso_code: "PL"
+  eccs {
+    phone_number: "112"
+    types: POLICE
+    types: AMBULANCE
+    types: FIRE
+  }
+  ecc_fallback: "112"
+}
+countries {
+  iso_code: "PM"
+  eccs {
+    phone_number: "17"
+    types: POLICE
+  }
+  eccs {
+    phone_number: "15"
+    types: AMBULANCE
+  }
+  eccs {
+    phone_number: "18"
+    types: FIRE
+  }
+  ecc_fallback: "112"
+}
+countries {
+  iso_code: "PR"
+  eccs {
+    phone_number: "911"
+    types: POLICE
+    types: AMBULANCE
+    types: FIRE
+  }
+  ecc_fallback: "911"
+}
+countries {
+  iso_code: "PS"
+  eccs {
+    phone_number: "100"
+    types: POLICE
+  }
+  eccs {
+    phone_number: "101"
+    types: AMBULANCE
+  }
+  eccs {
+    phone_number: "102"
+    types: FIRE
+  }
+  ecc_fallback: "112"
+}
+countries {
+  iso_code: "PT"
+  eccs {
+    phone_number: "112"
+    types: POLICE
+    types: AMBULANCE
+    types: FIRE
+  }
+  ecc_fallback: "112"
+}
+countries {
+  iso_code: "PW"
+  eccs {
+    phone_number: "911"
+    types: POLICE
+    types: AMBULANCE
+    types: FIRE
+  }
+  ecc_fallback: "911"
+}
+countries {
+  iso_code: "PY"
+  eccs {
+    phone_number: "911"
+    types: POLICE
+    types: AMBULANCE
+    types: FIRE
+  }
+  ecc_fallback: "911"
+}
+countries {
+  iso_code: "QA"
+  eccs {
+    phone_number: "999"
+    types: POLICE
+    types: AMBULANCE
+    types: FIRE
+  }
+  ecc_fallback: "112"
+}
+countries {
+  iso_code: "RE"
+  eccs {
+    phone_number: "17"
+    types: POLICE
+  }
+  eccs {
+    phone_number: "15"
+    types: AMBULANCE
+  }
+  eccs {
+    phone_number: "18"
+    types: FIRE
+  }
+  ecc_fallback: "112"
+}
+countries {
+  iso_code: "RO"
+  eccs {
+    phone_number: "112"
+    types: POLICE
+    types: AMBULANCE
+    types: FIRE
+  }
+  ecc_fallback: "112"
+}
+countries {
+  iso_code: "RS"
+  eccs {
+    phone_number: "192"
+    types: POLICE
+  }
+  eccs {
+    phone_number: "194"
+    types: AMBULANCE
+  }
+  eccs {
+    phone_number: "193"
+    types: FIRE
+  }
+  ecc_fallback: "112"
+}
+countries {
+  iso_code: "RU"
+  eccs {
+    phone_number: "112"
+    types: POLICE
+    types: AMBULANCE
+    types: FIRE
+  }
+  ecc_fallback: "112"
+}
+countries {
+  iso_code: "RW"
+  eccs {
+    phone_number: "112"
+    types: POLICE
+    types: AMBULANCE
+  }
+  eccs {
+    phone_number: "111"
+    types: FIRE
+  }
+  ecc_fallback: "112"
+}
+countries {
+  iso_code: "SA"
+  eccs {
+    phone_number: "999"
+    types: POLICE
+  }
+  eccs {
+    phone_number: "997"
+    types: AMBULANCE
+  }
+  eccs {
+    phone_number: "998"
+    types: FIRE
+  }
+  ecc_fallback: "911"
+}
+countries {
+  iso_code: "SB"
+  eccs {
+    phone_number: "999"
+    types: POLICE
+  }
+  eccs {
+    phone_number: "911"
+    types: AMBULANCE
+  }
+  eccs {
+    phone_number: "988"
+    types: FIRE
+  }
+  ecc_fallback: "911"
+}
+countries {
+  iso_code: "SC"
+  eccs {
+    phone_number: "999"
+    types: POLICE
+    types: AMBULANCE
+    types: FIRE
+  }
+  ecc_fallback: "112"
+}
+countries {
+  iso_code: "SD"
+  eccs {
+    phone_number: "999"
+    types: POLICE
+    types: FIRE
+  }
+  eccs {
+    phone_number: "333"
+    types: AMBULANCE
+  }
+  ecc_fallback: "112"
+}
+countries {
+  iso_code: "SE"
+  eccs {
+    phone_number: "112"
+    types: POLICE
+    types: AMBULANCE
+    types: FIRE
+  }
+  ecc_fallback: "112"
+}
+countries {
+  iso_code: "SG"
+  eccs {
+    phone_number: "999"
+    types: POLICE
+  }
+  eccs {
+    phone_number: "995"
+    types: AMBULANCE
+    types: FIRE
+  }
+  ecc_fallback: "112"
+}
+countries {
+  iso_code: "SH"
+  eccs {
+    phone_number: "999"
+    types: POLICE
+    types: FIRE
+  }
+  eccs {
+    phone_number: "911"
+    types: AMBULANCE
+  }
+  ecc_fallback: "911"
+}
+countries {
+  iso_code: "SI"
+  eccs {
+    phone_number: "112"
+    types: POLICE
+    types: AMBULANCE
+    types: FIRE
+  }
+  ecc_fallback: "112"
+}
+countries {
+  iso_code: "SK"
+  eccs {
+    phone_number: "112"
+    types: POLICE
+    types: AMBULANCE
+    types: FIRE
+  }
+  ecc_fallback: "112"
+}
+countries {
+  iso_code: "SL"
+  eccs {
+    phone_number: "019"
+    types: POLICE
+  }
+  eccs {
+    phone_number: "999"
+    types: AMBULANCE
+    types: FIRE
+  }
+  ecc_fallback: "112"
+}
+countries {
+  iso_code: "SM"
+  eccs {
+    phone_number: "113"
+    types: POLICE
+  }
+  eccs {
+    phone_number: "118"
+    types: AMBULANCE
+  }
+  eccs {
+    phone_number: "115"
+    types: FIRE
+  }
+  ecc_fallback: "112"
+}
+countries {
+  iso_code: "SN"
+  eccs {
+    phone_number: "17"
+    types: POLICE
+  }
+  eccs {
+    phone_number: "15"
+    types: AMBULANCE
+  }
+  eccs {
+    phone_number: "18"
+    types: FIRE
+  }
+  ecc_fallback: "112"
+}
+countries {
+  iso_code: "SO"
+  eccs {
+    phone_number: "888"
+    types: POLICE
+    types: AMBULANCE
+    types: FIRE
+  }
+  ecc_fallback: "112"
+}
+countries {
+  iso_code: "SR"
+  eccs {
+    phone_number: "115"
+    types: POLICE
+    types: AMBULANCE
+    types: FIRE
+  }
+  ecc_fallback: "112"
+}
+countries {
+  iso_code: "SS"
+  eccs {
+    phone_number: "999"
+    types: POLICE
+    types: AMBULANCE
+    types: FIRE
+  }
+  ecc_fallback: "112"
+}
+countries {
+  iso_code: "ST"
+  eccs {
+    phone_number: "222222"
+    types: POLICE
+  }
+  eccs {
+    phone_number: "221222"
+    types: AMBULANCE
+  }
+  eccs {
+    phone_number: "112"
+    types: FIRE
+  }
+  ecc_fallback: "112"
+}
+countries {
+  iso_code: "SV"
+  eccs {
+    phone_number: "911"
+    types: POLICE
+    types: AMBULANCE
+  }
+  eccs {
+    phone_number: "913"
+    types: FIRE
+  }
+  ecc_fallback: "911"
+}
+countries {
+  iso_code: "SY"
+  eccs {
+    phone_number: "112"
+    types: POLICE
+  }
+  eccs {
+    phone_number: "110"
+    types: AMBULANCE
+  }
+  eccs {
+    phone_number: "113"
+    types: FIRE
+  }
+  ecc_fallback: "112"
+}
+countries {
+  iso_code: "SZ"
+  eccs {
+    phone_number: "999"
+    types: POLICE
+  }
+  eccs {
+    phone_number: "911"
+    types: AMBULANCE
+  }
+  eccs {
+    phone_number: "933"
+    types: FIRE
+  }
+  ecc_fallback: "112"
+}
+countries {
+  iso_code: "TC"
+  eccs {
+    phone_number: "911"
+    types: POLICE
+    types: AMBULANCE
+    types: FIRE
+  }
+  ecc_fallback: "911"
+}
+countries {
+  iso_code: "TD"
+  eccs {
+    phone_number: "17"
+    types: POLICE
+  }
+  eccs {
+    phone_number: "18"
+    types: FIRE
+  }
+  ecc_fallback: "112"
+}
+countries {
+  iso_code: "TG"
+  eccs {
+    phone_number: "117"
+    types: POLICE
+  }
+  eccs {
+    phone_number: "118"
+    types: FIRE
+  }
+  ecc_fallback: "112"
+}
+countries {
+  iso_code: "TH"
+  eccs {
+    phone_number: "191"
+    types: POLICE
+  }
+  eccs {
+    phone_number: "1669"
+    types: AMBULANCE
+  }
+  eccs {
+    phone_number: "199"
+    types: FIRE
+  }
+  ecc_fallback: "911"
+}
+countries {
+  iso_code: "TJ"
+  eccs {
+    phone_number: "102"
+    types: POLICE
+  }
+  eccs {
+    phone_number: "103"
+    types: AMBULANCE
+  }
+  eccs {
+    phone_number: "101"
+    types: FIRE
+  }
+  ecc_fallback: "112"
+}
+countries {
+  iso_code: "TK"
+  eccs {
+    phone_number: "111"
+    types: POLICE
+    types: AMBULANCE
+    types: FIRE
+  }
+  ecc_fallback: "112"
+}
+countries {
+  iso_code: "TL"
+  eccs {
+    phone_number: "112"
+    types: POLICE
+  }
+  eccs {
+    phone_number: "110"
+    types: AMBULANCE
+  }
+  eccs {
+    phone_number: "3312210"
+    types: FIRE
+  }
+  ecc_fallback: "112"
+}
+countries {
+  iso_code: "TM"
+  eccs {
+    phone_number: "002"
+    types: POLICE
+  }
+  eccs {
+    phone_number: "003"
+    types: AMBULANCE
+  }
+  eccs {
+    phone_number: "001"
+    types: FIRE
+  }
+  ecc_fallback: "112"
+}
+countries {
+  iso_code: "TN"
+  eccs {
+    phone_number: "197"
+    types: POLICE
+  }
+  eccs {
+    phone_number: "190"
+    types: AMBULANCE
+  }
+  eccs {
+    phone_number: "198"
+    types: FIRE
+  }
+  ecc_fallback: "112"
+}
+countries {
+  iso_code: "TO"
+  eccs {
+    phone_number: "922"
+    types: POLICE
+  }
+  eccs {
+    phone_number: "933"
+    types: AMBULANCE
+  }
+  eccs {
+    phone_number: "999"
+    types: FIRE
+  }
+  ecc_fallback: "911"
+}
+countries {
+  iso_code: "TR"
+  eccs {
+    phone_number: "155"
+    types: POLICE
+  }
+  eccs {
+    phone_number: "112"
+    types: AMBULANCE
+  }
+  eccs {
+    phone_number: "110"
+    types: FIRE
+  }
+  ecc_fallback: "112"
+}
+countries {
+  iso_code: "TT"
+  eccs {
+    phone_number: "999"
+    types: POLICE
+  }
+  eccs {
+    phone_number: "990"
+    types: AMBULANCE
+    types: FIRE
+  }
+  ecc_fallback: "112"
+}
+countries {
+  iso_code: "TV"
+  eccs {
+    phone_number: "911"
+    types: POLICE
+    types: AMBULANCE
+    types: FIRE
+  }
+  ecc_fallback: "911"
+}
+countries {
+  iso_code: "TW"
+  eccs {
+    phone_number: "110"
+    types: POLICE
+  }
+  eccs {
+    phone_number: "119"
+    types: AMBULANCE
+    types: FIRE
+  }
+  ecc_fallback: "112"
+}
+countries {
+  iso_code: "TZ"
+  eccs {
+    phone_number: "112"
+    types: POLICE
+    types: AMBULANCE
+    types: FIRE
+  }
+  ecc_fallback: "112"
+}
+countries {
+  iso_code: "UA"
+  eccs {
+    phone_number: "02"
+    types: POLICE
+  }
+  eccs {
+    phone_number: "03"
+    types: AMBULANCE
+  }
+  eccs {
+    phone_number: "01"
+    types: FIRE
+  }
+  ecc_fallback: "112"
+}
+countries {
+  iso_code: "UG"
+  eccs {
+    phone_number: "999"
+    types: POLICE
+    types: AMBULANCE
+    types: FIRE
+  }
+  ecc_fallback: "112"
+}
+countries {
+  iso_code: "US"
+  eccs {
+    phone_number: "911"
+    types: POLICE
+    types: AMBULANCE
+    types: FIRE
+  }
+  ecc_fallback: "911"
+}
+countries {
+  iso_code: "UY"
+  eccs {
+    phone_number: "911"
+    types: POLICE
+    types: AMBULANCE
+    types: FIRE
+  }
+  ecc_fallback: "911"
+}
+countries {
+  iso_code: "UZ"
+  eccs {
+    phone_number: "102"
+    types: POLICE
+  }
+  eccs {
+    phone_number: "103"
+    types: AMBULANCE
+  }
+  eccs {
+    phone_number: "101"
+    types: FIRE
+  }
+  ecc_fallback: "112"
+}
+countries {
+  iso_code: "VA"
+  eccs {
+    phone_number: "113"
+    types: POLICE
+  }
+  eccs {
+    phone_number: "118"
+    types: AMBULANCE
+  }
+  eccs {
+    phone_number: "115"
+    types: FIRE
+  }
+  ecc_fallback: "112"
+}
+countries {
+  iso_code: "VC"
+  eccs {
+    phone_number: "911"
+    types: POLICE
+    types: AMBULANCE
+    types: FIRE
+  }
+  ecc_fallback: "911"
+}
+countries {
+  iso_code: "VE"
+  eccs {
+    phone_number: "911"
+    types: POLICE
+    types: AMBULANCE
+    types: FIRE
+  }
+  ecc_fallback: "911"
+}
+countries {
+  iso_code: "VG"
+  eccs {
+    phone_number: "911"
+    types: POLICE
+    types: AMBULANCE
+    types: FIRE
+  }
+  ecc_fallback: "911"
+}
+countries {
+  iso_code: "VI"
+  eccs {
+    phone_number: "911"
+    types: POLICE
+    types: AMBULANCE
+    types: FIRE
+  }
+  ecc_fallback: "911"
+}
+countries {
+  iso_code: "VN"
+  eccs {
+    phone_number: "113"
+    types: POLICE
+  }
+  eccs {
+    phone_number: "115"
+    types: AMBULANCE
+  }
+  eccs {
+    phone_number: "114"
+    types: FIRE
+  }
+  ecc_fallback: "112"
+}
+countries {
+  iso_code: "VU"
+  eccs {
+    phone_number: "111"
+    types: POLICE
+  }
+  eccs {
+    phone_number: "112"
+    types: AMBULANCE
+  }
+  eccs {
+    phone_number: "113"
+    types: FIRE
+  }
+  ecc_fallback: "112"
+}
+countries {
+  iso_code: "WF"
+  eccs {
+    phone_number: "17"
+    types: POLICE
+  }
+  eccs {
+    phone_number: "15"
+    types: AMBULANCE
+  }
+  eccs {
+    phone_number: "18"
+    types: FIRE
+  }
+  ecc_fallback: "112"
+}
+countries {
+  iso_code: "WS"
+  eccs {
+    phone_number: "911"
+    types: POLICE
+    types: AMBULANCE
+    types: FIRE
+  }
+  ecc_fallback: "911"
+}
+countries {
+  iso_code: "XK"
+  eccs {
+    phone_number: "192"
+    types: POLICE
+  }
+  eccs {
+    phone_number: "194"
+    types: AMBULANCE
+  }
+  eccs {
+    phone_number: "193"
+    types: FIRE
+  }
+  ecc_fallback: "112"
+}
+countries {
+  iso_code: "YE"
+  eccs {
+    phone_number: "199"
+    types: POLICE
+    types: AMBULANCE
+    types: FIRE
+  }
+  ecc_fallback: "112"
+}
+countries {
+  iso_code: "ZA"
+  eccs {
+    phone_number: "112"
+    types: POLICE
+    types: AMBULANCE
+    types: FIRE
+  }
+  ecc_fallback: "112"
+}
+countries {
+  iso_code: "ZM"
+  eccs {
+    phone_number: "991"
+    types: POLICE
+    types: AMBULANCE
+  }
+  eccs {
+    phone_number: "993"
+    types: FIRE
+  }
+  ecc_fallback: "112"
+}
+countries {
+  iso_code: "ZW"
+  eccs {
+    phone_number: "995"
+    types: POLICE
+  }
+  eccs {
+    phone_number: "999"
+    types: AMBULANCE
+  }
+  eccs {
+    phone_number: "993"
+    types: FIRE
+  }
+  ecc_fallback: "112"
+}
diff --git a/ecc/output/eccdata b/ecc/output/eccdata
new file mode 100644
index 0000000..2d0165a
--- /dev/null
+++ b/ecc/output/eccdata
Binary files differ
diff --git a/ecc/proto b/ecc/proto
new file mode 120000
index 0000000..1faef70
--- /dev/null
+++ b/ecc/proto
@@ -0,0 +1 @@
+conversion_toolset_v1/proto/
\ No newline at end of file
diff --git a/res/drawable-hdpi/fab_red.png b/res/drawable-hdpi/fab_red.png
new file mode 100644
index 0000000..ce672f2
--- /dev/null
+++ b/res/drawable-hdpi/fab_red.png
Binary files differ
diff --git a/res/drawable-hdpi/ic_arrow_go_next_18.png b/res/drawable-hdpi/ic_arrow_go_next_18.png
new file mode 100644
index 0000000..37cd6df
--- /dev/null
+++ b/res/drawable-hdpi/ic_arrow_go_next_18.png
Binary files differ
diff --git a/res/drawable-hdpi/ic_dialpad_white_24.png b/res/drawable-hdpi/ic_dialpad_white_24.png
new file mode 100644
index 0000000..9037f94
--- /dev/null
+++ b/res/drawable-hdpi/ic_dialpad_white_24.png
Binary files differ
diff --git a/res/drawable-hdpi/ic_emergency_number_24.png b/res/drawable-hdpi/ic_emergency_number_24.png
new file mode 100644
index 0000000..d5c0b28
--- /dev/null
+++ b/res/drawable-hdpi/ic_emergency_number_24.png
Binary files differ
diff --git a/res/drawable-hdpi/ic_location_on_white_18.png b/res/drawable-hdpi/ic_location_on_white_18.png
new file mode 100644
index 0000000..8f93ec9
--- /dev/null
+++ b/res/drawable-hdpi/ic_location_on_white_18.png
Binary files differ
diff --git a/res/drawable-hdpi/logo_avatar_anonymous_120.png b/res/drawable-hdpi/logo_avatar_anonymous_120.png
new file mode 100644
index 0000000..70d3011
--- /dev/null
+++ b/res/drawable-hdpi/logo_avatar_anonymous_120.png
Binary files differ
diff --git a/res/drawable-ldrtl-hdpi/ic_arrow_go_next_18.png b/res/drawable-ldrtl-hdpi/ic_arrow_go_next_18.png
new file mode 100644
index 0000000..b8cef90
--- /dev/null
+++ b/res/drawable-ldrtl-hdpi/ic_arrow_go_next_18.png
Binary files differ
diff --git a/res/drawable-ldrtl-mdpi/ic_arrow_go_next_18.png b/res/drawable-ldrtl-mdpi/ic_arrow_go_next_18.png
new file mode 100644
index 0000000..fc0a292
--- /dev/null
+++ b/res/drawable-ldrtl-mdpi/ic_arrow_go_next_18.png
Binary files differ
diff --git a/res/drawable-ldrtl-xhdpi/ic_arrow_go_next_18.png b/res/drawable-ldrtl-xhdpi/ic_arrow_go_next_18.png
new file mode 100644
index 0000000..76c1e7f
--- /dev/null
+++ b/res/drawable-ldrtl-xhdpi/ic_arrow_go_next_18.png
Binary files differ
diff --git a/res/drawable-ldrtl-xxhdpi/ic_arrow_go_next_18.png b/res/drawable-ldrtl-xxhdpi/ic_arrow_go_next_18.png
new file mode 100644
index 0000000..5914ace
--- /dev/null
+++ b/res/drawable-ldrtl-xxhdpi/ic_arrow_go_next_18.png
Binary files differ
diff --git a/res/drawable-mdpi/fab_red.png b/res/drawable-mdpi/fab_red.png
new file mode 100644
index 0000000..094a606
--- /dev/null
+++ b/res/drawable-mdpi/fab_red.png
Binary files differ
diff --git a/res/drawable-mdpi/ic_arrow_go_next_18.png b/res/drawable-mdpi/ic_arrow_go_next_18.png
new file mode 100644
index 0000000..d487ae0
--- /dev/null
+++ b/res/drawable-mdpi/ic_arrow_go_next_18.png
Binary files differ
diff --git a/res/drawable-mdpi/ic_dialpad_white_24.png b/res/drawable-mdpi/ic_dialpad_white_24.png
new file mode 100644
index 0000000..6c405f9
--- /dev/null
+++ b/res/drawable-mdpi/ic_dialpad_white_24.png
Binary files differ
diff --git a/res/drawable-mdpi/ic_emergency_number_24.png b/res/drawable-mdpi/ic_emergency_number_24.png
new file mode 100644
index 0000000..3db2d19
--- /dev/null
+++ b/res/drawable-mdpi/ic_emergency_number_24.png
Binary files differ
diff --git a/res/drawable-mdpi/ic_location_on_white_18.png b/res/drawable-mdpi/ic_location_on_white_18.png
new file mode 100644
index 0000000..5c5b0fb
--- /dev/null
+++ b/res/drawable-mdpi/ic_location_on_white_18.png
Binary files differ
diff --git a/res/drawable-mdpi/logo_avatar_anonymous_120.png b/res/drawable-mdpi/logo_avatar_anonymous_120.png
new file mode 100644
index 0000000..60d3c3a
--- /dev/null
+++ b/res/drawable-mdpi/logo_avatar_anonymous_120.png
Binary files differ
diff --git a/res/drawable-xhdpi/fab_red.png b/res/drawable-xhdpi/fab_red.png
new file mode 100644
index 0000000..ab1425e
--- /dev/null
+++ b/res/drawable-xhdpi/fab_red.png
Binary files differ
diff --git a/res/drawable-xhdpi/ic_arrow_go_next_18.png b/res/drawable-xhdpi/ic_arrow_go_next_18.png
new file mode 100644
index 0000000..766a889
--- /dev/null
+++ b/res/drawable-xhdpi/ic_arrow_go_next_18.png
Binary files differ
diff --git a/res/drawable-xhdpi/ic_dialpad_white_24.png b/res/drawable-xhdpi/ic_dialpad_white_24.png
new file mode 100644
index 0000000..0e89f6c
--- /dev/null
+++ b/res/drawable-xhdpi/ic_dialpad_white_24.png
Binary files differ
diff --git a/res/drawable-xhdpi/ic_emergency_number_24.png b/res/drawable-xhdpi/ic_emergency_number_24.png
new file mode 100644
index 0000000..b538c02
--- /dev/null
+++ b/res/drawable-xhdpi/ic_emergency_number_24.png
Binary files differ
diff --git a/res/drawable-xhdpi/ic_location_on_white_18.png b/res/drawable-xhdpi/ic_location_on_white_18.png
new file mode 100644
index 0000000..7c281c3
--- /dev/null
+++ b/res/drawable-xhdpi/ic_location_on_white_18.png
Binary files differ
diff --git a/res/drawable-xhdpi/logo_avatar_anonymous_120.png b/res/drawable-xhdpi/logo_avatar_anonymous_120.png
new file mode 100644
index 0000000..ec99ca6
--- /dev/null
+++ b/res/drawable-xhdpi/logo_avatar_anonymous_120.png
Binary files differ
diff --git a/res/drawable-xxhdpi/fab_red.png b/res/drawable-xxhdpi/fab_red.png
new file mode 100644
index 0000000..899a578
--- /dev/null
+++ b/res/drawable-xxhdpi/fab_red.png
Binary files differ
diff --git a/res/drawable-xxhdpi/ic_arrow_go_next_18.png b/res/drawable-xxhdpi/ic_arrow_go_next_18.png
new file mode 100644
index 0000000..bb4d45e
--- /dev/null
+++ b/res/drawable-xxhdpi/ic_arrow_go_next_18.png
Binary files differ
diff --git a/res/drawable-xxhdpi/ic_dialpad_white_24.png b/res/drawable-xxhdpi/ic_dialpad_white_24.png
new file mode 100644
index 0000000..1750005
--- /dev/null
+++ b/res/drawable-xxhdpi/ic_dialpad_white_24.png
Binary files differ
diff --git a/res/drawable-xxhdpi/ic_emergency_number_24.png b/res/drawable-xxhdpi/ic_emergency_number_24.png
new file mode 100644
index 0000000..13f253b
--- /dev/null
+++ b/res/drawable-xxhdpi/ic_emergency_number_24.png
Binary files differ
diff --git a/res/drawable-xxhdpi/ic_location_on_white_18.png b/res/drawable-xxhdpi/ic_location_on_white_18.png
new file mode 100644
index 0000000..b345cff
--- /dev/null
+++ b/res/drawable-xxhdpi/ic_location_on_white_18.png
Binary files differ
diff --git a/res/drawable-xxhdpi/logo_avatar_anonymous_120.png b/res/drawable-xxhdpi/logo_avatar_anonymous_120.png
new file mode 100644
index 0000000..2b009a3
--- /dev/null
+++ b/res/drawable-xxhdpi/logo_avatar_anonymous_120.png
Binary files differ
diff --git a/res/drawable/btn_emergency_shortcuts.xml b/res/drawable/btn_emergency_shortcuts.xml
new file mode 100644
index 0000000..063a824
--- /dev/null
+++ b/res/drawable/btn_emergency_shortcuts.xml
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2018 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.
+-->
+<shape xmlns:android="http://schemas.android.com/apk/res/android"
+       android:shape="rectangle">
+    <corners android:radius="8dp"/>
+</shape>
\ No newline at end of file
diff --git a/res/drawable/emergency_shortcuts_divider.xml b/res/drawable/emergency_shortcuts_divider.xml
new file mode 100644
index 0000000..988ffc5
--- /dev/null
+++ b/res/drawable/emergency_shortcuts_divider.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2018 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.
+-->
+<shape xmlns:android="http://schemas.android.com/apk/res/android"
+       android:shape="rectangle">
+    <size android:height="1px"/>
+    <solid android:color="#33FFFFFF"/>
+</shape>
diff --git a/res/drawable/floating_action_button_red.xml b/res/drawable/floating_action_button_red.xml
new file mode 100644
index 0000000..5fe74a3
--- /dev/null
+++ b/res/drawable/floating_action_button_red.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+     Copyright (C) 2018 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.
+-->
+<ripple xmlns:android="http://schemas.android.com/apk/res/android"
+        android:color="@color/floating_action_button_touch_tint">
+    <item android:drawable="@drawable/fab_red" />
+</ripple>
\ No newline at end of file
diff --git a/res/drawable/phone_type_icon_background.xml b/res/drawable/phone_type_icon_background.xml
new file mode 100644
index 0000000..b51c3b2
--- /dev/null
+++ b/res/drawable/phone_type_icon_background.xml
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2018 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.
+-->
+<shape xmlns:android="http://schemas.android.com/apk/res/android"
+       android:shape="oval">
+    <solid android:color="@color/emergency_shortcut_confirm_button_background_color"/>
+</shape>
\ No newline at end of file
diff --git a/res/layout/emergency_dialer.xml b/res/layout/emergency_dialer.xml
index 2a45433..cdb9530 100644
--- a/res/layout/emergency_dialer.xml
+++ b/res/layout/emergency_dialer.xml
@@ -16,51 +16,105 @@
 
 <!-- Layout for the emergency dialer; see EmergencyDialer.java. -->
 <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
-        android:id="@+id/top"
+        android:layout_width="match_parent"
+        android:layout_height="match_parent">
+
+    <!-- Emergency dialer shortcuts layout-->
+    <FrameLayout
+        android:id="@+id/emergency_dialer_shortcuts"
+        android:layout_width="match_parent"
+        android:layout_height="match_parent"
+        android:visibility="gone">
+        <LinearLayout
+            android:layout_width="match_parent"
+            android:layout_height="match_parent"
+            android:orientation="vertical">
+            <include layout="@layout/emergency_information"/>
+            <include layout="@layout/emergency_shortcut_buttons_group"/>
+        </LinearLayout>
+
+        <FrameLayout
+            android:id="@+id/dialpad_button_container"
+            android:layout_height="wrap_content"
+            android:layout_width="wrap_content"
+            android:layout_gravity="bottom|end"
+            android:layout_margin="@dimen/emergency_dialer_dialpad_button_margin">
+            <ImageButton
+                android:id="@+id/floating_action_button_dialpad"
+                android:layout_width="@dimen/dialpad_button_width"
+                android:layout_height="@dimen/dialpad_button_height"
+                android:background="@drawable/floating_action_button_red"
+                android:contentDescription="@string/description_dialpad_button"
+                android:src="@drawable/ic_dialpad_white_24"/>
+        </FrameLayout>
+    </FrameLayout>
+
+    <!--Emergency Dialer Layout-->
+    <FrameLayout
+        android:id="@+id/emergency_dialer"
         android:layout_width="match_parent"
         android:layout_height="match_parent"
         android:paddingLeft="36dp"
         android:paddingRight="36dp"
-        android:paddingBottom="@dimen/dialpad_bottom_padding">
-
-    <LinearLayout
+        android:paddingBottom="@dimen/dialpad_bottom_padding"
+        android:visibility="visible">
+        <LinearLayout
             android:layout_width="match_parent"
             android:layout_height="match_parent"
             android:layout_gravity="bottom"
             android:orientation="vertical">
 
-        <!-- FrameLayout -->
-        <com.android.phone.EmergencyActionGroup
+            <!--Emergency dialer shortcuts implement EmergencyInfoGroup to replace
+            EmergencyActionGroup. Using a title to indicate the dialpad is emergency calls only.-->
+            <FrameLayout
+                android:id="@+id/emergency_dialpad_title_container"
+                android:layout_height="64dp"
+                android:layout_width="match_parent"
+                android:layout_marginTop="16dp"
+                android:layout_marginBottom="24dp"
+                android:visibility="gone">
+                <TextView
+                    android:id="@+id/emergency_dialpad_title"
+                    android:layout_height="wrap_content"
+                    android:layout_width="wrap_content"
+                    android:layout_gravity="center"
+                    android:textStyle="bold"
+                    android:maxLines="1"
+                    android:text="@string/emergency_dialpad_title"/>
+            </FrameLayout>
+
+            <!-- FrameLayout -->
+            <com.android.phone.EmergencyActionGroup
                 android:id="@+id/emergency_action_group"
                 android:layout_height="64dp"
                 android:layout_width="match_parent"
                 android:layout_marginTop="16dp"
                 android:layout_marginBottom="24dp">
 
-            <!-- Button that says: Emergency Information -->
-            <LinearLayout
+                <!-- Button that says: Emergency Information -->
+                <LinearLayout
                     android:layout_width="match_parent"
                     android:layout_height="match_parent">
-                <Button android:layout_width="0dp"
-                        android:layout_height="match_parent"
-                        android:layout_weight="1"
-                        android:background="@drawable/btn_emergency"
-                        android:id="@+id/action1" />
-                <Button android:layout_width="0dp"
-                        android:layout_height="match_parent"
-                        android:layout_weight="1"
-                        android:background="@drawable/btn_emergency"
-                        android:id="@+id/action2" />
-                <Button android:layout_width="0dp"
-                        android:layout_height="match_parent"
-                        android:layout_weight="1"
-                        android:background="@drawable/btn_emergency"
-                        android:id="@+id/action3" />
-            </LinearLayout>
+                    <Button android:layout_width="0dp"
+                            android:layout_height="match_parent"
+                            android:layout_weight="1"
+                            android:background="@drawable/btn_emergency"
+                            android:id="@+id/action1" />
+                    <Button android:layout_width="0dp"
+                            android:layout_height="match_parent"
+                            android:layout_weight="1"
+                            android:background="@drawable/btn_emergency"
+                            android:id="@+id/action2" />
+                    <Button android:layout_width="0dp"
+                            android:layout_height="match_parent"
+                            android:layout_weight="1"
+                            android:background="@drawable/btn_emergency"
+                            android:id="@+id/action3" />
+                </LinearLayout>
 
-            <!-- View that shows up on top of "emergency information" button
-            and asks you to tap again to confirm the action -->
-            <FrameLayout
+                <!-- View that shows up on top of "emergency information" button
+                and asks you to tap again to confirm the action -->
+                <FrameLayout
                     android:layout_width="match_parent"
                     android:layout_height="match_parent"
                     android:id="@+id/selected_container"
@@ -68,7 +122,7 @@
                     android:focusable="true"
                     android:clickable="true">
 
-                <View
+                    <View
                         android:layout_width="match_parent"
                         android:layout_height="match_parent"
                         android:backgroundTint="#ffe53935"
@@ -76,7 +130,7 @@
                         android:clickable="false"
                         style="?android:attr/buttonStyle"/>
 
-                <View
+                    <View
                         android:layout_width="match_parent"
                         android:layout_height="match_parent"
                         android:id="@+id/ripple_view"
@@ -86,7 +140,7 @@
                         android:clickable="false"
                         style="?android:attr/buttonStyle"/>
 
-                <LinearLayout
+                    <LinearLayout
                         android:layout_width="match_parent"
                         android:layout_height="match_parent"
                         android:orientation="vertical"
@@ -94,7 +148,7 @@
                         android:clickable="false"
                         android:backgroundTint="#00000000"
                         style="?android:attr/buttonStyle">
-                    <TextView
+                        <TextView
                             android:layout_width="match_parent"
                             android:layout_height="wrap_content"
                             android:gravity="center"
@@ -102,7 +156,7 @@
                             android:id="@+id/selected_label"
                             android:textColor="@android:color/white"
                             android:textAppearance="?android:attr/textAppearanceButton" />
-                    <TextView
+                        <TextView
                             android:layout_width="wrap_content"
                             android:layout_height="wrap_content"
                             android:id="@+id/launch_hint"
@@ -111,37 +165,39 @@
                             android:text="@string/emergency_action_launch_hint"
                             android:textColor="@android:color/white"
                             android:textStyle="italic" />
-                </LinearLayout>
+                    </LinearLayout>
 
-            </FrameLayout>
+                </FrameLayout>
 
-        </com.android.phone.EmergencyActionGroup>
+            </com.android.phone.EmergencyActionGroup>
 
-        <include layout="@layout/dialpad_view_unthemed"
-                android:theme="?attr/dialpadTheme" />
+            <include layout="@layout/dialpad_view_unthemed"
+                     android:theme="?attr/dialpadTheme" />
 
-    </LinearLayout>
+        </LinearLayout>
 
-    <Space
-        android:id="@+id/floating_action_button_margin_bottom"
-        android:layout_width="match_parent"
-        android:layout_height="@dimen/floating_action_button_margin_bottom"
-        android:layout_alignParentBottom="true"/>
+        <Space
+            android:id="@+id/floating_action_button_margin_bottom"
+            android:layout_width="match_parent"
+            android:layout_height="@dimen/floating_action_button_margin_bottom"
+            android:layout_alignParentBottom="true"/>
 
-    <FrameLayout
-        android:id="@+id/floating_action_button_container"
-        android:layout_width="@dimen/floating_action_button_width"
-        android:layout_height="@dimen/floating_action_button_height"
-        android:layout_gravity="center_horizontal|bottom" >
+        <FrameLayout
+            android:id="@+id/floating_action_button_container"
+            android:layout_width="@dimen/floating_action_button_width"
+            android:layout_height="@dimen/floating_action_button_height"
+            android:layout_gravity="center_horizontal|bottom" >
 
-        <ImageButton
-            android:id="@+id/floating_action_button"
-            android:layout_width="wrap_content"
-            android:layout_height="wrap_content"
-            android:layout_gravity="center"
-            android:background="@drawable/floating_action_button"
-            android:contentDescription="@string/description_dial_button"
-            android:src="@drawable/fab_ic_call"/>
+            <ImageButton
+                android:id="@+id/floating_action_button"
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:layout_gravity="center"
+                android:background="@drawable/floating_action_button"
+                android:contentDescription="@string/description_dial_button"
+                android:src="@drawable/fab_ic_call"/>
+        </FrameLayout>
+
     </FrameLayout>
 
 </FrameLayout>
diff --git a/res/layout/emergency_information.xml b/res/layout/emergency_information.xml
new file mode 100644
index 0000000..c4ab74b
--- /dev/null
+++ b/res/layout/emergency_information.xml
@@ -0,0 +1,77 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2018 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.
+-->
+<com.android.phone.EmergencyInfoGroup
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    android:id="@+id/emergency_info_button"
+    android:layout_height="@dimen/emergency_info_button_singleline_height"
+    android:layout_width="match_parent"
+    android:layout_marginTop="@dimen/emergency_info_button_margin_top">
+    <LinearLayout
+        android:layout_height="match_parent"
+        android:layout_width="match_parent"
+        android:layout_marginEnd="56dp"
+        android:orientation="horizontal">
+        <FrameLayout
+            android:id="@+id/emergency_info_image_container"
+            android:layout_height="wrap_content"
+            android:layout_width="wrap_content"
+            android:layout_gravity="center_vertical|start"
+            android:layout_marginHorizontal="@dimen/emergency_dialer_image_margin_horizontal">
+            <ImageView
+                android:id="@+id/emergency_info_image"
+                android:layout_height="@dimen/emergency_info_image_height"
+                android:layout_width="@dimen/emergency_info_image_width"
+                android:scaleType="centerCrop"/>
+        </FrameLayout>
+        <LinearLayout
+            android:layout_height="wrap_content"
+            android:layout_width="match_parent"
+            android:orientation="vertical"
+            android:layout_gravity="center_vertical">
+            <TextView
+                android:id="@+id/emergency_info_name"
+                android:layout_height="wrap_content"
+                android:layout_width="wrap_content"
+                android:includeFontPadding="false"
+                android:maxLines="1"
+                android:ellipsize="end"
+                android:textAppearance="@style/HeadlineTextAppearance"/>
+            <TextView
+                android:id="@+id/emergency_info_hint"
+                android:layout_height="wrap_content"
+                android:layout_width="wrap_content"
+                android:maxLines="2"
+                android:ellipsize="end"
+                android:lineHeight="@dimen/emergency_info_hint_line_height"
+                android:alpha="0.7"
+                android:textAppearance="@style/SubtitleTextAppearance"
+                android:text="@string/emergency_information_hint"/>
+        </LinearLayout>
+    </LinearLayout>
+
+    <FrameLayout
+        android:id="@+id/arrow_go_next_container"
+        android:layout_height="wrap_content"
+        android:layout_width="wrap_content"
+        android:layout_gravity="center_vertical|end"
+        android:layout_marginHorizontal="@dimen/emergency_dialer_image_margin_horizontal">
+        <ImageView
+            android:id="@+id/arrow_go_next"
+            android:layout_height="@dimen/emergency_shortcuts_function_icon_height"
+            android:layout_width="@dimen/emergency_shortcuts_function_icon_width"
+            android:src="@drawable/ic_arrow_go_next_18"/>
+    </FrameLayout>
+</com.android.phone.EmergencyInfoGroup>
diff --git a/res/layout/emergency_shortcut_button.xml b/res/layout/emergency_shortcut_button.xml
new file mode 100644
index 0000000..6087dba
--- /dev/null
+++ b/res/layout/emergency_shortcut_button.xml
@@ -0,0 +1,136 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2018 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.
+-->
+<com.android.phone.EmergencyShortcutButton
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_height="@dimen/emergency_shortcut_button_height"
+    android:layout_width="match_parent">
+    <!-- Normal emergency call button view -->
+    <FrameLayout
+        android:id="@+id/emergency_call_number_info_view"
+        android:layout_height="match_parent"
+        android:layout_width="match_parent"
+        android:background="@color/emergency_shortcut_button_background_color"
+        android:focusable="true"
+        android:clickable="true">
+        <LinearLayout
+            android:layout_height="match_parent"
+            android:layout_width="wrap_content"
+            android:layout_marginEnd="@dimen/emergency_info_image_width"
+            android:layout_gravity="center_vertical|start"
+            android:orientation="horizontal">
+            <FrameLayout
+                android:layout_height="@dimen/phone_number_type_circle_image_height"
+                android:layout_width="@dimen/phone_number_type_circle_image_width"
+                android:layout_gravity="center_vertical"
+                android:layout_marginHorizontal="@dimen/emergency_dialer_image_margin_horizontal"
+                android:background="@drawable/phone_type_icon_background">
+                <ImageView
+                    android:id="@+id/phone_type_icon"
+                    android:layout_width="@dimen/phone_number_type_image_height"
+                    android:layout_height="@dimen/phone_number_type_image_width"
+                    android:layout_gravity="center"/>
+            </FrameLayout>
+            <LinearLayout
+                android:layout_height="wrap_content"
+                android:layout_width="match_parent"
+                android:layout_gravity="center_vertical"
+                android:orientation="vertical">
+                <TextView
+                    android:id="@+id/phone_number"
+                    android:layout_height="wrap_content"
+                    android:layout_width="wrap_content"
+                    android:includeFontPadding="false"
+                    android:maxLines="1"
+                    android:ellipsize="end"
+                    android:textAppearance="@style/HeadlineTextAppearance"/>
+                <TextView
+                    android:id="@+id/phone_number_description"
+                    android:layout_height="wrap_content"
+                    android:layout_width="wrap_content"
+                    android:alpha="0.8"
+                    android:maxLines="1"
+                    android:ellipsize="end"
+                    android:textAppearance="@style/SubtitleTextAppearance"/>
+            </LinearLayout>
+        </LinearLayout>
+        <FrameLayout
+            android:layout_height="wrap_content"
+            android:layout_width="wrap_content"
+            android:layout_marginHorizontal="@dimen/emergency_dialer_image_margin_horizontal"
+            android:layout_gravity="center_vertical|end">
+            <ImageView
+                android:id="@+id/microphone_icon"
+                android:layout_height="@dimen/phone_icon_height"
+                android:layout_width="@dimen/phone_icon_width"
+                android:src="@drawable/ic_emergency_callback_mode"/>
+        </FrameLayout>
+    </FrameLayout>
+
+    <!-- "Tap again to call" view -->
+    <FrameLayout
+        android:id="@+id/emergency_call_confirm_view"
+        android:layout_height="match_parent"
+        android:layout_width="match_parent"
+        android:background="@color/emergency_shortcut_confirm_button_background_color"
+        android:focusable="true"
+        android:clickable="true"
+        android:visibility="invisible">
+        <LinearLayout
+            android:layout_height="match_parent"
+            android:layout_width="wrap_content"
+            android:layout_marginEnd="@dimen/emergency_info_image_width"
+            android:layout_gravity="center_vertical|start"
+            android:gravity="center_vertical"
+            android:orientation="horizontal">
+            <FrameLayout
+                android:layout_height="@dimen/phone_number_type_circle_image_height"
+                android:layout_width="@dimen/phone_number_type_circle_image_width"
+                android:layout_marginHorizontal="@dimen/emergency_dialer_image_margin_horizontal"
+                android:background="@drawable/phone_type_icon_background"
+                android:backgroundTint="@android:color/white">
+                <ImageView
+                    android:id="@+id/confirmed_phone_type_icon"
+                    android:layout_width="@dimen/phone_number_type_image_height"
+                    android:layout_height="@dimen/phone_number_type_image_width"
+                    android:layout_gravity="center"
+                    android:tint="@color/emergency_shortcut_confirm_button_background_color"/>
+            </FrameLayout>
+            <FrameLayout
+                android:layout_height="wrap_content"
+                android:layout_width="match_parent"
+                android:gravity="center_vertical">
+                <TextView
+                    android:id="@+id/phone_call_hint"
+                    android:layout_height="wrap_content"
+                    android:layout_width="wrap_content"
+                    android:maxLines="2"
+                    android:ellipsize="end"
+                    android:lineHeight="@dimen/phone_call_hint_line_height"
+                    android:textAppearance="@style/ShortcutsHintTextAppearance"/>
+            </FrameLayout>
+        </LinearLayout>
+        <FrameLayout
+            android:layout_height="wrap_content"
+            android:layout_width="wrap_content"
+            android:layout_marginHorizontal="@dimen/emergency_dialer_image_margin_horizontal"
+            android:layout_gravity="center_vertical|end">
+            <ImageView
+                android:layout_height="@dimen/phone_icon_height"
+                android:layout_width="@dimen/phone_icon_width"
+                android:src="@drawable/ic_emergency_callback_mode"/>
+        </FrameLayout>
+    </FrameLayout>
+</com.android.phone.EmergencyShortcutButton>
\ No newline at end of file
diff --git a/res/layout/emergency_shortcut_buttons_group.xml b/res/layout/emergency_shortcut_buttons_group.xml
new file mode 100644
index 0000000..619eac6
--- /dev/null
+++ b/res/layout/emergency_shortcut_buttons_group.xml
@@ -0,0 +1,77 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2018 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.
+-->
+<LinearLayout
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    android:id="@+id/emergency_shortcut_buttons_group"
+    android:layout_height="wrap_content"
+    android:layout_width="match_parent"
+    android:layout_marginTop="@dimen/emergency_shortcuts_group_margin_top"
+    android:orientation="vertical">
+    <FrameLayout
+        android:id="@+id/emergency_number_title_group"
+        android:layout_height="@dimen/emergency_number_title_height"
+        android:layout_width="match_parent"
+        android:paddingHorizontal="@dimen/emergency_number_title_group_padding_horizontal">
+        <FrameLayout
+            android:id="@+id/emergency_number_title_container"
+            android:layout_height="wrap_content"
+            android:layout_width="@dimen/emergency_number_title_container_width"
+            android:layout_gravity="center_vertical|start">
+            <TextView
+                android:id="@+id/emergency_number_title"
+                android:layout_height="wrap_content"
+                android:layout_width="wrap_content"
+                android:layout_gravity="start"
+                android:maxLines="1"
+                android:ellipsize="end"
+                android:textAppearance="@style/SubtitleTextAppearance"
+                android:text="@string/single_emergency_number_title"/>
+        </FrameLayout>
+        <LinearLayout
+            android:id="@+id/location_info"
+            android:layout_height="wrap_content"
+            android:layout_width="wrap_content"
+            android:layout_marginStart="@dimen/emergency_number_title_container_width"
+            android:layout_gravity="center_vertical|end"
+            android:gravity="center_vertical"
+            android:orientation="horizontal"
+            android:alpha="0.7">
+            <ImageView
+                android:id="@+id/location_icon"
+                android:layout_width="@dimen/location_image_width"
+                android:layout_height="@dimen/location_image_height"
+                android:src="@drawable/ic_location_on_white_18"/>
+            <TextView
+                android:id="@+id/location_text"
+                android:layout_height="wrap_content"
+                android:layout_width="wrap_content"
+                android:paddingStart="4dp"
+                android:maxLines="1"
+                android:ellipsize="end"
+                android:textAppearance="@style/SubtitleTextAppearance"/>
+        </LinearLayout>
+    </FrameLayout>
+    <LinearLayout
+        android:id="@+id/emergency_shortcut_buttons_container"
+        android:layout_height="wrap_content"
+        android:layout_width="match_parent"
+        android:layout_marginHorizontal="@dimen/emergency_shortcut_buttons_margin_horizontal"
+        android:orientation="vertical"
+        android:divider="@drawable/emergency_shortcuts_divider"
+        android:showDividers="middle"
+        android:background="@drawable/btn_emergency_shortcuts">
+    </LinearLayout>
+</LinearLayout>
\ No newline at end of file
diff --git a/res/values/colors.xml b/res/values/colors.xml
index 870d692..7136819 100644
--- a/res/values/colors.xml
+++ b/res/values/colors.xml
@@ -54,4 +54,6 @@
 
     <color name="dialer_dialpad_touch_tint">#330288d1</color>
     <color name="floating_action_button_touch_tint">#80ffffff</color>
+    <color name="emergency_shortcut_button_background_color">#1FFFFFFF</color>
+    <color name="emergency_shortcut_confirm_button_background_color">#E25142</color>
 </resources>
diff --git a/res/values/dimens.xml b/res/values/dimens.xml
index 42f9563..97417bd 100644
--- a/res/values/dimens.xml
+++ b/res/values/dimens.xml
@@ -113,4 +113,66 @@
 
     <!-- The size of the "emergency calling unavailable" message shown in the emergency dialer -->
     <dimen name="emergency_call_warning_size">16sp</dimen>
+
+    <!-- Horizontal margin for the image on emergency dialer.-->
+    <dimen name="emergency_dialer_image_margin_horizontal">16dp</dimen>
+
+    <!-- Margin of dialpad button -->
+    <dimen name="emergency_dialer_dialpad_button_margin">16dp</dimen>
+
+    <!-- Horizontal margin for button of emergency shortcut. -->
+    <dimen name="emergency_shortcut_buttons_margin_horizontal">16dp</dimen>
+
+    <!-- Margin top of emergency shortcuts group -->
+    <dimen name="emergency_shortcuts_group_margin_top">48dp</dimen>
+
+    <!-- Horizontal padding for group of emergency number title-->
+    <dimen name="emergency_number_title_group_padding_horizontal">16dp</dimen>
+
+    <!-- Height and top margin for the emergency information button. -->
+    <dimen name="emergency_info_button_singleline_height">72dp</dimen>
+    <dimen name="emergency_info_button_margin_top">56dp</dimen>
+    <dimen name="emergency_info_button_multiline_height">90dp</dimen>
+
+    <!-- The height and width for the image of emergency information. -->
+    <dimen name="emergency_info_image_height">56dp</dimen>
+    <dimen name="emergency_info_image_width">56dp</dimen>
+
+    <!-- The height and width for the function icon of emergency shortcuts. -->
+    <dimen name="emergency_shortcuts_function_icon_height">24dp</dimen>
+    <dimen name="emergency_shortcuts_function_icon_width">24dp</dimen>
+
+    <!-- The height and width for the dialpad button -->
+    <dimen name="dialpad_button_height">56dp</dimen>
+    <dimen name="dialpad_button_width">56dp</dimen>
+
+    <!-- The height for title of emergency number and location info. -->
+    <dimen name="emergency_number_title_height">48dp</dimen>
+
+    <!-- The height and width for the image of location info.-->
+    <dimen name="location_image_height">15dp</dimen>
+    <dimen name="location_image_width">15dp</dimen>
+
+    <!-- The height for button of emergency shortcut. -->
+    <dimen name="emergency_shortcut_button_height">80dp</dimen>
+
+    <!-- The height and width for the circle image of phone number type.-->
+    <dimen name="phone_number_type_circle_image_height">40dp</dimen>
+    <dimen name="phone_number_type_circle_image_width">40dp</dimen>
+
+    <!-- The height and width for the image of phone number type.-->
+    <dimen name="phone_number_type_image_height">24dp</dimen>
+    <dimen name="phone_number_type_image_width">24dp</dimen>
+
+    <!-- The height and width of phone icon.-->
+    <dimen name="phone_icon_height">24dp</dimen>
+    <dimen name="phone_icon_width">24dp</dimen>
+
+    <!-- The line height for emergency info hint and phone call hint.-->
+    <dimen name="emergency_info_hint_line_height">17dp</dimen>
+    <dimen name="phone_call_hint_line_height">20dp</dimen>
+
+    <!-- The width for emergency number title container.-->
+    <dimen name="emergency_number_title_container_width">210dp</dimen>
+
 </resources>
diff --git a/res/values/strings.xml b/res/values/strings.xml
index 8f192ae..b60d85f 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -1122,8 +1122,20 @@
     <!-- In-call screen: call failure message displayed in an error dialog when the user is connected to a wireless network, but wifi calling is turned off. [CHAR_LIMIT=NONE] -->
     <string name="incall_error_promote_wfc">Enable Wi-Fi calling to make a call.</string>
 
+    <!-- Hint for the button of emergency information -->
+    <string name="emergency_information_hint">Emergency information</string>
+    <!-- Hint for the owner of emergency information -->
+    <string name="emergency_information_owner_hint">Owner</string>
     <!-- Dialog title for the "radio enable" UI for emergency calls -->
     <string name="emergency_enable_radio_dialog_title">Emergency call</string>
+    <!-- Title for the emergency dialpad UI -->
+    <string name="emergency_dialpad_title">Emergency calls only</string>
+    <!-- Emergency dialer: Title of single emergency shortcut button -->
+    <string name="single_emergency_number_title">Emergency number</string>
+    <!-- Emergency dialer: Title of numerous emergency shortcut buttons -->
+    <string name="numerous_emergency_numbers_title">Emergency numbers</string>
+    <!-- Emergency dialer: Hint of selected emergency shortcut button -->
+    <string name="emergency_call_shortcut_hint">Tap again to call <xliff:g id="emergency_number">%s</xliff:g></string>
     <!-- Status message for the "radio enable" UI for emergency calls -->
     <string name="emergency_enable_radio_dialog_message">Turning on radio\u2026</string>
     <!-- Status message for the "radio enable" UI for emergency calls -->
@@ -1367,6 +1379,13 @@
     -->
     <string name="description_dial_button">dial</string>
 
+    <!-- String describing the Dialpad ImageButton
+
+         Used by AccessibilityService to announce the purpose of the button.
+         [CHAR LIMIT=NONE]
+    -->
+    <string name="description_dialpad_button">show dialpad</string>
+
     <!-- Visual voicemail on/off title [CHAR LIMIT=40] -->
     <string name="voicemail_visual_voicemail_switch_title">Visual Voicemail</string>
 
diff --git a/res/values/styles.xml b/res/values/styles.xml
index d003aec..73b5c40 100644
--- a/res/values/styles.xml
+++ b/res/values/styles.xml
@@ -313,4 +313,17 @@
     <style name="CallSettingsWithoutDividerTheme" parent="SettingsLight">
         <item name="android:listDivider">@null</item>
     </style>
+
+    <style name="HeadlineTextAppearance">
+        <item name="android:textColor">@android:color/white</item>
+        <item name="android:textSize">24sp</item>
+    </style>
+
+    <style name="SubtitleTextAppearance" parent="@style/HeadlineTextAppearance">
+        <item name="android:textSize">14sp</item>
+    </style>
+
+    <style name="ShortcutsHintTextAppearance" parent="@style/HeadlineTextAppearance">
+        <item name="android:textSize">16sp</item>
+    </style>
 </resources>
diff --git a/src/com/android/phone/EmergencyActionGroup.java b/src/com/android/phone/EmergencyActionGroup.java
index b647623..d72c265 100644
--- a/src/com/android/phone/EmergencyActionGroup.java
+++ b/src/com/android/phone/EmergencyActionGroup.java
@@ -22,11 +22,7 @@
 import android.content.ComponentName;
 import android.content.Context;
 import android.content.Intent;
-import android.content.pm.ApplicationInfo;
-import android.content.pm.PackageInfo;
-import android.content.pm.PackageManager;
 import android.content.pm.ResolveInfo;
-import android.provider.Settings;
 import android.telephony.TelephonyManager;
 import android.text.Layout;
 import android.text.TextUtils;
@@ -125,15 +121,13 @@
         mPendingTouchEvent = null;
     }
 
-
-
     private void setupAssistActions() {
         int[] buttonIds = new int[] {R.id.action1, R.id.action2, R.id.action3};
 
         List<ResolveInfo> infos;
 
         if (TelephonyManager.EMERGENCY_ASSISTANCE_ENABLED) {
-            infos = resolveAssistPackageAndQueryActivites();
+            infos = EmergencyAssistanceHelper.resolveAssistPackageAndQueryActivities(getContext());
         } else {
             infos = null;
         }
@@ -146,7 +140,7 @@
 
             if (infos != null && infos.size() > i && infos.get(i) != null) {
                 ResolveInfo info = infos.get(i);
-                ComponentName name = getComponentName(info);
+                ComponentName name = EmergencyAssistanceHelper.getComponentName(info);
 
                 button.setTag(R.id.tag_intent,
                         new Intent(TelephonyManager.ACTION_EMERGENCY_ASSISTANCE)
@@ -159,69 +153,6 @@
         }
     }
 
-    private List<ResolveInfo> resolveAssistPackageAndQueryActivites() {
-        List<ResolveInfo> infos = queryAssistActivities();
-
-        if (infos == null || infos.isEmpty()) {
-            PackageManager packageManager = getContext().getPackageManager();
-            Intent queryIntent = new Intent(TelephonyManager.ACTION_EMERGENCY_ASSISTANCE);
-            infos = packageManager.queryIntentActivities(queryIntent, 0);
-
-            PackageInfo bestMatch = null;
-            for (int i = 0; i < infos.size(); i++) {
-                if (infos.get(i).activityInfo == null) continue;
-                String packageName = infos.get(i).activityInfo.packageName;
-                PackageInfo packageInfo;
-                try {
-                    packageInfo = packageManager.getPackageInfo(packageName, 0);
-                } catch (PackageManager.NameNotFoundException e) {
-                    continue;
-                }
-                // Get earliest installed system app.
-                if (isSystemApp(packageInfo) && (bestMatch == null ||
-                        bestMatch.firstInstallTime > packageInfo.firstInstallTime)) {
-                    bestMatch = packageInfo;
-                }
-            }
-
-            if (bestMatch != null) {
-                Settings.Secure.putString(getContext().getContentResolver(),
-                        Settings.Secure.EMERGENCY_ASSISTANCE_APPLICATION,
-                        bestMatch.packageName);
-                return queryAssistActivities();
-            } else {
-                return null;
-            }
-        } else {
-            return infos;
-        }
-    }
-
-    private List<ResolveInfo> queryAssistActivities() {
-        String assistPackage = Settings.Secure.getString(
-                getContext().getContentResolver(),
-                Settings.Secure.EMERGENCY_ASSISTANCE_APPLICATION);
-        List<ResolveInfo> infos = null;
-
-        if (!TextUtils.isEmpty(assistPackage)) {
-            Intent queryIntent = new Intent(TelephonyManager.ACTION_EMERGENCY_ASSISTANCE)
-                    .setPackage(assistPackage);
-            infos = getContext().getPackageManager().queryIntentActivities(queryIntent, 0);
-        }
-        return infos;
-    }
-
-    private boolean isSystemApp(PackageInfo info) {
-        return info.applicationInfo != null
-                && (info.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0;
-    }
-
-    private ComponentName getComponentName(ResolveInfo resolveInfo) {
-        if (resolveInfo == null || resolveInfo.activityInfo == null) return null;
-        return new ComponentName(resolveInfo.activityInfo.packageName,
-                resolveInfo.activityInfo.name);
-    }
-
     @Override
     public void onClick(View v) {
         Intent intent = (Intent) v.getTag(R.id.tag_intent);
@@ -405,6 +336,4 @@
             startRipple();
         }
     };
-
-
 }
diff --git a/src/com/android/phone/EmergencyAssistanceHelper.java b/src/com/android/phone/EmergencyAssistanceHelper.java
new file mode 100644
index 0000000..3053125
--- /dev/null
+++ b/src/com/android/phone/EmergencyAssistanceHelper.java
@@ -0,0 +1,107 @@
+/*
+ * Copyright (C) 2018 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.phone;
+
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.Intent;
+import android.content.pm.ApplicationInfo;
+import android.content.pm.PackageInfo;
+import android.content.pm.PackageManager;
+import android.content.pm.ResolveInfo;
+import android.provider.Settings;
+import android.telephony.TelephonyManager;
+import android.text.TextUtils;
+
+import java.util.List;
+
+/**
+ * A helper to query activities of emergency assistance.
+ */
+public class EmergencyAssistanceHelper {
+
+    /**
+     * Query activities of emergency assistance.
+     *
+     * @param context The context of the application.
+     * @return A list of {@link ResolveInfo} which is queried from default assistance package,
+     * or null if there is no installed system application of emergency assistance.
+     */
+    public static List<ResolveInfo> resolveAssistPackageAndQueryActivities(Context context) {
+        List<ResolveInfo> infos = queryAssistActivities(context);
+
+        if (infos == null || infos.isEmpty()) {
+            PackageManager packageManager = context.getPackageManager();
+            Intent queryIntent = new Intent(TelephonyManager.ACTION_EMERGENCY_ASSISTANCE);
+            infos = packageManager.queryIntentActivities(queryIntent, 0);
+
+            PackageInfo bestMatch = null;
+            for (int i = 0; i < infos.size(); i++) {
+                if (infos.get(i).activityInfo == null) continue;
+                String packageName = infos.get(i).activityInfo.packageName;
+                PackageInfo packageInfo;
+                try {
+                    packageInfo = packageManager.getPackageInfo(packageName, 0);
+                } catch (PackageManager.NameNotFoundException e) {
+                    continue;
+                }
+                // Get earliest installed system app.
+                if (isSystemApp(packageInfo) && (bestMatch == null
+                        || bestMatch.firstInstallTime > packageInfo.firstInstallTime)) {
+                    bestMatch = packageInfo;
+                }
+            }
+
+            if (bestMatch != null) {
+                Settings.Secure.putString(context.getContentResolver(),
+                        Settings.Secure.EMERGENCY_ASSISTANCE_APPLICATION, bestMatch.packageName);
+                return queryAssistActivities(context);
+            } else {
+                return null;
+            }
+        } else {
+            return infos;
+        }
+    }
+
+    /**
+     * Compose {@link ComponentName} from {@link ResolveInfo}.
+     */
+    public static ComponentName getComponentName(ResolveInfo resolveInfo) {
+        if (resolveInfo == null || resolveInfo.activityInfo == null) return null;
+        return new ComponentName(resolveInfo.activityInfo.packageName,
+                resolveInfo.activityInfo.name);
+    }
+
+    private static List<ResolveInfo> queryAssistActivities(Context context) {
+        final String assistPackage = Settings.Secure.getString(context.getContentResolver(),
+                Settings.Secure.EMERGENCY_ASSISTANCE_APPLICATION);
+        List<ResolveInfo> infos = null;
+
+        if (!TextUtils.isEmpty(assistPackage)) {
+            Intent queryIntent = new Intent(TelephonyManager.ACTION_EMERGENCY_ASSISTANCE)
+                    .setPackage(assistPackage);
+            infos = context.getPackageManager().queryIntentActivities(queryIntent, 0);
+        }
+        return infos;
+    }
+
+    private static boolean isSystemApp(PackageInfo info) {
+        return info.applicationInfo != null
+                && (info.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0;
+    }
+}
diff --git a/src/com/android/phone/EmergencyDialer.java b/src/com/android/phone/EmergencyDialer.java
index 157cf1d..fc4ef6a 100644
--- a/src/com/android/phone/EmergencyDialer.java
+++ b/src/com/android/phone/EmergencyDialer.java
@@ -18,6 +18,8 @@
 
 import static android.telephony.ServiceState.RIL_RADIO_TECHNOLOGY_UNKNOWN;
 
+import android.animation.Animator;
+import android.animation.AnimatorListenerAdapter;
 import android.app.Activity;
 import android.app.AlertDialog;
 import android.app.Dialog;
@@ -26,6 +28,7 @@
 import android.content.Context;
 import android.content.Intent;
 import android.content.IntentFilter;
+import android.graphics.Color;
 import android.graphics.Point;
 import android.media.AudioManager;
 import android.media.ToneGenerator;
@@ -38,6 +41,7 @@
 import android.telecom.TelecomManager;
 import android.telephony.CarrierConfigManager;
 import android.telephony.PhoneNumberUtils;
+import android.telephony.Rlog;
 import android.telephony.ServiceState;
 import android.telephony.SubscriptionManager;
 import android.telephony.TelephonyManager;
@@ -56,7 +60,9 @@
 import android.view.MenuItem;
 import android.view.MotionEvent;
 import android.view.View;
+import android.view.ViewGroup;
 import android.view.WindowManager;
+import android.widget.TextView;
 
 import com.android.internal.colorextraction.ColorExtractor;
 import com.android.internal.colorextraction.ColorExtractor.GradientColors;
@@ -65,6 +71,9 @@
 import com.android.phone.common.util.ViewUtil;
 import com.android.phone.common.widget.ResizingTextEditText;
 
+import java.util.ArrayList;
+import java.util.List;
+
 /**
  * EmergencyDialer is a special dialer that is used ONLY for dialing emergency calls.
  *
@@ -81,10 +90,17 @@
  * moved into a shared base class that would live in the framework?
  * Or could we figure out some way to move *this* class into apps/Contacts
  * also?
+ *
+ * TODO: Implement emergency dialer shortcut.
+ *  Emergency dialer shortcut offer a local emergency number list. Directly clicking a call button
+ *  to place an emergency phone call without entering numbers from dialpad.
+ *  TODO item:
+ *     1.integrate emergency phone number table.
  */
 public class EmergencyDialer extends Activity implements View.OnClickListener,
         View.OnLongClickListener, View.OnKeyListener, TextWatcher,
-        DialpadKeyButton.OnPressedListener, ColorExtractor.OnColorsChangedListener {
+        DialpadKeyButton.OnPressedListener, ColorExtractor.OnColorsChangedListener,
+        EmergencyShortcutButton.OnConfirmClickListener {
     // Keys used with onSaveInstanceState().
     private static final String LAST_NUMBER = "lastNumber";
 
@@ -116,9 +132,16 @@
     /** 90% opacity, different from other gradients **/
     private static final int BACKGROUND_GRADIENT_ALPHA = 230;
 
+    /** 85% opacity for black background **/
+    private static final int BLACK_BACKGROUND_GRADIENT_ALPHA = 217;
+
     ResizingTextEditText mDigits;
     private View mDialButton;
     private View mDelete;
+    private View mEmergencyShortcutView;
+    private View mDialpadView;
+
+    private List<EmergencyShortcutButton> mEmergencyShortcutButtonList;
 
     private ToneGenerator mToneGenerator;
     private Object mToneGeneratorLock = new Object();
@@ -148,6 +171,8 @@
     private boolean mIsWfcEmergencyCallingWarningEnabled;
     private float mDefaultDigitsTextSize;
 
+    private boolean mAreEmergencyDialerShortcutsEnabled;
+
     @Override
     public void beforeTextChanged(CharSequence s, int start, int count, int after) {
         // Do nothing
@@ -187,10 +212,20 @@
         // Allow turning screen on
         setTurnScreenOn(true);
 
+        mAreEmergencyDialerShortcutsEnabled = Settings.Global.getInt(getContentResolver(),
+                Settings.Global.FASTER_EMERGENCY_PHONE_CALL_ENABLED, 0) != 0;
+
         mColorExtractor = new ColorExtractor(this);
-        GradientColors lockScreenColors = mColorExtractor.getColors(WallpaperManager.FLAG_LOCK,
-                ColorExtractor.TYPE_EXTRA_DARK);
-        updateTheme(lockScreenColors.supportsDarkText());
+
+        // It does not support dark text theme, when emergency dialer shortcuts are enabled.
+        // And the background color is black with 85% opacity.
+        if (mAreEmergencyDialerShortcutsEnabled) {
+            updateTheme(false);
+        } else {
+            GradientColors lockScreenColors = mColorExtractor.getColors(WallpaperManager.FLAG_LOCK,
+                    ColorExtractor.TYPE_EXTRA_DARK);
+            updateTheme(lockScreenColors.supportsDarkText());
+        }
 
         setContentView(R.layout.emergency_dialer);
 
@@ -208,7 +243,8 @@
         ((WindowManager) getSystemService(Context.WINDOW_SERVICE))
                 .getDefaultDisplay().getSize(displaySize);
         mBackgroundGradient.setScreenSize(displaySize.x, displaySize.y);
-        mBackgroundGradient.setAlpha(BACKGROUND_GRADIENT_ALPHA);
+        mBackgroundGradient.setAlpha(mAreEmergencyDialerShortcutsEnabled
+                ? BLACK_BACKGROUND_GRADIENT_ALPHA : BACKGROUND_GRADIENT_ALPHA);
         getWindow().setBackgroundDrawable(mBackgroundGradient);
 
         // Check for the presence of the keypad
@@ -273,6 +309,10 @@
         registerReceiver(mBroadcastReceiver, intentFilter);
 
         mEmergencyActionGroup = (EmergencyActionGroup) findViewById(R.id.emergency_action_group);
+
+        if (mAreEmergencyDialerShortcutsEnabled) {
+            setupEmergencyShortcutsView();
+        }
     }
 
     @Override
@@ -328,6 +368,19 @@
         view.setOnLongClickListener(this);
     }
 
+    @Override
+    public void onBackPressed() {
+        // If emergency dialer shortcut is enabled and Dialpad view is visible, pressing the
+        // back key will back to display EmergencyShortcutView view.
+        // Otherwise, it would finish the activity.
+        if (mAreEmergencyDialerShortcutsEnabled && mDialpadView != null
+                && mDialpadView.getVisibility() == View.VISIBLE) {
+            switchView(mEmergencyShortcutView, mDialpadView, true);
+            return;
+        }
+        super.onBackPressed();
+    }
+
     /**
      * handle key events
      */
@@ -375,13 +428,28 @@
 
     @Override
     public boolean dispatchTouchEvent(MotionEvent ev) {
-        mEmergencyActionGroup.onPreTouchEvent(ev);
+        onPreTouchEvent(ev);
         boolean handled = super.dispatchTouchEvent(ev);
-        mEmergencyActionGroup.onPostTouchEvent(ev);
+        onPostTouchEvent(ev);
         return handled;
     }
 
     @Override
+    public void onConfirmClick(EmergencyShortcutButton button) {
+        if (button == null) return;
+
+        String phoneNumber = button.getPhoneNumber();
+
+        if (!TextUtils.isEmpty(phoneNumber)) {
+            if (DBG) Log.d(LOG_TAG, "dial emergency number: " + Rlog.pii(LOG_TAG, phoneNumber));
+            TelecomManager tm = (TelecomManager) getSystemService(TELECOM_SERVICE);
+            tm.placeCall(Uri.fromParts(PhoneAccount.SCHEME_TEL, phoneNumber, null), null);
+        } else {
+            Log.d(LOG_TAG, "emergency number is empty");
+        }
+    }
+
+    @Override
     public void onClick(View view) {
         switch (view.getId()) {
             case R.id.deleteButton: {
@@ -399,6 +467,18 @@
                 }
                 return;
             }
+            case R.id.floating_action_button_dialpad: {
+                mDigits.getText().clear();
+                switchView(mDialpadView, mEmergencyShortcutView, true);
+                return;
+            }
+            case R.id.emergency_info_button: {
+                Intent intent = (Intent) view.getTag(R.id.tag_intent);
+                if (intent != null) {
+                    startActivity(intent);
+                }
+                return;
+            }
         }
     }
 
@@ -494,13 +574,19 @@
     @Override
     protected void onStart() {
         super.onStart();
-
-        mColorExtractor.addOnColorsChangedListener(this);
-        GradientColors lockScreenColors = mColorExtractor.getColors(WallpaperManager.FLAG_LOCK,
-                ColorExtractor.TYPE_EXTRA_DARK);
-        // Do not animate when view isn't visible yet, just set an initial state.
-        mBackgroundGradient.setColors(lockScreenColors, false);
-        updateTheme(lockScreenColors.supportsDarkText());
+        // It does not support dark text theme, when emergency dialer shortcuts are enabled.
+        // And set background color to black.
+        if (mAreEmergencyDialerShortcutsEnabled) {
+            mBackgroundGradient.setColors(Color.BLACK, Color.BLACK, false);
+            updateTheme(false);
+        } else {
+            mColorExtractor.addOnColorsChangedListener(this);
+            GradientColors lockScreenColors = mColorExtractor.getColors(WallpaperManager.FLAG_LOCK,
+                    ColorExtractor.TYPE_EXTRA_DARK);
+            // Do not animate when view isn't visible yet, just set an initial state.
+            mBackgroundGradient.setColors(lockScreenColors, false);
+            updateTheme(lockScreenColors.supportsDarkText());
+        }
     }
 
     @Override
@@ -536,7 +622,6 @@
     @Override
     protected void onStop() {
         super.onStop();
-
         mColorExtractor.removeOnColorsChangedListener(this);
     }
 
@@ -792,4 +877,150 @@
             Log.i(LOG_TAG, "hint - setting to " + mDigits.getScaledTextSize());
         }
     }
+
+    private void setupEmergencyShortcutsView() {
+        mEmergencyShortcutView = findViewById(R.id.emergency_dialer_shortcuts);
+        mDialpadView = findViewById(R.id.emergency_dialer);
+
+        final View dialpadButton = findViewById(R.id.floating_action_button_dialpad);
+        dialpadButton.setOnClickListener(this);
+
+        final View emergencyInfoButton = findViewById(R.id.emergency_info_button);
+        emergencyInfoButton.setOnClickListener(this);
+
+        // EmergencyActionGroup is replaced by EmergencyInfoGroup.
+        mEmergencyActionGroup.setVisibility(View.GONE);
+
+        // Setup dialpad title.
+        final View emergencyDialpadTitle = findViewById(R.id.emergency_dialpad_title_container);
+        emergencyDialpadTitle.setVisibility(View.VISIBLE);
+
+        // TODO: Integrating emergency phone number table will get location information.
+        // Using null to present no location status.
+        setLocationInfo(null);
+
+        mEmergencyShortcutButtonList = new ArrayList<>();
+        setupEmergencyCallShortcutButton();
+
+        switchView(mEmergencyShortcutView, mDialpadView, false);
+    }
+
+    private void setLocationInfo(String country) {
+        final View locationInfo = findViewById(R.id.location_info);
+
+        if (TextUtils.isEmpty(country)) {
+            locationInfo.setVisibility(View.INVISIBLE);
+        } else {
+            final TextView location = (TextView) locationInfo.findViewById(R.id.location_text);
+            location.setText(country);
+            locationInfo.setVisibility(View.VISIBLE);
+        }
+    }
+
+    // TODO: Integrate emergency phone number table.
+    // Using default layout(no location, phone number is 112, description is Emergency,
+    // and icon is cross shape) until integrating emergency phone number table.
+    private void setupEmergencyCallShortcutButton() {
+        final ViewGroup shortcutButtonContainer = findViewById(
+                R.id.emergency_shortcut_buttons_container);
+        shortcutButtonContainer.setClipToOutline(true);
+
+        final EmergencyShortcutButton button =
+                (EmergencyShortcutButton) getLayoutInflater().inflate(
+                        R.layout.emergency_shortcut_button,
+                        shortcutButtonContainer, false);
+
+        button.setPhoneNumber("112");
+        button.setPhoneDescription("Emergency");
+        button.setPhoneTypeIcon(R.drawable.ic_emergency_number_24);
+        button.setOnConfirmClickListener(this);
+
+        shortcutButtonContainer.addView(button);
+        mEmergencyShortcutButtonList.add(button);
+
+        //Set emergency number title for numerous buttons.
+        if (shortcutButtonContainer.getChildCount() > 1) {
+            final TextView emergencyNumberTitle = findViewById(R.id.emergency_number_title);
+            emergencyNumberTitle.setText(getString(R.string.numerous_emergency_numbers_title));
+        }
+    }
+
+    /**
+     * Called by the activity before a touch event is dispatched to the view hierarchy.
+     */
+    private void onPreTouchEvent(MotionEvent event) {
+        mEmergencyActionGroup.onPreTouchEvent(event);
+
+        if (mEmergencyShortcutButtonList != null) {
+            for (EmergencyShortcutButton button : mEmergencyShortcutButtonList) {
+                button.onPreTouchEvent(event);
+            }
+        }
+    }
+
+    /**
+     * Called by the activity after a touch event is dispatched to the view hierarchy.
+     */
+    private void onPostTouchEvent(MotionEvent event) {
+        mEmergencyActionGroup.onPostTouchEvent(event);
+
+        if (mEmergencyShortcutButtonList != null) {
+            for (EmergencyShortcutButton button : mEmergencyShortcutButtonList) {
+                button.onPostTouchEvent(event);
+            }
+        }
+    }
+
+    /**
+     * Switch two view.
+     *
+     * @param displayView the view would be displayed.
+     * @param hideView the view would be hidden.
+     * @param hasAnimation is {@code true} when the view should be displayed with animation.
+     */
+    private void switchView(View displayView, View hideView, boolean hasAnimation) {
+        if (displayView == null || hideView == null) {
+            return;
+        }
+
+        if (displayView.getVisibility() == View.VISIBLE) {
+            return;
+        }
+
+        if (hasAnimation) {
+            crossfade(hideView, displayView);
+        } else {
+            hideView.setVisibility(View.GONE);
+            displayView.setVisibility(View.VISIBLE);
+        }
+    }
+
+    /**
+     * Fade out and fade in animation between two view transition.
+     */
+    private void crossfade(View fadeOutView, View fadeInView) {
+        if (fadeOutView == null || fadeInView == null) {
+            return;
+        }
+        final int shortAnimationDuration = getResources().getInteger(
+                android.R.integer.config_shortAnimTime);
+
+        fadeInView.setAlpha(0f);
+        fadeInView.setVisibility(View.VISIBLE);
+
+        fadeInView.animate()
+                .alpha(1f)
+                .setDuration(shortAnimationDuration)
+                .setListener(null);
+
+        fadeOutView.animate()
+                .alpha(0f)
+                .setDuration(shortAnimationDuration)
+                .setListener(new AnimatorListenerAdapter() {
+                    @Override
+                    public void onAnimationEnd(Animator animation) {
+                        fadeOutView.setVisibility(View.GONE);
+                    }
+                });
+    }
 }
diff --git a/src/com/android/phone/EmergencyInfoGroup.java b/src/com/android/phone/EmergencyInfoGroup.java
new file mode 100644
index 0000000..d0dc322
--- /dev/null
+++ b/src/com/android/phone/EmergencyInfoGroup.java
@@ -0,0 +1,148 @@
+/*
+ * Copyright (C) 2018 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.phone;
+
+import android.annotation.Nullable;
+import android.content.Context;
+import android.content.Intent;
+import android.content.pm.ResolveInfo;
+import android.graphics.Bitmap;
+import android.graphics.drawable.Drawable;
+import android.os.UserHandle;
+import android.os.UserManager;
+import android.telephony.TelephonyManager;
+import android.text.TextUtils;
+import android.util.AttributeSet;
+import android.view.View;
+import android.widget.FrameLayout;
+import android.widget.ImageView;
+import android.widget.LinearLayout;
+import android.widget.TextView;
+
+import androidx.core.graphics.drawable.RoundedBitmapDrawable;
+import androidx.core.graphics.drawable.RoundedBitmapDrawableFactory;
+
+import com.android.internal.util.UserIcons;
+
+import java.util.List;
+
+/**
+ * EmergencyInfoGroup display user icon and user name. And it is an entry point to
+ * Emergency Information.
+ */
+public class EmergencyInfoGroup extends FrameLayout {
+    private ImageView mEmergencyInfoImage;
+    private TextView mEmergencyInfoName;
+    private TextView mEmergencyInfoHint;
+    private View mEmergencyInfoButton;
+
+    public EmergencyInfoGroup(Context context, @Nullable AttributeSet attrs) {
+        super(context, attrs);
+    }
+
+    @Override
+    protected void onFinishInflate() {
+        super.onFinishInflate();
+        mEmergencyInfoButton = findViewById(R.id.emergency_info_button);
+        mEmergencyInfoImage = (ImageView) findViewById(R.id.emergency_info_image);
+        mEmergencyInfoName = (TextView) findViewById(R.id.emergency_info_name);
+        mEmergencyInfoHint = (TextView) findViewById(R.id.emergency_info_hint);
+    }
+
+    @Override
+    protected void onWindowVisibilityChanged(int visibility) {
+        super.onWindowVisibilityChanged(visibility);
+        if (visibility == View.VISIBLE) {
+            setupButtonInfo();
+        }
+    }
+
+    @Override
+    protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
+        super.onLayout(changed, left, top, right, bottom);
+        updateLayoutHeight();
+    }
+
+    private void setupButtonInfo() {
+        List<ResolveInfo> infos;
+
+        if (TelephonyManager.EMERGENCY_ASSISTANCE_ENABLED) {
+            infos = EmergencyAssistanceHelper.resolveAssistPackageAndQueryActivities(getContext());
+        } else {
+            infos = null;
+        }
+
+        boolean visible = false;
+
+        if (infos != null && infos.size() > 0) {
+            final String packageName = infos.get(0).activityInfo.packageName;
+            final Intent intent = new Intent(TelephonyManager.ACTION_EMERGENCY_ASSISTANCE)
+                    .setPackage(packageName);
+            mEmergencyInfoButton.setTag(R.id.tag_intent, intent);
+            mEmergencyInfoImage.setImageDrawable(getCircularUserIcon());
+
+            visible = true;
+        }
+        mEmergencyInfoName.setText(getUserName());
+
+        setVisibility(visible ? View.VISIBLE : View.GONE);
+    }
+
+    /**
+     * Get user icon.
+     *
+     * @return user icon, or default user icon if user do not set photo.
+     */
+    private Drawable getCircularUserIcon() {
+        final UserManager userManager = (UserManager) getContext().getSystemService(
+                Context.USER_SERVICE);
+        Bitmap bitmapUserIcon = userManager.getUserIcon(UserHandle.getCallingUserId());
+
+        if (bitmapUserIcon == null) {
+            // get default user icon.
+            final Drawable defaultUserIcon = UserIcons.getDefaultUserIcon(
+                    getContext().getResources(), UserHandle.myUserId(), false);
+            bitmapUserIcon = UserIcons.convertToBitmap(defaultUserIcon);
+        }
+        RoundedBitmapDrawable drawableUserIcon = RoundedBitmapDrawableFactory.create(
+                getContext().getResources(), bitmapUserIcon);
+        drawableUserIcon.setCircular(true);
+
+        return drawableUserIcon;
+    }
+
+    private CharSequence getUserName() {
+        final UserManager userManager = (UserManager) getContext().getSystemService(
+                Context.USER_SERVICE);
+        final String userName = userManager.getUserName();
+
+        return TextUtils.isEmpty(userName) ? getContext().getText(
+                R.string.emergency_information_owner_hint) : userName;
+    }
+
+    private void updateLayoutHeight() {
+        LinearLayout.LayoutParams params = (LinearLayout.LayoutParams) getLayoutParams();
+        // Update height if mEmergencyInfoHint text line more than 1.
+        // EmergencyInfoGroup max line is 2, eclipse type "end" will be adopt if string too long.
+        params.height =
+                mEmergencyInfoHint.getLineCount() > 1 ? getResources().getDimensionPixelSize(
+                        R.dimen.emergency_info_button_multiline_height)
+                        : getResources().getDimensionPixelSize(
+                                R.dimen.emergency_info_button_singleline_height);
+        setLayoutParams(params);
+    }
+}
\ No newline at end of file
diff --git a/src/com/android/phone/EmergencyShortcutButton.java b/src/com/android/phone/EmergencyShortcutButton.java
new file mode 100644
index 0000000..92877c7
--- /dev/null
+++ b/src/com/android/phone/EmergencyShortcutButton.java
@@ -0,0 +1,257 @@
+/*
+ * Copyright (C) 2018 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.phone;
+
+import android.animation.Animator;
+import android.animation.AnimatorListenerAdapter;
+import android.content.Context;
+import android.util.AttributeSet;
+import android.view.MotionEvent;
+import android.view.View;
+import android.view.ViewAnimationUtils;
+import android.view.accessibility.AccessibilityManager;
+import android.widget.FrameLayout;
+import android.widget.ImageView;
+import android.widget.TextView;
+
+import androidx.annotation.NonNull;
+
+/**
+ * Emergency shortcut button displays a local emergency phone number information(including phone
+ * number, and phone type). To decrease false clicking, it need to click twice to confirm to place
+ * an emergency phone call.
+ *
+ * <p> The button need to be set an {@link OnConfirmClickListener} from activity to handle dial
+ * function.
+ *
+ * <p> First clicking on the button, it would change the view of call number information to
+ * the view of confirmation. And then clicking on the view of confirmation, it will place an
+ * emergency call.
+ *
+ * <p> For screen reader, it changed to click twice on the view of call number information to
+ * place an emergency call. The view of confirmation will not display.
+ */
+public class EmergencyShortcutButton extends FrameLayout implements View.OnClickListener {
+    // Time to hide view of confirmation.
+    private static final long HIDE_DELAY = 3000;
+
+    private static final int[] ICON_VIEWS = {R.id.phone_type_icon, R.id.confirmed_phone_type_icon};
+    private View mCallNumberInfoView;
+    private View mConfirmView;
+
+    private TextView mPhoneNumber;
+    private TextView mPhoneTypeDescription;
+    private TextView mPhoneCallHint;
+    private MotionEvent mPendingTouchEvent;
+    private OnConfirmClickListener mOnConfirmClickListener;
+
+    private boolean mConfirmViewHiding;
+
+    public EmergencyShortcutButton(Context context, AttributeSet attrs) {
+        super(context, attrs);
+    }
+
+    /**
+     * Interface definition for a callback to be invoked when the view of confirmation on shortcut
+     * button is clicked.
+     */
+    public interface OnConfirmClickListener {
+        /**
+         * Called when the view of confirmation on shortcut button has been clicked.
+         *
+         * @param button The shortcut button that was clicked.
+         */
+        void onConfirmClick(EmergencyShortcutButton button);
+    }
+
+    /**
+     * Register a callback {@link OnConfirmClickListener} to be invoked when view of confirmation
+     * is clicked.
+     *
+     * @param onConfirmClickListener The callback that will run.
+     */
+    public void setOnConfirmClickListener(OnConfirmClickListener onConfirmClickListener) {
+        mOnConfirmClickListener = onConfirmClickListener;
+    }
+
+    /**
+     * Set icon for different phone number type.
+     *
+     * @param resId The resource identifier of the drawable.
+     */
+    public void setPhoneTypeIcon(int resId) {
+        for (int iconView : ICON_VIEWS) {
+            ImageView phoneTypeIcon = findViewById(iconView);
+            phoneTypeIcon.setImageResource(resId);
+        }
+    }
+
+    /**
+     * Set emergency phone number description.
+     */
+    public void setPhoneDescription(@NonNull String description) {
+        mPhoneTypeDescription.setText(description);
+    }
+
+    /**
+     * Set emergency phone number.
+     */
+    public void setPhoneNumber(@NonNull String number) {
+        mPhoneNumber.setText(number);
+        mPhoneCallHint.setText(
+                getContext().getString(R.string.emergency_call_shortcut_hint, number));
+
+        // Set content description for phone number.
+        if (number.length() > 1) {
+            StringBuilder stringBuilder = new StringBuilder();
+            for (char c : number.toCharArray()) {
+                stringBuilder.append(c).append(" ");
+            }
+            mPhoneNumber.setContentDescription(stringBuilder.toString().trim());
+        }
+    }
+
+    /**
+     * Get emergency phone number.
+     *
+     * @return phone number, or {@code null} if {@code mPhoneNumber} does not be set.
+     */
+    public String getPhoneNumber() {
+        return mPhoneNumber != null ? mPhoneNumber.getText().toString() : null;
+    }
+
+    /**
+     * Called by the activity before a touch event is dispatched to the view hierarchy.
+     */
+    public void onPreTouchEvent(MotionEvent event) {
+        mPendingTouchEvent = event;
+    }
+
+    @Override
+    public boolean dispatchTouchEvent(MotionEvent event) {
+        boolean handled = super.dispatchTouchEvent(event);
+        if (mPendingTouchEvent == event && handled) {
+            mPendingTouchEvent = null;
+        }
+        return handled;
+    }
+
+    /**
+     * Called by the activity after a touch event is dispatched to the view hierarchy.
+     */
+    public void onPostTouchEvent(MotionEvent event) {
+        // Hide the confirmation button if a touch event was delivered to the activity but not to
+        // this view.
+        if (mPendingTouchEvent != null) {
+            hideSelectedButton();
+        }
+        mPendingTouchEvent = null;
+    }
+
+    @Override
+    protected void onFinishInflate() {
+        super.onFinishInflate();
+        mCallNumberInfoView = findViewById(R.id.emergency_call_number_info_view);
+        mConfirmView = findViewById(R.id.emergency_call_confirm_view);
+
+        mCallNumberInfoView.setOnClickListener(this);
+        mConfirmView.setOnClickListener(this);
+
+        mPhoneNumber = (TextView) mCallNumberInfoView.findViewById(R.id.phone_number);
+        mPhoneTypeDescription = (TextView) mCallNumberInfoView.findViewById(
+                R.id.phone_number_description);
+
+        mPhoneCallHint = (TextView) mConfirmView.findViewById(R.id.phone_call_hint);
+
+        mConfirmViewHiding = true;
+    }
+
+    @Override
+    public void onClick(View view) {
+        switch (view.getId()) {
+            case R.id.emergency_call_number_info_view:
+                if (AccessibilityManager.getInstance(mContext).isTouchExplorationEnabled()) {
+                    if (mOnConfirmClickListener != null) {
+                        mOnConfirmClickListener.onConfirmClick(this);
+                    }
+                } else {
+                    revealSelectedButton();
+                }
+                break;
+            case R.id.emergency_call_confirm_view:
+                if (mOnConfirmClickListener != null) {
+                    mOnConfirmClickListener.onConfirmClick(this);
+                }
+                break;
+        }
+    }
+
+    private void revealSelectedButton() {
+        mConfirmViewHiding = false;
+
+        mConfirmView.setVisibility(View.VISIBLE);
+        int centerX = mCallNumberInfoView.getLeft() + mCallNumberInfoView.getWidth() / 2;
+        int centerY = mCallNumberInfoView.getTop() + mCallNumberInfoView.getHeight() / 2;
+        Animator reveal = ViewAnimationUtils.createCircularReveal(
+                mConfirmView,
+                centerX,
+                centerY,
+                0,
+                Math.max(centerX, mConfirmView.getWidth() - centerX)
+                        + Math.max(centerY, mConfirmView.getHeight() - centerY));
+        reveal.start();
+
+        postDelayed(mCancelSelectedButtonRunnable, HIDE_DELAY);
+        mConfirmView.requestFocus();
+    }
+
+    private void hideSelectedButton() {
+        if (mConfirmViewHiding || mConfirmView.getVisibility() != VISIBLE) {
+            return;
+        }
+
+        mConfirmViewHiding = true;
+
+        removeCallbacks(mCancelSelectedButtonRunnable);
+        int centerX = mConfirmView.getLeft() + mConfirmView.getWidth() / 2;
+        int centerY = mConfirmView.getTop() + mConfirmView.getHeight() / 2;
+        Animator reveal = ViewAnimationUtils.createCircularReveal(
+                mConfirmView,
+                centerX,
+                centerY,
+                Math.max(centerX, mCallNumberInfoView.getWidth() - centerX)
+                        + Math.max(centerY, mCallNumberInfoView.getHeight() - centerY),
+                0);
+        reveal.addListener(new AnimatorListenerAdapter() {
+            @Override
+            public void onAnimationEnd(Animator animation) {
+                mConfirmView.setVisibility(INVISIBLE);
+            }
+        });
+        reveal.start();
+
+        mCallNumberInfoView.requestFocus();
+    }
+
+    private final Runnable mCancelSelectedButtonRunnable = new Runnable() {
+        @Override
+        public void run() {
+            if (!isAttachedToWindow()) return;
+            hideSelectedButton();
+        }
+    };
+}
diff --git a/src/com/android/phone/PhoneInterfaceManager.java b/src/com/android/phone/PhoneInterfaceManager.java
index 2df3bbe..444eae0 100755
--- a/src/com/android/phone/PhoneInterfaceManager.java
+++ b/src/com/android/phone/PhoneInterfaceManager.java
@@ -102,6 +102,7 @@
 import com.android.internal.telephony.NetworkScanRequestTracker;
 import com.android.internal.telephony.OperatorInfo;
 import com.android.internal.telephony.Phone;
+import com.android.internal.telephony.PhoneConfigurationManager;
 import com.android.internal.telephony.PhoneConstantConversions;
 import com.android.internal.telephony.PhoneConstants;
 import com.android.internal.telephony.PhoneFactory;
@@ -216,6 +217,7 @@
     private MainThreadHandler mMainThreadHandler;
     private SubscriptionController mSubscriptionController;
     private SharedPreferences mTelephonySharedPreferences;
+    private PhoneConfigurationManager mPhoneConfigurationManager;
 
     private static final String PREF_CARRIERS_ALPHATAG_PREFIX = "carrier_alphtag_";
     private static final String PREF_CARRIERS_NUMBER_PREFIX = "carrier_number_";
@@ -1091,6 +1093,7 @@
                 PreferenceManager.getDefaultSharedPreferences(mPhone.getContext());
         mSubscriptionController = SubscriptionController.getInstance();
         mNetworkScanRequestTracker = new NetworkScanRequestTracker();
+        mPhoneConfigurationManager = PhoneConfigurationManager.getInstance();
 
         publish();
     }
@@ -5173,4 +5176,19 @@
             Binder.restoreCallingIdentity(identity);
         }
     }
+
+    @Override
+    public int getNumberOfModemsWithSimultaneousDataConnections(int subId, String callingPackage) {
+        if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
+                mApp, subId, callingPackage, "getNumberOfModemsWithSimultaneousDataConnections")) {
+            return -1;
+        }
+
+        final long identity = Binder.clearCallingIdentity();
+        try {
+            return mPhoneConfigurationManager.getNumberOfModemsWithSimultaneousDataConnections();
+        } finally {
+            Binder.restoreCallingIdentity(identity);
+        }
+    }
 }
diff --git a/src/com/android/phone/ecc/CountryEccInfo.java b/src/com/android/phone/ecc/CountryEccInfo.java
new file mode 100644
index 0000000..6bef8d3
--- /dev/null
+++ b/src/com/android/phone/ecc/CountryEccInfo.java
@@ -0,0 +1,46 @@
+/*
+ * Copyright (C) 2018 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.phone.ecc;
+
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+
+import java.util.List;
+
+/**
+ * ECC info of a country.
+ */
+public class CountryEccInfo {
+    private final String mFallbackEcc;
+    private final EccInfo[] mEccInfoList;
+
+    public CountryEccInfo(String eccFallback, @NonNull List<EccInfo> eccInfoList) {
+        mFallbackEcc = eccFallback;
+        mEccInfoList = eccInfoList.toArray(new EccInfo[eccInfoList.size()]);
+    }
+
+    /**
+     * @return fallback ECC, null if not available.
+     */
+    public @Nullable String getFallbackEcc() {
+        return mFallbackEcc;
+    }
+
+    public @NonNull EccInfo[] getEccInfoList() {
+        return mEccInfoList.clone();
+    }
+}
diff --git a/src/com/android/phone/ecc/EccInfo.java b/src/com/android/phone/ecc/EccInfo.java
new file mode 100644
index 0000000..d047b9b
--- /dev/null
+++ b/src/com/android/phone/ecc/EccInfo.java
@@ -0,0 +1,88 @@
+/*
+ * Copyright (C) 2018 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.phone.ecc;
+
+import androidx.annotation.NonNull;
+
+import java.util.List;
+
+/**
+ * Emergency call code info.
+ */
+public class EccInfo {
+    /**
+     * ECC Types.
+     */
+    public enum Type {
+        POLICE,
+        AMBULANCE,
+        FIRE,
+    }
+
+    private final String mNumber;
+    private final Type[] mTypes;
+
+    public EccInfo(@NonNull String number, @NonNull Type type) {
+        mNumber = number;
+        mTypes = new Type[]{ type };
+    }
+
+    public EccInfo(@NonNull String number, @NonNull List<Type> types) {
+        mNumber = number;
+        mTypes = types.toArray(new Type[types.size()]);
+    }
+
+    /**
+     * @return ECC number.
+     */
+    public @NonNull String getNumber() {
+        return mNumber;
+    }
+
+    /**
+     * Check whether the ECC number has any matches to the target type.
+     *
+     * @param target The target type to check.
+     * @return true if the target matches.
+     */
+    public boolean containsType(@NonNull Type target) {
+        for (Type type : mTypes) {
+            if (target.equals(type)) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    /**
+     * Get the types of the ECC number.
+     *
+     * @return Copied types array.
+     */
+    public Type[] getTypes() {
+        return mTypes.clone();
+    }
+
+    /**
+     * Get how many types the ECC number is.
+     *
+     * @return Count of types.
+     */
+    public int getTypesCount() {
+        return mTypes.length;
+    }
+}
diff --git a/src/com/android/phone/ecc/EccInfoHelper.java b/src/com/android/phone/ecc/EccInfoHelper.java
new file mode 100644
index 0000000..514f388
--- /dev/null
+++ b/src/com/android/phone/ecc/EccInfoHelper.java
@@ -0,0 +1,213 @@
+/*
+ * Copyright (C) 2018 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.phone.ecc;
+
+import android.content.Context;
+import android.os.AsyncTask;
+import android.provider.Settings;
+import android.telephony.CellIdentityGsm;
+import android.telephony.CellIdentityLte;
+import android.telephony.CellIdentityWcdma;
+import android.telephony.CellInfo;
+import android.telephony.CellInfoGsm;
+import android.telephony.CellInfoLte;
+import android.telephony.CellInfoWcdma;
+import android.telephony.PhoneNumberUtils;
+import android.telephony.TelephonyManager;
+import android.text.TextUtils;
+import android.util.Log;
+import android.util.Pair;
+
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+
+import com.android.internal.telephony.MccTable;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Helper for retrieve ECC info for current country.
+ */
+public class EccInfoHelper {
+    private static final String LOG_TAG = "EccInfoHelper";
+
+    // country ISO to ECC list data source
+    private IsoToEccRepository mEccRepo;
+
+    /**
+     * Callback for {@link #getCountryEccInfoAsync}.
+     */
+    public interface CountryEccInfoResultCallback {
+        /**
+         * Called if successfully get country ECC info.
+         *
+         * @param iso Detected current country ISO.
+         * @param countryEccInfo The EccInfo of current country.
+         */
+        void onSuccess(@NonNull String iso, @NonNull CountryEccInfo countryEccInfo);
+
+        /**
+         * Called if failed to get country ISO.
+         */
+        void onDetectCountryFailed();
+
+        /**
+         * Called if failed to get ECC info for given country ISO.
+         *
+         * @param iso Detected current country ISO.
+         */
+        void onRetrieveCountryEccInfoFailed(@NonNull String iso);
+    }
+
+    /**
+     * Constructor of EccInfoHelper
+     *
+     * @param eccRepository A repository for ECC info, indexed by country ISO.
+     */
+    public EccInfoHelper(@NonNull IsoToEccRepository eccRepository) {
+        mEccRepo = eccRepository;
+    }
+
+    /**
+     * Get ECC info for current location, base on detected country ISO.
+     * It's possible we cannot detect current country, ex. device is in airplane mode,
+     * or there's no available base station near by.
+     *
+     * @param context The context used to access resources.
+     * @param callback Callback for result.
+     */
+    public void getCountryEccInfoAsync(final @NonNull Context context,
+            final CountryEccInfoResultCallback callback) {
+        new AsyncTask<Void, Void, Pair<String, CountryEccInfo>>() {
+            @Override
+            protected Pair<String, CountryEccInfo> doInBackground(Void... voids) {
+                String iso = getCurrentCountryIso(context);
+                if (TextUtils.isEmpty(iso)) {
+                    return null;
+                }
+
+                CountryEccInfo dialableCountryEccInfo;
+                try {
+                    // access data source in background thread to avoid possible file IO caused ANR.
+                    CountryEccInfo rawEccInfo = mEccRepo.getCountryEccInfo(context, iso);
+                    dialableCountryEccInfo = getDialableCountryEccInfo(rawEccInfo);
+                } catch (IOException e) {
+                    Log.e(LOG_TAG, "Failed to retrieve ECC: " + e.getMessage());
+                    dialableCountryEccInfo = null;
+                }
+                return new Pair<>(iso, dialableCountryEccInfo);
+            }
+
+            @Override
+            protected void onPostExecute(Pair<String, CountryEccInfo> result) {
+                if (callback != null) {
+                    if (result == null) {
+                        callback.onDetectCountryFailed();
+                    } else {
+                        String iso = result.first;
+                        CountryEccInfo countryEccInfo = result.second;
+                        if (countryEccInfo == null) {
+                            callback.onRetrieveCountryEccInfoFailed(iso);
+                        } else {
+                            callback.onSuccess(iso, countryEccInfo);
+                        }
+                    }
+                }
+            }
+        }.execute();
+    }
+
+    private @NonNull CountryEccInfo getDialableCountryEccInfo(CountryEccInfo countryEccInfo) {
+        ArrayList<EccInfo> dialableECCList = new ArrayList<>();
+        String dialableFallback = null;
+
+        // filter out non-dialable ECC
+        if (countryEccInfo != null) {
+            for (EccInfo entry : countryEccInfo.getEccInfoList()) {
+                if (PhoneNumberUtils.isEmergencyNumber(entry.getNumber())) {
+                    dialableECCList.add(entry);
+                }
+            }
+            String defaultFallback = countryEccInfo.getFallbackEcc();
+            if (PhoneNumberUtils.isEmergencyNumber(defaultFallback)) {
+                dialableFallback = defaultFallback;
+            }
+        }
+        return new CountryEccInfo(dialableFallback, dialableECCList);
+    }
+
+    private @Nullable String getCurrentCountryIso(@NonNull Context context) {
+        // Do not detect country ISO if airplane mode is on
+        int airplaneMode = Settings.System.getInt(context.getContentResolver(),
+                Settings.Global.AIRPLANE_MODE_ON, 0);
+        if (airplaneMode != 0) {
+            Log.d(LOG_TAG, "Airplane mode is on, do not get country ISO.");
+            return null;
+        }
+
+        TelephonyManager tm = (TelephonyManager) context.getSystemService(
+                Context.TELEPHONY_SERVICE);
+        String iso = tm.getNetworkCountryIso();
+        Log.d(LOG_TAG, "Current country ISO is " + iso);
+
+        if (TextUtils.isEmpty(iso)) {
+            // XXX: according to ServiceStateTracker's implementation, retrieve cell info in a
+            // thread other than TelephonyManager's main thread.
+            String mcc = getCurrentMccFromCellInfo(context);
+            iso = MccTable.countryCodeForMcc(mcc);
+            Log.d(LOG_TAG, "Current mcc is " + mcc + ", mapping to ISO: " + iso);
+        }
+        return iso;
+    }
+
+    // XXX: According to ServiceStateTracker implementation, to actually get current cell info,
+    // this method must be called in a separate thread from ServiceStateTracker, which is the
+    // main thread of Telephony service.
+    private @Nullable String getCurrentMccFromCellInfo(@NonNull Context context) {
+        // retrieve mcc info from base station even no SIM present.
+        TelephonyManager tm = (TelephonyManager) context.getSystemService(
+                Context.TELEPHONY_SERVICE);
+        List<CellInfo> cellInfos = tm.getAllCellInfo();
+        String mcc = null;
+        if (cellInfos != null) {
+            for (CellInfo ci : cellInfos) {
+                if (ci instanceof CellInfoGsm) {
+                    CellInfoGsm cellInfoGsm = (CellInfoGsm) ci;
+                    CellIdentityGsm cellIdentityGsm = cellInfoGsm.getCellIdentity();
+                    mcc = cellIdentityGsm.getMccString();
+                    break;
+                } else if (ci instanceof CellInfoWcdma) {
+                    CellInfoWcdma cellInfoWcdma = (CellInfoWcdma) ci;
+                    CellIdentityWcdma cellIdentityWcdma = cellInfoWcdma.getCellIdentity();
+                    mcc = cellIdentityWcdma.getMccString();
+                    break;
+                } else if (ci instanceof CellInfoLte) {
+                    CellInfoLte cellInfoLte = (CellInfoLte) ci;
+                    CellIdentityLte cellIdentityLte = cellInfoLte.getCellIdentity();
+                    mcc = cellIdentityLte.getMccString();
+                    break;
+                }
+            }
+            Log.d(LOG_TAG, "Retrieve MCC from cell info list: " + mcc);
+        } else {
+            Log.w(LOG_TAG, "Cannot get cell info list.");
+        }
+        return mcc;
+    }
+}
diff --git a/src/com/android/phone/ecc/IsoToEccRepository.java b/src/com/android/phone/ecc/IsoToEccRepository.java
new file mode 100644
index 0000000..6d95af4
--- /dev/null
+++ b/src/com/android/phone/ecc/IsoToEccRepository.java
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 2018 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.phone.ecc;
+
+import android.content.Context;
+
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+
+import java.io.IOException;
+
+/**
+ * Data source for country ISO to ECC info list mapping.
+ */
+public interface IsoToEccRepository {
+    /**
+     * Get available emergency numbers for given country ISO. Because the possible of IO wait
+     * (depends on the implementation), this method should not be called in the main thread.
+     *
+     * @param context The context used to access resources.
+     * @param iso For which ECC info list is returned.
+     * @return The ECC info of given ISO. Null if no match.
+     * @throws IOException if an error occurs while initialize the repository or retrieving
+     * the {@link CountryEccInfo}.
+     */
+    @Nullable CountryEccInfo getCountryEccInfo(@NonNull Context context, @Nullable String iso)
+            throws IOException;
+}
diff --git a/src/com/android/phone/settings/AccessibilitySettingsFragment.java b/src/com/android/phone/settings/AccessibilitySettingsFragment.java
index 57b6d8e..0eb3845 100644
--- a/src/com/android/phone/settings/AccessibilitySettingsFragment.java
+++ b/src/com/android/phone/settings/AccessibilitySettingsFragment.java
@@ -57,10 +57,17 @@
             if (DBG) Log.d(LOG_TAG, "PhoneStateListener.onCallStateChanged: state=" + state);
             Preference pref = getPreferenceScreen().findPreference(BUTTON_TTY_KEY);
             if (pref != null) {
-                final boolean isVolteTtySupported = ImsManager.isVolteEnabledByPlatform(mContext)
-                        && getVolteTtySupported();
-                pref.setEnabled((isVolteTtySupported && !isVideoCallOrConferenceInProgress()) ||
-                        (state == TelephonyManager.CALL_STATE_IDLE));
+                // Use TelephonyManager#getCallState instead of 'state' parameter because
+                // needs to check the current state of all phone calls to
+                // support multi sim configuration.
+                TelephonyManager telephonyManager =
+                        (TelephonyManager) mContext.getSystemService(Context.TELEPHONY_SERVICE);
+                final boolean isVolteTtySupported = getVolteTtySupported();
+                final boolean isVolteCurrentlyEnabled =
+                        ImsManager.isVolteEnabledByPlatform(mContext);
+                pref.setEnabled((isVolteTtySupported && isVolteCurrentlyEnabled &&
+                        !isVideoCallOrConferenceInProgress()) ||
+                        (telephonyManager.getCallState() == TelephonyManager.CALL_STATE_IDLE));
             }
         }
     };