Merge "Wire up the stopRtt API"
diff --git a/res/drawable-hdpi/ic_emergency_number_24.png b/res/drawable-hdpi/ic_emergency_number_24.png
deleted file mode 100644
index d5c0b28..0000000
--- a/res/drawable-hdpi/ic_emergency_number_24.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-hdpi/ic_fire_white_24.png b/res/drawable-hdpi/ic_fire_white_24.png
deleted file mode 100644
index 0c0c6ed..0000000
--- a/res/drawable-hdpi/ic_fire_white_24.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-hdpi/ic_shield_white_24.png b/res/drawable-hdpi/ic_shield_white_24.png
deleted file mode 100644
index bf23794..0000000
--- a/res/drawable-hdpi/ic_shield_white_24.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-mdpi/ic_emergency_number_24.png b/res/drawable-mdpi/ic_emergency_number_24.png
deleted file mode 100644
index 3db2d19..0000000
--- a/res/drawable-mdpi/ic_emergency_number_24.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-mdpi/ic_fire_white_24.png b/res/drawable-mdpi/ic_fire_white_24.png
deleted file mode 100644
index de8fda9..0000000
--- a/res/drawable-mdpi/ic_fire_white_24.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-mdpi/ic_shield_white_24.png b/res/drawable-mdpi/ic_shield_white_24.png
deleted file mode 100644
index 9a5d958..0000000
--- a/res/drawable-mdpi/ic_shield_white_24.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xhdpi/ic_emergency_number_24.png b/res/drawable-xhdpi/ic_emergency_number_24.png
deleted file mode 100644
index b538c02..0000000
--- a/res/drawable-xhdpi/ic_emergency_number_24.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xhdpi/ic_fire_white_24.png b/res/drawable-xhdpi/ic_fire_white_24.png
deleted file mode 100644
index 750072e..0000000
--- a/res/drawable-xhdpi/ic_fire_white_24.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xhdpi/ic_shield_white_24.png b/res/drawable-xhdpi/ic_shield_white_24.png
deleted file mode 100644
index e886233..0000000
--- a/res/drawable-xhdpi/ic_shield_white_24.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xxhdpi/ic_emergency_number_24.png b/res/drawable-xxhdpi/ic_emergency_number_24.png
deleted file mode 100644
index 13f253b..0000000
--- a/res/drawable-xxhdpi/ic_emergency_number_24.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xxhdpi/ic_fire_white_24.png b/res/drawable-xxhdpi/ic_fire_white_24.png
deleted file mode 100644
index 37c6ecd..0000000
--- a/res/drawable-xxhdpi/ic_fire_white_24.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xxhdpi/ic_shield_white_24.png b/res/drawable-xxhdpi/ic_shield_white_24.png
deleted file mode 100644
index 1621836..0000000
--- a/res/drawable-xxhdpi/ic_shield_white_24.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xxxhdpi/ic_fire_white_24.png b/res/drawable-xxxhdpi/ic_fire_white_24.png
deleted file mode 100644
index fb1d630..0000000
--- a/res/drawable-xxxhdpi/ic_fire_white_24.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xxxhdpi/ic_shield_white_24.png b/res/drawable-xxxhdpi/ic_shield_white_24.png
deleted file mode 100644
index 8b9f129..0000000
--- a/res/drawable-xxxhdpi/ic_shield_white_24.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable/btn_emergency_confirm_information.xml b/res/drawable/btn_emergency_confirm_information.xml
new file mode 100644
index 0000000..22b3069
--- /dev/null
+++ b/res/drawable/btn_emergency_confirm_information.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">
+    <corners android:radius="8dp"/>
+    <solid android:color="@color/emergency_shortcut_confirm_button_background_color"/>
+</shape>
\ No newline at end of file
diff --git a/res/drawable/btn_emergency_confirm_shortcuts.xml b/res/drawable/btn_emergency_confirm_shortcuts.xml
new file mode 100644
index 0000000..22b3069
--- /dev/null
+++ b/res/drawable/btn_emergency_confirm_shortcuts.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">
+    <corners android:radius="8dp"/>
+    <solid android:color="@color/emergency_shortcut_confirm_button_background_color"/>
+</shape>
\ No newline at end of file
diff --git a/res/drawable/btn_emergency_information.xml b/res/drawable/btn_emergency_information.xml
new file mode 100644
index 0000000..29b4a7a
--- /dev/null
+++ b/res/drawable/btn_emergency_information.xml
@@ -0,0 +1,22 @@
+<?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"/>
+    <!-- White, Opacity 16% -->
+    <stroke android:width="1dp"
+            android:color="#40FFFFFF"/>
+</shape>
\ No newline at end of file
diff --git a/res/drawable/btn_emergency_shortcuts.xml b/res/drawable/btn_emergency_shortcuts.xml
index 063a824..449e4e0 100644
--- a/res/drawable/btn_emergency_shortcuts.xml
+++ b/res/drawable/btn_emergency_shortcuts.xml
@@ -16,4 +16,5 @@
 <shape xmlns:android="http://schemas.android.com/apk/res/android"
        android:shape="rectangle">
     <corners android:radius="8dp"/>
+    <solid android:color="@color/emergency_shortcut_button_background_color"/>
 </shape>
\ No newline at end of file
diff --git a/res/drawable/emergency_shortcuts_divider.xml b/res/drawable/emergency_shortcuts_divider.xml
index 988ffc5..930d563 100644
--- a/res/drawable/emergency_shortcuts_divider.xml
+++ b/res/drawable/emergency_shortcuts_divider.xml
@@ -15,6 +15,6 @@
 -->
 <shape xmlns:android="http://schemas.android.com/apk/res/android"
        android:shape="rectangle">
-    <size android:height="1px"/>
-    <solid android:color="#33FFFFFF"/>
+    <size android:height="8dp"/>
+    <solid android:color="@android:color/transparent"/>
 </shape>
diff --git a/res/drawable/ic_local_fire_department_gm2_24px.xml b/res/drawable/ic_local_fire_department_gm2_24px.xml
new file mode 100644
index 0000000..a99792c
--- /dev/null
+++ b/res/drawable/ic_local_fire_department_gm2_24px.xml
@@ -0,0 +1,28 @@
+<!--
+  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.
+  -->
+
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+        android:width="24dp"
+        android:height="24dp"
+        android:viewportWidth="24"
+        android:viewportHeight="24">
+    <path
+        android:fillColor="#FFFFFFFF"
+        android:pathData="M12.06,3.74c0.26,1.65 1.03,3.21 2.26,4.46c0.53,0.53 1.09,0.95 1.59,1.33c0.38,0.29 0.74,0.55 1.04,0.83c0.3,0.28 0.54,0.55 0.74,0.82l0.03,0.03l0.03,0.03c0.27,0.34 0.52,0.74 0.72,1.15l0.05,0.1c0.02,0.04 0.03,0.07 0.05,0.11l0.02,0.04l0.02,0.04c0.88,2.11 0.31,4.6 -1.4,6.19c-1.45,1.34 -3.35,1.62 -4.69,1.62c-0.42,0 -0.86,-0.03 -1.29,-0.08c-1.87,-0.24 -3.67,-1.45 -4.71,-3.18c-0.31,-0.51 -0.56,-1.08 -0.74,-1.72c-0.11,-0.38 -0.18,-0.79 -0.22,-1.23c0.03,0.05 0.07,0.09 0.1,0.14c0.14,0.2 0.29,0.34 0.38,0.43l0.02,0.02l0.02,0.02c0.53,0.5 1.21,0.78 1.91,0.78c0.2,0 0.72,-0.02 1.17,-0.23c0.99,-0.43 1.63,-1.41 1.63,-2.49c0,-0.37 -0.08,-0.67 -0.14,-0.88l-0.03,-0.13l-0.05,-0.12C9.48,9.01 10.1,5.89 12.06,3.74M13.88,0c-0.06,0 -0.11,0.01 -0.17,0.04c-0.78,0.34 -1.43,0.83 -2.08,1.36C8.37,4.05 7.16,8.51 8.67,12.53c0.03,0.14 0.09,0.29 0.09,0.43c0,0.29 -0.18,0.55 -0.43,0.66c-0.09,0.04 -0.27,0.06 -0.37,0.06c-0.19,0 -0.38,-0.09 -0.53,-0.23c-0.07,-0.07 -0.13,-0.13 -0.19,-0.21C6.2,11.86 5.8,10 6.1,8.28c0.05,-0.29 -0.18,-0.5 -0.41,-0.5c-0.12,0 -0.23,0.05 -0.32,0.16c-1.32,1.72 -1.98,4.03 -1.85,6.2c0.04,0.65 0.14,1.29 0.32,1.92c0.22,0.78 0.54,1.54 0.96,2.23c1.32,2.21 3.65,3.8 6.16,4.11c0.51,0.07 1.03,0.1 1.54,0.1c2.19,0 4.38,-0.62 6.05,-2.15c2.29,-2.12 3.12,-5.49 1.89,-8.43c-0.04,-0.12 -0.1,-0.23 -0.15,-0.35c-0.27,-0.57 -0.6,-1.11 -1,-1.59c-0.3,-0.39 -0.62,-0.75 -0.97,-1.08c-0.82,-0.77 -1.78,-1.32 -2.58,-2.12c-1.63,-1.66 -2.19,-3.99 -1.47,-6.21C14.37,0.28 14.15,0 13.88,0L13.88,0z"/>
+    <path
+        android:fillColor="#FFFFFFFF"
+        android:pathData="M12.93,18.32c-0.56,0 -1.12,-0.16 -1.67,-0.49c-0.08,-0.05 -0.13,-0.13 -0.12,-0.22c0,-0.09 0.06,-0.17 0.14,-0.21c0.98,-0.49 1.67,-1.37 1.9,-2.42c0.17,-0.76 0,-1.44 -0.16,-2.09c-0.07,-0.28 -0.13,-0.52 -0.17,-0.78c-0.06,-0.38 -0.09,-0.72 -0.07,-1.03c0,-0.1 0.07,-0.2 0.17,-0.23c0.1,-0.03 0.21,0 0.27,0.08c0.33,0.42 0.73,0.8 1.12,1.16c0.74,0.69 1.49,1.38 1.68,2.35c0.03,0.18 0.05,0.33 0.05,0.47c0.03,0.97 -0.38,1.99 -1.05,2.59c-0.31,0.27 -0.83,0.56 -1.24,0.69C13.5,18.27 13.22,18.32 12.93,18.32z"/>
+</vector>
\ No newline at end of file
diff --git a/res/drawable/ic_local_hospital_gm2_24px.xml b/res/drawable/ic_local_hospital_gm2_24px.xml
new file mode 100644
index 0000000..2e535f2
--- /dev/null
+++ b/res/drawable/ic_local_hospital_gm2_24px.xml
@@ -0,0 +1,28 @@
+<!--
+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.
+-->
+
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+        android:width="24dp"
+        android:height="24dp"
+        android:viewportWidth="24"
+        android:viewportHeight="24">
+    <path
+        android:fillColor="#FFFFFFFF"
+        android:pathData="M19,3H5C3.9,3 3.01,3.9 3.01,5L3,19c0,1.1 0.9,2 2,2h14c1.1,0 2,-0.9 2,-2V5C21,3.9 20.1,3 19,3zM19,19L5,19V5h14V19z"/>
+    <path
+        android:fillColor="#FFFFFFFF"
+        android:pathData="M10.5,17l3,0l0,-3.5l3.5,0l0,-3l-3.5,0l0,-3.5l-3,0l0,3.5l-3.5,0l0,3l3.5,0z"/>
+</vector>
\ No newline at end of file
diff --git a/res/drawable/ic_local_police_gm2_24px.xml b/res/drawable/ic_local_police_gm2_24px.xml
new file mode 100644
index 0000000..c65d0b1
--- /dev/null
+++ b/res/drawable/ic_local_police_gm2_24px.xml
@@ -0,0 +1,28 @@
+<!--
+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.
+-->
+
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+        android:width="24dp"
+        android:height="24dp"
+        android:viewportWidth="24"
+        android:viewportHeight="24">
+    <path
+        android:fillColor="#FFFFFFFF"
+        android:pathData="M19,6.3c0,1.57 0,3.13 0,4.7c0,4.52 -2.98,8.69 -7,9.93C7.98,19.69 5,15.52 5,11V6.3c2.33,-1.04 4.67,-2.07 7,-3.11C14.33,4.23 16.67,5.26 19,6.3zM12,1L3,5v6c0,5.55 3.84,10.74 9,12c5.16,-1.26 9,-6.45 9,-12V5L12,1z"/>
+    <path
+        android:fillColor="#FFFFFFFF"
+        android:pathData="M13.54,9.66l-1.54,-3.64l-1.54,3.65l-3.96,0.34l3,2.59l-0.9,3.87l3.4,-2.05l3.4,2.05l-0.9,-3.88l3,-2.59z"/>
+</vector>
\ No newline at end of file
diff --git a/res/drawable/place_gm2_24px.xml b/res/drawable/place_gm2_24px.xml
new file mode 100644
index 0000000..4fd2274
--- /dev/null
+++ b/res/drawable/place_gm2_24px.xml
@@ -0,0 +1,28 @@
+<!--
+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.
+-->
+
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+        android:width="24dp"
+        android:height="24dp"
+        android:viewportWidth="24"
+        android:viewportHeight="24">
+    <path
+        android:fillColor="#FFFFFFFF"
+        android:pathData="M12,2C8.13,2 5,5.13 5,9c0,5.25 7,13 7,13s7,-7.75 7,-13C19,5.13 15.87,2 12,2zM7,9c0,-2.76 2.24,-5 5,-5s5,2.24 5,5c0,2.88 -2.88,7.19 -5,9.88C9.92,16.21 7,11.85 7,9z"/>
+    <path
+        android:fillColor="#FFFFFFFF"
+        android:pathData="M12,9m-2.5,0a2.5,2.5 0,1 1,5 0a2.5,2.5 0,1 1,-5 0"/>
+</vector>
\ No newline at end of file
diff --git a/res/layout/emergency_dialer.xml b/res/layout/emergency_dialer.xml
index 7f99664..491b661 100644
--- a/res/layout/emergency_dialer.xml
+++ b/res/layout/emergency_dialer.xml
@@ -38,8 +38,8 @@
             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">
+            android:layout_gravity="bottom|center"
+            android:layout_marginBottom="@dimen/emergency_dialer_dialpad_button_margin">
             <ImageButton
                 android:id="@+id/floating_action_button_dialpad"
                 android:layout_width="@dimen/dialpad_button_width"
diff --git a/res/layout/emergency_information.xml b/res/layout/emergency_information.xml
index c4ab74b..e925479 100644
--- a/res/layout/emergency_information.xml
+++ b/res/layout/emergency_information.xml
@@ -16,62 +16,92 @@
 <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_height="@dimen/emergency_info_button_height"
     android:layout_width="match_parent"
-    android:layout_marginTop="@dimen/emergency_info_button_margin_top">
-    <LinearLayout
+    android:layout_marginHorizontal="@dimen/emergency_shortcut_buttons_margin_horizontal"
+    android:layout_marginVertical="@dimen/emergency_info_button_margin_vertical">
+    <FrameLayout
+        android:id="@+id/emergency_info_view"
         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">
+        android:background="@drawable/btn_emergency_information"
+        android:focusable="true"
+        android:clickable="true" >
+        <LinearLayout
+            android:layout_height="match_parent"
+            android:layout_width="match_parent"
+            android:orientation="horizontal">
             <ImageView
                 android:id="@+id/emergency_info_image"
+                android:layout_gravity="center_vertical|start"
+                android:layout_marginStart="@dimen/emergency_dialer_image_margin_start"
+                android:layout_marginEnd="@dimen/emergency_dialer_image_margin_end"
                 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"
+            <LinearLayout
                 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"/>
+                android:layout_width="match_parent"
+                android:layout_marginEnd="@dimen/emergency_info_text_margin_end"
+                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:lineHeight="@dimen/emergency_info_name_line_height"
+                    android:fontFamily="google-sans"
+                    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>
-    </LinearLayout>
+    </FrameLayout>
 
     <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"/>
+        android:id="@+id/emergency_info_confirm_view"
+        android:layout_height="match_parent"
+        android:layout_width="match_parent"
+        android:background="@drawable/btn_emergency_confirm_information"
+        android:focusable="true"
+        android:clickable="true"
+        android:visibility="invisible" >
+        <LinearLayout
+            android:layout_height="match_parent"
+            android:layout_width="match_parent"
+            android:orientation="horizontal">
+            <ImageView
+                android:id="@+id/confirmed_emergency_info_image"
+                android:layout_gravity="center_vertical|start"
+                android:layout_height="@dimen/emergency_info_image_height"
+                android:layout_width="@dimen/emergency_info_image_width"
+                android:layout_marginStart="@dimen/emergency_dialer_image_margin_start"
+                android:layout_marginEnd="@dimen/emergency_dialer_image_margin_end"
+                android:scaleType="centerCrop"/>
+            <TextView
+                android:id="@+id/confirmed_emergency_info"
+                android:layout_height="wrap_content"
+                android:layout_width="wrap_content"
+                android:layout_gravity="center_vertical"
+                android:layout_marginEnd="@dimen/emergency_info_text_margin_end"
+                android:includeFontPadding="false"
+                android:maxLines="2"
+                android:ellipsize="end"
+                android:lineHeight="@dimen/confirmed_emergency_info_line_height"
+                android:fontFamily="google-sans"
+                android:textAppearance="@style/PhoneCallHintTextAppearance"
+                android:text="@string/emergency_information_confirm_hint"/>
+        </LinearLayout>
     </FrameLayout>
 </com.android.phone.EmergencyInfoGroup>
diff --git a/res/layout/emergency_shortcut_button.xml b/res/layout/emergency_shortcut_button.xml
index 6087dba..136db0c 100644
--- a/res/layout/emergency_shortcut_button.xml
+++ b/res/layout/emergency_shortcut_button.xml
@@ -22,20 +22,21 @@
         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:background="@drawable/btn_emergency_shortcuts"
         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_width="match_parent"
+            android:layout_marginEnd="@dimen/emergency_shortcuts_margin_end"
             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:layout_marginStart="@dimen/emergency_dialer_image_margin_start"
+                android:layout_marginEnd="@dimen/emergency_dialer_image_margin_end"
                 android:background="@drawable/phone_type_icon_background">
                 <ImageView
                     android:id="@+id/phone_type_icon"
@@ -55,21 +56,24 @@
                     android:includeFontPadding="false"
                     android:maxLines="1"
                     android:ellipsize="end"
-                    android:textAppearance="@style/HeadlineTextAppearance"/>
+                    android:lineHeight="@dimen/phone_number_line_height"
+                    android:fontFamily="google-sans"
+                    android:textAppearance="@style/PhoneNumberTextAppearance"/>
                 <TextView
                     android:id="@+id/phone_number_description"
                     android:layout_height="wrap_content"
                     android:layout_width="wrap_content"
-                    android:alpha="0.8"
+                    android:alpha="0.7"
                     android:maxLines="1"
                     android:ellipsize="end"
+                    android:fontFamily="sans-serif-medium"
                     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_marginEnd="@dimen/emergency_dialer_image_margin_end"
             android:layout_gravity="center_vertical|end">
             <ImageView
                 android:id="@+id/microphone_icon"
@@ -84,21 +88,22 @@
         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:background="@drawable/btn_emergency_confirm_shortcuts"
         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_width="match_parent"
+            android:layout_marginEnd="@dimen/emergency_shortcuts_margin_end"
             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:layout_marginStart="@dimen/emergency_dialer_image_margin_start"
+                android:layout_marginEnd="@dimen/emergency_dialer_image_margin_end"
                 android:background="@drawable/phone_type_icon_background"
                 android:backgroundTint="@android:color/white">
                 <ImageView
@@ -119,13 +124,15 @@
                     android:maxLines="2"
                     android:ellipsize="end"
                     android:lineHeight="@dimen/phone_call_hint_line_height"
-                    android:textAppearance="@style/ShortcutsHintTextAppearance"/>
+                    android:fontFamily="google-sans"
+                    android:textAppearance="@style/PhoneCallHintTextAppearance"/>
             </FrameLayout>
         </LinearLayout>
         <FrameLayout
             android:layout_height="wrap_content"
             android:layout_width="wrap_content"
-            android:layout_marginHorizontal="@dimen/emergency_dialer_image_margin_horizontal"
+            android:layout_marginStart="@dimen/emergency_dialer_image_margin_start"
+            android:layout_marginEnd="@dimen/emergency_dialer_image_margin_end"
             android:layout_gravity="center_vertical|end">
             <ImageView
                 android:layout_height="@dimen/phone_icon_height"
diff --git a/res/layout/emergency_shortcut_buttons_group.xml b/res/layout/emergency_shortcut_buttons_group.xml
index 619eac6..bafedd1 100644
--- a/res/layout/emergency_shortcut_buttons_group.xml
+++ b/res/layout/emergency_shortcut_buttons_group.xml
@@ -18,13 +18,12 @@
     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">
+        android:layout_marginHorizontal="@dimen/emergency_number_title_group_padding_horizontal">
         <FrameLayout
             android:id="@+id/emergency_number_title_container"
             android:layout_height="wrap_content"
@@ -35,8 +34,10 @@
                 android:layout_height="wrap_content"
                 android:layout_width="wrap_content"
                 android:layout_gravity="start"
-                android:maxLines="1"
+                android:maxLines="2"
                 android:ellipsize="end"
+                android:lineHeight="@dimen/emergency_number_title_line_height"
+                android:fontFamily="sans-serif-medium"
                 android:textAppearance="@style/SubtitleTextAppearance"
                 android:text="@string/single_emergency_number_title"/>
         </FrameLayout>
@@ -53,14 +54,15 @@
                 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"/>
+                android:src="@drawable/place_gm2_24px"/>
             <TextView
                 android:id="@+id/location_text"
                 android:layout_height="wrap_content"
                 android:layout_width="wrap_content"
-                android:paddingStart="4dp"
-                android:maxLines="1"
+                android:layout_marginStart="@dimen/location_text_margin_start"
+                android:maxLines="2"
                 android:ellipsize="end"
+                android:lineHeight="@dimen/location_text_line_height"
                 android:textAppearance="@style/SubtitleTextAppearance"/>
         </LinearLayout>
     </FrameLayout>
@@ -71,7 +73,6 @@
         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">
+        android:showDividers="middle">
     </LinearLayout>
 </LinearLayout>
\ No newline at end of file
diff --git a/res/values/colors.xml b/res/values/colors.xml
index 7136819..cc6f727 100644
--- a/res/values/colors.xml
+++ b/res/values/colors.xml
@@ -54,6 +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_button_background_color">#40FFFFFF</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 97417bd..b657e64 100644
--- a/res/values/dimens.xml
+++ b/res/values/dimens.xml
@@ -115,28 +115,29 @@
     <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>
+    <dimen name="emergency_dialer_image_margin_start">20dp</dimen>
+    <dimen name="emergency_dialer_image_margin_end">16dp</dimen>
 
     <!-- Margin of dialpad button -->
