Merge "Revert "have PhoneInterfaceManager use phone obj with default subid instead of""
diff --git a/ecc/README.md b/ecc/README.md
index ef795d5..b5dc538 100644
--- a/ecc/README.md
+++ b/ecc/README.md
@@ -6,43 +6,28 @@
 
 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 into output/eccdata.
 
 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.
+  - The binary file generated from input files.
 
 conversion_toolset_v*
-  - Contains format definitions, converting tools and verification tools of
-    one version of ECC data format.
+  - Contains format definitions and converting tools.
 
 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.
-
+4. Make TeleService
+5. Push TeleService.apk to system/priv-app/TeleService
+6. Reboot device
+7. run 'atest TeleServiceTests:IsoToEccProtobufRepositoryTest#testEccDataContent'
diff --git a/ecc/conversion_toolset_v1/env.sh b/ecc/conversion_toolset_v1/env.sh
index 23d9f10..534c807 100644
--- a/ecc/conversion_toolset_v1/env.sh
+++ b/ecc/conversion_toolset_v1/env.sh
@@ -20,19 +20,3 @@
 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
index 8dd751f..1efac37 100644
--- a/ecc/conversion_toolset_v1/gen_eccdata.sh
+++ b/ecc/conversion_toolset_v1/gen_eccdata.sh
@@ -18,19 +18,12 @@
 LOCAL_TOOLSET_DIR="${ECC_ROOT}/conversion_toolset_v1"
 source "${LOCAL_TOOLSET_DIR}/env.sh"
 