-    <dimen name="emergency_dialer_dialpad_button_margin">16dp</dimen>
+    <dimen name="emergency_dialer_dialpad_button_margin">40dp</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>
+    <!-- Height and vertical margin for the emergency information button. -->
+    <dimen name="emergency_info_button_height">96dp</dimen>
+    <dimen name="emergency_info_button_margin_vertical">56dp</dimen>
+    <dimen name="emergency_info_button_fix_margin_vertical">40dp</dimen>
+
+    <!-- Margin for the emergency information button text. -->
+    <dimen name="emergency_info_text_margin_end">20dp</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>
+    <dimen name="emergency_info_image_height">40dp</dimen>
+    <dimen name="emergency_info_image_width">40dp</dimen>
 
     <!-- The height and width for the function icon of emergency shortcuts. -->
     <dimen name="emergency_shortcuts_function_icon_height">24dp</dimen>
@@ -150,11 +151,11 @@
     <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>
+    <dimen name="location_image_height">16dp</dimen>
+    <dimen name="location_image_width">16dp</dimen>
 
     <!-- The height for button of emergency shortcut. -->
-    <dimen name="emergency_shortcut_button_height">80dp</dimen>
+    <dimen name="emergency_shortcut_button_height">96dp</dimen>
 
     <!-- The height and width for the circle image of phone number type.-->
     <dimen name="phone_number_type_circle_image_height">40dp</dimen>
@@ -168,9 +169,30 @@
     <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>
+    <!-- Margin for the emergency shortcut button.-->
+    <dimen name="emergency_shortcuts_margin_end">60dp</dimen>
+
+    <!-- The line height and margin start for location text.-->
+    <dimen name="location_text_line_height">20sp</dimen>
+    <dimen name="location_text_margin_start">4dp</dimen>
+
+    <!-- The line height for emergency number title.-->
+    <dimen name="emergency_number_title_line_height">20sp</dimen>
+
+    <!-- The line height for phone number.-->
+    <dimen name="phone_number_line_height">40sp</dimen>
+
+    <!-- The line height for phone call hint.-->
+    <dimen name="phone_call_hint_line_height">24sp</dimen>
+
+    <!-- The line height for emergency info name.-->
+    <dimen name="emergency_info_name_line_height">28sp</dimen>
+
+    <!-- The line height for emergency info hint.-->
+    <dimen name="emergency_info_hint_line_height">20sp</dimen>
+
+    <!-- The line height for confirmed emergency info.-->
+    <dimen name="confirmed_emergency_info_line_height">24sp</dimen>
 
     <!-- The width for emergency number title container.-->
     <dimen name="emergency_number_title_container_width">210dp</dimen>
diff --git a/res/values/strings.xml b/res/values/strings.xml
index de14389..9e55501 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -382,6 +382,8 @@
     <string name="already_auto">Already in automatic selection.</string>
     <!-- Available networks screen, name of switch button for whether to select network automatically -->
     <string name="select_automatically">Automatically select network</string>
+    <!-- Available networks screen, summary when button disallowed due to permanent automatic mode -->
+    <string name="manual_mode_disallowed_summary">Unavailable when connected to %1$s</string>
     <!-- Available networks screen, name of button when user wants to select network manually  -->
     <string name="network_select_title">Network</string>
     <string name="register_automatically">Automatic registration\u2026</string>
@@ -517,7 +519,15 @@
     <!-- Mobile network 4G title [CHAR LIMIT=30] -->
     <string name="enhanced_4g_lte_mode_title">Enhanced 4G LTE Mode</string>
     <!-- Carrier variant of Enhaced 4G LTE Mode title.  [CHAR LIMIT=50] -->
-    <string name="enhanced_4g_lte_mode_title_variant">Advanced Calling</string>
+    <string-array name="enhanced_4g_lte_mode_title_variant">
+        <!-- 0: Default -->
+        <item>@string/enhanced_4g_lte_mode_title</item>
+        <!-- 1: Verizon -->
+        <item>Advanced Calling</item>
+        <!-- 2: O2 UK -->
+        <item>4G Calling</item>
+    </string-array>
+
     <!-- Mobile network 4G summary [CHAR LIMIT=80] -->
     <string name="enhanced_4g_lte_mode_summary">Use LTE services to improve voice and other communications (recommended)</string>
 
@@ -1126,6 +1136,8 @@
     <string name="emergency_information_hint">Emergency information</string>
     <!-- Hint for the owner of emergency information -->
     <string name="emergency_information_owner_hint">Owner</string>
+    <!-- Hint for confirm the emergency information -->
+    <string name="emergency_information_confirm_hint">Tap again to view info</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 -->
@@ -1790,4 +1802,17 @@
     <!-- Message displayed to the user to indicate that a held call has been released /
          disconnected. -->
     <string name="supp_service_held_call_released">Held call has been released.</string>
+
+    <!-- In-call screen: error message shown when the user has attempted to place a new outgoing
+         call, but there is already a call in dialing state. -->
+    <string name="callFailed_already_dialing">Cannot place a call as another outgoing call is already dialing.</string>
+    <!-- In-call screen: error message shown when the user has attempted to place a new outgoing
+         call while there is already a call in ringing state. -->
+    <string name="callFailed_already_ringing">Cannot place a call as there is an unanswered incoming call.  Answer or reject the incoming call prior to placing a new call.</string>
+    <!-- In-call screen: error message shown when the user attempts to place a call, but calling has
+         been disabled using a debug property. -->
+    <string name="callFailed_calling_disabled">Cannot place a call as calling has been disabled using the ro.telephony.disable-call system property.</string>
+    <!-- In-call screen: error message shown when the user attempts to place a call, but calling has
+         been disabled using a debug property. -->
+    <string name="callFailed_too_many_calls">Cannot place a call a there are already two calls in progress.  Disconnect one of the calls or merge them into a conference prior to placing a new call.</string>
 </resources>
diff --git a/res/values/styles.xml b/res/values/styles.xml
index 73b5c40..6093cee 100644
--- a/res/values/styles.xml
+++ b/res/values/styles.xml
@@ -316,13 +316,22 @@
 
     <style name="HeadlineTextAppearance">
         <item name="android:textColor">@android:color/white</item>
-        <item name="android:textSize">24sp</item>
+        <item name="android:textSize">22sp</item>
     </style>
 
     <style name="SubtitleTextAppearance" parent="@style/HeadlineTextAppearance">
         <item name="android:textSize">14sp</item>
     </style>
 
+    <style name="PhoneNumberTextAppearance">
+        <item name="android:textColor">@android:color/white</item>
+        <item name="android:textSize">32sp</item>
+    </style>
+
+    <style name="PhoneCallHintTextAppearance" parent="@style/PhoneNumberTextAppearance">
+        <item name="android:textSize">18sp</item>
+    </style>
+
     <style name="ShortcutsHintTextAppearance" parent="@style/HeadlineTextAppearance">
         <item name="android:textSize">16sp</item>
     </style>
diff --git a/src/com/android/phone/CallGatewayManager.java b/src/com/android/phone/CallGatewayManager.java
index bdac983..1dd75c4 100644
--- a/src/com/android/phone/CallGatewayManager.java
+++ b/src/com/android/phone/CallGatewayManager.java
@@ -16,184 +16,19 @@
 
 package com.android.phone;
 
-import android.content.Intent;
 import android.net.Uri;
-import android.telecom.PhoneAccount;
-import android.telephony.PhoneNumberUtils;
 import android.text.TextUtils;
-import android.util.Log;
-
-import com.android.internal.telephony.Connection;
-
-import java.util.concurrent.ConcurrentHashMap;
 
 /**
- * This class manages gateway information for outgoing calls. When calls are made, they may contain
- * gateway information for services which route phone calls through their own service/numbers.
- * The data consists of a number to call and the package name of the service. This data is used in
- * two ways:<br/>
- * 1. Call the appropriate routing number<br/>
- * 2. Display information about the routing to the user<br/>
- *
- * <p>When an outgoing call is finally placed in PhoneUtils.placeCall, it uses this class to get the
- * proper number to dial. It also saves an association between the connection object and the gateway
- * data into this class.
+ * TODO: Not much of this class is even used any more.  Need to unwind the RawGatewayInfo class as
+ * it is used in part of the placeCall method used in OTASP.
  */
 public class CallGatewayManager {
-    private static final String LOG_TAG = CallGatewayManager.class.getSimpleName();
-
-    /**
-     * Intent extra to specify the package name of the gateway
-     * provider.  Used to get the name displayed in the in-call screen
-     * during the call setup. The value is a string.
-     */
-    // TODO: This extra is currently set by the gateway application as
-    // a temporary measure. Ultimately, the framework will securely
-    // set it.
-    /* package */ static final String EXTRA_GATEWAY_PROVIDER_PACKAGE =
-            "com.android.phone.extra.GATEWAY_PROVIDER_PACKAGE";
-
-    /**
-     * Intent extra to specify the URI of the provider to place the
-     * call. The value is a string. It holds the gateway address
-     * (phone gateway URL should start with the 'tel:' scheme) that
-     * will actually be contacted to call the number passed in the
-     * intent URL or in the EXTRA_PHONE_NUMBER extra.
-     */
-    // TODO: Should the value be a Uri (Parcelable)? Need to make sure
-    // MMI code '#' don't get confused as URI fragments.
-    /* package */ static final String EXTRA_GATEWAY_URI =
-            "com.android.phone.extra.GATEWAY_URI";
-
     public static final RawGatewayInfo EMPTY_INFO = new RawGatewayInfo(null, null, null);
 
-    private final ConcurrentHashMap<Connection, RawGatewayInfo> mMap =
-        new ConcurrentHashMap<Connection, RawGatewayInfo>(4, 0.9f, 1);
-
-    private static CallGatewayManager sSingleton;
-
-    public static synchronized CallGatewayManager getInstance() {
-        if (sSingleton == null) {
-            sSingleton = new CallGatewayManager();
-        }
-        return sSingleton;
-    }
-
     private CallGatewayManager() {
     }
 
-    /**
-     * Static method returns an object containing the gateway data stored in the extras of the
-     * Intent parameter.  If no such data exists, returns a Null-Object RawGatewayInfo.
-     * @param intent The intent from which to read gateway data.
-     * @return A populated or empty RawGatewayInfo object.
-     */
-    public static RawGatewayInfo getRawGatewayInfo(Intent intent, String number) {
-        if (hasPhoneProviderExtras(intent)) {
-            return new RawGatewayInfo(intent.getStringExtra(EXTRA_GATEWAY_PROVIDER_PACKAGE),
-                    getProviderGatewayUri(intent), number);
-        }
-        return EMPTY_INFO;
-    }
-
-    /**
-     * This function sets the current mapping from connection to gatewayInfo.
-     * @param connection The connection object for the placed outgoing call.
-     * @param gatewayInfo Gateway info gathered using getRawGatewayInfo.
-     */
-    public void setGatewayInfoForConnection(Connection connection, RawGatewayInfo gatewayInfo) {
-        if (!gatewayInfo.isEmpty()) {
-            mMap.put(connection, gatewayInfo);
-        } else {
-            mMap.remove(connection);
-        }
-    }
-
-    /**
-     * Clears the gateway information previously stored via setGatewayInfoForConnection.
-     */
-    public void clearGatewayData(Connection connection) {
-        setGatewayInfoForConnection(connection, EMPTY_INFO);
-    }
-
-    /**
-     * If the parameter matches the connection object we previously saved through
-     * setGatewayInfoForConnection, return the associated raw gateway info data. If not, then
-     * return an empty raw gateway info.
-     */
-    public RawGatewayInfo getGatewayInfo(Connection connection) {
-        final RawGatewayInfo info = mMap.get(connection);
-        if (info != null) {
-            return info;
-        }
-
-        return EMPTY_INFO;
-    }
-
-    /**
-     * Check if all the provider's info is present in the intent.
-     * @param intent Expected to have the provider's extra.
-     * @return true if the intent has all the extras to build the
-     * in-call screen's provider info overlay.
-     */
-    public static boolean hasPhoneProviderExtras(Intent intent) {
-        if (null == intent) {
-            return false;
-        }
-        final String name = intent.getStringExtra(EXTRA_GATEWAY_PROVIDER_PACKAGE);
-        final String gatewayUri = intent.getStringExtra(EXTRA_GATEWAY_URI);
-
-        return !TextUtils.isEmpty(name) && !TextUtils.isEmpty(gatewayUri);
-    }
-
-    /**
-     * Copy all the expected extras set when a 3rd party provider is
-     * used from the source intent to the destination one.  Checks all
-     * the required extras are present, if any is missing, none will
-     * be copied.
-     * @param src Intent which may contain the provider's extras.
-     * @param dst Intent where a copy of the extras will be added if applicable.
-     */
-    public static void checkAndCopyPhoneProviderExtras(Intent src, Intent dst) {
-        if (!hasPhoneProviderExtras(src)) {
-            Log.d(LOG_TAG, "checkAndCopyPhoneProviderExtras: some or all extras are missing.");
-            return;
-        }
-
-        dst.putExtra(EXTRA_GATEWAY_PROVIDER_PACKAGE,
-                     src.getStringExtra(EXTRA_GATEWAY_PROVIDER_PACKAGE));
-        dst.putExtra(EXTRA_GATEWAY_URI,
-                     src.getStringExtra(EXTRA_GATEWAY_URI));
-    }
-
-    /**
-     * Return the gateway uri from the intent.
-     * @param intent With the gateway uri extra.
-     * @return The gateway URI or null if not found.
-     */
-    public static Uri getProviderGatewayUri(Intent intent) {
-        final String uri = intent.getStringExtra(EXTRA_GATEWAY_URI);
-        return TextUtils.isEmpty(uri) ? null : Uri.parse(uri);
-    }
-
-    /**
-     * Return a formatted version of the uri's scheme specific
-     * part. E.g for 'tel:12345678', return '1-234-5678'.
-     * @param uri A 'tel:' URI with the gateway phone number.
-     * @return the provider's address (from the gateway uri) formatted
-     * for user display. null if uri was null or its scheme was not 'tel:'.
-     */
-    public static String formatProviderUri(Uri uri) {
-        if (uri != null) {
-            if (PhoneAccount.SCHEME_TEL.equals(uri.getScheme())) {
-                return PhoneNumberUtils.formatNumber(uri.getSchemeSpecificPart());
-            } else {
-                return uri.toString();
-            }
-        }
-        return null;
-    }
-
     public static class RawGatewayInfo {
         public String packageName;
         public Uri gatewayUri;
@@ -206,10 +41,6 @@
             this.trueNumber = trueNumber;
         }
 
-        public String getFormattedGatewayNumber() {
-            return formatProviderUri(gatewayUri);
-        }
-
         public boolean isEmpty() {
             return TextUtils.isEmpty(packageName) || gatewayUri == null;
         }
diff --git a/src/com/android/phone/CallLogger.java b/src/com/android/phone/CallLogger.java
deleted file mode 100644
index 60a2590..0000000
--- a/src/com/android/phone/CallLogger.java
+++ /dev/null
@@ -1,215 +0,0 @@
-/*
- * Copyright (C) 2013 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.net.Uri;
-import android.os.SystemProperties;
-import android.provider.CallLog.Calls;
-import android.telephony.DisconnectCause;
-import android.telephony.PhoneNumberUtils;
-import android.text.TextUtils;
-import android.util.Log;
-
-import com.android.internal.telephony.CallerInfo;
-import com.android.internal.telephony.Connection;
-import com.android.internal.telephony.Phone;
-import com.android.internal.telephony.PhoneConstants;
-import com.android.internal.telephony.TelephonyCapabilities;
-import com.android.phone.common.CallLogAsync;
-
-/**
- * Helper class for interacting with the call log.
- */
-class CallLogger {
-    private static final String LOG_TAG = CallLogger.class.getSimpleName();
-    private static final boolean DBG = (PhoneGlobals.DBG_LEVEL >= 1) &&
-        (SystemProperties.getInt("ro.debuggable", 0) == 1);
-    private static final boolean VDBG = (PhoneGlobals.DBG_LEVEL >= 2);
-
-    private PhoneGlobals mApplication;
-    private CallLogAsync mCallLog;
-
-    public CallLogger(PhoneGlobals application, CallLogAsync callLogAsync) {
-        mApplication = application;
-        mCallLog = callLogAsync;
-    }
-
-    /**
-     * Logs a call to the call log based on the connection object passed in.
-     *
-     * @param c The connection object for the call being logged.
-     * @param callLogType The type of call log entry.
-     */
-    public void logCall(Connection c, int callLogType) {
-        final String number = c.getAddress();
-        final long date = c.getCreateTime();
-        final long duration = c.getDurationMillis();
-        final Phone phone = c.getCall().getPhone();
-
-        final CallerInfo ci = getCallerInfoFromConnection(c);  // May be null.
-        final String logNumber = getLogNumber(c, ci);
-
-        if (DBG) {
-            log("- onDisconnect(): logNumber set to:" + PhoneUtils.toLogSafePhoneNumber(logNumber) +
-                ", number set to: " + PhoneUtils.toLogSafePhoneNumber(number));
-        }
-
-        // TODO: In getLogNumber we use the presentation from
-        // the connection for the CNAP. Should we use the one
-        // below instead? (comes from caller info)
-
-        // For international calls, 011 needs to be logged as +
-        final int presentation = getPresentation(c, ci);
-
-        final boolean isOtaspNumber = TelephonyCapabilities.supportsOtasp(phone)
-                && phone.isOtaSpNumber(number);
-
-        // Don't log OTASP calls.
-        if (!isOtaspNumber) {
-            logCall(ci, logNumber, presentation, callLogType, date, duration);
-        }
-    }
-
-    /**
-     * Came as logCall(Connection,int) but calculates the call type from the connection object.
-     */
-    public void logCall(Connection c) {
-        final int cause = c.getDisconnectCause();
-
-        // Set the "type" to be displayed in the call log (see constants in CallLog.Calls)
-        final int callLogType;
-
-        if (c.isIncoming()) {
-            callLogType = (cause == DisconnectCause.INCOMING_MISSED ?
-                           Calls.MISSED_TYPE : Calls.INCOMING_TYPE);
-        } else {
-            callLogType = Calls.OUTGOING_TYPE;
-        }
-        if (VDBG) log("- callLogType: " + callLogType + ", UserData: " + c.getUserData());
-
-        logCall(c, callLogType);
-    }
-
-    /**
-     * Logs a call to the call from the parameters passed in.
-     */
-    public void logCall(CallerInfo ci, String number, int presentation, int callType, long start,
-                        long duration) {
-        // no-op
-    }
-
-    /**
-     * Get the caller info.
-     *
-     * @param conn The phone connection.
-     * @return The CallerInfo associated with the connection. Maybe null.
-     */
-    private CallerInfo getCallerInfoFromConnection(Connection conn) {
-        CallerInfo ci = null;
-        Object o = conn.getUserData();
-
-        if ((o == null) || (o instanceof CallerInfo)) {
-            ci = (CallerInfo) o;
-        } else if (o instanceof Uri) {
-            ci = CallerInfo.getCallerInfo(mApplication.getApplicationContext(), (Uri) o);
-        } else {
-            ci = ((PhoneUtils.CallerInfoToken) o).currentInfo;
-        }
-        return ci;
-    }
-
-    /**
-     * Retrieve the phone number from the caller info or the connection.
-     *
-     * For incoming call the number is in the Connection object. For
-     * outgoing call we use the CallerInfo phoneNumber field if
-     * present. All the processing should have been done already (CDMA vs GSM numbers).
-     *
-     * If CallerInfo is missing the phone number, get it from the connection.
-     * Apply the Call Name Presentation (CNAP) transform in the connection on the number.
-     *
-     * @param conn The phone connection.
-     * @param callerInfo The CallerInfo. Maybe null.
-     * @return the phone number.
-     */
-    private String getLogNumber(Connection conn, CallerInfo callerInfo) {
-        String number = null;
-
-        if (conn.isIncoming()) {
-            number = conn.getAddress();
-        } else {
-            // For emergency and voicemail calls,
-            // CallerInfo.phoneNumber does *not* contain a valid phone
-            // number.  Instead it contains an I18N'd string such as
-            // "Emergency Number" or "Voice Mail" so we get the number
-            // from the connection.
-            if (null == callerInfo || TextUtils.isEmpty(callerInfo.phoneNumber) ||
-                callerInfo.isEmergencyNumber() || callerInfo.isVoiceMailNumber()) {
-                if (conn.getCall().getPhone().getPhoneType() == PhoneConstants.PHONE_TYPE_CDMA) {
-                    // In cdma getAddress() is not always equals to getOrigDialString().
-                    number = conn.getOrigDialString();
-                } else {
-                    number = conn.getAddress();
-                }
-            } else {
-                number = callerInfo.phoneNumber;
-            }
-        }
-
-        if (null == number) {
-            return null;
-        } else {
-            int presentation = conn.getNumberPresentation();
-
-            // Do final CNAP modifications.
-            String newNumber = PhoneUtils.modifyForSpecialCnapCases(mApplication, callerInfo,
-                                                          number, presentation);
-
-            if (!PhoneNumberUtils.isUriNumber(number)) {
-                number = PhoneNumberUtils.stripSeparators(number);
-            }
-            if (VDBG) log("getLogNumber: " + number);
-            return number;
-        }
-    }
-
-    /**
-     * Get the presentation from the callerinfo if not null otherwise,
-     * get it from the connection.
-     *
-     * @param conn The phone connection.
-     * @param callerInfo The CallerInfo. Maybe null.
-     * @return The presentation to use in the logs.
-     */
-    private int getPresentation(Connection conn, CallerInfo callerInfo) {
-        int presentation;
-
-        if (null == callerInfo) {
-            presentation = conn.getNumberPresentation();
-        } else {
-            presentation = callerInfo.numberPresentation;
-            if (DBG) log("- getPresentation(): ignoring connection's presentation: " +
-                         conn.getNumberPresentation());
-        }
-        if (DBG) log("- getPresentation: presentation: " + presentation);
-        return presentation;
-    }
-
-    private void log(String msg) {
-        Log.d(LOG_TAG, msg);
-    }
-}
diff --git a/src/com/android/phone/CallNotifier.java b/src/com/android/phone/CallNotifier.java
index 6e55c13..bd97b69 100644
--- a/src/com/android/phone/CallNotifier.java
+++ b/src/com/android/phone/CallNotifier.java
@@ -253,23 +253,6 @@
     }
 
     /**
-     * Resets the audio mode and speaker state when a call ends.
-     */
-    private void resetAudioStateAfterDisconnect() {
-        if (VDBG) log("resetAudioStateAfterDisconnect()...");
-
-        if (mBluetoothHeadset != null) {
-            mBluetoothHeadset.disconnectAudio();
-        }
-
-        // call turnOnSpeaker() with state=false and store=true even if speaker
-        // is already off to reset user requested speaker state.
-        PhoneUtils.turnOnSpeaker(mApplication, false, true);
-
-        PhoneUtils.setAudioMode(mCM);
-    }
-
-    /**
      * Helper class to play tones through the earpiece (or speaker / BT)
      * during a call, using the ToneGenerator.
      *
@@ -493,23 +476,6 @@
                     mState = TONE_OFF;
                 }
             }
-
-            // Finally, do the same cleanup we otherwise would have done
-            // in onDisconnect().
-            //
-            // (But watch out: do NOT do this if the phone is in use,
-            // since some of our tones get played *during* a call (like
-            // CALL_WAITING) and we definitely *don't*
-            // want to reset the audio mode / speaker / bluetooth after
-            // playing those!
-            // This call is really here for use with tones that get played
-            // *after* a call disconnects, like "busy" or "congestion" or
-            // "call ended", where the phone has already become idle but
-            // we need to defer the resetAudioStateAfterDisconnect() call
-            // till the tone finishes playing.)
-            if (mCM.getState() == PhoneConstants.State.IDLE) {
-                resetAudioStateAfterDisconnect();
-            }
         }
     }
 
diff --git a/src/com/android/phone/CellInfoUtil.java b/src/com/android/phone/CellInfoUtil.java
index 462cafe..8272029 100644
--- a/src/com/android/phone/CellInfoUtil.java
+++ b/src/com/android/phone/CellInfoUtil.java
@@ -127,6 +127,35 @@
         return oi;
     }
 
+    /**
+     * Creates a CellInfo object from OperatorInfo. GsmCellInfo is used here only because
+     * operatorInfo does not contain technology type while CellInfo is an abstract object that
+     * requires to specify technology type. It doesn't matter which CellInfo type to use here, since
+     * we only want to wrap the operator info and PLMN to a CellInfo object.
+     */
+    public static CellInfo convertOperatorInfoToCellInfo(OperatorInfo operatorInfo) {
+        String operatorNumeric = operatorInfo.getOperatorNumeric();
+        String mcc = null;
+        String mnc = null;
+        if (operatorNumeric != null && operatorNumeric.matches("^[0-9]{5,6}$")) {
+            mcc = operatorNumeric.substring(0, 3);
+            mnc = operatorNumeric.substring(3);
+        }
+        CellIdentityGsm cig = new CellIdentityGsm(
+                Integer.MAX_VALUE /* lac */,
+                Integer.MAX_VALUE /* cid */,
+                Integer.MAX_VALUE /* arfcn */,
+                Integer.MAX_VALUE /* bsic */,
+                mcc,
+                mnc,
+                operatorInfo.getOperatorAlphaLong(),
+                operatorInfo.getOperatorAlphaShort());
+
+        CellInfoGsm ci = new CellInfoGsm();
+        ci.setCellIdentity(cig);
+        return ci;
+    }
+
     /** Checks whether the network operator is forbidden. */
     public static boolean isForbidden(CellInfo cellInfo, List<String> forbiddenPlmns) {
         String plmn = CellInfoUtil.getOperatorInfoFromCellInfo(cellInfo).getOperatorNumeric();
diff --git a/src/com/android/phone/EccShortcutAdapter.java b/src/com/android/phone/EccShortcutAdapter.java
index deeb82f..e14b90a 100644
--- a/src/com/android/phone/EccShortcutAdapter.java
+++ b/src/com/android/phone/EccShortcutAdapter.java
@@ -186,15 +186,15 @@
             switch (type) {
                 case POLICE:
                     description = mPoliceDescription;
-                    material.iconRes = R.drawable.ic_shield_white_24;
+                    material.iconRes = R.drawable.ic_local_police_gm2_24px;
                     break;
                 case AMBULANCE:
                     description = mAmbulanceDescription;
-                    material.iconRes = R.drawable.ic_emergency_number_24;
+                    material.iconRes = R.drawable.ic_local_hospital_gm2_24px;
                     break;
                 case FIRE:
                     description = mFireDescription;
-                    material.iconRes = R.drawable.ic_fire_white_24;
+                    material.iconRes = R.drawable.ic_local_fire_department_gm2_24px;
                     break;
                 default:
                     // ignore unknown types
@@ -204,7 +204,7 @@
                 material.description = description;
             } else {
                 // concatenate multiple types
-                material.iconRes = R.drawable.ic_emergency_number_24;
+                material.iconRes = R.drawable.ic_local_hospital_gm2_24px;
                 material.description = context.getString(R.string.description_concat_format,
                         material.description, description);
             }
diff --git a/src/com/android/phone/EmergencyDialer.java b/src/com/android/phone/EmergencyDialer.java
index 66701d5..1fbbd33 100644
--- a/src/com/android/phone/EmergencyDialer.java
+++ b/src/com/android/phone/EmergencyDialer.java
@@ -108,17 +108,12 @@
  * 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,
-        EmergencyShortcutButton.OnConfirmClickListener, SensorEventListener {
+        EmergencyShortcutButton.OnConfirmClickListener, SensorEventListener,
+        EmergencyInfoGroup.OnConfirmClickListener {
 
     private class MetricsWriter {
         // Metrics constants indicating the entry type that user opened emergency dialer.
@@ -244,6 +239,8 @@
 
     private EmergencyActionGroup mEmergencyActionGroup;
 
+    private EmergencyInfoGroup mEmergencyInfoGroup;
+
     // close activity when screen turns off
     private BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() {
         @Override
@@ -451,6 +448,8 @@
 
         mEmergencyActionGroup = (EmergencyActionGroup) findViewById(R.id.emergency_action_group);
 
+        mEmergencyInfoGroup = (EmergencyInfoGroup) findViewById(R.id.emergency_info_button);
+
         if (mAreEmergencyDialerShortcutsEnabled) {
             mEccInfoHelper = new EccInfoHelper(new IsoToEccProtobufRepository());
             setupEmergencyShortcutsView();
@@ -606,6 +605,17 @@
     }
 
     @Override
+    public void onConfirmClick(EmergencyInfoGroup button) {
+        if (button == null) return;
+
+        mUserActions |= MetricsWriter.USER_ACTION_OPEN_EMERGENCY_INFO;
+        Intent intent = (Intent) button.getTag(R.id.tag_intent);
+        if (intent != null) {
+            startActivity(intent);
+        }
+    }
+
+    @Override
     public void onClick(View view) {
         switch (view.getId()) {
             case R.id.deleteButton: {
@@ -629,14 +639,6 @@
                 switchView(mDialpadView, mEmergencyShortcutView, true);
                 return;
             }
-            case R.id.emergency_info_button: {
-                mUserActions |= MetricsWriter.USER_ACTION_OPEN_EMERGENCY_INFO;
-                Intent intent = (Intent) view.getTag(R.id.tag_intent);
-                if (intent != null) {
-                    startActivity(intent);
-                }
-                return;
-            }
         }
     }
 
@@ -1099,8 +1101,7 @@
         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);
+        mEmergencyInfoGroup.setOnConfirmClickListener(this);
 
         // EmergencyActionGroup is replaced by EmergencyInfoGroup.
         mEmergencyActionGroup.setVisibility(View.GONE);
@@ -1179,10 +1180,15 @@
                     shortcutButtonContainer.addView(button);
                 }
 
-                // update emergency numbers title for numerous buttons.
+                // Update emergency numbers title for numerous buttons.
                 if (mEmergencyShortcutButtonList.size() > 1) {
                     emergencyNumberTitle.setText(getString(
                             R.string.numerous_emergency_numbers_title));
+                    // Update mEmergencyInfoGroup margin to avoid UI overlay when
+                    // emergency shortcut button more than 2.
+                    if (mEmergencyShortcutButtonList.size() > 2) {
+                        mEmergencyInfoGroup.updateLayoutMargin();
+                    }
                 } else {
                     emergencyNumberTitle.setText(getText(R.string.single_emergency_number_title));
                 }
@@ -1205,6 +1211,7 @@
      */
     private void onPreTouchEvent(MotionEvent event) {
         mEmergencyActionGroup.onPreTouchEvent(event);
+        mEmergencyInfoGroup.onPreTouchEvent(event);
 
         if (mEmergencyShortcutButtonList != null) {
             for (EmergencyShortcutButton button : mEmergencyShortcutButtonList) {
@@ -1218,6 +1225,7 @@
      */
     private void onPostTouchEvent(MotionEvent event) {
         mEmergencyActionGroup.onPostTouchEvent(event);
+        mEmergencyInfoGroup.onPostTouchEvent(event);
 
         if (mEmergencyShortcutButtonList != null) {
             for (EmergencyShortcutButton button : mEmergencyShortcutButtonList) {
diff --git a/src/com/android/phone/EmergencyInfoGroup.java b/src/com/android/phone/EmergencyInfoGroup.java
index d0dc322..5c01834 100644
--- a/src/com/android/phone/EmergencyInfoGroup.java
+++ b/src/com/android/phone/EmergencyInfoGroup.java
@@ -16,6 +16,8 @@
 
 package com.android.phone;
 
+import android.animation.Animator;
+import android.animation.AnimatorListenerAdapter;
 import android.annotation.Nullable;
 import android.content.Context;
 import android.content.Intent;
@@ -27,7 +29,10 @@
 import android.telephony.TelephonyManager;
 import android.text.TextUtils;
 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.LinearLayout;
@@ -44,23 +49,60 @@
  * EmergencyInfoGroup display user icon and user name. And it is an entry point to
  * Emergency Information.
  */
-public class EmergencyInfoGroup extends FrameLayout {
-    private ImageView mEmergencyInfoImage;
+public class EmergencyInfoGroup extends FrameLayout implements View.OnClickListener {
+    // Time to hide view of confirmation.
+    private static final long HIDE_DELAY_MS = 3000;
+    private static final int[] ICON_VIEWS =
+            {R.id.emergency_info_image, R.id.confirmed_emergency_info_image};
+
     private TextView mEmergencyInfoName;
-    private TextView mEmergencyInfoHint;
     private View mEmergencyInfoButton;
+    private View mEmergencyInfoConfirmButton;
+
+    private MotionEvent mPendingTouchEvent;
+    private OnConfirmClickListener mOnConfirmClickListener;
+
+    private boolean mConfirmViewHiding;
 
     public EmergencyInfoGroup(Context context, @Nullable AttributeSet attrs) {
         super(context, attrs);
     }
 
+    /**
+     * Interface definition for a callback to be invoked when the view of confirmation on emergency
+     * info button is clicked.
+     */
+    public interface OnConfirmClickListener {
+        /**
+         * Called when the view of confirmation on emergency info button has been clicked.
+         *
+         * @param button The shortcut button that was clicked.
+         */
+        void onConfirmClick(EmergencyInfoGroup 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;
+    }
+
     @Override
     protected void onFinishInflate() {
         super.onFinishInflate();
-        mEmergencyInfoButton = findViewById(R.id.emergency_info_button);
-        mEmergencyInfoImage = (ImageView) findViewById(R.id.emergency_info_image);
+        mEmergencyInfoButton = findViewById(R.id.emergency_info_view);
         mEmergencyInfoName = (TextView) findViewById(R.id.emergency_info_name);
-        mEmergencyInfoHint = (TextView) findViewById(R.id.emergency_info_hint);
+
+        mEmergencyInfoConfirmButton = findViewById(R.id.emergency_info_confirm_view);
+
+        mEmergencyInfoButton.setOnClickListener(this);
+        mEmergencyInfoConfirmButton.setOnClickListener(this);
+
+        mConfirmViewHiding = true;
     }
 
     @Override
@@ -71,12 +113,6 @@
         }
     }
 
-    @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;
 
@@ -92,8 +128,8 @@
             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());
+            setTag(R.id.tag_intent, intent);
+            setUserIcon();
 
             visible = true;
         }
@@ -102,6 +138,13 @@
         setVisibility(visible ? View.VISIBLE : View.GONE);
     }
 
+    private void setUserIcon() {
+        for (int iconView : ICON_VIEWS) {
+            ImageView userIcon = findViewById(iconView);
+            userIcon.setImageDrawable(getCircularUserIcon());
+        }
+    }
+
     /**
      * Get user icon.
      *
@@ -134,15 +177,124 @@
                 R.string.emergency_information_owner_hint) : userName;
     }
 
-    private void updateLayoutHeight() {
+    /**
+     * Called by the activity before a touch event is dispatched to the view hierarchy.
+     */
+    public void onPreTouchEvent(MotionEvent event) {
+        mPendingTouchEvent = event;
+    }
+
+    /**
+     * 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
+    public boolean dispatchTouchEvent(MotionEvent event) {
+        boolean handled = super.dispatchTouchEvent(event);
+        if (mPendingTouchEvent == event && handled) {
+            mPendingTouchEvent = null;
+        }
+        return handled;
+    }
+
+    @Override
+    public void onClick(View view) {
+        switch (view.getId()) {
+            case R.id.emergency_info_view:
+                if (AccessibilityManager.getInstance(mContext).isTouchExplorationEnabled()) {
+                    if (mOnConfirmClickListener != null) {
+                        mOnConfirmClickListener.onConfirmClick(this);
+                    }
+                } else {
+                    revealSelectedButton();
+                }
+                break;
+            case R.id.emergency_info_confirm_view:
+                if (mOnConfirmClickListener != null) {
+                    mOnConfirmClickListener.onConfirmClick(this);
+                }
+                break;
+            default:
+                break;
+        }
+    }
+
+    private void revealSelectedButton() {
+        mConfirmViewHiding = false;
+
+        mEmergencyInfoConfirmButton.setVisibility(View.VISIBLE);
+        int centerX = mEmergencyInfoButton.getLeft() + mEmergencyInfoButton.getWidth() / 2;
+        int centerY = mEmergencyInfoButton.getTop() + mEmergencyInfoButton.getHeight() / 2;
+        Animator reveal = ViewAnimationUtils.createCircularReveal(
+                mEmergencyInfoConfirmButton,
+                centerX,
+                centerY,
+                0,
+                Math.max(centerX, mEmergencyInfoConfirmButton.getWidth() - centerX)
+                        + Math.max(centerY, mEmergencyInfoConfirmButton.getHeight() - centerY));
+        reveal.start();
+
+        postDelayed(mCancelSelectedButtonRunnable, HIDE_DELAY_MS);
+        mEmergencyInfoConfirmButton.requestFocus();
+    }
+
+    private void hideSelectedButton() {
+        if (mConfirmViewHiding || mEmergencyInfoConfirmButton.getVisibility() != VISIBLE) {
+            return;
+        }
+
+        mConfirmViewHiding = true;
+
+        removeCallbacks(mCancelSelectedButtonRunnable);
+        int centerX =
+                mEmergencyInfoConfirmButton.getLeft() + mEmergencyInfoConfirmButton.getWidth() / 2;
+        int centerY =
+                mEmergencyInfoConfirmButton.getTop() + mEmergencyInfoConfirmButton.getHeight() / 2;
+        Animator reveal = ViewAnimationUtils.createCircularReveal(
+                mEmergencyInfoConfirmButton,
+                centerX,
+                centerY,
+                Math.max(centerX, mEmergencyInfoButton.getWidth() - centerX)
+                        + Math.max(centerY, mEmergencyInfoButton.getHeight() - centerY),
+                0);
+        reveal.addListener(new AnimatorListenerAdapter() {
+            @Override
+            public void onAnimationEnd(Animator animation) {
+                mEmergencyInfoConfirmButton.setVisibility(INVISIBLE);
+            }
+        });
+        reveal.start();
+
+        mEmergencyInfoButton.requestFocus();
+    }
+
+    private final Runnable mCancelSelectedButtonRunnable = new Runnable() {
+        @Override
+        public void run() {
+            if (!isAttachedToWindow()) return;
+            hideSelectedButton();
+        }
+    };
+
+    /**
+     * Update layout margin when emergency shortcut button more than 2.
+     */
+    public void updateLayoutMargin() {
         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);
+
+        params.topMargin = getResources().getDimensionPixelSize(
+                R.dimen.emergency_info_button_fix_margin_vertical);
+        params.bottomMargin = getResources().getDimensionPixelSize(
+                R.dimen.emergency_info_button_fix_margin_vertical);
+
         setLayoutParams(params);
     }
 }
\ No newline at end of file
diff --git a/src/com/android/phone/GsmUmtsOptions.java b/src/com/android/phone/GsmUmtsOptions.java
index a3f5cfb..3e45173 100644
--- a/src/com/android/phone/GsmUmtsOptions.java
+++ b/src/com/android/phone/GsmUmtsOptions.java
@@ -54,7 +54,7 @@
     private PreferenceScreen mPrefScreen;
 
     public GsmUmtsOptions(PreferenceFragment prefFragment, PreferenceScreen prefScreen,
-            final int subId, INetworkQueryService queryService) {
+            final int subId) {
         final Context context = prefFragment.getContext();
         mPrefFragment = prefFragment;
         mPrefScreen = prefScreen;
@@ -68,12 +68,12 @@
 
         mNetworkOperator.initialize();
 
-        update(subId, queryService);
+        update(subId);
     }
 
-    // Unlike mPrefFragment or mPrefScreen, subId or queryService may change during lifecycle of
-    // GsmUmtsOptions. When that happens, we update GsmUmtsOptions with new parameters.
-    protected void update(final int subId, INetworkQueryService queryService) {
+    // Unlike mPrefFragment or mPrefScreen, subId  may change during lifecycle of GsmUmtsOptions.
+    // When that happens, we update GsmUmtsOptions with new parameters.
+    protected void update(final int subId) {
         boolean addAPNExpand = true;
         boolean addNetworkOperatorsCategory = true;
         boolean addCarrierSettings = true;
@@ -151,7 +151,7 @@
 
         if (addNetworkOperatorsCategory) {
             mPrefScreen.addPreference(mNetworkOperator);
-            mNetworkOperator.update(subId, queryService);
+            mNetworkOperator.update(subId);
         } else {
             mPrefScreen.removePreference(mNetworkOperator);
         }
diff --git a/src/com/android/phone/MobileDataPreference.java b/src/com/android/phone/MobileDataPreference.java
index 4e82f20..e1ceab0 100644
--- a/src/com/android/phone/MobileDataPreference.java
+++ b/src/com/android/phone/MobileDataPreference.java
@@ -63,6 +63,11 @@
         super(context, attrs, com.android.internal.R.attr.switchPreferenceStyle);
     }
 
+    // Must be called to avoid binder leakage.
+    void dispose() {
+        mListener.setListener(false, mSubId, getContext());
+    }
+
     @Override
     protected void onRestoreInstanceState(Parcelable s) {
         CellDataState state = (CellDataState) s;
diff --git a/src/com/android/phone/MobileNetworkSettings.java b/src/com/android/phone/MobileNetworkSettings.java
index 9e8eaf3..3d37c4d 100644
--- a/src/com/android/phone/MobileNetworkSettings.java
+++ b/src/com/android/phone/MobileNetworkSettings.java
@@ -24,12 +24,10 @@
 import android.app.Fragment;
 import android.app.FragmentManager;
 import android.content.BroadcastReceiver;
-import android.content.ComponentName;
 import android.content.ContentResolver;
 import android.content.Context;
 import android.content.Intent;
 import android.content.IntentFilter;
-import android.content.ServiceConnection;
 import android.content.pm.PackageManager;
 import android.content.pm.ResolveInfo;
 import android.database.ContentObserver;
@@ -38,7 +36,6 @@
 import android.os.AsyncTask;
 import android.os.Bundle;
 import android.os.Handler;
-import android.os.IBinder;
 import android.os.Message;
 import android.os.PersistableBundle;
 import android.os.SystemProperties;
@@ -77,7 +74,6 @@
 import com.android.internal.telephony.Phone;
 import com.android.internal.telephony.PhoneConstants;
 import com.android.internal.telephony.TelephonyIntents;
-import com.android.phone.settings.PhoneAccountSettingsFragment;
 import com.android.settingslib.RestrictedLockUtils;
 
 import java.util.ArrayList;
@@ -108,6 +104,9 @@
     private static final String KEY_ENABLE_ESIM_UI_BY_DEFAULT =
             "esim.enable_esim_system_ui_by_default";
 
+    private static final String LEGACY_ACTION_CONFIGURE_PHONE_ACCOUNT =
+            "android.telecom.action.CONNECTION_SERVICE_CONFIGURE";
+
     private enum TabState {
         NO_TABS, UPDATE, DO_NOTHING
     }
@@ -171,8 +170,8 @@
 
         boolean isWifiCallingEnabled;
         if (simCallManager != null) {
-            Intent intent = PhoneAccountSettingsFragment
-                    .buildPhoneAccountConfigureIntent(context, simCallManager);
+            Intent intent = MobileNetworkSettings.buildPhoneAccountConfigureIntent(
+                    context, simCallManager);
             PackageManager pm = context.getPackageManager();
             isWifiCallingEnabled = intent != null
                     && !pm.queryIntentActivities(intent, 0 /* flags */).isEmpty();
@@ -291,6 +290,47 @@
         return isImsServiceStateReady;
     }
 
+
+    private static Intent buildPhoneAccountConfigureIntent(
+            Context context, PhoneAccountHandle accountHandle) {
+        Intent intent = buildConfigureIntent(
+                context, accountHandle, TelecomManager.ACTION_CONFIGURE_PHONE_ACCOUNT);
+
+        if (intent == null) {
+            // If the new configuration didn't work, try the old configuration intent.
+            intent = buildConfigureIntent(
+                    context, accountHandle, LEGACY_ACTION_CONFIGURE_PHONE_ACCOUNT);
+            if (intent != null) {
+                Log.w(MobileNetworkFragment.LOG_TAG,
+                        "Phone account using old configuration intent: " + accountHandle);
+            }
+        }
+        return intent;
+    }
+
+    private static Intent buildConfigureIntent(
+            Context context, PhoneAccountHandle accountHandle, String actionStr) {
+        if (accountHandle == null || accountHandle.getComponentName() == null
+                || TextUtils.isEmpty(accountHandle.getComponentName().getPackageName())) {
+            return null;
+        }
+
+        // Build the settings intent.
+        Intent intent = new Intent(actionStr);
+        intent.setPackage(accountHandle.getComponentName().getPackageName());
+        intent.addCategory(Intent.CATEGORY_DEFAULT);
+        intent.putExtra(TelecomManager.EXTRA_PHONE_ACCOUNT_HANDLE, accountHandle);
+
+        // Check to see that the phone account package can handle the setting intent.
+        PackageManager pm = context.getPackageManager();
+        List<ResolveInfo> resolutions = pm.queryIntentActivities(intent, 0);
+        if (resolutions.size() == 0) {
+            intent = null;  // set no intent if the package cannot handle it.
+        }
+
+        return intent;
+    }
+
     public static class MobileNetworkFragment extends PreferenceFragment implements
             Preference.OnPreferenceChangeListener, RoamingDialogFragment.RoamingDialogListener {
 
@@ -385,6 +425,7 @@
         private Preference mClickedPreference;
         private boolean mShow4GForLTE;
         private boolean mIsGlobalCdma;
+        private boolean mOnlyAutoSelectInHomeNW;
         private boolean mUnavailable;
 
         private class PhoneCallStateListener extends PhoneStateListener {
@@ -425,53 +466,6 @@
 
         private final PhoneCallStateListener mPhoneStateListener = new PhoneCallStateListener();
 
-        /**
-         * Service connection code for the NetworkQueryService.
-         * Handles the work of binding to a local object so that we can make
-         * the appropriate service calls.
-         */
-
-        /** Local service interface */
-        private INetworkQueryService mNetworkQueryService = null;
-
-        private void setNetworkQueryService() {
-            mButtonNetworkSelect = (NetworkSelectListPreference) getPreferenceScreen()
-                    .findPreference(NetworkOperators.BUTTON_NETWORK_SELECT_KEY);
-            if (mButtonNetworkSelect != null) {
-                mButtonNetworkSelect.setNetworkQueryService(mNetworkQueryService);
-            }
-
-        }
-        /** Service connection */
-        private final ServiceConnection mNetworkQueryServiceConnection = new ServiceConnection() {
-
-            /** Handle the task of binding the local object to the service */
-            public void onServiceConnected(ComponentName className, IBinder service) {
-                if (DBG) log("connection created, binding local service.");
-                mNetworkQueryService = ((NetworkQueryService.LocalBinder) service).getService();
-                setNetworkQueryService();
-            }
-
-            /** Handle the task of cleaning up the local binding */
-            public void onServiceDisconnected(ComponentName className) {
-                if (DBG) log("connection disconnected, cleaning local binding.");
-                mNetworkQueryService = null;
-                setNetworkQueryService();
-            }
-        };
-
-        private void bindNetworkQueryService() {
-            getContext().startService(new Intent(getContext(), NetworkQueryService.class));
-            getContext().bindService(new Intent(getContext(), NetworkQueryService.class).setAction(
-                        NetworkQueryService.ACTION_LOCAL_BINDER),
-                        mNetworkQueryServiceConnection, Context.BIND_AUTO_CREATE);
-        }
-
-        private void unbindNetworkQueryService() {
-            // unbind the service.
-            getContext().unbindService(mNetworkQueryServiceConnection);
-        }
-
         @Override
         public void onPositiveButtonClick(DialogFragment dialog) {
             mTelephonyManager.setDataRoamingEnabled(true);
@@ -799,8 +793,6 @@
                 mExpandAdvancedFields = true;
             }
 
-            bindNetworkQueryService();
-
             addPreferencesFromResource(R.xml.network_setting_fragment);
 
             mButton4glte = (SwitchPreference)findPreference(BUTTON_4G_LTE_KEY);
@@ -903,8 +895,10 @@
 
         @Override
         public void onDestroy() {
-            unbindNetworkQueryService();
             super.onDestroy();
+            if (mMobileDataPref != null) {
+                mMobileDataPref.dispose();
+            }
         }
 
         @Override
@@ -1076,7 +1070,7 @@
                 if (phoneType == PhoneConstants.PHONE_TYPE_CDMA) {
                     updateCdmaOptions(this, prefSet, mSubId);
                 } else if (phoneType == PhoneConstants.PHONE_TYPE_GSM) {
-                    updateGsmUmtsOptions(this, prefSet, phoneSubId, mNetworkQueryService);
+                    updateGsmUmtsOptions(this, prefSet, phoneSubId);
                 } else {
                     throw new IllegalStateException("Unexpected phone type: " + phoneType);
                 }
@@ -1092,7 +1086,7 @@
                 mButtonPreferredNetworkMode.setOnPreferenceChangeListener(this);
 
                 updateCdmaOptions(this, prefSet, mSubId);
-                updateGsmUmtsOptions(this, prefSet, phoneSubId, mNetworkQueryService);
+                updateGsmUmtsOptions(this, prefSet, phoneSubId);
             } else {
                 prefSet.removePreference(mButtonPreferredNetworkMode);
                 updateEnabledNetworksEntries();
@@ -1160,13 +1154,19 @@
              * but you do need to remember that this all needs to work when subscriptions
              * change dynamically such as when hot swapping sims.
              */
-            boolean useVariant4glteTitle = carrierConfig.getBoolean(
-                    CarrierConfigManager.KEY_ENHANCED_4G_LTE_TITLE_VARIANT_BOOL);
-            int enhanced4glteModeTitleId = useVariant4glteTitle ?
-                    R.string.enhanced_4g_lte_mode_title_variant :
-                    R.string.enhanced_4g_lte_mode_title;
+            int variant4glteTitleIndex = carrierConfig.getInt(
+                    CarrierConfigManager.KEY_ENHANCED_4G_LTE_TITLE_VARIANT_INT);
+            CharSequence[] variantTitles = getContext().getResources()
+                    .getTextArray(R.array.enhanced_4g_lte_mode_title_variant);
+            // Default index 0 indicates the default title string
+            CharSequence enhanced4glteModeTitle = variantTitles[0];
+            if (variant4glteTitleIndex >= 0 && variant4glteTitleIndex < variantTitles.length) {
+                enhanced4glteModeTitle = variantTitles[variant4glteTitleIndex];
+            }
 
-            mButton4glte.setTitle(enhanced4glteModeTitleId);
+            mOnlyAutoSelectInHomeNW = carrierConfig.getBoolean(
+                    CarrierConfigManager.KEY_ONLY_AUTO_SELECT_IN_HOME_NETWORK_BOOL);
+            mButton4glte.setTitle(enhanced4glteModeTitle);
             mLteDataServicePref.setEnabled(hasActiveSubscriptions);
             Preference ps;
             ps = findPreference(BUTTON_CELL_BROADCAST_SETTINGS);
@@ -1197,6 +1197,20 @@
             if (ps != null) {
                 ps.setEnabled(hasActiveSubscriptions);
             }
+            ps = findPreference(NetworkOperators.BUTTON_AUTO_SELECT_KEY);
+            if (ps != null) {
+                ps.setSummary(null);
+                if (mTelephonyManager.getServiceState().getRoaming()) {
+                    ps.setEnabled(true);
+                } else {
+                    ps.setEnabled(!mOnlyAutoSelectInHomeNW);
+                    if (mOnlyAutoSelectInHomeNW) {
+                        ps.setSummary(getResources().getString(
+                                R.string.manual_mode_disallowed_summary,
+                                mTelephonyManager.getSimOperatorName()));
+                    }
+                }
+            }
         }
 
         // Requires that mSubId is up to date
@@ -1222,18 +1236,18 @@
                                 R.array.enabled_networks_cdma_values);
                     } else {
                         switch (settingsNetworkMode) {
-                            case Phone.NT_MODE_CDMA:
-                            case Phone.NT_MODE_CDMA_NO_EVDO:
-                            case Phone.NT_MODE_EVDO_NO_CDMA:
+                            case TelephonyManager.NETWORK_MODE_CDMA_EVDO:
+                            case TelephonyManager.NETWORK_MODE_CDMA_NO_EVDO:
+                            case TelephonyManager.NETWORK_MODE_EVDO_NO_CDMA:
                                 mButtonEnabledNetworks.setEntries(
                                         R.array.enabled_networks_cdma_no_lte_choices);
                                 mButtonEnabledNetworks.setEntryValues(
                                         R.array.enabled_networks_cdma_no_lte_values);
                                 break;
-                            case Phone.NT_MODE_GLOBAL:
-                            case Phone.NT_MODE_LTE_CDMA_AND_EVDO:
-                            case Phone.NT_MODE_LTE_CDMA_EVDO_GSM_WCDMA:
-                            case Phone.NT_MODE_LTE_ONLY:
+                            case TelephonyManager.NETWORK_MODE_GLOBAL:
+                            case TelephonyManager.NETWORK_MODE_LTE_CDMA_EVDO:
+                            case TelephonyManager.NETWORK_MODE_LTE_CDMA_EVDO_GSM_WCDMA:
+                            case TelephonyManager.NETWORK_MODE_LTE_ONLY:
                                 mButtonEnabledNetworks.setEntries(
                                         R.array.enabled_networks_cdma_only_lte_choices);
                                 mButtonEnabledNetworks.setEntryValues(
@@ -1286,8 +1300,7 @@
                     mButtonEnabledNetworks.setEntryValues(
                             R.array.enabled_networks_values);
                 }
-                updateGsmUmtsOptions(this, getPreferenceScreen(), mSubId,
-                        mNetworkQueryService);
+                updateGsmUmtsOptions(this, getPreferenceScreen(), mSubId);
             } else {
                 throw new IllegalStateException("Unexpected phone type: " + phoneType);
             }
@@ -1341,29 +1354,29 @@
                     int modemNetworkMode;
                     // if new mode is invalid ignore it
                     switch (buttonNetworkMode) {
-                        case Phone.NT_MODE_WCDMA_PREF:
-                        case Phone.NT_MODE_GSM_ONLY:
-                        case Phone.NT_MODE_WCDMA_ONLY:
-                        case Phone.NT_MODE_GSM_UMTS:
-                        case Phone.NT_MODE_CDMA:
-                        case Phone.NT_MODE_CDMA_NO_EVDO:
-                        case Phone.NT_MODE_EVDO_NO_CDMA:
-                        case Phone.NT_MODE_GLOBAL:
-                        case Phone.NT_MODE_LTE_CDMA_AND_EVDO:
-                        case Phone.NT_MODE_LTE_GSM_WCDMA:
-                        case Phone.NT_MODE_LTE_CDMA_EVDO_GSM_WCDMA:
-                        case Phone.NT_MODE_LTE_ONLY:
-                        case Phone.NT_MODE_LTE_WCDMA:
-                        case Phone.NT_MODE_TDSCDMA_ONLY:
-                        case Phone.NT_MODE_TDSCDMA_WCDMA:
-                        case Phone.NT_MODE_LTE_TDSCDMA:
-                        case Phone.NT_MODE_TDSCDMA_GSM:
-                        case Phone.NT_MODE_LTE_TDSCDMA_GSM:
-                        case Phone.NT_MODE_TDSCDMA_GSM_WCDMA:
-                        case Phone.NT_MODE_LTE_TDSCDMA_WCDMA:
-                        case Phone.NT_MODE_LTE_TDSCDMA_GSM_WCDMA:
-                        case Phone.NT_MODE_TDSCDMA_CDMA_EVDO_GSM_WCDMA:
-                        case Phone.NT_MODE_LTE_TDSCDMA_CDMA_EVDO_GSM_WCDMA:
+                        case TelephonyManager.NETWORK_MODE_WCDMA_PREF:
+                        case TelephonyManager.NETWORK_MODE_GSM_ONLY:
+                        case TelephonyManager.NETWORK_MODE_WCDMA_ONLY:
+                        case TelephonyManager.NETWORK_MODE_GSM_UMTS:
+                        case TelephonyManager.NETWORK_MODE_CDMA_EVDO:
+                        case TelephonyManager.NETWORK_MODE_CDMA_NO_EVDO:
+                        case TelephonyManager.NETWORK_MODE_EVDO_NO_CDMA:
+                        case TelephonyManager.NETWORK_MODE_GLOBAL:
+                        case TelephonyManager.NETWORK_MODE_LTE_CDMA_EVDO:
+                        case TelephonyManager.NETWORK_MODE_LTE_GSM_WCDMA:
+                        case TelephonyManager.NETWORK_MODE_LTE_CDMA_EVDO_GSM_WCDMA:
+                        case TelephonyManager.NETWORK_MODE_LTE_ONLY:
+                        case TelephonyManager.NETWORK_MODE_LTE_WCDMA:
+                        case TelephonyManager.NETWORK_MODE_TDSCDMA_ONLY:
+                        case TelephonyManager.NETWORK_MODE_TDSCDMA_WCDMA:
+                        case TelephonyManager.NETWORK_MODE_LTE_TDSCDMA:
+                        case TelephonyManager.NETWORK_MODE_TDSCDMA_GSM:
+                        case TelephonyManager.NETWORK_MODE_LTE_TDSCDMA_GSM:
+                        case TelephonyManager.NETWORK_MODE_TDSCDMA_GSM_WCDMA:
+                        case TelephonyManager.NETWORK_MODE_LTE_TDSCDMA_WCDMA:
+                        case TelephonyManager.NETWORK_MODE_LTE_TDSCDMA_GSM_WCDMA:
+                        case TelephonyManager.NETWORK_MODE_TDSCDMA_CDMA_EVDO_GSM_WCDMA:
+                        case TelephonyManager.NETWORK_MODE_LTE_TDSCDMA_CDMA_EVDO_GSM_WCDMA:
                             // This is one of the modes we recognize
                             modemNetworkMode = buttonNetworkMode;
                             break;
@@ -1397,23 +1410,23 @@
                     int modemNetworkMode;
                     // if new mode is invalid ignore it
                     switch (buttonNetworkMode) {
-                        case Phone.NT_MODE_WCDMA_PREF:
-                        case Phone.NT_MODE_GSM_ONLY:
-                        case Phone.NT_MODE_LTE_GSM_WCDMA:
-                        case Phone.NT_MODE_LTE_CDMA_EVDO_GSM_WCDMA:
-                        case Phone.NT_MODE_CDMA:
-                        case Phone.NT_MODE_CDMA_NO_EVDO:
-                        case Phone.NT_MODE_LTE_CDMA_AND_EVDO:
-                        case Phone.NT_MODE_TDSCDMA_ONLY:
-                        case Phone.NT_MODE_TDSCDMA_WCDMA:
-                        case Phone.NT_MODE_LTE_TDSCDMA:
-                        case Phone.NT_MODE_TDSCDMA_GSM:
-                        case Phone.NT_MODE_LTE_TDSCDMA_GSM:
-                        case Phone.NT_MODE_TDSCDMA_GSM_WCDMA:
-                        case Phone.NT_MODE_LTE_TDSCDMA_WCDMA:
-                        case Phone.NT_MODE_LTE_TDSCDMA_GSM_WCDMA:
-                        case Phone.NT_MODE_TDSCDMA_CDMA_EVDO_GSM_WCDMA:
-                        case Phone.NT_MODE_LTE_TDSCDMA_CDMA_EVDO_GSM_WCDMA:
+                        case TelephonyManager.NETWORK_MODE_WCDMA_PREF:
+                        case TelephonyManager.NETWORK_MODE_GSM_ONLY:
+                        case TelephonyManager.NETWORK_MODE_LTE_GSM_WCDMA:
+                        case TelephonyManager.NETWORK_MODE_LTE_CDMA_EVDO_GSM_WCDMA:
+                        case TelephonyManager.NETWORK_MODE_CDMA_EVDO:
+                        case TelephonyManager.NETWORK_MODE_CDMA_NO_EVDO:
+                        case TelephonyManager.NETWORK_MODE_LTE_CDMA_EVDO:
+                        case TelephonyManager.NETWORK_MODE_TDSCDMA_ONLY:
+                        case TelephonyManager.NETWORK_MODE_TDSCDMA_WCDMA:
+                        case TelephonyManager.NETWORK_MODE_LTE_TDSCDMA:
+                        case TelephonyManager.NETWORK_MODE_TDSCDMA_GSM:
+                        case TelephonyManager.NETWORK_MODE_LTE_TDSCDMA_GSM:
+                        case TelephonyManager.NETWORK_MODE_TDSCDMA_GSM_WCDMA:
+                        case TelephonyManager.NETWORK_MODE_LTE_TDSCDMA_WCDMA:
+                        case TelephonyManager.NETWORK_MODE_LTE_TDSCDMA_GSM_WCDMA:
+                        case TelephonyManager.NETWORK_MODE_TDSCDMA_CDMA_EVDO_GSM_WCDMA:
+                        case TelephonyManager.NETWORK_MODE_LTE_TDSCDMA_CDMA_EVDO_GSM_WCDMA:
                             // This is one of the modes we recognize
                             modemNetworkMode = buttonNetworkMode;
                             break;
@@ -1575,35 +1588,35 @@
 
         private void UpdatePreferredNetworkModeSummary(int NetworkMode) {
             switch(NetworkMode) {
-                case Phone.NT_MODE_TDSCDMA_GSM_WCDMA:
+                case TelephonyManager.NETWORK_MODE_TDSCDMA_GSM_WCDMA:
                     mButtonPreferredNetworkMode.setSummary(
                             R.string.preferred_network_mode_tdscdma_gsm_wcdma_summary);
                     break;
-                case Phone.NT_MODE_TDSCDMA_GSM:
+                case TelephonyManager.NETWORK_MODE_TDSCDMA_GSM:
                     mButtonPreferredNetworkMode.setSummary(
                             R.string.preferred_network_mode_tdscdma_gsm_summary);
                     break;
-                case Phone.NT_MODE_WCDMA_PREF:
+                case TelephonyManager.NETWORK_MODE_WCDMA_PREF:
                     mButtonPreferredNetworkMode.setSummary(
                             R.string.preferred_network_mode_wcdma_perf_summary);
                     break;
-                case Phone.NT_MODE_GSM_ONLY:
+                case TelephonyManager.NETWORK_MODE_GSM_ONLY:
                     mButtonPreferredNetworkMode.setSummary(
                             R.string.preferred_network_mode_gsm_only_summary);
                     break;
-                case Phone.NT_MODE_TDSCDMA_WCDMA:
+                case TelephonyManager.NETWORK_MODE_TDSCDMA_WCDMA:
                     mButtonPreferredNetworkMode.setSummary(
                             R.string.preferred_network_mode_tdscdma_wcdma_summary);
                     break;
-                case Phone.NT_MODE_WCDMA_ONLY:
+                case TelephonyManager.NETWORK_MODE_WCDMA_ONLY:
                     mButtonPreferredNetworkMode.setSummary(
                             R.string.preferred_network_mode_wcdma_only_summary);
                     break;
-                case Phone.NT_MODE_GSM_UMTS:
+                case TelephonyManager.NETWORK_MODE_GSM_UMTS:
                     mButtonPreferredNetworkMode.setSummary(
                             R.string.preferred_network_mode_gsm_wcdma_summary);
                     break;
-                case Phone.NT_MODE_CDMA:
+                case TelephonyManager.NETWORK_MODE_CDMA_EVDO:
                     switch (mTelephonyManager.getLteOnCdmaMode()) {
                         case PhoneConstants.LTE_ON_CDMA_TRUE:
                             mButtonPreferredNetworkMode.setSummary(
@@ -1616,47 +1629,47 @@
                             break;
                     }
                     break;
-                case Phone.NT_MODE_CDMA_NO_EVDO:
+                case TelephonyManager.NETWORK_MODE_CDMA_NO_EVDO:
                     mButtonPreferredNetworkMode.setSummary(
                             R.string.preferred_network_mode_cdma_only_summary);
                     break;
-                case Phone.NT_MODE_EVDO_NO_CDMA:
+                case TelephonyManager.NETWORK_MODE_EVDO_NO_CDMA:
                     mButtonPreferredNetworkMode.setSummary(
                             R.string.preferred_network_mode_evdo_only_summary);
                     break;
-                case Phone.NT_MODE_LTE_TDSCDMA:
+                case TelephonyManager.NETWORK_MODE_LTE_TDSCDMA:
                     mButtonPreferredNetworkMode.setSummary(
                             R.string.preferred_network_mode_lte_tdscdma_summary);
                     break;
-                case Phone.NT_MODE_LTE_ONLY:
+                case TelephonyManager.NETWORK_MODE_LTE_ONLY:
                     mButtonPreferredNetworkMode.setSummary(
                             R.string.preferred_network_mode_lte_summary);
                     break;
-                case Phone.NT_MODE_LTE_TDSCDMA_GSM:
+                case TelephonyManager.NETWORK_MODE_LTE_TDSCDMA_GSM:
                     mButtonPreferredNetworkMode.setSummary(
                             R.string.preferred_network_mode_lte_tdscdma_gsm_summary);
                     break;
-                case Phone.NT_MODE_LTE_TDSCDMA_GSM_WCDMA:
+                case TelephonyManager.NETWORK_MODE_LTE_TDSCDMA_GSM_WCDMA:
                     mButtonPreferredNetworkMode.setSummary(
                             R.string.preferred_network_mode_lte_tdscdma_gsm_wcdma_summary);
                     break;
-                case Phone.NT_MODE_LTE_GSM_WCDMA:
+                case TelephonyManager.NETWORK_MODE_LTE_GSM_WCDMA:
                     mButtonPreferredNetworkMode.setSummary(
                             R.string.preferred_network_mode_lte_gsm_wcdma_summary);
                     break;
-                case Phone.NT_MODE_LTE_CDMA_AND_EVDO:
+                case TelephonyManager.NETWORK_MODE_LTE_CDMA_EVDO:
                     mButtonPreferredNetworkMode.setSummary(
                             R.string.preferred_network_mode_lte_cdma_evdo_summary);
                     break;
-                case Phone.NT_MODE_TDSCDMA_ONLY:
+                case TelephonyManager.NETWORK_MODE_TDSCDMA_ONLY:
                     mButtonPreferredNetworkMode.setSummary(
                             R.string.preferred_network_mode_tdscdma_summary);
                     break;
-                case Phone.NT_MODE_LTE_TDSCDMA_CDMA_EVDO_GSM_WCDMA:
+                case TelephonyManager.NETWORK_MODE_LTE_TDSCDMA_CDMA_EVDO_GSM_WCDMA:
                     mButtonPreferredNetworkMode.setSummary(
                             R.string.preferred_network_mode_lte_tdscdma_cdma_evdo_gsm_wcdma_summary);
                     break;
-                case Phone.NT_MODE_LTE_CDMA_EVDO_GSM_WCDMA:
+                case TelephonyManager.NETWORK_MODE_LTE_CDMA_EVDO_GSM_WCDMA:
                     if (mTelephonyManager.getPhoneType() == PhoneConstants.PHONE_TYPE_CDMA
                             || mIsGlobalCdma
                             || isWorldMode()) {
@@ -1667,19 +1680,19 @@
                                 R.string.preferred_network_mode_lte_summary);
                     }
                     break;
-                case Phone.NT_MODE_TDSCDMA_CDMA_EVDO_GSM_WCDMA:
+                case TelephonyManager.NETWORK_MODE_TDSCDMA_CDMA_EVDO_GSM_WCDMA:
                     mButtonPreferredNetworkMode.setSummary(
                             R.string.preferred_network_mode_tdscdma_cdma_evdo_gsm_wcdma_summary);
                     break;
-                case Phone.NT_MODE_GLOBAL:
+                case TelephonyManager.NETWORK_MODE_GLOBAL:
                     mButtonPreferredNetworkMode.setSummary(
                             R.string.preferred_network_mode_cdma_evdo_gsm_wcdma_summary);
                     break;
-                case Phone.NT_MODE_LTE_TDSCDMA_WCDMA:
+                case TelephonyManager.NETWORK_MODE_LTE_TDSCDMA_WCDMA:
                     mButtonPreferredNetworkMode.setSummary(
                             R.string.preferred_network_mode_lte_tdscdma_wcdma_summary);
                     break;
-                case Phone.NT_MODE_LTE_WCDMA:
+                case TelephonyManager.NETWORK_MODE_LTE_WCDMA:
                     mButtonPreferredNetworkMode.setSummary(
                             R.string.preferred_network_mode_lte_wcdma_summary);
                     break;
@@ -1691,38 +1704,40 @@
 
         private void UpdateEnabledNetworksValueAndSummary(int NetworkMode) {
             switch (NetworkMode) {
-                case Phone.NT_MODE_TDSCDMA_WCDMA:
-                case Phone.NT_MODE_TDSCDMA_GSM_WCDMA:
-                case Phone.NT_MODE_TDSCDMA_GSM:
+                case TelephonyManager.NETWORK_MODE_TDSCDMA_WCDMA:
+                case TelephonyManager.NETWORK_MODE_TDSCDMA_GSM_WCDMA:
+                case TelephonyManager.NETWORK_MODE_TDSCDMA_GSM:
                     mButtonEnabledNetworks.setValue(
-                            Integer.toString(Phone.NT_MODE_TDSCDMA_GSM_WCDMA));
+                            Integer.toString(TelephonyManager.NETWORK_MODE_TDSCDMA_GSM_WCDMA));
                     mButtonEnabledNetworks.setSummary(R.string.network_3G);
                     break;
-                case Phone.NT_MODE_WCDMA_ONLY:
-                case Phone.NT_MODE_GSM_UMTS:
-                case Phone.NT_MODE_WCDMA_PREF:
+                case TelephonyManager.NETWORK_MODE_WCDMA_ONLY:
+                case TelephonyManager.NETWORK_MODE_GSM_UMTS:
+                case TelephonyManager.NETWORK_MODE_WCDMA_PREF:
                     if (!mIsGlobalCdma) {
                         mButtonEnabledNetworks.setValue(
-                                Integer.toString(Phone.NT_MODE_WCDMA_PREF));
+                                Integer.toString(TelephonyManager.NETWORK_MODE_WCDMA_PREF));
                         mButtonEnabledNetworks.setSummary(R.string.network_3G);
                     } else {
                         mButtonEnabledNetworks.setValue(
-                                Integer.toString(Phone.NT_MODE_LTE_CDMA_EVDO_GSM_WCDMA));
+                                Integer.toString(TelephonyManager
+                                        .NETWORK_MODE_LTE_CDMA_EVDO_GSM_WCDMA));
                         mButtonEnabledNetworks.setSummary(R.string.network_global);
                     }
                     break;
-                case Phone.NT_MODE_GSM_ONLY:
+                case TelephonyManager.NETWORK_MODE_GSM_ONLY:
                     if (!mIsGlobalCdma) {
                         mButtonEnabledNetworks.setValue(
-                                Integer.toString(Phone.NT_MODE_GSM_ONLY));
+                                Integer.toString(TelephonyManager.NETWORK_MODE_GSM_ONLY));
                         mButtonEnabledNetworks.setSummary(R.string.network_2G);
                     } else {
                         mButtonEnabledNetworks.setValue(
-                                Integer.toString(Phone.NT_MODE_LTE_CDMA_EVDO_GSM_WCDMA));
+                                Integer.toString(TelephonyManager
+                                        .NETWORK_MODE_LTE_CDMA_EVDO_GSM_WCDMA));
                         mButtonEnabledNetworks.setSummary(R.string.network_global);
                     }
                     break;
-                case Phone.NT_MODE_LTE_GSM_WCDMA:
+                case TelephonyManager.NETWORK_MODE_LTE_GSM_WCDMA:
                     if (isWorldMode()) {
                         mButtonEnabledNetworks.setSummary(
                                 R.string.preferred_network_mode_lte_gsm_umts_summary);
@@ -1730,20 +1745,21 @@
                         controlGsmOptions(true);
                         break;
                     }
-                case Phone.NT_MODE_LTE_ONLY:
-                case Phone.NT_MODE_LTE_WCDMA:
+                case TelephonyManager.NETWORK_MODE_LTE_ONLY:
+                case TelephonyManager.NETWORK_MODE_LTE_WCDMA:
                     if (!mIsGlobalCdma) {
                         mButtonEnabledNetworks.setValue(
-                                Integer.toString(Phone.NT_MODE_LTE_GSM_WCDMA));
+                                Integer.toString(TelephonyManager.NETWORK_MODE_LTE_GSM_WCDMA));
                         mButtonEnabledNetworks.setSummary((mShow4GForLTE == true)
                                 ? R.string.network_4G : R.string.network_lte);
                     } else {
                         mButtonEnabledNetworks.setValue(
-                                Integer.toString(Phone.NT_MODE_LTE_CDMA_EVDO_GSM_WCDMA));
+                                Integer.toString(TelephonyManager
+                                        .NETWORK_MODE_LTE_CDMA_EVDO_GSM_WCDMA));
                         mButtonEnabledNetworks.setSummary(R.string.network_global);
                     }
                     break;
-                case Phone.NT_MODE_LTE_CDMA_AND_EVDO:
+                case TelephonyManager.NETWORK_MODE_LTE_CDMA_EVDO:
                     if (isWorldMode()) {
                         mButtonEnabledNetworks.setSummary(
                                 R.string.preferred_network_mode_lte_cdma_summary);
@@ -1751,41 +1767,43 @@
                         controlGsmOptions(false);
                     } else {
                         mButtonEnabledNetworks.setValue(
-                                Integer.toString(Phone.NT_MODE_LTE_CDMA_AND_EVDO));
+                                Integer.toString(TelephonyManager.NETWORK_MODE_LTE_CDMA_EVDO));
                         mButtonEnabledNetworks.setSummary(R.string.network_lte);
                     }
                     break;
-                case Phone.NT_MODE_TDSCDMA_CDMA_EVDO_GSM_WCDMA:
+                case TelephonyManager.NETWORK_MODE_TDSCDMA_CDMA_EVDO_GSM_WCDMA:
                     mButtonEnabledNetworks.setValue(
-                            Integer.toString(Phone.NT_MODE_TDSCDMA_CDMA_EVDO_GSM_WCDMA));
+                            Integer.toString(TelephonyManager
+                                    .NETWORK_MODE_TDSCDMA_CDMA_EVDO_GSM_WCDMA));
                     mButtonEnabledNetworks.setSummary(R.string.network_3G);
                     break;
-                case Phone.NT_MODE_CDMA:
-                case Phone.NT_MODE_EVDO_NO_CDMA:
-                case Phone.NT_MODE_GLOBAL:
+                case TelephonyManager.NETWORK_MODE_CDMA_EVDO:
+                case TelephonyManager.NETWORK_MODE_EVDO_NO_CDMA:
+                case TelephonyManager.NETWORK_MODE_GLOBAL:
                     mButtonEnabledNetworks.setValue(
-                            Integer.toString(Phone.NT_MODE_CDMA));
+                            Integer.toString(TelephonyManager.NETWORK_MODE_CDMA_EVDO));
                     mButtonEnabledNetworks.setSummary(R.string.network_3G);
                     break;
-                case Phone.NT_MODE_CDMA_NO_EVDO:
+                case TelephonyManager.NETWORK_MODE_CDMA_NO_EVDO:
                     mButtonEnabledNetworks.setValue(
-                            Integer.toString(Phone.NT_MODE_CDMA_NO_EVDO));
+                            Integer.toString(TelephonyManager.NETWORK_MODE_CDMA_NO_EVDO));
                     mButtonEnabledNetworks.setSummary(R.string.network_1x);
                     break;
-                case Phone.NT_MODE_TDSCDMA_ONLY:
+                case TelephonyManager.NETWORK_MODE_TDSCDMA_ONLY:
                     mButtonEnabledNetworks.setValue(
-                            Integer.toString(Phone.NT_MODE_TDSCDMA_ONLY));
+                            Integer.toString(TelephonyManager.NETWORK_MODE_TDSCDMA_ONLY));
                     mButtonEnabledNetworks.setSummary(R.string.network_3G);
                     break;
-                case Phone.NT_MODE_LTE_TDSCDMA_GSM:
-                case Phone.NT_MODE_LTE_TDSCDMA_GSM_WCDMA:
-                case Phone.NT_MODE_LTE_TDSCDMA:
-                case Phone.NT_MODE_LTE_TDSCDMA_WCDMA:
-                case Phone.NT_MODE_LTE_TDSCDMA_CDMA_EVDO_GSM_WCDMA:
-                case Phone.NT_MODE_LTE_CDMA_EVDO_GSM_WCDMA:
+                case TelephonyManager.NETWORK_MODE_LTE_TDSCDMA_GSM:
+                case TelephonyManager.NETWORK_MODE_LTE_TDSCDMA_GSM_WCDMA:
+                case TelephonyManager.NETWORK_MODE_LTE_TDSCDMA:
+                case TelephonyManager.NETWORK_MODE_LTE_TDSCDMA_WCDMA:
+                case TelephonyManager.NETWORK_MODE_LTE_TDSCDMA_CDMA_EVDO_GSM_WCDMA:
+                case TelephonyManager.NETWORK_MODE_LTE_CDMA_EVDO_GSM_WCDMA:
                     if (isSupportTdscdma()) {
                         mButtonEnabledNetworks.setValue(
-                                Integer.toString(Phone.NT_MODE_LTE_TDSCDMA_CDMA_EVDO_GSM_WCDMA));
+                                Integer.toString(TelephonyManager
+                                        .NETWORK_MODE_LTE_TDSCDMA_CDMA_EVDO_GSM_WCDMA));
                         mButtonEnabledNetworks.setSummary(R.string.network_lte);
                     } else {
                         if (isWorldMode()) {
@@ -1793,7 +1811,8 @@
                             controlGsmOptions(false);
                         }
                         mButtonEnabledNetworks.setValue(
-                                Integer.toString(Phone.NT_MODE_LTE_CDMA_EVDO_GSM_WCDMA));
+                                Integer.toString(TelephonyManager
+                                        .NETWORK_MODE_LTE_CDMA_EVDO_GSM_WCDMA));
                         if (mTelephonyManager.getPhoneType() == PhoneConstants.PHONE_TYPE_CDMA
                                 || mIsGlobalCdma
                                 || isWorldMode()) {
@@ -1845,7 +1864,7 @@
                     TelecomManager.from(getContext()).getSimCallManager();
 
             if (simCallManager != null) {
-                Intent intent = PhoneAccountSettingsFragment.buildPhoneAccountConfigureIntent(
+                Intent intent = MobileNetworkSettings.buildPhoneAccountConfigureIntent(
                         getContext(), simCallManager);
                 PackageManager pm = getContext().getPackageManager();
                 List<ResolveInfo> resolutions = pm.queryIntentActivities(intent, 0);
@@ -2025,7 +2044,7 @@
                 return;
             }
 
-            updateGsmUmtsOptions(this, prefSet, mSubId, mNetworkQueryService);
+            updateGsmUmtsOptions(this, prefSet, mSubId);
 
             PreferenceCategory networkOperatorCategory =
                     (PreferenceCategory) prefSet.findPreference(
@@ -2178,14 +2197,14 @@
         }
 
         private void updateGsmUmtsOptions(PreferenceFragment prefFragment,
-                PreferenceScreen prefScreen, final int subId, INetworkQueryService queryService) {
+                PreferenceScreen prefScreen, final int subId) {
             // We don't want to re-create GsmUmtsOptions if already exists. Otherwise, the
             // preferences inside it will also be re-created which causes unexpected behavior.
             // For example, the open dialog gets dismissed or detached after pause / resume.
             if (mGsmUmtsOptions == null) {
-                mGsmUmtsOptions = new GsmUmtsOptions(prefFragment, prefScreen, subId, queryService);
+                mGsmUmtsOptions = new GsmUmtsOptions(prefFragment, prefScreen, subId);
             } else {
-                mGsmUmtsOptions.update(subId, queryService);
+                mGsmUmtsOptions.update(subId);
             }
         }
 
diff --git a/src/com/android/phone/NetworkOperators.java b/src/com/android/phone/NetworkOperators.java
index 6d798b0..938ca34 100644
--- a/src/com/android/phone/NetworkOperators.java
+++ b/src/com/android/phone/NetworkOperators.java
@@ -94,12 +94,11 @@
     }
 
     /**
-     * Update NetworkOperators instance if like subId or queryService are updated.
+     * Update NetworkOperators instance if like subId is updated.
      *
      * @param subId Corresponding subscription ID of this network.
-     * @param queryService The service to do network queries.
      */
-    protected void update(final int subId, INetworkQueryService queryService) {
+    protected void update(final int subId) {
         mSubId = subId;
         mTelephonyManager = TelephonyManager.from(getContext()).createForSubscriptionId(mSubId);
 
@@ -118,7 +117,7 @@
             }
         } else {
             if (mNetworkSelect != null) {
-                mNetworkSelect.initialize(mSubId, queryService, this, mProgressDialog);
+                mNetworkSelect.initialize(mSubId, this, mProgressDialog);
             }
         }
         getNetworkSelectionMode();
diff --git a/src/com/android/phone/NetworkScanHelper.java b/src/com/android/phone/NetworkScanHelper.java
new file mode 100644
index 0000000..a21f547
--- /dev/null
+++ b/src/com/android/phone/NetworkScanHelper.java
@@ -0,0 +1,286 @@
+/*
+ * 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.IntDef;
+import android.telephony.AccessNetworkConstants.AccessNetworkType;
+import android.telephony.CellInfo;
+import android.telephony.NetworkScan;
+import android.telephony.NetworkScanRequest;
+import android.telephony.RadioAccessSpecifier;
+import android.telephony.TelephonyManager;
+import android.telephony.TelephonyScanManager;
+import android.util.Log;
+
+import com.android.internal.telephony.CellNetworkScanResult;
+
+import com.google.common.util.concurrent.FutureCallback;
+import com.google.common.util.concurrent.Futures;
+import com.google.common.util.concurrent.ListenableFuture;
+import com.google.common.util.concurrent.SettableFuture;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.util.List;
+import java.util.concurrent.Executor;
+import java.util.stream.Collectors;
+
+/**
+ * A helper class that builds the common interface and performs the network scan for two different
+ * network scan APIs.
+ */
+public class NetworkScanHelper {
+    public static final String TAG = "NetworkScanHelper";
+    private static final boolean DBG = true;
+
+    /**
+     * Callbacks interface to inform the network scan results.
+     */
+    public interface NetworkScanCallback {
+        /**
+         * Called when the results is returned from {@link TelephonyManager}. This method will be
+         * called at least one time if there is no error occurred during the network scan.
+         *
+         * <p> This method can be called multiple times in one network scan, until
+         * {@link #onComplete()} or {@link #onError(int)} is called.
+         *
+         * @param results
+         */
+        void onResults(List<CellInfo> results);
+
+        /**
+         * Called when the current network scan process is finished. No more
+         * {@link #onResults(List)} will be called for the current network scan after this method is
+         * called.
+         */
+        void onComplete();
+
+        /**
+         * Called when an error occurred during the network scan process.
+         *
+         * <p> There is no more result returned from {@link TelephonyManager} if an error occurred.
+         *
+         * <p> {@link #onComplete()} will not be called if an error occurred.
+         *
+         * @see {@link android.telephony.NetworkScan.ScanErrorCode}
+         */
+        void onError(int errorCode);
+    }
+
+    @Retention(RetentionPolicy.SOURCE)
+    @IntDef({NETWORK_SCAN_TYPE_WAIT_FOR_ALL_RESULTS, NETWORK_SCAN_TYPE_INCREMENTAL_RESULTS})
+    public @interface NetworkQueryType {}
+
+    /**
+     * Performs the network scan using {@link TelephonyManager#getAvailableNetworks()}. The network
+     * scan results won't be returned to the caller until the network scan is completed.
+     *
+     * <p> This is typically used when the modem doesn't support the new network scan api
+     * {@link TelephonyManager#requestNetworkScan(
+     * NetworkScanRequest, Executor, TelephonyScanManager.NetworkScanCallback)}.
+     */
+    public static final int NETWORK_SCAN_TYPE_WAIT_FOR_ALL_RESULTS = 1;
+
+    /**
+     * Performs the network scan using {@link TelephonyManager#requestNetworkScan(
+     * NetworkScanRequest, Executor, TelephonyScanManager.NetworkScanCallback)} The network scan
+     * results will be returned to the caller periodically in a small time window until the network
+     * scan is completed. The complete results should be returned in the last called of
+     * {@link NetworkScanCallback#onResults(List)}.
+     *
+     * <p> This is recommended to be used if modem supports the new network scan api
+     * {@link TelephonyManager#requestNetworkScan(
+     * NetworkScanRequest, Executor, TelephonyScanManager.NetworkScanCallback)}
+     */
+    public static final int NETWORK_SCAN_TYPE_INCREMENTAL_RESULTS = 2;
+
+    /** The constants below are used in the async network scan. */
+    private static final boolean INCREMENTAL_RESULTS = true;
+    private static final int SEARCH_PERIODICITY_SEC = 5;
+    private static final int MAX_SEARCH_TIME_SEC = 300;
+    private static final int INCREMENTAL_RESULTS_PERIODICITY_SEC = 3;
+
+    private static final NetworkScanRequest NETWORK_SCAN_REQUEST =
+            new NetworkScanRequest(
+                    NetworkScanRequest.SCAN_TYPE_ONE_SHOT,
+                    new RadioAccessSpecifier[]{
+                            // GSM
+                            new RadioAccessSpecifier(
+                                    AccessNetworkType.GERAN,
+                                    null /* bands */,
+                                    null /* channels */),
+                            // LTE
+                            new RadioAccessSpecifier(
+                                    AccessNetworkType.EUTRAN,
+                                    null /* bands */,
+                                    null /* channels */),
+                            // WCDMA
+                            new RadioAccessSpecifier(
+                                    AccessNetworkType.UTRAN,
+                                    null /* bands */,
+                                    null /* channels */)
+                    },
+                    SEARCH_PERIODICITY_SEC,
+                    MAX_SEARCH_TIME_SEC,
+                    INCREMENTAL_RESULTS,
+                    INCREMENTAL_RESULTS_PERIODICITY_SEC,
+                    null /* List of PLMN ids (MCC-MNC) */);
+
+    private final NetworkScanCallback mNetworkScanCallback;
+    private final TelephonyManager mTelephonyManager;
+    private final TelephonyScanManager.NetworkScanCallback mInternalNetworkScanCallback;
+    private final Executor mExecutor;
+
+    private NetworkScan mNetworkScanRequester;
+
+    /** Callbacks for sync network scan */
+    private ListenableFuture<List<CellInfo>> mNetworkScanFuture;
+
+    public NetworkScanHelper(TelephonyManager tm, NetworkScanCallback callback, Executor executor) {
+        mTelephonyManager = tm;
+        mNetworkScanCallback = callback;
+        mInternalNetworkScanCallback = new NetworkScanCallbackImpl();
+        mExecutor = executor;
+    }
+
+    /**
+     * Performs a network scan for the given type {@code type}.
+     * {@link #NETWORK_SCAN_TYPE_INCREMENTAL_RESULTS} is recommended if modem supports
+     * {@link TelephonyManager#requestNetworkScan(
+     * NetworkScanRequest, Executor, TelephonyScanManager.NetworkScanCallback)}.
+     *
+     * @param type used to tell which network scan API should be used.
+     */
+    public void startNetworkScan(@NetworkQueryType int type) {
+        if (type == NETWORK_SCAN_TYPE_WAIT_FOR_ALL_RESULTS) {
+            mNetworkScanFuture = SettableFuture.create();
+            Futures.addCallback(mNetworkScanFuture, new FutureCallback<List<CellInfo>>() {
+                @Override
+                public void onSuccess(List<CellInfo> result) {
+                    onResults(result);
+                    onComplete();
+                }
+
+                @Override
+                public void onFailure(Throwable t) {
+                    int errCode = Integer.parseInt(t.getMessage());
+                    onError(errCode);
+                }
+            });
+            mExecutor.execute(new NetworkScanSyncTask(
+                    mTelephonyManager, (SettableFuture) mNetworkScanFuture));
+        } else if (type == NETWORK_SCAN_TYPE_INCREMENTAL_RESULTS) {
+            if (DBG) Log.d(TAG, "start network scan async");
+            mNetworkScanRequester = mTelephonyManager.requestNetworkScan(
+                    NETWORK_SCAN_REQUEST,
+                    mExecutor,
+                    mInternalNetworkScanCallback);
+        }
+    }
+
+    /**
+     * The network scan of type {@link #NETWORK_SCAN_TYPE_WAIT_FOR_ALL_RESULTS} can't be stopped,
+     * however, the result of the current network scan won't be returned to the callback after
+     * calling this method.
+     */
+    public void stopNetworkQuery() {
+        if (mNetworkScanRequester != null) {
+            mNetworkScanRequester.stopScan();
+            mNetworkScanFuture = null;
+        }
+
+        if (mNetworkScanFuture != null) {
+            mNetworkScanFuture.cancel(true /* mayInterruptIfRunning */);
+            mNetworkScanFuture = null;
+        }
+    }
+
+    private void onResults(List<CellInfo> cellInfos) {
+        mNetworkScanCallback.onResults(cellInfos);
+    }
+
+    private void onComplete() {
+        mNetworkScanCallback.onComplete();
+    }
+
+    private void onError(int errCode) {
+        mNetworkScanCallback.onError(errCode);
+    }
+
+    /**
+     * Converts the status code of {@link CellNetworkScanResult} to one of the
+     * {@link android.telephony.NetworkScan.ScanErrorCode}.
+     * @param errCode status code from {@link CellNetworkScanResult}.
+     *
+     * @return one of the scan error code from {@link android.telephony.NetworkScan.ScanErrorCode}.
+     */
+    private static int convertToScanErrorCode(int errCode) {
+        switch (errCode) {
+            case CellNetworkScanResult.STATUS_RADIO_NOT_AVAILABLE:
+                return NetworkScan.ERROR_RADIO_INTERFACE_ERROR;
+            case CellNetworkScanResult.STATUS_RADIO_GENERIC_FAILURE:
+            default:
+                return NetworkScan.ERROR_MODEM_ERROR;
+        }
+    }
+
+    private final class NetworkScanCallbackImpl extends TelephonyScanManager.NetworkScanCallback {
+        public void onResults(List<CellInfo> results) {
+            if (DBG) Log.d(TAG, "async scan onResults() results = " + results);
+            NetworkScanHelper.this.onResults(results);
+        }
+
+        public void onComplete() {
+            if (DBG) Log.d(TAG, "async scan onComplete()");
+            NetworkScanHelper.this.onComplete();
+        }
+
+        public void onError(@NetworkScan.ScanErrorCode int errCode) {
+            if (DBG) Log.d(TAG, "async scan onError() errorCode = " + errCode);
+            NetworkScanHelper.this.onError(errCode);
+        }
+    }
+
+    private static final class NetworkScanSyncTask implements Runnable {
+        private final SettableFuture<List<CellInfo>> mCallback;
+        private final TelephonyManager mTelephonyManager;
+
+        NetworkScanSyncTask(
+                TelephonyManager telephonyManager, SettableFuture<List<CellInfo>> callback) {
+            mTelephonyManager = telephonyManager;
+            mCallback = callback;
+        }
+
+        @Override
+        public void run() {
+            if (DBG) Log.d(TAG, "sync scan start");
+            CellNetworkScanResult result = mTelephonyManager.getAvailableNetworks();
+            if (result.getStatus() == CellNetworkScanResult.STATUS_SUCCESS) {
+                List<CellInfo> cellInfos = result.getOperators()
+                        .stream()
+                        .map(operatorInfo
+                                -> CellInfoUtil.convertOperatorInfoToCellInfo(operatorInfo))
+                        .collect(Collectors.toList());
+                if (DBG) Log.d(TAG, "sync scan complete");
+                mCallback.set(cellInfos);
+            } else {
+                mCallback.setException(new Throwable(
+                        Integer.toString(convertToScanErrorCode(result.getStatus()))));
+            }
+        }
+    }
+}
diff --git a/src/com/android/phone/NetworkSelectListPreference.java b/src/com/android/phone/NetworkSelectListPreference.java
index 5b841c9..9af1c77 100644
--- a/src/com/android/phone/NetworkSelectListPreference.java
+++ b/src/com/android/phone/NetworkSelectListPreference.java
@@ -24,7 +24,6 @@
 import android.os.Message;
 import android.os.Parcel;
 import android.os.Parcelable;
-import android.os.RemoteException;
 import android.preference.ListPreference;
 import android.preference.Preference;
 import android.telephony.CellInfo;
@@ -39,15 +38,19 @@
 import android.text.TextUtils;
 import android.util.AttributeSet;
 import android.util.Log;
+import android.widget.Toast;
 
 import com.android.internal.logging.MetricsLogger;
 import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
 import com.android.internal.telephony.OperatorInfo;
+import com.android.phone.NetworkScanHelper.NetworkScanCallback;
 import com.android.settingslib.utils.ThreadUtils;
 
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.List;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
 
 
 /**
@@ -65,16 +68,20 @@
     private static final int EVENT_MANUALLY_NETWORK_SELECTION_DONE = 1;
     private static final int EVENT_NETWORK_SCAN_RESULTS = 2;
     private static final int EVENT_NETWORK_SCAN_COMPLETED = 3;
+    private static final int EVENT_NETWORK_SCAN_ERROR = 4;
 
     //dialog ids
     private static final int DIALOG_NETWORK_SELECTION = 100;
     private static final int DIALOG_NETWORK_LIST_LOAD = 200;
 
+    private final ExecutorService mNetworkScanExecutor = Executors.newFixedThreadPool(1);
+
     private List<CellInfo> mCellInfoList;
     private CellInfo mCellInfo;
 
     private int mSubId;
     private TelephonyManager mTelephonyManager;
+    private NetworkScanHelper mNetworkScanHelper;
     private NetworkOperators mNetworkOperators;
     private List<String> mForbiddenPlmns;
 
@@ -113,11 +120,7 @@
             switch (msg.what) {
                 case EVENT_MANUALLY_NETWORK_SELECTION_DONE:
                     if (DBG) logd("hideProgressPanel");
-                    try {
-                        dismissProgressBar();
-                    } catch (IllegalArgumentException e) {
-                    }
-                    setEnabled(true);
+                    dismissProgressDialog();
 
                     boolean isSuccessed = (boolean) msg.obj;
                     if (isSuccessed) {
@@ -138,72 +141,51 @@
                     results.removeIf(cellInfo -> cellInfo == null);
                     mCellInfoList = new ArrayList<>(results);
                     if (DBG) logd("CALLBACK_SCAN_RESULTS" + mCellInfoList.toString());
-
                     break;
 
                 case EVENT_NETWORK_SCAN_COMPLETED:
-                    try {
-                        if (mNetworkQueryService != null) {
-                            mNetworkQueryService.unregisterCallback(mCallback);
-                        }
-                    } catch (RemoteException e) {
-                        loge("onComplete: exception from unregisterCallback " + e);
-                    }
                     if (DBG) logd("scan complete, load the cellInfosList");
-                    // Modify UI to indicate users that the scan has completed.
+                    dismissProgressDialog();
                     networksListLoaded();
+                    break;
+                case EVENT_NETWORK_SCAN_ERROR:
+                    dismissProgressDialog();
+                    displayNetworkQueryFailed();
+                    mNetworkOperators.getNetworkSelectionMode();
+                    break;
             }
             return;
         }
     };
 
-    INetworkQueryService mNetworkQueryService = null;
-    /**
-     * This implementation of INetworkQueryServiceCallback is used to receive
-     * callback notifications from the network query service.
-     */
-    private final INetworkQueryServiceCallback mCallback = new INetworkQueryServiceCallback.Stub() {
-
-        /** Returns the scan results to the user, this callback will be called only one time. */
+    private final NetworkScanHelper.NetworkScanCallback mCallback = new NetworkScanCallback() {
         public void onResults(List<CellInfo> results) {
             if (DBG) logd("get scan results: " + results.toString());
             Message msg = mHandler.obtainMessage(EVENT_NETWORK_SCAN_RESULTS, results);
             msg.sendToTarget();
         }
 
-        /**
-         * Informs the user that the scan has stopped.
-         *
-         * This callback will be called when the scan is finished or cancelled by the user.
-         * The related NetworkScanRequest will be deleted after this callback.
-         */
         public void onComplete() {
             if (DBG) logd("network scan completed.");
             Message msg = mHandler.obtainMessage(EVENT_NETWORK_SCAN_COMPLETED);
             msg.sendToTarget();
         }
 
-        /**
-         * This callback will not be called, since the old Scan API won't send this callback.
-         */
-        public void onError(int error) {}
+        public void onError(int error) {
+            if (DBG) logd("network scan error.");
+            Message msg = mHandler.obtainMessage(EVENT_NETWORK_SCAN_ERROR);
+            msg.sendToTarget();
+        }
     };
 
     @Override
     //implemented for DialogInterface.OnCancelListener
     public void onCancel(DialogInterface dialog) {
         if (DBG) logd("user manually close the dialog");
-        // request that the service stop the query with this callback object.
-        try {
-            if (mNetworkQueryService != null) {
-                mNetworkQueryService.stopNetworkQuery();
-                mNetworkQueryService.unregisterCallback(mCallback);
-            }
-            // If cancelled, we query NetworkSelectMode and update states of AutoSelect button.
-            mNetworkOperators.getNetworkSelectionMode();
-        } catch (RemoteException e) {
-            loge("onCancel: exception from stopNetworkQuery " + e);
-        }
+        mNetworkScanHelper.stopNetworkQuery();
+
+        // If cancelled, we query NetworkSelectMode and update states of AutoSelect button.
+        mNetworkOperators.getNetworkSelectionMode();
     }
 
     @Override
@@ -215,23 +197,17 @@
         }
     }
 