+echo "Converting eccdata..."
 ${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"
+echo "Compressing eccdata..."
 gzip -c < "${RAW_DATA}" > "${OUTPUT_DATA}"
-echo "Done"
 
+echo "Done"
diff --git a/ecc/conversion_toolset_v1/verify_eccdata_compatibility.sh b/ecc/conversion_toolset_v1/verify_eccdata_compatibility.sh
deleted file mode 100644
index 8686722..0000000
--- a/ecc/conversion_toolset_v1/verify_eccdata_compatibility.sh
+++ /dev/null
@@ -1,28 +0,0 @@
-#!/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
deleted file mode 100644
index bc707eb..0000000
--- a/ecc/conversion_toolset_v1/verify_protobuf_compatibility.py
+++ /dev/null
@@ -1,85 +0,0 @@
-#!/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
index 5cf52de..4f3a097 100755
--- a/ecc/gen_eccdata.sh
+++ b/ecc/gen_eccdata.sh
@@ -53,15 +53,8 @@
 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!"
-
+echo "To verify data compatibility:"
+echo "  1. make TeleService"
+echo "  2. push TeleService.apk to system/priv-app/TeleService"
+echo "  3. reboot device"
+echo "  4. run 'atest TeleServiceTests:IsoToEccProtobufRepositoryTest#testEccDataContent'"
diff --git a/res/values-es/config.xml b/res/values-es/config.xml
index 509a3c8..abbe91d 100644
--- a/res/values-es/config.xml
+++ b/res/values-es/config.xml
@@ -25,4 +25,5 @@
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="system_visual_voicemail_client" msgid="1787338073957698459"></string>
+    <string name="config_emergency_app_intent" msgid="4647337643851943548"></string>
 </resources>
diff --git a/res/values-es/strings.xml b/res/values-es/strings.xml
index 1f346b4..8143e5d 100644
--- a/res/values-es/strings.xml
+++ b/res/values-es/strings.xml
@@ -49,7 +49,7 @@
     <string name="puk_unlocked" msgid="2284912838477558454">"La tarjeta SIM se ha desbloqueado. El teléfono se está desbloqueando..."</string>
     <string name="label_ndp" msgid="780479633159517250">"PIN de desbloqueo de red de tarjeta SIM"</string>
     <string name="sim_ndp_unlock_text" msgid="683628237760543009">"Desbloquear"</string>
-    <string name="sim_ndp_dismiss_text" msgid="1604823375752456947">"Descartar"</string>
+    <string name="sim_ndp_dismiss_text" msgid="1604823375752456947">"Cerrar"</string>
     <string name="requesting_unlock" msgid="6412629401033249351">"Solicitando desbloqueo de red..."</string>
     <string name="unlock_failed" msgid="6490531697031504225">"La solicitud de desbloqueo de red no se ha realizado correctamente."</string>
     <string name="unlock_success" msgid="6770085622238180152">"El desbloqueo de red se ha realizado correctamente."</string>
@@ -605,7 +605,7 @@
     <string name="progress_dialog_exiting_ecm" msgid="4835734101617817074">"Saliendo del modo de devolución de llamada de emergencia"</string>
     <string name="alert_dialog_yes" msgid="6674268047820703974">"Sí"</string>
     <string name="alert_dialog_no" msgid="1476091437797628703">"No"</string>
-    <string name="alert_dialog_dismiss" msgid="2491494287075907171">"Descartar"</string>
+    <string name="alert_dialog_dismiss" msgid="2491494287075907171">"Cerrar"</string>
     <string name="voicemail_provider" msgid="5135942703327136909">"Servicio"</string>
     <string name="voicemail_settings" msgid="72448049107749316">"Configuración"</string>
     <string name="voicemail_number_not_set" msgid="6724904736891087856">"&lt;No definido&gt;"</string>
@@ -779,5 +779,5 @@
     <string name="supp_service_over_ut_precautions_roaming" msgid="1597142936802114092">"Para utilizar <xliff:g id="SUPP_SERVICE">%s</xliff:g>, los datos móviles y la itinerancia de datos deben estar activados. Puedes cambiar estas opciones en los ajustes de red móvil."</string>
     <string name="supp_service_over_ut_precautions_dual_sim" msgid="1682814794340311300">"Para utilizar <xliff:g id="SUPP_SERVICE">%1$s</xliff:g>, los datos móviles deben estar activados en la SIM <xliff:g id="SIM_NUMBER">%2$d</xliff:g>. Puedes cambiar esta opción en los ajustes de red móvil."</string>
     <string name="supp_service_over_ut_precautions_roaming_dual_sim" msgid="8062345092837168385">"Para utilizar <xliff:g id="SUPP_SERVICE">%1$s</xliff:g>, los datos móviles y la itinerancia de datos deben estar activados en la SIM <xliff:g id="SIM_NUMBER">%2$d</xliff:g>. Puedes cambiar estas opciones en los ajustes de red móvil."</string>
-    <string name="supp_service_over_ut_precautions_dialog_dismiss" msgid="5061044213859557398">"Ignorar"</string>
+    <string name="supp_service_over_ut_precautions_dialog_dismiss" msgid="5061044213859557398">"Cerrar"</string>
 </resources>
diff --git a/res/values-gl/config.xml b/res/values-gl/config.xml
index 509a3c8..abbe91d 100644
--- a/res/values-gl/config.xml
+++ b/res/values-gl/config.xml
@@ -25,4 +25,5 @@
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="system_visual_voicemail_client" msgid="1787338073957698459"></string>
+    <string name="config_emergency_app_intent" msgid="4647337643851943548"></string>
 </resources>
diff --git a/res/values-hi/config.xml b/res/values-hi/config.xml
index 509a3c8..abbe91d 100644
--- a/res/values-hi/config.xml
+++ b/res/values-hi/config.xml
@@ -25,4 +25,5 @@
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="system_visual_voicemail_client" msgid="1787338073957698459"></string>
+    <string name="config_emergency_app_intent" msgid="4647337643851943548"></string>
 </resources>
diff --git a/res/values-mr/config.xml b/res/values-mr/config.xml
index 509a3c8..abbe91d 100644
--- a/res/values-mr/config.xml
+++ b/res/values-mr/config.xml
@@ -25,4 +25,5 @@
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="system_visual_voicemail_client" msgid="1787338073957698459"></string>
+    <string name="config_emergency_app_intent" msgid="4647337643851943548"></string>
 </resources>
diff --git a/res/values-mr/strings.xml b/res/values-mr/strings.xml
index f9ab34c..24b4f1e 100644
--- a/res/values-mr/strings.xml
+++ b/res/values-mr/strings.xml
@@ -436,8 +436,8 @@
     <string name="fdn_failed" msgid="540018079008319747">"FDN कार्य अयशस्‍वी झाले."</string>
     <string name="simContacts_emptyLoading" msgid="2203331234764498011">"सिक कार्डमधून वाचत आहे..."</string>
     <string name="simContacts_empty" msgid="5270660846489561932">"आपल्‍या सिम कार्डवर कोणतेही संपर्क नाहीत."</string>
-    <string name="simContacts_title" msgid="1861472842524839921">"आयात करण्यासाठी संपर्क निवडा"</string>
-    <string name="simContacts_airplaneMode" msgid="5254946758982621072">"सिम कार्डमधील संपर्क आयात करण्‍यासाठी विमान मोड बंद करा."</string>
+    <string name="simContacts_title" msgid="1861472842524839921">"इंपोर्ट करण्यासाठी संपर्क निवडा"</string>
+    <string name="simContacts_airplaneMode" msgid="5254946758982621072">"सिम कार्डमधील संपर्क इंपोर्ट करण्‍यासाठी विमान मोड बंद करा."</string>
     <string name="enable_pin" msgid="5422767284133234860">"सिम पिन सक्षम करा/अक्षम करा"</string>
     <string name="change_pin" msgid="9174186126330785343">"सिम पिन बदला"</string>
     <string name="enter_pin_text" msgid="8532615714751931951">"सिम पिन"</string>
@@ -539,12 +539,12 @@
     <string name="onscreenManageConferenceText" msgid="6485935856534311346">"परिषद व्यवस्थापित करा"</string>
     <string name="onscreenAudioText" msgid="1710087112800041743">"ऑडिओ"</string>
     <string name="onscreenVideoCallText" msgid="4800924186056115442">"व्हिडिओ कॉल"</string>
-    <string name="importSimEntry" msgid="6614358325359736031">"आयात"</string>
-    <string name="importAllSimEntries" msgid="1503181169636198673">"सर्व आयात करा"</string>
-    <string name="importingSimContacts" msgid="7374056215462575769">"सिम संपर्क आयात करत आहे"</string>
-    <string name="importToFDNfromContacts" msgid="2130620207013368580">"संपर्कांमधून आयात करा"</string>
-    <string name="singleContactImportedMsg" msgid="6868483416182599206">"आयात केलेला संपर्क"</string>
-    <string name="failedToImportSingleContactMsg" msgid="415399285420353917">"संपर्क आयात करण्यात अयशस्वी"</string>
+    <string name="importSimEntry" msgid="6614358325359736031">"इंपोर्ट"</string>
+    <string name="importAllSimEntries" msgid="1503181169636198673">"सर्व इंपोर्ट करा"</string>
+    <string name="importingSimContacts" msgid="7374056215462575769">"सिम संपर्क इंपोर्ट करत आहे"</string>
+    <string name="importToFDNfromContacts" msgid="2130620207013368580">"संपर्कांमधून इंपोर्ट करा"</string>
+    <string name="singleContactImportedMsg" msgid="6868483416182599206">"इंपोर्ट केलेला संपर्क"</string>
+    <string name="failedToImportSingleContactMsg" msgid="415399285420353917">"संपर्क इंपोर्ट करण्यात अयशस्वी"</string>
     <string name="hac_mode_title" msgid="8740268574688743289">"श्रवणयंत्रे"</string>
     <string name="hac_mode_summary" msgid="6833851160514929341">"श्रवणयंत्र सुसंगतता चालू करा"</string>
     <string name="rtt_mode_title" msgid="6954652435543570121">"रीअल-टाइम टेक्‍स्‍ट (RTT) कॉल"</string>
diff --git a/res/xml/telephony_injection.xml b/res/xml/telephony_injection.xml
new file mode 100644
index 0000000..2af425c
--- /dev/null
+++ b/res/xml/telephony_injection.xml
@@ -0,0 +1,33 @@
+<?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.
+-->
+
+<!-- package: customized component factory to inject,
+        e.g. "example.package.exampleTelephonyComponentFactory"
+     jar: jar path to customized jar which contains exampleTelephonyComponentFactory to inject, and
+     "/system/framework/" should be the target directory.
+        e.g. "/system/framework/eg-telephony-common.jar"
+-->
+<injection package=""
+           jar="">
+    <components>
+        <!-- Components use injected component factory,
+            e.g. com.android.internal.telephony.ServiceStateTracker
+        -->
+        <!--<component>com.example.componentA</component>-->
+        <!--<component>com.example.componentB</component>-->
+    </components>
+</injection>
diff --git a/src/com/android/phone/PhoneGlobals.java b/src/com/android/phone/PhoneGlobals.java
index 5009bfe..2cefd52 100644
--- a/src/com/android/phone/PhoneGlobals.java
+++ b/src/com/android/phone/PhoneGlobals.java
@@ -25,6 +25,7 @@
 import android.content.ContextWrapper;
 import android.content.Intent;
 import android.content.IntentFilter;
+import android.content.res.XmlResourceParser;
 import android.media.AudioManager;
 import android.net.ConnectivityManager;
 import android.net.Uri;
@@ -59,6 +60,7 @@
 import com.android.internal.telephony.PhoneFactory;
 import com.android.internal.telephony.SettingsObserver;
 import com.android.internal.telephony.TelephonyCapabilities;
+import com.android.internal.telephony.TelephonyComponentFactory;
 import com.android.internal.telephony.TelephonyIntents;
 import com.android.internal.telephony.dataconnection.DataConnectionReasons;
 import com.android.internal.telephony.dataconnection.DataConnectionReasons.DataDisallowedReasonType;
@@ -281,6 +283,9 @@
         //   getPackageManager().hasSystemFeature(PackageManager.FEATURE_TELEPHONY_VOICE_CALLS);
 
         if (mCM == null) {
+            // Inject telephony component factory if configured using other jars.
+            XmlResourceParser parser = getResources().getXml(R.xml.telephony_injection);
+            TelephonyComponentFactory.getInstance().injectTheComponentFactory(parser);
             // Initialize the telephony framework
             PhoneFactory.makeDefaultPhones(this);
 
diff --git a/src/com/android/phone/PhoneInterfaceManager.java b/src/com/android/phone/PhoneInterfaceManager.java
index 973ddf0..81a82d4 100755
--- a/src/com/android/phone/PhoneInterfaceManager.java
+++ b/src/com/android/phone/PhoneInterfaceManager.java
@@ -69,6 +69,7 @@
 import android.telephony.NeighboringCellInfo;
 import android.telephony.NetworkScanRequest;
 import android.telephony.PhoneNumberRange;
+import android.telephony.PhoneNumberUtils;
 import android.telephony.RadioAccessFamily;
 import android.telephony.Rlog;
 import android.telephony.ServiceState;
@@ -151,9 +152,12 @@
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Collection;
+import java.util.HashMap;
+import java.util.HashSet;
 import java.util.List;
 import java.util.Locale;
 import java.util.Map;
+import java.util.Set;
 
 /**
  * Implementation of the ITelephony interface.
@@ -5964,14 +5968,142 @@
     @Override
     public Map<Integer, List<EmergencyNumber>> getCurrentEmergencyNumberList(
             String callingPackage) {
-        // TODO connect with internal content
-        return null;
+        if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
+                mApp, getDefaultSubscription(), callingPackage, "getCurrentEmergencyNumberList")) {
+            throw new SecurityException("Requires READ_PHONE_STATE permission.");
+        }
+        final long identity = Binder.clearCallingIdentity();
+        try {
+            Map<Integer, List<EmergencyNumber>> results = getEmergencyNumberListInternal();
+            // Use ecclist to construct Emergency number list for backward compatibality
+            if (results.isEmpty()) {
+                results = getEmergencyNumberListFromEccList();
+            }
+            return results;
+        } finally {
+            Binder.restoreCallingIdentity(identity);
+        }
     }
 
     @Override
-    public boolean isCurrentEmergencyNumber(String number) {
-        // TODO connect with internal content
-        return false;
+    public boolean isCurrentEmergencyNumber(String number, boolean exactMatch) {
+        if (!exactMatch) {
+            TelephonyPermissions
+                    .enforeceCallingOrSelfReadPrivilegedPhoneStatePermissionOrCarrierPrivilege(
+                            mApp, mPhone.getSubId(), "isCurrentEmergencyNumber(Potential)");
+        }
+        final long identity = Binder.clearCallingIdentity();
+        try {
+            Map<Integer, List<EmergencyNumber>> emergencyNumberLists =
+                    getEmergencyNumberListInternal();
+
+            String defaultCountryIso = getNetworkCountryIsoForPhone(mPhone.getPhoneId());
+
+            if (!emergencyNumberLists.isEmpty()) {
+                for (List<EmergencyNumber> emergencyNumberList : emergencyNumberLists.values()) {
+                    if (emergencyNumberList != null) {
+                        for (EmergencyNumber num : emergencyNumberList) {
+                            // According to com.android.i18n.phonenumbers.ShortNumberInfo, in
+                            // these countries, if extra digits are added to an emergency number,
+                            // it no longer connects to the emergency service.
+                            Set<String> countriesRequiredForExactMatch = new HashSet<>();
+                            countriesRequiredForExactMatch.add("br");
+                            countriesRequiredForExactMatch.add("cl");
+                            countriesRequiredForExactMatch.add("ni");
+                            if (exactMatch || countriesRequiredForExactMatch.contains(
+                                    defaultCountryIso)) {
+                                if (num.getNumber().equals(number)) {
+                                    return true;
+                                }
+                            } else {
+                                if (number.startsWith(num.getNumber())) {
+                                    return true;
+                                }
+                            }
+
+                        }
+                    }
+                }
+            } else {
+                // For backward compatibility for devices launched before Q
+                return PhoneNumberUtils.isEmergencyNumberInternal(number, exactMatch,
+                        defaultCountryIso);
+            }
+            return false;
+        } finally {
+            Binder.restoreCallingIdentity(identity);
+        }
+    }
+
+    private Map<Integer, List<EmergencyNumber>> getEmergencyNumberListInternal() {
+        Map<Integer, List<EmergencyNumber>> emergencyNumberListInternal = new HashMap<>();
+
+        for (Phone phone: PhoneFactory.getPhones()) {
+            if (phone.getEmergencyNumberTracker() != null
+                    && phone.getEmergencyNumberTracker().getEmergencyNumberList() != null) {
+                emergencyNumberListInternal.put(
+                        phone.getSubId(),
+                        phone.getEmergencyNumberTracker().getEmergencyNumberList());
+            }
+        }
+        return emergencyNumberListInternal;
+    }
+
+    private List<EmergencyNumber> getEmergencyNumberListFromEccList(int subscriptionId) {
+        SubscriptionManager sm = (SubscriptionManager) mPhone.getContext().getSystemService(
+                Context.TELEPHONY_SUBSCRIPTION_SERVICE);
+        List<EmergencyNumber> emergencyNumberList = new ArrayList<>();
+        int slotId = sm.getSlotIndex(subscriptionId);
+
+        String ecclist = (slotId <= 0) ? "ril.ecclist" : ("ril.ecclist" + slotId);
+        String emergencyNumbers = SystemProperties.get(ecclist, "");
+        if (TextUtils.isEmpty(emergencyNumbers)) {
+            // then read-only ecclist property since old RIL only uses this
+            emergencyNumbers = SystemProperties.get("ro.ril.ecclist");
+        }
+        if (!TextUtils.isEmpty(emergencyNumbers)) {
+            // searches through the comma-separated list for a match,
+            // return true if one is found.
+            for (String emergencyNum : emergencyNumbers.split(",")) {
+                emergencyNumberList.add(new EmergencyNumber(emergencyNum, "", "",
+                        EmergencyNumber.EMERGENCY_SERVICE_CATEGORY_UNSPECIFIED, 0));
+            }
+        }
+        emergencyNumbers = ((slotId < 0) ? "112,911,000,08,110,118,119,999" : "112,911");
+        for (String emergencyNum : emergencyNumbers.split(",")) {
+            emergencyNumberList.add(new EmergencyNumber(emergencyNum, "", "",
+                    EmergencyNumber.EMERGENCY_SERVICE_CATEGORY_UNSPECIFIED, 0));
+        }
+        EmergencyNumber.mergeSameNumbersInEmergencyNumberList(emergencyNumberList);
+        return emergencyNumberList;
+    }
+
+    /**
+     * Get Emergency number list based on EccList. This util is used for solving backward
+     * compatibility if device does not support the 1.4 IRadioIndication HAL that reports
+     * emergency number list.
+     *
+     * @return Map including the key as the active subscription ID (Note: if there is no active
+     *         subscription, the key is {@link SubscriptionManager#getDefaultSubscriptionId})
+     *         and the value as the list of {@link EmergencyNumber}.
+     */
+    private Map<Integer, List<EmergencyNumber>> getEmergencyNumberListFromEccList() {
+        Map<Integer, List<EmergencyNumber>> results = new HashMap<>();
+        SubscriptionManager sm = (SubscriptionManager) mPhone.getContext().getSystemService(
+                Context.TELEPHONY_SUBSCRIPTION_SERVICE);
+        int[] activeSubscriptionIds = sm.getActiveSubscriptionIdList();
+
+        if (activeSubscriptionIds.length == 0) {
+            int defaultSubscriptionId = getDefaultSubscription();
+            results.put(defaultSubscriptionId,
+                    getEmergencyNumberListFromEccList(defaultSubscriptionId));
+        } else {
+            for (int activeSubscriptionId : activeSubscriptionIds) {
+                results.put(activeSubscriptionId,
+                        getEmergencyNumberListFromEccList(activeSubscriptionId));
+            }
+        }
+        return results;
     }
 
     @Override
diff --git a/src/com/android/phone/TelephonyShellCommand.java b/src/com/android/phone/TelephonyShellCommand.java
index dc1e7d1..9250118 100644
--- a/src/com/android/phone/TelephonyShellCommand.java
+++ b/src/com/android/phone/TelephonyShellCommand.java
@@ -55,6 +55,7 @@
     private static final String SMS_SET_DEFAULT_APP = "set-default-app";
 
     private static final String NUMBER_VERIFICATION_OVERRIDE_PACKAGE = "override-package";
+    private static final String NUMBER_VERIFICATION_FAKE_CALL = "fake-call";
 
     // Take advantage of existing methods that already contain permissions checks when possible.
     private final ITelephony mInterface;
@@ -141,6 +142,9 @@
         pw.println("  numverify override-package PACKAGE_NAME;");
         pw.println("    Set the authorized package for number verification.");
         pw.println("    Leave the package name blank to reset.");
+        pw.println("  numverify fake-call NUMBER;");
+        pw.println("    Fake an incoming call from NUMBER. This is for testing. Output will be");
+        pw.println("    1 if the call would have been intercepted, 0 otherwise.");
     }
 
     private int handleImsCommand() {
@@ -175,14 +179,21 @@
             return 0;
         }
 
+        if (!checkShellUid()) {
+            return -1;
+        }
+
         switch (arg) {
             case NUMBER_VERIFICATION_OVERRIDE_PACKAGE: {
-                if (!checkShellUid()) {
-                    return -1;
-                }
                 NumberVerificationManager.overrideAuthorizedPackage(getNextArg());
                 return 0;
             }
+            case NUMBER_VERIFICATION_FAKE_CALL: {
+                boolean val = NumberVerificationManager.getInstance()
+                        .checkIncomingCall(getNextArg());
+                getOutPrintWriter().println(val ? "1" : "0");
+                return 0;
+            }
         }
 
         return -1;
@@ -439,6 +450,8 @@
     }
 
     private boolean checkShellUid() {
-        return Binder.getCallingUid() == Process.SHELL_UID;
+        // adb can run as root or as shell, depending on whether the device is rooted.
+        return Binder.getCallingUid() == Process.SHELL_UID
+                || Binder.getCallingUid() == Process.ROOT_UID;
     }
 }