-    // This method is provided besides initialize() because bind to network query service
-    // may be binded after initialize(). In that case this method needs to be called explicitly
-    // to set mNetworkQueryService. Otherwise mNetworkQueryService will remain null.
-    public void setNetworkQueryService(INetworkQueryService queryService) {
-        mNetworkQueryService = queryService;
-    }
-
     // This initialize method needs to be called for this preference to work properly.
-    protected void initialize(int subId, INetworkQueryService queryService,
-                              NetworkOperators networkOperators, ProgressDialog progressDialog) {
+    protected void initialize(int subId, NetworkOperators networkOperators,
+            ProgressDialog progressDialog) {
         mSubId = subId;
-        mNetworkQueryService = queryService;
         mNetworkOperators = networkOperators;
         // This preference should share the same progressDialog with networkOperators category.
         mProgressDialog = progressDialog;
 
         mTelephonyManager = TelephonyManager.from(getContext()).createForSubscriptionId(mSubId);
+        mNetworkScanHelper = new NetworkScanHelper(
+                mTelephonyManager, mCallback, mNetworkScanExecutor);
 
         setSummary(mTelephonyManager.getNetworkOperatorName());
 
@@ -245,79 +221,32 @@
     }
 
     private void destroy() {
-        try {
-            dismissProgressBar();
-        } catch (IllegalArgumentException e) {
-            loge("onDestroy: exception from dismissProgressBar " + e);
+        dismissProgressDialog();
+
+        if (mNetworkScanHelper != null) {
+            mNetworkScanHelper.stopNetworkQuery();
         }
 
-        try {
-            if (mNetworkQueryService != null) {
-                // used to un-register callback
-                mNetworkQueryService.unregisterCallback(mCallback);
-            }
-        } catch (RemoteException e) {
-            loge("onDestroy: exception from unregisterCallback " + e);
-        }
+        mNetworkScanExecutor.shutdown();
     }
 
     private void displayEmptyNetworkList() {
-        String status = getContext().getResources().getString(R.string.empty_networks_list);
-
-        final PhoneGlobals app = PhoneGlobals.getInstance();
-        app.notificationMgr.postTransientNotification(
-                NotificationMgr.NETWORK_SELECTION_NOTIFICATION, status);
+        Toast.makeText(getContext(), R.string.empty_networks_list, Toast.LENGTH_LONG).show();
     }
 
-    private void displayNetworkSelectionInProgress() {
-        showProgressDialog(DIALOG_NETWORK_SELECTION);
-    }
-
-    private void displayNetworkQueryFailed(int error) {
-        String status = getContext().getResources().getString(R.string.network_query_error);
-
-        try {
-            dismissProgressBar();
-        } catch (IllegalArgumentException e1) {
-            // do nothing
-        }
-
-        final PhoneGlobals app = PhoneGlobals.getInstance();
-        app.notificationMgr.postTransientNotification(
-                NotificationMgr.NETWORK_SELECTION_NOTIFICATION, status);
+    private void displayNetworkQueryFailed() {
+        Toast.makeText(getContext(), R.string.network_query_error, Toast.LENGTH_LONG).show();
     }
 
     private void loadNetworksList() {
         if (DBG) logd("load networks list...");
-        try {
-            if (mNetworkQueryService != null) {
-                mNetworkQueryService.startNetworkQuery(
-                        mCallback, mSubId, false /* isIncrementalResult */);
-            } else {
-                displayNetworkQueryFailed(NetworkQueryService.QUERY_EXCEPTION);
-            }
-        } catch (RemoteException e) {
-            loge("loadNetworksList: exception from startNetworkQuery " + e);
-            displayNetworkQueryFailed(NetworkQueryService.QUERY_EXCEPTION);
-        }
+        mNetworkScanHelper.startNetworkScan(
+                NetworkScanHelper.NETWORK_SCAN_TYPE_WAIT_FOR_ALL_RESULTS);
     }
 
     private void networksListLoaded() {
         if (DBG) logd("networks list loaded");
 
-        // update the state of the preferences.
-        if (DBG) logd("hideProgressPanel");
-
-        // Always try to dismiss the dialog because activity may
-        // be moved to background after dialog is shown.
-        try {
-            dismissProgressBar();
-        } catch (IllegalArgumentException e) {
-            // It's not a error in following scenario, we just ignore it.
-            // "Load list" dialog will not show, if NetworkQueryService is
-            // connected after this activity is moved to background.
-            loge("Fail to dismiss network load list dialog " + e);
-        }
         mNetworkOperators.getNetworkSelectionMode();
         if (mCellInfoList != null) {
             // create a preference for each item in the list.
@@ -345,9 +274,13 @@
         }
     }
 
-    private void dismissProgressBar() {
+    private void dismissProgressDialog() {
         if (mProgressDialog != null && mProgressDialog.isShowing()) {
-            mProgressDialog.dismiss();
+            try {
+                mProgressDialog.dismiss();
+            } catch (IllegalArgumentException ex) {
+                loge("Can't close the progress dialog " + ex);
+            }
         }
     }
 
@@ -356,7 +289,7 @@
             mProgressDialog = new ProgressDialog(getContext());
         } else {
             // Dismiss progress bar if it's showing now.
-            dismissProgressBar();
+            dismissProgressDialog();
         }
 
         switch (id) {
diff --git a/src/com/android/phone/NetworkSelectSetting.java b/src/com/android/phone/NetworkSelectSetting.java
index c8a29ce..66cd8a1 100644
--- a/src/com/android/phone/NetworkSelectSetting.java
+++ b/src/com/android/phone/NetworkSelectSetting.java
@@ -17,17 +17,12 @@
 
 import android.app.ActionBar;
 import android.app.Activity;
-import android.content.ComponentName;
 import android.content.Context;
-import android.content.Intent;
-import android.content.ServiceConnection;
 import android.content.pm.PackageManager;
 import android.os.AsyncTask;
 import android.os.Bundle;
 import android.os.Handler;
-import android.os.IBinder;
 import android.os.Message;
-import android.os.RemoteException;
 import android.preference.Preference;
 import android.preference.PreferenceCategory;
 import android.preference.PreferenceFragment;
@@ -47,6 +42,7 @@
 import com.android.internal.logging.MetricsLogger;
 import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
 import com.android.internal.telephony.OperatorInfo;
+import com.android.phone.NetworkScanHelper.NetworkScanCallback;
 import com.android.settingslib.utils.ThreadUtils;
 
 import java.util.ArrayList;
@@ -54,6 +50,8 @@
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
 
 /**
  * "Choose network" settings UI for the Phone app.
@@ -86,6 +84,8 @@
     private TelephonyManager mTelephonyManager;
     private List<String> mForbiddenPlmns;
     private boolean mShow4GForLTE;
+    private NetworkScanHelper mNetworkScanHelper;
+    private final ExecutorService mNetworkScanExecutor = Executors.newFixedThreadPool(1);
 
     private final Runnable mUpdateNetworkOperatorsRunnable = () -> {
         updateNetworkOperatorsPreferenceCategory();
@@ -118,6 +118,8 @@
         mStatusMessagePreference = new Preference(getContext());
         mSelectedNetworkOperatorPreference = null;
         mTelephonyManager = TelephonyManager.from(getContext()).createForSubscriptionId(mSubId);
+        mNetworkScanHelper = new NetworkScanHelper(
+                mTelephonyManager, mCallback, mNetworkScanExecutor);
         try {
             Context con = getActivity().createPackageContext("com.android.systemui", 0);
             int id = con.getResources().getIdentifier("config_show4GForLTE",
@@ -172,7 +174,7 @@
             @Override
             protected void onPostExecute(List<String> result) {
                 mForbiddenPlmns = result;
-                bindNetworkQueryService();
+                loadNetworksList();
             }
         }.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
     }
@@ -260,8 +262,6 @@
         if (DBG) logd("onStop");
         getView().removeCallbacks(mUpdateNetworkOperatorsRunnable);
         stopNetworkQuery();
-        // Unbind the NetworkQueryService
-        unbindNetworkQueryService();
     }
 
     private final Handler mHandler = new Handler() {
@@ -320,52 +320,23 @@
     private void loadNetworksList() {
         if (DBG) logd("load networks list...");
         setProgressBarVisible(true);
-        try {
-            if (mNetworkQueryService != null) {
-                if (DBG) logd("start network query");
-                mNetworkQueryService
-                        .startNetworkQuery(mCallback, mSubId, true /* is incremental result */);
-            } else {
-                if (DBG) logd("unable to start network query, mNetworkQueryService is null");
-                addMessagePreference(R.string.network_query_error);
-            }
-        } catch (RemoteException e) {
-            loge("loadNetworksList: exception from startNetworkQuery " + e);
-            addMessagePreference(R.string.network_query_error);
-        }
+        mNetworkScanHelper.startNetworkScan(
+                NetworkScanHelper.NETWORK_SCAN_TYPE_INCREMENTAL_RESULTS);
     }
 
-    /**
-     * This implementation of INetworkQueryServiceCallback is used to receive
-     * callback notifications from the network query service.
-     */
-    private final INetworkQueryServiceCallback mCallback = new INetworkQueryServiceCallback.Stub() {
-
-        /** Returns the scan results to the user, this callback will be called at lease one time. */
+    private final NetworkScanHelper.NetworkScanCallback mCallback = new NetworkScanCallback() {
         public void onResults(List<CellInfo> results) {
             if (DBG) logd("get scan results.");
             Message msg = mHandler.obtainMessage(EVENT_NETWORK_SCAN_RESULTS, results);
             msg.sendToTarget();
         }
 
-        /**
-         * Informs the user that the scan has stopped.
-         *
-         * This callback will be called when the scan is finished or cancelled by the user.
-         * The related NetworkScanRequest will be deleted after this callback.
-         */
         public void onComplete() {
             if (DBG) logd("network scan completed.");
             Message msg = mHandler.obtainMessage(EVENT_NETWORK_SCAN_COMPLETED);
             msg.sendToTarget();
         }
 
-        /**
-         * Informs the user that there is some error about the scan.
-         *
-         * This callback will be called whenever there is any error about the scan, and the scan
-         * will be terminated. onComplete() will NOT be called.
-         */
         public void onError(int error) {
             if (DBG) logd("get onError callback with error code: " + error);
             Message msg = mHandler.obtainMessage(EVENT_NETWORK_SCAN_ERROR, error, 0 /* arg2 */);
@@ -373,9 +344,6 @@
         }
     };
 
-    /**
-     * Updates network operators from {@link INetworkQueryServiceCallback#onResults()}.
-     */
     private void updateNetworkOperators() {
         if (DBG) logd("updateNetworkOperators");
         if (getActivity() != null) {
@@ -580,66 +548,18 @@
         return new ArrayList<>(map.values());
     }
 
-    /**
-     * Service connection code for the NetworkQueryService.
-     * Handles the work of binding to a local object so that we can make
-     * the appropriate service calls.
-     */
-
-    /** Local service interface */
-    private INetworkQueryService mNetworkQueryService = null;
-    /** Flag indicating whether we have called bind on the service. */
-    boolean mShouldUnbind;
-
-    /** Service connection */
-    private final ServiceConnection mNetworkQueryServiceConnection = new ServiceConnection() {
-
-        /** Handle the task of binding the local object to the service */
-        public void onServiceConnected(ComponentName className, IBinder service) {
-            if (DBG) logd("connection created, binding local service.");
-            mNetworkQueryService = ((NetworkQueryService.LocalBinder) service).getService();
-            // Load the network list only when the service is well connected.
-            loadNetworksList();
-        }
-
-        /** Handle the task of cleaning up the local binding */
-        public void onServiceDisconnected(ComponentName className) {
-            if (DBG) logd("connection disconnected, cleaning local binding.");
-            mNetworkQueryService = null;
-        }
-    };
-
-    private void bindNetworkQueryService() {
-        if (DBG) logd("bindNetworkQueryService");
-        getContext().bindService(new Intent(getContext(), NetworkQueryService.class).setAction(
-                NetworkQueryService.ACTION_LOCAL_BINDER),
-                mNetworkQueryServiceConnection, Context.BIND_AUTO_CREATE);
-        mShouldUnbind = true;
-    }
-
-    private void unbindNetworkQueryService() {
-        if (DBG) logd("unbindNetworkQueryService");
-        if (mShouldUnbind) {
-            if (DBG) logd("mShouldUnbind is true");
-            // unbind the service.
-            getContext().unbindService(mNetworkQueryServiceConnection);
-            mShouldUnbind = false;
-        }
-    }
-
     private void stopNetworkQuery() {
-        // Stop the network query process
-        try {
-            if (mNetworkQueryService != null) {
-                if (DBG) logd("Stop network query");
-                mNetworkQueryService.stopNetworkQuery();
-                mNetworkQueryService.unregisterCallback(mCallback);
-            }
-        } catch (RemoteException e) {
-            loge("Exception from stopNetworkQuery " + e);
+        if (mNetworkScanHelper != null) {
+            mNetworkScanHelper.stopNetworkQuery();
         }
     }
 
+    @Override
+    public void onDestroy() {
+        mNetworkScanExecutor.shutdown();
+        super.onDestroy();
+    }
+
     private void logd(String msg) {
         Log.d(TAG, msg);
     }
diff --git a/src/com/android/phone/PhoneGlobals.java b/src/com/android/phone/PhoneGlobals.java
index 67ec932..3f679ed 100644
--- a/src/com/android/phone/PhoneGlobals.java
+++ b/src/com/android/phone/PhoneGlobals.java
@@ -50,7 +50,6 @@
 import android.util.Log;
 import android.widget.Toast;
 
-import com.android.internal.telephony.Call;
 import com.android.internal.telephony.CallManager;
 import com.android.internal.telephony.IccCardConstants;
 import com.android.internal.telephony.MmiCode;
@@ -142,7 +141,6 @@
     public PhoneInterfaceManager phoneMgr;
     CarrierConfigLoader configLoader;
 
-    private CallGatewayManager callGatewayManager;
     private Phone phoneInEcm;
 
     static boolean sVoiceCapable = true;
@@ -321,10 +319,6 @@
 
             if (DBG) Log.d(LOG_TAG, "onCreate: mUpdateLock: " + mUpdateLock);
 
-            CallLogger callLogger = new CallLogger(this, new CallLogAsync());
-
-            callGatewayManager = CallGatewayManager.getInstance();
-
             // Create the CallerInfoCache singleton, which remembers custom ring tone and
             // send-to-voicemail settings.
             //
@@ -346,9 +340,6 @@
             // register for MMI/USSD
             mCM.registerForMmiComplete(mHandler, MMI_COMPLETE, null);
 
-            // register connection tracking to PhoneUtils
-            PhoneUtils.initializeConnectionHandler(mCM);
-
             // Register for misc other intent broadcasts.
             IntentFilter intentFilter =
                     new IntentFilter(Intent.ACTION_AIRPLANE_MODE_CHANGED);
@@ -372,11 +363,6 @@
             PreferenceManager.setDefaultValues(this, R.xml.network_setting_fragment, false);
 
             PreferenceManager.setDefaultValues(this, R.xml.call_feature_setting, false);
-
-            // Make sure the audio mode (along with some
-            // audio-mode-related state of our own) is initialized
-            // correctly, given the current state of the phone.
-            PhoneUtils.setAudioMode(mCM);
         }
 
         // XXX pre-load the SimProvider so that it's ready
@@ -409,14 +395,6 @@
     }
 
     /**
-     * Returns the singleton instance of the PhoneApp if running as the
-     * primary user, otherwise null.
-     */
-    static PhoneGlobals getInstanceIfPrimary() {
-        return sMe;
-    }
-
-    /**
      * Returns the default phone.
      *
      * WARNING: This method should be used carefully, now that there may be multiple phones.
@@ -496,52 +474,6 @@
     }
 
     /**
-     * Controls whether or not the screen is allowed to sleep.
-     *
-     * Once sleep is allowed (WakeState is SLEEP), it will rely on the
-     * settings for the poke lock to determine when to timeout and let
-     * the device sleep {@link PhoneGlobals#setScreenTimeout}.
-     *
-     * @param ws tells the device to how to wake.
-     */
-    /* package */ void requestWakeState(WakeState ws) {
-        if (VDBG) Log.d(LOG_TAG, "requestWakeState(" + ws + ")...");
-        synchronized (this) {
-            if (mWakeState != ws) {
-                switch (ws) {
-                    case PARTIAL:
-                        // acquire the processor wake lock, and release the FULL
-                        // lock if it is being held.
-                        mPartialWakeLock.acquire();
-                        if (mWakeLock.isHeld()) {
-                            mWakeLock.release();
-                        }
-                        break;
-                    case FULL:
-                        // acquire the full wake lock, and release the PARTIAL
-                        // lock if it is being held.
-                        mWakeLock.acquire();
-                        if (mPartialWakeLock.isHeld()) {
-                            mPartialWakeLock.release();
-                        }
-                        break;
-                    case SLEEP:
-                    default:
-                        // release both the PARTIAL and FULL locks.
-                        if (mWakeLock.isHeld()) {
-                            mWakeLock.release();
-                        }
-                        if (mPartialWakeLock.isHeld()) {
-                            mPartialWakeLock.release();
-                        }
-                        break;
-                }
-                mWakeState = ws;
-            }
-        }
-    }
-
-    /**
      * If we are not currently keeping the screen on, then poke the power
      * manager to wake up the screen for the user activity timeout duration.
      */
@@ -554,52 +486,6 @@
         }
     }
 