diff --git a/src/com/android/phone/ecc/IsoToEccProtobufRepository.java b/src/com/android/phone/ecc/IsoToEccProtobufRepository.java
index 0cd3108..7d9b4f0 100644
--- a/src/com/android/phone/ecc/IsoToEccProtobufRepository.java
+++ b/src/com/android/phone/ecc/IsoToEccProtobufRepository.java
@@ -25,6 +25,7 @@
 
 import androidx.annotation.NonNull;
 import androidx.annotation.Nullable;
+import androidx.annotation.VisibleForTesting;
 
 import java.io.BufferedInputStream;
 import java.io.IOException;
@@ -109,6 +110,11 @@
         }
     }
 
+    @VisibleForTesting(otherwise = VisibleForTesting.PRIVATE)
+    Map<String, CountryEccInfo> getEccTable() {
+        return mEccTable;
+    }
+
     private ProtobufEccData.AllInfo parseEccData(InputStream input) throws IOException {
         return ProtobufEccData.AllInfo.parseFrom(new GZIPInputStream(input));
     }
diff --git a/src/com/android/services/telephony/TelephonyConnectionService.java b/src/com/android/services/telephony/TelephonyConnectionService.java
index f986994..8ae7b8a 100644
--- a/src/com/android/services/telephony/TelephonyConnectionService.java
+++ b/src/com/android/services/telephony/TelephonyConnectionService.java
@@ -433,7 +433,7 @@
                         // been powered on and isn't in the UNAVAILABLE state, even if it is
                         // reporting the OUT_OF_SERVICE state.
                         return (phone.getState() == PhoneConstants.State.OFFHOOK)