-    /**
-     * Sets the wake state and screen timeout based on the current state
-     * of the phone, and the current state of the in-call UI.
-     *
-     * This method is a "UI Policy" wrapper around
-     * {@link PhoneGlobals#requestWakeState} and {@link PhoneGlobals#setScreenTimeout}.
-     *
-     * It's safe to call this method regardless of the state of the Phone
-     * (e.g. whether or not it's idle), and regardless of the state of the
-     * Phone UI (e.g. whether or not the InCallScreen is active.)
-     */
-    /* package */ void updateWakeState() {
-        PhoneConstants.State state = mCM.getState();
-
-        // True if the speakerphone is in use.  (If so, we *always* use
-        // the default timeout.  Since the user is obviously not holding
-        // the phone up to his/her face, we don't need to worry about
-        // false touches, and thus don't need to turn the screen off so
-        // aggressively.)
-        // Note that we need to make a fresh call to this method any
-        // time the speaker state changes.  (That happens in
-        // PhoneUtils.turnOnSpeaker().)
-        boolean isSpeakerInUse = (state == PhoneConstants.State.OFFHOOK) && PhoneUtils.isSpeakerOn(this);
-
-        // TODO (bug 1440854): The screen timeout *might* also need to
-        // depend on the bluetooth state, but this isn't as clear-cut as
-        // the speaker state (since while using BT it's common for the
-        // user to put the phone straight into a pocket, in which case the
-        // timeout should probably still be short.)
-
-        // Decide whether to force the screen on or not.
-        //
-        // Force the screen to be on if the phone is ringing or dialing,
-        // or if we're displaying the "Call ended" UI for a connection in
-        // the "disconnected" state.
-        // However, if the phone is disconnected while the user is in the
-        // middle of selecting a quick response message, we should not force
-        // the screen to be on.
-        //
-        boolean isRinging = (state == PhoneConstants.State.RINGING);
-        boolean isDialing = (mCM.getFgPhone().getForegroundCall().getState() == Call.State.DIALING);
-        boolean keepScreenOn = isRinging || isDialing;
-        // keepScreenOn == true means we'll hold a full wake lock:
-        requestWakeState(keepScreenOn ? WakeState.FULL : WakeState.SLEEP);
-    }
-
     KeyguardManager getKeyguardManager() {
         return mKeyguardManager;
     }
@@ -879,41 +765,6 @@
     }
 
     /**
-     * Dismisses the message waiting (voicemail) indicator.
-     *
-     * @param subId the subscription id we should dismiss the notification for.
-     */
-    public void clearMwiIndicator(int subId) {
-        // Setting voiceMessageCount to 0 will remove the current notification and clear the system
-        // cached value.
-        Phone phone = getPhone(subId);
-        if (phone == null) {
-            Log.w(LOG_TAG, "clearMwiIndicator on null phone, subId:" + subId);
-        } else {
-            phone.setVoiceMessageCount(0);
-        }
-    }
-
-    /**
-     * Enables or disables the visual voicemail check for message waiting indicator. Default value
-     * is true. MWI is the traditional voicemail notification which should be suppressed if visual
-     * voicemail is active. {@link NotificationMgr#updateMwi(int, boolean, boolean)} currently
-     * checks the {@link android.provider.VoicemailContract.Status#CONFIGURATION_STATE} to suppress
-     * the MWI, but there are several issues. b/31229016 is a bug that when the device boots the
-     * configuration state will be cleared and the MWI for voicemail that arrives when the device
-     * is offline will be cleared, even if the account cannot be activated. A full solution will be
-     * adding a setMwiEnabled() method and stop checking the configuration state, but that is too
-     * risky at this moment. This is a temporary workaround to shut down the configuration state
-     * check if visual voicemail cannot be activated.
-     * <p>TODO(twyen): implement the setMwiEnabled() mentioned above.
-     *
-     * @param subId the account to set the enabled state
-     */
-    public void setShouldCheckVisualVoicemailConfigurationForMwi(int subId, boolean enabled) {
-        notificationMgr.setShouldCheckVisualVoicemailConfigurationForMwi(subId, enabled);
-    }
-
-    /**
      * Dump the state of the object, add calls to other objects as desired.
      *
      * @param fd File descriptor
diff --git a/src/com/android/phone/PhoneInterfaceManager.java b/src/com/android/phone/PhoneInterfaceManager.java
index 353f4b5..cef0e53 100755
--- a/src/com/android/phone/PhoneInterfaceManager.java
+++ b/src/com/android/phone/PhoneInterfaceManager.java
@@ -990,7 +990,9 @@
                 case EVENT_GET_ALL_CELL_INFO_DONE:
                     ar = (AsyncResult) msg.obj;
                     request = (MainThreadRequest) ar.userObj;
-                    request.result = (ar.exception == null) ? ar.result : new ArrayList<CellInfo>();
+                    // If a timeout occurs, the response will be null
+                    request.result = (ar.exception == null && ar.result != null)
+                            ? ar.result : new ArrayList<CellInfo>();
                     synchronized (request) {
                         request.notifyAll();
                     }
@@ -1255,112 +1257,6 @@
         }
     }
 
-    /**
-     * End a call based on call state
-     * @return true is a call was ended
-     */
-    public boolean endCall() {
-        return false;
-    }
-
-    /**
-     * End a call based on the call state of the subId
-     * @return true is a call was ended
-     */
-    public boolean endCallForSubscriber(int subId) {
-        return false;
-    }
-
-    public void answerRingingCall() {
-        // Deprecated.
-    }
-
-    public void answerRingingCallForSubscriber(int subId) {
-        // Deprecated
-    }
-
-    /**
-     * This method is no longer used and can be removed once TelephonyManager stops referring to it.
-     */
-    public void silenceRinger() {
-        Log.e(LOG_TAG, "silenseRinger not supported");
-    }
-
-    @Override
-    public boolean isOffhook(String callingPackage) {
-        return isOffhookForSubscriber(getDefaultSubscription(), callingPackage);
-    }
-
-    @Override
-    public boolean isOffhookForSubscriber(int subId, String callingPackage) {
-        if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
-                mApp, subId, callingPackage, "isOffhookForSubscriber")) {
-            return false;
-        }
-
-        final long identity = Binder.clearCallingIdentity();
-        try {
-            final Phone phone = getPhone(subId);
-            if (phone != null) {
-                return (phone.getState() == PhoneConstants.State.OFFHOOK);
-            } else {
-                return false;
-            }
-        } finally {
-            Binder.restoreCallingIdentity(identity);
-        }
-    }
-
-    @Override
-    public boolean isRinging(String callingPackage) {
-        return (isRingingForSubscriber(getDefaultSubscription(), callingPackage));
-    }
-
-    @Override
-    public boolean isRingingForSubscriber(int subId, String callingPackage) {
-        if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
-                mApp, subId, callingPackage, "isRingingForSubscriber")) {
-            return false;
-        }
-
-        final long identity = Binder.clearCallingIdentity();
-        try {
-            final Phone phone = getPhone(subId);
-            if (phone != null) {
-                return (phone.getState() == PhoneConstants.State.RINGING);
-            } else {
-                return false;
-            }
-        } finally {
-            Binder.restoreCallingIdentity(identity);
-        }
-    }
-
-    @Override
-    public boolean isIdle(String callingPackage) {
-        return isIdleForSubscriber(getDefaultSubscription(), callingPackage);
-    }
-
-    @Override
-    public boolean isIdleForSubscriber(int subId, String callingPackage) {
-        if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
-                mApp, subId, callingPackage, "isIdleForSubscriber")) {
-            return false;
-        }
-
-        final long identity = Binder.clearCallingIdentity();
-        try {
-            final Phone phone = getPhone(subId);
-            if (phone != null) {
-                return (phone.getState() == PhoneConstants.State.IDLE);
-            } else {
-                return false;
-            }
-        } finally {
-            Binder.restoreCallingIdentity(identity);
-        }
-    }
-
     public boolean supplyPin(String pin) {
         return supplyPinForSubscriber(getDefaultSubscription(), pin);
     }
@@ -3216,21 +3112,6 @@
     }
 
     /**
-     * @return true if the IMS resolver is busy resolving a binding and should not be considered
-     * available, false if the IMS resolver is idle.
-     */
-    public boolean isResolvingImsBinding() {
-        enforceModifyPermission();
-
-        final long identity = Binder.clearCallingIdentity();
-        try {
-            return PhoneFactory.getImsResolver().isResolvingBinding();
-        } finally {
-            Binder.restoreCallingIdentity(identity);
-        }
-    }
-
-    /**
      * Sets the ImsService Package Name that Telephony will bind to.
      *
      * @param slotId the slot ID that the ImsService should bind for.
diff --git a/src/com/android/phone/PhoneUtils.java b/src/com/android/phone/PhoneUtils.java
index 9ede914..c1bd1b6 100644
--- a/src/com/android/phone/PhoneUtils.java
+++ b/src/com/android/phone/PhoneUtils.java
@@ -23,9 +23,6 @@
 import android.content.ComponentName;
 import android.content.Context;
 import android.content.DialogInterface;
-import android.content.Intent;
-import android.content.res.Configuration;
-import android.media.AudioManager;
 import android.net.Uri;
 import android.os.Handler;
 import android.os.Message;
@@ -56,7 +53,6 @@
 import com.android.internal.telephony.PhoneConstants;
 import com.android.internal.telephony.PhoneFactory;
 import com.android.internal.telephony.TelephonyCapabilities;
-import com.android.internal.telephony.sip.SipPhone;
 import com.android.phone.CallGatewayManager.RawGatewayInfo;
 
 import java.util.Arrays;
@@ -73,43 +69,15 @@
     // Do not check in with VDBG = true, since that may write PII to the system log.
     private static final boolean VDBG = false;
 
-    /** Control stack trace for Audio Mode settings */
-    private static final boolean DBG_SETAUDIOMODE_STACK = false;
-
-    /** Identifier for the "Add Call" intent extra. */
-    static final String ADD_CALL_MODE_KEY = "add_call_mode";
-
     // Return codes from placeCall()
     public static final int CALL_STATUS_DIALED = 0;  // The number was successfully dialed
     public static final int CALL_STATUS_DIALED_MMI = 1;  // The specified number was an MMI code
     public static final int CALL_STATUS_FAILED = 2;  // The call failed
 
-    // State of the Phone's audio modes
-    // Each state can move to the other states, but within the state only certain
-    //  transitions for AudioManager.setMode() are allowed.
-    static final int AUDIO_IDLE = 0;  /** audio behaviour at phone idle */
-    static final int AUDIO_RINGING = 1;  /** audio behaviour while ringing */
-    static final int AUDIO_OFFHOOK = 2;  /** audio behaviour while in call. */
-
     // USSD string length for MMI operations
     static final int MIN_USSD_LEN = 1;
     static final int MAX_USSD_LEN = 160;
 
-    /** Speaker state, persisting between wired headset connection events */
-    private static boolean sIsSpeakerEnabled = false;
-
-    /** Static handler for the connection/mute tracking */
-    private static ConnectionHandler mConnectionHandler;
-
-    /** Phone state changed event*/
-    private static final int PHONE_STATE_CHANGED = -1;
-
-    /** poll phone DISCONNECTING status interval */
-    private static final int DISCONNECTING_POLLING_INTERVAL_MS = 200;
-
-    /** poll phone DISCONNECTING status times limit */
-    private static final int DISCONNECTING_POLLING_TIMES_LIMIT = 8;
-
     /** Define for not a special CNAP string */
     private static final int CNAP_SPECIAL_CASE_NO = -1;
 
@@ -128,26 +96,6 @@
             new ComponentName("com.android.phone",
                     "com.android.services.telephony.TelephonyConnectionService");
 
-    /**
-     * Handler that tracks the connections and updates the value of the
-     * Mute settings for each connection as needed.
-     */
-    private static class ConnectionHandler extends Handler {
-    }
-
-    /**
-     * Register the ConnectionHandler with the phone, to receive connection events
-     */
-    public static void initializeConnectionHandler(CallManager cm) {
-        if (mConnectionHandler == null) {
-            mConnectionHandler = new ConnectionHandler();
-        }
-
-        // pass over cm as user.obj
-        cm.registerForPreciseCallStateChanged(mConnectionHandler, PHONE_STATE_CHANGED, cm);
-
-    }
-
     /** This class is never instantiated. */
     private PhoneUtils() {
     }
@@ -255,10 +203,6 @@
             numberToDial = number;
         }
 
-        // Remember if the phone state was in IDLE state before this call.
-        // After calling CallManager#dial(), getState() will return different state.
-        final boolean initiallyIdle = app.mCM.getState() == PhoneConstants.State.IDLE;
-
         try {
             connection = app.mCM.dial(phone, numberToDial, VideoProfile.STATE_AUDIO_ONLY);
         } catch (CallStateException ex) {
@@ -279,11 +223,6 @@
         if (null == connection) {
             status = CALL_STATUS_FAILED;
         } else {
-            // Now that the call is successful, we can save the gateway info for the call
-            if (callGateway != null) {
-                callGateway.setGatewayInfoForConnection(connection, gatewayInfo);
-            }
-
             if (phoneType == PhoneConstants.PHONE_TYPE_CDMA) {
                 updateCdmaCallStateOnNewOutgoingCall(app, connection);
             }
@@ -314,8 +253,6 @@
             }
 
             startGetCallerInfo(context, connection, null, null, gatewayInfo);
-
-            setAudioMode();
         }
 
         return status;
@@ -346,15 +283,6 @@
         return builder.toString();
     }
 
-    static void separateCall(Connection c) {
-        try {
-            if (DBG) log("separateCall: " + toLogSafePhoneNumber(c.getAddress()));
-            c.separate();
-        } catch (CallStateException ex) {
-            Log.w(LOG_TAG, "separateCall: caught " + ex, ex);
-        }
-    }
-
     /**
      * Handle the MMIInitiate message and put up an alert that lets
      * the user cancel the operation, if applicable.
@@ -688,64 +616,6 @@
         return canceled;
     }
 
-    public static class VoiceMailNumberMissingException extends Exception {
-        VoiceMailNumberMissingException() {
-            super();
-        }
-
-        VoiceMailNumberMissingException(String msg) {
-            super(msg);
-        }
-    }
-
-    /**
-     * Gets the phone number to be called from an intent.  Requires a Context
-     * to access the contacts database, and a Phone to access the voicemail
-     * number.
-     *
-     * <p>If <code>phone</code> is <code>null</code>, the function will return
-     * <code>null</code> for <code>voicemail:</code> URIs;
-     * if <code>context</code> is <code>null</code>, the function will return
-     * <code>null</code> for person/phone URIs.</p>
-     *
-     * <p>If the intent contains a <code>sip:</code> URI, the returned
-     * "number" is actually the SIP address.
-     *
-     * @param context a context to use (or
-     * @param intent the intent
-     *
-     * @throws VoiceMailNumberMissingException if <code>intent</code> contains
-     *         a <code>voicemail:</code> URI, but <code>phone</code> does not
-     *         have a voicemail number set.
-     *
-     * @return the phone number (or SIP address) that would be called by the intent,
-     *         or <code>null</code> if the number cannot be found.
-     */
-    private static String getNumberFromIntent(Context context, Intent intent)
-            throws VoiceMailNumberMissingException {
-        Uri uri = intent.getData();
-        String scheme = uri.getScheme();
-
-        // The sip: scheme is simple: just treat the rest of the URI as a
-        // SIP address.
-        if (PhoneAccount.SCHEME_SIP.equals(scheme)) {
-            return uri.getSchemeSpecificPart();
-        }
-
-        // Otherwise, let PhoneNumberUtils.getNumberFromIntent() handle
-        // the other cases (i.e. tel: and voicemail: and contact: URIs.)
-
-        final String number = PhoneNumberUtils.getNumberFromIntent(intent, context);
-
-        // Check for a voicemail-dialing request.  If the voicemail number is
-        // empty, throw a VoiceMailNumberMissingException.
-        if (PhoneAccount.SCHEME_VOICEMAIL.equals(scheme) &&
-                (number == null || TextUtils.isEmpty(number)))
-            throw new VoiceMailNumberMissingException();
-
-        return number;
-    }
-
     /**
      * Returns the caller-id info corresponding to the specified Connection.
      * (This is just a simple wrapper around CallerInfo.getCallerInfo(): we
@@ -816,32 +686,6 @@
     }
 
     /**
-     * Start a CallerInfo Query based on the earliest connection in the call.
-     */
-    static CallerInfoToken startGetCallerInfo(Context context, Call call,
-            CallerInfoAsyncQuery.OnQueryCompleteListener listener, Object cookie) {
-        Connection conn = null;
-        int phoneType = call.getPhone().getPhoneType();
-        if (phoneType == PhoneConstants.PHONE_TYPE_CDMA) {
-            conn = call.getLatestConnection();
-        } else if ((phoneType == PhoneConstants.PHONE_TYPE_GSM)
-                || (phoneType == PhoneConstants.PHONE_TYPE_SIP)
-                || (phoneType == PhoneConstants.PHONE_TYPE_IMS)
-                || (phoneType == PhoneConstants.PHONE_TYPE_THIRD_PARTY)) {
-            conn = call.getEarliestConnection();
-        } else {
-            throw new IllegalStateException("Unexpected phone type: " + phoneType);
-        }
-
-        return startGetCallerInfo(context, conn, listener, cookie);
-    }
-
-    static CallerInfoToken startGetCallerInfo(Context context, Connection c,
-            CallerInfoAsyncQuery.OnQueryCompleteListener listener, Object cookie) {
-        return startGetCallerInfo(context, c, listener, cookie, null);
-    }
-
-    /**
      * place a temporary callerinfo object in the hands of the caller and notify
      * caller when the actual query is done.
      */
@@ -1191,188 +1035,15 @@
         return compactName;
     }
 