-                            || phone.getServiceStateTracker().isRadioOn();
+                            || phone.getServiceState().getState() != ServiceState.STATE_POWER_OFF;
                     } else {
                         // It is not an emergency number, so wait until we are in service and ready
                         // to make calls. This can happen when we power down the radio on bluetooth
diff --git a/tests/src/com/android/phone/ecc/IsoToEccProtobufRepositoryTest.java b/tests/src/com/android/phone/ecc/IsoToEccProtobufRepositoryTest.java
new file mode 100644
index 0000000..f6e5ba2
--- /dev/null
+++ b/tests/src/com/android/phone/ecc/IsoToEccProtobufRepositoryTest.java
@@ -0,0 +1,81 @@
+/*
+ * 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 static com.google.common.truth.Truth.assertThat;
+
+import android.support.test.InstrumentationRegistry;
+import android.support.test.runner.AndroidJUnit4;
+import android.util.Log;
+
+import com.android.TelephonyTestBase;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.util.HashSet;
+import java.util.Map;
+
+/**
+ * Unit tests for IsoToEccProtobufRepository.
+ */
+
+@RunWith(AndroidJUnit4.class)
+public class IsoToEccProtobufRepositoryTest extends TelephonyTestBase {
+    private static final String LOG_TAG = "IsoToEccProtobufRepositoryTest";
+
+    @Test
+    public void testEccDataContent() {
+        IsoToEccProtobufRepository repository = IsoToEccProtobufRepository.getInstance();
+        repository.loadMappingTable(InstrumentationRegistry.getTargetContext());
+        Map<String, CountryEccInfo> eccTable = repository.getEccTable();
+        HashSet loadedIsos = new HashSet(300);
+        HashSet loadedNumbers = new HashSet(5);
+
+        assertThat(eccTable).isNotEmpty();
+        for (Map.Entry<String, CountryEccInfo> entry : eccTable.entrySet()) {
+            String countryIso = entry.getKey();
+            CountryEccInfo countryEccInfo = entry.getValue();
+            EccInfo[] eccInfoList = countryEccInfo.getEccInfoList();
+            if (eccInfoList.length > 0) {
+                Log.i(LOG_TAG, "Verifying country " + countryIso + " with "
+                        + eccInfoList.length + " ecc(s)");
+            } else {
+                Log.w(LOG_TAG, "Verifying country " + countryIso + " with no ecc");
+            }
+
+            assertThat(countryIso).isNotEmpty();
+            assertThat(countryIso).isEqualTo(countryIso.toUpperCase().trim());
+            assertThat(loadedIsos.contains(countryIso)).isFalse();
+            loadedIsos.add(countryIso);
+
+            assertThat(countryEccInfo.getFallbackEcc()).isNotEmpty();
+
+            if (eccInfoList.length != 0) {
+                loadedNumbers.clear();
+                for (EccInfo eccInfo : eccInfoList) {
+                    String eccNumber = eccInfo.getNumber();
+                    assertThat(eccNumber).isNotEmpty();
+                    assertThat(eccNumber).isEqualTo(eccNumber.trim());
+                    assertThat(eccInfo.getTypes()).isNotEmpty();
+                    assertThat(loadedNumbers.contains(eccNumber)).isFalse();
+                    loadedNumbers.add(eccNumber);
+                }
+            }
+        }
+    }
+}