-    /**
-     * Returns true if the specified Call is a "conference call", meaning
-     * that it owns more than one Connection object.  This information is
-     * used to trigger certain UI changes that appear when a conference
-     * call is active (like displaying the label "Conference call", and
-     * enabling the "Manage conference" UI.)
-     *
-     * Watch out: This method simply checks the number of Connections,
-     * *not* their states.  So if a Call has (for example) one ACTIVE
-     * connection and one DISCONNECTED connection, this method will return
-     * true (which is unintuitive, since the Call isn't *really* a
-     * conference call any more.)
-     *
-     * @return true if the specified call has more than one connection (in any state.)
-     */
-    static boolean isConferenceCall(Call call) {
-        // CDMA phones don't have the same concept of "conference call" as
-        // GSM phones do; there's no special "conference call" state of
-        // the UI or a "manage conference" function.  (Instead, when
-        // you're in a 3-way call, all we can do is display the "generic"
-        // state of the UI.)  So as far as the in-call UI is concerned,
-        // Conference corresponds to generic display.
-        final PhoneGlobals app = PhoneGlobals.getInstance();
-        int phoneType = call.getPhone().getPhoneType();
-        if (phoneType == PhoneConstants.PHONE_TYPE_CDMA) {
-            CdmaPhoneCallState.PhoneCallState state = app.cdmaPhoneCallState.getCurrentCallState();
-            if ((state == CdmaPhoneCallState.PhoneCallState.CONF_CALL)
-                    || ((state == CdmaPhoneCallState.PhoneCallState.THRWAY_ACTIVE)
-                    && !app.cdmaPhoneCallState.IsThreeWayCallOrigStateDialing())) {
-                return true;
-            }
-        } else {
-            List<Connection> connections = call.getConnections();
-            if (connections != null && connections.size() > 1) {
-                return true;
-            }
-        }
-        return false;
-
-        // TODO: We may still want to change the semantics of this method
-        // to say that a given call is only really a conference call if
-        // the number of ACTIVE connections, not the total number of
-        // connections, is greater than one.  (See warning comment in the
-        // javadoc above.)
-        // Here's an implementation of that:
-        //        if (connections == null) {
-        //            return false;
-        //        }
-        //        int numActiveConnections = 0;
-        //        for (Connection conn : connections) {
-        //            if (DBG) log("  - CONN: " + conn + ", state = " + conn.getState());
-        //            if (conn.getState() == Call.State.ACTIVE) numActiveConnections++;
-        //            if (numActiveConnections > 1) {
-        //                return true;
-        //            }
-        //        }
-        //        return false;
-    }
-
-    /**
-     * Launch the Dialer to start a new call.
-     * This is just a wrapper around the ACTION_DIAL intent.
-     */
-    /* package */ static boolean startNewCall(final CallManager cm) {
-        final PhoneGlobals app = PhoneGlobals.getInstance();
-
-        // Sanity-check that this is OK given the current state of the phone.
-        if (!okToAddCall(cm)) {
-            Log.w(LOG_TAG, "startNewCall: can't add a new call in the current state");
-            dumpCallManager();
-            return false;
-        }
-
-        Intent intent = new Intent(Intent.ACTION_DIAL);
-        intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
-
-        // when we request the dialer come up, we also want to inform
-        // it that we're going through the "add call" option from the
-        // InCallScreen / PhoneUtils.
-        intent.putExtra(ADD_CALL_MODE_KEY, true);
-        try {
-            app.startActivity(intent);
-        } catch (ActivityNotFoundException e) {
-            // This is rather rare but possible.
-            // Note: this method is used even when the phone is encrypted. At that moment
-            // the system may not find any Activity which can accept this Intent.
-            Log.e(LOG_TAG, "Activity for adding calls isn't found.");
-            return false;
-        }
-
-        return true;
-    }
-
-    /**
-     * Turns on/off speaker.
-     *
-     * @param context Context
-     * @param flag True when speaker should be on. False otherwise.
-     * @param store True when the settings should be stored in the device.
-     */
-    /* package */ static void turnOnSpeaker(Context context, boolean flag, boolean store) {
-        if (DBG) log("turnOnSpeaker(flag=" + flag + ", store=" + store + ")...");
-        final PhoneGlobals app = PhoneGlobals.getInstance();
-
-        AudioManager audioManager = (AudioManager) context.getSystemService(Context.AUDIO_SERVICE);
-        audioManager.setSpeakerphoneOn(flag);
-
-        // record the speaker-enable value
-        if (store) {
-            sIsSpeakerEnabled = flag;
-        }
-
-        // We also need to make a fresh call to PhoneApp.updateWakeState()
-        // any time the speaker state changes, since the screen timeout is
-        // sometimes different depending on whether or not the speaker is
-        // in use.
-        app.updateWakeState();
-
-        app.mCM.setEchoSuppressionEnabled();
-    }
-
-    /**
-     * Restore the speaker mode, called after a wired headset disconnect
-     * event.
-     */
-    static void restoreSpeakerMode(Context context) {
-        if (DBG) log("restoreSpeakerMode, restoring to: " + sIsSpeakerEnabled);
-
-        // change the mode if needed.
-        if (isSpeakerOn(context) != sIsSpeakerEnabled) {
-            turnOnSpeaker(context, sIsSpeakerEnabled, false);
-        }
-    }
-
-    static boolean isSpeakerOn(Context context) {
-        AudioManager audioManager = (AudioManager) context.getSystemService(Context.AUDIO_SERVICE);
-        return audioManager.isSpeakerphoneOn();
-    }
-
-    /**
-     * Get the mute state of foreground phone, which has the current
-     * foreground call
-     */
-    static boolean getMute() {
-        return false;
-    }
-
-    /* package */ static void setAudioMode() {
-    }
-
-    /**
-     * Sets the audio mode per current phone state.
-     */
-    /* package */ static void setAudioMode(CallManager cm) {
-    }
-
-    /**
-     * Look for ANY connections on the phone that qualify as being
-     * disconnected.
-     *
-     * @return true if we find a connection that is disconnected over
-     * all the phone's call objects.
-     */
-    /* package */ static boolean hasDisconnectedConnections(Phone phone) {
-        return hasDisconnectedConnections(phone.getForegroundCall()) ||
-                hasDisconnectedConnections(phone.getBackgroundCall()) ||
-                hasDisconnectedConnections(phone.getRingingCall());
-    }
-
-    /**
-     * Iterate over all connections in a call to see if there are any
-     * that are not alive (disconnected or idle).
-     *
-     * @return true if we find a connection that is disconnected, and
-     * pending removal via
-     * {@link com.android.internal.telephony.Call#clearDisconnected()}.
-     */
-    private static final boolean hasDisconnectedConnections(Call call) {
-        // look through all connections for non-active ones.
-        for (Connection c : call.getConnections()) {
-            if (!c.isAlive()) {
-                return true;
+    static boolean isInEmergencyCall(CallManager cm) {
+        Call fgCall = cm.getActiveFgCall();
+        // isIdle includes checks for the DISCONNECTING/DISCONNECTED state.
+        if(!fgCall.isIdle()) {
+            for (Connection cn : fgCall.getConnections()) {
+                if (PhoneNumberUtils.isLocalEmergencyNumber(PhoneGlobals.getInstance(),
+                        cn.getAddress())) {
+                    return true;
+                }
             }
         }
         return false;
@@ -1383,147 +1054,6 @@
     //
 
     /**
-     * @return true if we're allowed to hold calls, given the current
-     * state of the Phone.
-     */
-    /* package */ static boolean okToHoldCall(CallManager cm) {
-        final Call fgCall = cm.getActiveFgCall();
-        final boolean hasHoldingCall = cm.hasActiveBgCall();
-        final Call.State fgCallState = fgCall.getState();
-
-        // The "Hold" control is disabled entirely if there's
-        // no way to either hold or unhold in the current state.
-        final boolean okToHold = (fgCallState == Call.State.ACTIVE) && !hasHoldingCall;
-        final boolean okToUnhold = cm.hasActiveBgCall() && (fgCallState == Call.State.IDLE);
-        final boolean canHold = okToHold || okToUnhold;
-
-        return canHold;
-    }
-
-    /**
-     * @return true if we support holding calls, given the current
-     * state of the Phone.
-     */
-    /* package */ static boolean okToSupportHold(CallManager cm) {
-        boolean supportsHold = false;
-
-        final Call fgCall = cm.getActiveFgCall();
-        final boolean hasHoldingCall = cm.hasActiveBgCall();
-        final Call.State fgCallState = fgCall.getState();
-
-        if (TelephonyCapabilities.supportsHoldAndUnhold(fgCall.getPhone())) {
-            // This phone has the concept of explicit "Hold" and "Unhold" actions.
-            supportsHold = true;
-        } else if (hasHoldingCall && (fgCallState == Call.State.IDLE)) {
-            // Even when foreground phone device doesn't support hold/unhold, phone devices
-            // for background holding calls may do.
-            final Call bgCall = cm.getFirstActiveBgCall();
-            if (bgCall != null &&
-                    TelephonyCapabilities.supportsHoldAndUnhold(bgCall.getPhone())) {
-                supportsHold = true;
-            }
-        }
-        return supportsHold;
-    }
-
-    /**
-     * @return true if we're allowed to swap calls, given the current
-     * state of the Phone.
-     */
-    /* package */ static boolean okToSwapCalls(CallManager cm) {
-        int phoneType = cm.getDefaultPhone().getPhoneType();
-        if (phoneType == PhoneConstants.PHONE_TYPE_CDMA) {
-            // CDMA: "Swap" is enabled only when the phone reaches a *generic*.
-            // state by either accepting a Call Waiting or by merging two calls
-            PhoneGlobals app = PhoneGlobals.getInstance();
-            return (app.cdmaPhoneCallState.getCurrentCallState()
-                    == CdmaPhoneCallState.PhoneCallState.CONF_CALL);
-        } else if ((phoneType == PhoneConstants.PHONE_TYPE_GSM)
-                || (phoneType == PhoneConstants.PHONE_TYPE_SIP)
-                || (phoneType == PhoneConstants.PHONE_TYPE_IMS)
-                || (phoneType == PhoneConstants.PHONE_TYPE_THIRD_PARTY)) {
-            // GSM: "Swap" is available if both lines are in use and there's no
-            // incoming call.  (Actually we need to verify that the active
-            // call really is in the ACTIVE state and the holding call really
-            // is in the HOLDING state, since you *can't* actually swap calls
-            // when the foreground call is DIALING or ALERTING.)
-            return !cm.hasActiveRingingCall()
-                    && (cm.getActiveFgCall().getState() == Call.State.ACTIVE)
-                    && (cm.getFirstActiveBgCall().getState() == Call.State.HOLDING);
-        } else {
-            throw new IllegalStateException("Unexpected phone type: " + phoneType);
-        }
-    }
-
-    /**
-     * @return true if we're allowed to merge calls, given the current
-     * state of the Phone.
-     */
-    /* package */ static boolean okToMergeCalls(CallManager cm) {
-        int phoneType = cm.getFgPhone().getPhoneType();
-        if (phoneType == PhoneConstants.PHONE_TYPE_CDMA) {
-            // CDMA: "Merge" is enabled only when the user is in a 3Way call.
-            PhoneGlobals app = PhoneGlobals.getInstance();
-            return ((app.cdmaPhoneCallState.getCurrentCallState()
-                    == CdmaPhoneCallState.PhoneCallState.THRWAY_ACTIVE)
-                    && !app.cdmaPhoneCallState.IsThreeWayCallOrigStateDialing());
-        } else {
-            // GSM: "Merge" is available if both lines are in use and there's no
-            // incoming call, *and* the current conference isn't already
-            // "full".
-            // TODO: shall move all okToMerge logic to CallManager
-            return !cm.hasActiveRingingCall() && cm.hasActiveFgCall()
-                    && cm.hasActiveBgCall()
-                    && cm.canConference(cm.getFirstActiveBgCall());
-        }
-    }
-
-    /**
-     * @return true if the UI should let you add a new call, given the current
-     * state of the Phone.
-     */
-    /* package */ static boolean okToAddCall(CallManager cm) {
-        Phone phone = cm.getActiveFgCall().getPhone();
-
-        // "Add call" is never allowed in emergency callback mode (ECM).
-        if (isPhoneInEcm(phone)) {
-            return false;
-        }
-
-        int phoneType = phone.getPhoneType();
-        final Call.State fgCallState = cm.getActiveFgCall().getState();
-        if (phoneType == PhoneConstants.PHONE_TYPE_CDMA) {
-           // CDMA: "Add call" button is only enabled when:
-           // - ForegroundCall is in ACTIVE state
-           // - After 30 seconds of user Ignoring/Missing a Call Waiting call.
-            PhoneGlobals app = PhoneGlobals.getInstance();
-            return ((fgCallState == Call.State.ACTIVE)
-                    && (app.cdmaPhoneCallState.getAddCallMenuStateAfterCallWaiting()));
-        } else if ((phoneType == PhoneConstants.PHONE_TYPE_GSM)
-                || (phoneType == PhoneConstants.PHONE_TYPE_SIP)
-                || (phoneType == PhoneConstants.PHONE_TYPE_IMS)
-                || (phoneType == PhoneConstants.PHONE_TYPE_THIRD_PARTY)) {
-            // GSM: "Add call" is available only if ALL of the following are true:
-            // - There's no incoming ringing call
-            // - There's < 2 lines in use
-            // - The foreground call is ACTIVE or IDLE or DISCONNECTED.
-            //   (We mainly need to make sure it *isn't* DIALING or ALERTING.)
-            final boolean hasRingingCall = cm.hasActiveRingingCall();
-            final boolean hasActiveCall = cm.hasActiveFgCall();
-            final boolean hasHoldingCall = cm.hasActiveBgCall();
-            final boolean allLinesTaken = hasActiveCall && hasHoldingCall;
-
-            return !hasRingingCall
-                    && !allLinesTaken
-                    && ((fgCallState == Call.State.ACTIVE)
-                        || (fgCallState == Call.State.IDLE)
-                        || (fgCallState == Call.State.DISCONNECTED));
-        } else {
-            throw new IllegalStateException("Unexpected phone type: " + phoneType);
-        }
-    }
-
-    /**
      * Based on the input CNAP number string,
      * @return _RESTRICTED or _UNKNOWN for all the special CNAP strings.
      * Otherwise, return CNAP_SPECIAL_CASE_NO.
@@ -1646,47 +1176,6 @@
     }
 
     /**
-     * Returns the most appropriate Phone object to handle a call
-     * to the specified number.
-     *
-     * @param cm the CallManager.
-     * @param scheme the scheme from the data URI that the number originally came from.
-     * @param number the phone number, or SIP address.
-     */
-    public static Phone pickPhoneBasedOnNumber(CallManager cm, String scheme, String number,
-            String primarySipUri, ComponentName thirdPartyCallComponent) {
-        if (DBG) {
-            log("pickPhoneBasedOnNumber: scheme " + scheme
-                    + ", number " + toLogSafePhoneNumber(number)
-                    + ", sipUri "
-                    + (primarySipUri != null ? Uri.parse(primarySipUri).toSafeString() : "null")
-                    + ", thirdPartyCallComponent: " + thirdPartyCallComponent);
-        }
-
-        if (primarySipUri != null) {
-            Phone phone = getSipPhoneFromUri(cm, primarySipUri);
-            if (phone != null) return phone;
-        }
-
-        return cm.getDefaultPhone();
-    }
-
-    public static Phone getSipPhoneFromUri(CallManager cm, String target) {
-        for (Phone phone : cm.getAllPhones()) {
-            if (phone.getPhoneType() == PhoneConstants.PHONE_TYPE_SIP) {
-                String sipUri = ((SipPhone) phone).getSipUri();
-                if (target.equals(sipUri)) {
-                    if (DBG) log("- pickPhoneBasedOnNumber:" +
-                            "found SipPhone! obj = " + phone + ", "
-                            + phone.getClass());
-                    return phone;
-                }
-            }
-        }
-        return null;
-    }
-
-    /**
      * Returns true when the given call is in INCOMING state and there's no foreground phone call,
      * meaning the call is the first real incoming call the phone is having.
      */
@@ -1694,166 +1183,14 @@
         return (state == Call.State.INCOMING && !PhoneGlobals.getInstance().mCM.hasActiveFgCall());
     }
 
-    public static String getPresentationString(Context context, int presentation) {
-        String name = context.getString(R.string.unknown);
-        if (presentation == PhoneConstants.PRESENTATION_RESTRICTED) {
-            name = context.getString(R.string.private_num);
-        } else if (presentation == PhoneConstants.PRESENTATION_PAYPHONE) {
-            name = context.getString(R.string.payphone);
-        }
-        return name;
-    }
-
-    public static void sendViewNotificationAsync(Context context, Uri contactUri) {
-        if (DBG) Log.d(LOG_TAG, "Send view notification to Contacts (uri: " + contactUri + ")");
-        Intent intent = new Intent("com.android.contacts.VIEW_NOTIFICATION", contactUri);
-        intent.setClassName("com.android.contacts",
-                "com.android.contacts.ViewNotificationService");
-        context.startService(intent);
-    }
-
     //
     // General phone and call state debugging/testing code
     //
 
-    /* package */ static void dumpCallState(Phone phone) {
-        PhoneGlobals app = PhoneGlobals.getInstance();
-        Log.d(LOG_TAG, "dumpCallState():");
-        Log.d(LOG_TAG, "- Phone: " + phone + ", name = " + phone.getPhoneName()
-              + ", state = " + phone.getState());
-
-        StringBuilder b = new StringBuilder(128);
-
-        Call call = phone.getForegroundCall();
-        b.setLength(0);
-        b.append("  - FG call: ").append(call.getState());
-        b.append(" isAlive ").append(call.getState().isAlive());
-        b.append(" isRinging ").append(call.getState().isRinging());
-        b.append(" isDialing ").append(call.getState().isDialing());
-        b.append(" isIdle ").append(call.isIdle());
-        b.append(" hasConnections ").append(call.hasConnections());
-        Log.d(LOG_TAG, b.toString());
-
-        call = phone.getBackgroundCall();
-        b.setLength(0);
-        b.append("  - BG call: ").append(call.getState());
-        b.append(" isAlive ").append(call.getState().isAlive());
-        b.append(" isRinging ").append(call.getState().isRinging());
-        b.append(" isDialing ").append(call.getState().isDialing());
-        b.append(" isIdle ").append(call.isIdle());
-        b.append(" hasConnections ").append(call.hasConnections());
-        Log.d(LOG_TAG, b.toString());
-
-        call = phone.getRingingCall();
-        b.setLength(0);
-        b.append("  - RINGING call: ").append(call.getState());
-        b.append(" isAlive ").append(call.getState().isAlive());
-        b.append(" isRinging ").append(call.getState().isRinging());
-        b.append(" isDialing ").append(call.getState().isDialing());
-        b.append(" isIdle ").append(call.isIdle());
-        b.append(" hasConnections ").append(call.hasConnections());
-        Log.d(LOG_TAG, b.toString());
-
-
-        final boolean hasRingingCall = !phone.getRingingCall().isIdle();
-        final boolean hasActiveCall = !phone.getForegroundCall().isIdle();
-        final boolean hasHoldingCall = !phone.getBackgroundCall().isIdle();
-        final boolean allLinesTaken = hasActiveCall && hasHoldingCall;
-        b.setLength(0);
-        b.append("  - hasRingingCall ").append(hasRingingCall);
-        b.append(" hasActiveCall ").append(hasActiveCall);
-        b.append(" hasHoldingCall ").append(hasHoldingCall);
-        b.append(" allLinesTaken ").append(allLinesTaken);
-        Log.d(LOG_TAG, b.toString());
-
-        // On CDMA phones, dump out the CdmaPhoneCallState too:
-        if (phone.getPhoneType() == PhoneConstants.PHONE_TYPE_CDMA) {
-            if (app.cdmaPhoneCallState != null) {
-                Log.d(LOG_TAG, "  - CDMA call state: "
-                      + app.cdmaPhoneCallState.getCurrentCallState());
-            } else {
-                Log.d(LOG_TAG, "  - CDMA device, but null cdmaPhoneCallState!");
-            }
-        }
-    }
-
     private static void log(String msg) {
         Log.d(LOG_TAG, msg);
     }
 
-    static void dumpCallManager() {
-        Call call;
-        CallManager cm = PhoneGlobals.getInstance().mCM;
-        StringBuilder b = new StringBuilder(128);
-
-
-
-        Log.d(LOG_TAG, "############### dumpCallManager() ##############");
-        // TODO: Don't log "cm" itself, since CallManager.toString()
-        // already spews out almost all this same information.
-        // We should fix CallManager.toString() to be more minimal, and
-        // use an explicit dumpState() method for the verbose dump.
-        // Log.d(LOG_TAG, "CallManager: " + cm
-        //         + ", state = " + cm.getState());
-        Log.d(LOG_TAG, "CallManager: state = " + cm.getState());
-        b.setLength(0);
-        call = cm.getActiveFgCall();
-        b.append(" - FG call: ").append(cm.hasActiveFgCall()? "YES ": "NO ");
-        b.append(call);
-        b.append( "  State: ").append(cm.getActiveFgCallState());
-        b.append( "  Conn: ").append(cm.getFgCallConnections());
-        Log.d(LOG_TAG, b.toString());
-        b.setLength(0);
-        call = cm.getFirstActiveBgCall();
-        b.append(" - BG call: ").append(cm.hasActiveBgCall()? "YES ": "NO ");
-        b.append(call);
-        b.append( "  State: ").append(cm.getFirstActiveBgCall().getState());
-        b.append( "  Conn: ").append(cm.getBgCallConnections());
-        Log.d(LOG_TAG, b.toString());
-        b.setLength(0);
-        call = cm.getFirstActiveRingingCall();
-        b.append(" - RINGING call: ").append(cm.hasActiveRingingCall()? "YES ": "NO ");
-        b.append(call);
-        b.append( "  State: ").append(cm.getFirstActiveRingingCall().getState());
-        Log.d(LOG_TAG, b.toString());
-
-
-
-        for (Phone phone : CallManager.getInstance().getAllPhones()) {
-            if (phone != null) {
-                Log.d(LOG_TAG, "Phone: " + phone + ", name = " + phone.getPhoneName()
-                        + ", state = " + phone.getState());
-                b.setLength(0);
-                call = phone.getForegroundCall();
-                b.append(" - FG call: ").append(call);
-                b.append( "  State: ").append(call.getState());
-                b.append( "  Conn: ").append(call.hasConnections());
-                Log.d(LOG_TAG, b.toString());
-                b.setLength(0);
-                call = phone.getBackgroundCall();
-                b.append(" - BG call: ").append(call);
-                b.append( "  State: ").append(call.getState());
-                b.append( "  Conn: ").append(call.hasConnections());
-                Log.d(LOG_TAG, b.toString());b.setLength(0);
-                call = phone.getRingingCall();
-                b.append(" - RINGING call: ").append(call);
-                b.append( "  State: ").append(call.getState());
-                b.append( "  Conn: ").append(call.hasConnections());
-                Log.d(LOG_TAG, b.toString());
-            }
-        }
-
-        Log.d(LOG_TAG, "############## END dumpCallManager() ###############");
-    }
-
-    /**
-     * @return if the context is in landscape orientation.
-     */
-    public static boolean isLandscape(Context context) {
-        return context.getResources().getConfiguration().orientation
-                == Configuration.ORIENTATION_LANDSCAPE;
-    }
-
     public static PhoneAccountHandle makePstnPhoneAccountHandle(String id) {
         return makePstnPhoneAccountHandleWithPrefix(id, "", false);
     }
@@ -1904,7 +1241,6 @@
         return null;
     }
 
-
     /**
      * Determine if a given phone account corresponds to an active SIM
      *
diff --git a/src/com/android/services/telephony/DisconnectCauseUtil.java b/src/com/android/services/telephony/DisconnectCauseUtil.java
index 7d6a86f..a82c346 100644
--- a/src/com/android/services/telephony/DisconnectCauseUtil.java
+++ b/src/com/android/services/telephony/DisconnectCauseUtil.java
@@ -169,6 +169,10 @@
             case android.telephony.DisconnectCause.SERVER_ERROR:
             case android.telephony.DisconnectCause.SERVER_UNREACHABLE:
             case android.telephony.DisconnectCause.TIMED_OUT:
+            case android.telephony.DisconnectCause.ALREADY_DIALING:
+            case android.telephony.DisconnectCause.CANT_CALL_WHILE_RINGING:
+            case android.telephony.DisconnectCause.CALLING_DISABLED:
+            case android.telephony.DisconnectCause.TOO_MANY_ONGOING_CALLS:
             case android.telephony.DisconnectCause.UNOBTAINABLE_NUMBER:
             case android.telephony.DisconnectCause.VOICEMAIL_NUMBER_MISSING:
             case android.telephony.DisconnectCause.DIAL_MODIFIED_TO_USSD:
@@ -320,6 +324,18 @@
             case android.telephony.DisconnectCause.DATA_LIMIT_REACHED:
                 resourceId = R.string.callFailed_data_limit_reached;
                 break;
+            case android.telephony.DisconnectCause.ALREADY_DIALING:
+                resourceId = R.string.callFailed_already_dialing;
+                break;
+            case android.telephony.DisconnectCause.CANT_CALL_WHILE_RINGING:
+                resourceId = R.string.callFailed_already_ringing;
+                break;
+            case android.telephony.DisconnectCause.CALLING_DISABLED:
+                resourceId = R.string.callFailed_calling_disabled;
+                break;
+            case android.telephony.DisconnectCause.TOO_MANY_ONGOING_CALLS:
+                resourceId = R.string.callFailed_too_many_calls;
+                break;
 
             default:
                 break;
@@ -684,6 +700,18 @@
             case android.telephony.DisconnectCause.WIFI_LOST:
                 resourceId = R.string.callFailed_wifi_lost;
                 break;
+            case android.telephony.DisconnectCause.ALREADY_DIALING:
+                resourceId = R.string.callFailed_already_dialing;
+                break;
+            case android.telephony.DisconnectCause.CANT_CALL_WHILE_RINGING:
+                resourceId = R.string.callFailed_already_ringing;
+                break;
+            case android.telephony.DisconnectCause.CALLING_DISABLED:
+                resourceId = R.string.callFailed_calling_disabled;
+                break;
+            case android.telephony.DisconnectCause.TOO_MANY_ONGOING_CALLS:
+                resourceId = R.string.callFailed_too_many_calls;
+                break;
 
             default:
                 break;
diff --git a/src/com/android/services/telephony/TelephonyConnectionService.java b/src/com/android/services/telephony/TelephonyConnectionService.java
index 3ec00b9..16be893 100644
--- a/src/com/android/services/telephony/TelephonyConnectionService.java
+++ b/src/com/android/services/telephony/TelephonyConnectionService.java
@@ -1120,10 +1120,25 @@
         } catch (CallStateException e) {
             Log.e(this, e, "placeOutgoingConnection, phone.dial exception: " + e);
             int cause = android.telephony.DisconnectCause.OUTGOING_FAILURE;
-            if (e.getError() == CallStateException.ERROR_OUT_OF_SERVICE) {
-                cause = android.telephony.DisconnectCause.OUT_OF_SERVICE;
-            } else if (e.getError() == CallStateException.ERROR_POWER_OFF) {
-                cause = android.telephony.DisconnectCause.POWER_OFF;
+            switch (e.getError()) {
+                case CallStateException.ERROR_OUT_OF_SERVICE:
+                    cause = android.telephony.DisconnectCause.OUT_OF_SERVICE;
+                    break;
+                case CallStateException.ERROR_POWER_OFF:
+                    cause = android.telephony.DisconnectCause.POWER_OFF;
+                    break;
+                case CallStateException.ERROR_ALREADY_DIALING:
+                    cause = android.telephony.DisconnectCause.ALREADY_DIALING;
+                    break;
+                case CallStateException.ERROR_CALL_RINGING:
+                    cause = android.telephony.DisconnectCause.CANT_CALL_WHILE_RINGING;
+                    break;
+                case CallStateException.ERROR_CALLING_DISABLED:
+                    cause = android.telephony.DisconnectCause.CALLING_DISABLED;
+                    break;
+                case CallStateException.ERROR_TOO_MANY_CALLS:
+                    cause = android.telephony.DisconnectCause.TOO_MANY_ONGOING_CALLS;
+                    break;
             }
             connection.setDisconnected(DisconnectCauseUtil.toTelecomDisconnectCause(
                     cause, e.getMessage(), phone.getPhoneId()));