diff --git a/AndroidManifest.xml b/AndroidManifest.xml
index aabff7b..e9173e5 100644
--- a/AndroidManifest.xml
+++ b/AndroidManifest.xml
@@ -15,6 +15,7 @@
 -->
 
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
+        xmlns:androidprv="http://schemas.android.com/apk/prv/res/android"
         package="com.android.phone"
         coreApp="true"
         android:sharedUserId="android.uid.phone"
@@ -82,7 +83,9 @@
     <uses-permission android:name="android.permission.USE_SIP" />
     <uses-permission android:name="android.permission.REBOOT" />
     <uses-permission android:name="android.permission.UPDATE_LOCK" />
+    <uses-permission android:name="android.permission.INTERACT_ACROSS_USERS_FULL" />
     <uses-permission android:name="com.android.smspush.WAPPUSH_MANAGER_BIND" />
+    <uses-permission android:name="android.permission.MANAGE_USERS" />
 
     <!-- This tells the activity manager to not delay any of our activity
          start requests, even if they happen immediately after the user
@@ -92,10 +95,11 @@
     <application android:name="PhoneApp"
                  android:persistent="true"
                  android:label="@string/phoneAppLabel"
-                 android:icon="@drawable/ic_launcher_phone">
+                 android:icon="@mipmap/ic_launcher_phone">
             <provider android:name="IccProvider"
                       android:authorities="icc"
                       android:multiprocess="true"
+                      android:exported="true"
                       android:readPermission="android.permission.READ_CONTACTS"
                       android:writePermission="android.permission.WRITE_CONTACTS" />
 
@@ -141,7 +145,7 @@
         <activity android:name="OutgoingCallBroadcaster"
                 android:theme="@style/OutgoingCallBroadcasterTheme"
                 android:permission="android.permission.CALL_PHONE"
-                android:screenOrientation="portrait"
+                android:screenOrientation="nosensor"
                 android:configChanges="orientation|screenSize|keyboardHidden">
             <!-- CALL action intent filters, for the various ways
                  of initiating an outgoing call. -->
@@ -198,6 +202,7 @@
 
         <activity-alias android:name="PrivilegedOutgoingCallBroadcaster"
                 android:targetActivity="OutgoingCallBroadcaster"
+                android:screenOrientation="nosensor"
                 android:permission="android.permission.CALL_PRIVILEGED">
             <intent-filter android:priority="1000">
                 <action android:name="android.intent.action.CALL_PRIVILEGED" />
@@ -241,8 +246,8 @@
             android:label="@string/phoneIconLabel"
             android:excludeFromRecents="true"
             android:launchMode="singleInstance"
-            android:screenOrientation="portrait"
-            android:configChanges="orientation|screenSize|keyboardHidden|uiMode"
+            android:screenOrientation="nosensor"
+            android:configChanges="keyboardHidden"
             android:exported="false">
         </activity>
 
@@ -435,15 +440,16 @@
             </intent-filter>
         </activity>
 
-        <!-- bluetooth headset service -->
-        <service android:name="BluetoothHeadsetService">
+        <!-- bluetooth phone service -->
+        <service android:name="BluetoothPhoneService">
             <intent-filter>
-                <action android:name="android.bluetooth.IBluetoothHeadset" />
+                <action android:name="android.bluetooth.IBluetoothHeadsetPhone" />
             </intent-filter>
         </service>
 
         <!-- Broadcast Receiver that will process BOOT Complete and launch OTA -->
-        <receiver android:name="OtaStartupReceiver" android:exported="false">
+        <receiver android:name="OtaStartupReceiver" android:exported="false"
+                androidprv:primaryUserOnly="true">
             <intent-filter android:priority="100">
                  <action android:name="android.intent.action.BOOT_COMPLETED"/>
             </intent-filter>
@@ -495,7 +501,7 @@
         </activity>
         <activity android:name=".SipCallOptionHandler"
                 android:theme="@style/SipCallOptionHandlerTheme"
-                android:screenOrientation="portrait"
+                android:screenOrientation="nosensor"
                 android:configChanges="orientation|screenSize|keyboardHidden">
         </activity>
 
@@ -515,7 +521,7 @@
         </receiver>
 
         <!-- BroadcastReceiver for receiving Intents from Notification mechanism. -->
-        <receiver android:name="PhoneApp$NotificationBroadcastReceiver" android:exported="false">
+        <receiver android:name="PhoneGlobals$NotificationBroadcastReceiver" android:exported="false">
             <intent-filter>
                 <action android:name="com.android.phone.ACTION_HANG_UP_ONGOING_CALL" />
                 <action android:name="com.android.phone.ACTION_CALL_BACK_FROM_NOTIFICATION" />
diff --git a/res/drawable-hdpi/ic_launcher_phone.png b/res/drawable-hdpi/ic_launcher_phone.png
deleted file mode 100644
index 5a3dff1..0000000
--- a/res/drawable-hdpi/ic_launcher_phone.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-mdpi/ic_launcher_phone.png b/res/drawable-mdpi/ic_launcher_phone.png
deleted file mode 100644
index 9ea0d8c..0000000
--- a/res/drawable-mdpi/ic_launcher_phone.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-nodpi/background_dial_holo_dark.png b/res/drawable-nodpi/background_dial_holo_dark.png
new file mode 100644
index 0000000..3dba50c
--- /dev/null
+++ b/res/drawable-nodpi/background_dial_holo_dark.png
Binary files differ
diff --git a/res/drawable-xhdpi/ic_launcher_phone.png b/res/drawable-xhdpi/ic_launcher_phone.png
deleted file mode 100644
index e97836c..0000000
--- a/res/drawable-xhdpi/ic_launcher_phone.png
+++ /dev/null
Binary files differ
diff --git a/res/layout-land/incall_screen.xml b/res/layout-land/incall_screen.xml
new file mode 100644
index 0000000..1278115
--- /dev/null
+++ b/res/layout-land/incall_screen.xml
@@ -0,0 +1,80 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2012 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.
+-->
+
+<!-- In-call Phone UI; see InCallScreen.java. -->
+<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:id="@+id/landscape_incall_screen"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent">
+    <!-- The "Call Card", which displays info about the currently
+         active phone call(s) on the device.  See call_card.xml. -->
+    <LinearLayout
+        android:layout_width="match_parent"
+        android:layout_height="match_parent"
+        android:background="@drawable/background_dial_holo_dark">
+        <include
+            layout="@layout/call_card"
+            android:id="@+id/callCard"
+            android:layout_width="0dp"
+            android:layout_weight="3"
+            android:layout_height="match_parent" />
+        <!-- Note: This center margin is repeated in layout-land/incall_touch_ui
+             Both layouts need to have this margin to be aligned correctly. -->
+        <View
+            android:layout_width="@dimen/dialpad_center_margin"
+            android:layout_weight="0"
+            android:layout_height="match_parent" />
+        <View
+            android:layout_width="0dp"
+            android:layout_weight="2"
+            android:layout_height="match_parent" />
+    </LinearLayout>
+
+    <!-- In-call onscreen touch controls; see InCallTouchUi.java.
+         This widget contains the cluster of buttons shown at the right
+         of the in-call screen, and also the DTMF dialpad (which, when
+         visible, covers the contact picture/call_card on the left half of the screen) -->
+
+    <ViewStub
+        android:id="@+id/inCallTouchUiStub"
+        android:layout="@layout/incall_touch_ui"
+        android:layout_width="match_parent"
+        android:layout_height="match_parent" />
+    <ViewStub
+        android:id="@+id/inCallTouchUiCdmaStub"
+        android:layout="@layout/incall_touch_ui_cdma"
+        android:layout_width="match_parent"
+        android:layout_height="match_parent" />
+
+    <!-- ViewStub for OTASP-related UI elements (for the CDMA "activation"
+         call.)  Note that this ViewStub provides the *entire* OTASP
+         screen, including the status area at the top *and* touch controls
+         at the bottom of the screen.  The regular CallCard and the
+         InCallTouchUi widget are not used at all during an OTASP call. -->
+    <ViewStub android:id="@+id/otaCallCardStub"
+              android:layout="@layout/otacall_card"
+              android:layout_width="match_parent"
+              android:layout_height="match_parent" />
+
+    <!-- The "Manage conference" UI.  This panel is displayed (and covers up
+         the entire normal in-call UI) when the user clicks "Manage conference"
+         during a GSM conference call. -->
+    <ViewStub android:id="@+id/manageConferencePanelStub"
+              android:layout="@layout/manage_conference_panel"
+              android:layout_width="match_parent"
+              android:layout_height="match_parent" />
+
+</FrameLayout>
diff --git a/res/layout-land/incall_touch_ui.xml b/res/layout-land/incall_touch_ui.xml
new file mode 100644
index 0000000..7ab56a1
--- /dev/null
+++ b/res/layout-land/incall_touch_ui.xml
@@ -0,0 +1,251 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2012 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.
+-->
+
+<!-- In-call onscreen touch UI elements, used on some platforms.
+
+     This layout is a fullscreen overlay, drawn on top of the
+     non-touch-sensitive parts of the in-call UI (i.e. the call card).
+
+     The top-level View here is a InCallTouchUi (FrameLayout) with 2 children:
+       (1) inCallControls: the widgets visible while a regular call (or calls) is in progress
+       (2) incomingCallWidget: the UI displayed while an incoming call is ringing
+     In usual cases, one of these is visible at any given moment.
+     One exception is when incomingCallWidget is fading-out. At that moment, we show
+     inCallControls beneath incomingCallWidget for smoother transition.
+     -->
+<com.android.phone.InCallTouchUi xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:prvandroid="http://schemas.android.com/apk/prv/res/android"
+    android:id="@+id/inCallTouchUi"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent">
+
+    <!--
+        (1) inCallControls: the widgets visible while a regular call
+        (or calls) is in progress
+    -->
+    <LinearLayout
+        android:id="@+id/inCallControls"
+        android:layout_width="match_parent"
+        android:layout_height="match_parent"
+        android:visibility="gone">
+
+        <!-- DTMF dialpad shown in the left part of the screen.
+             This is wrapped in a FrameLayout because otherwise the ViewStub has no width,
+             causing the other buttons to span the full width of the screen -->
+        <FrameLayout
+            android:layout_width="0dp"
+            android:layout_weight="3"
+            android:layout_height="match_parent">
+            <ViewStub
+                android:id="@+id/dtmf_twelve_key_dialer_stub"
+                android:layout="@layout/dtmf_twelve_key_dialer_view"
+                android:layout_width="match_parent"
+                android:layout_height="match_parent" />
+
+            <!-- The "extra button row": Rare button used for statues such as conference
+                 calls (GSM). Refer to layout(portrait)/incall_touch_ui for more details.
+                 When shown, this extra button row hovers over the call card, just above
+                 the primary_call_banner of layout-land/primary_call_info. -->
+            <ViewStub
+                android:id="@+id/extraButtonRow"
+                android:layout_gravity="bottom"
+                android:layout_marginBottom="@dimen/call_banner_height"
+                android:layout="@layout/extra_button_row"
+                android:layout_width="match_parent"
+                android:layout_height="wrap_content" />
+        </FrameLayout>
+
+        <!-- Note: This center margin is repeated in layout-land/incall_screen -->
+        <View
+            android:layout_width="@dimen/dialpad_center_margin"
+            android:layout_height="match_parent"
+            android:background="#66000000" />
+
+        <!-- Cluster of buttons on the right part of the screen.
+             It is named id/bottomButtons from the naming when in portrait layout. -->
+        <LinearLayout
+            android:id="@+id/bottomButtons"
+            android:background="@drawable/dialpad_background"
+            android:orientation="vertical"
+            android:layout_width="0dp"
+            android:layout_weight="2"
+            android:layout_height="match_parent">
+
+            <!-- "Audio mode" -->
+            <!-- This is a multi-mode button that can behave either like a
+                 simple "compound button" with two states *or* like an
+                 action button that brings up a popup menu; see
+                 btn_compound_audio.xml and InCallTouchUi.updateAudioButton()
+                 for the full details. -->
+            <ToggleButton
+                android:id="@+id/audioButton"
+                android:layout_height="0dp"
+                android:layout_weight="1"
+                android:layout_width="match_parent"
+                style="@style/InCallCompoundButton"
+                android:background="@drawable/btn_compound_audio"
+                android:contentDescription="@string/onscreenAudioText" />
+
+            <View
+                android:layout_height="@dimen/dialpad_button_margin"
+                android:layout_width="match_parent"
+                android:background="#66000000" />
+
+            <LinearLayout
+                android:layout_height="0dp"
+                android:layout_weight="1"
+                android:layout_width="match_parent">
+                <ToggleButton
+                    android:id="@+id/muteButton"
+                    android:layout_width="0dp"
+                    android:layout_weight="1"
+                    android:layout_height="match_parent"
+                    style="@style/InCallCompoundButton"
+                    android:background="@drawable/btn_compound_mute"
+                    android:contentDescription="@string/onscreenMuteText" />
+                <View
+                    android:layout_width="@dimen/dialpad_button_margin"
+                    android:layout_height="match_parent"
+                    android:background="#66000000" />
+                <!-- This slot is either "Hold" or "Swap", depending on
+                     the state of the call.   One or the other of these
+                     must always be set to GONE. -->
+                <!-- "Hold" -->
+                <!-- This is a "compound button": it has checked and unchecked states. -->
+                <ToggleButton
+                    android:id="@+id/holdButton"
+                    android:layout_width="0dp"
+                    android:layout_weight="1"
+                    android:layout_height="match_parent"
+                    style="@style/InCallCompoundButton"
+                    android:background="@drawable/btn_compound_hold"
+                    android:contentDescription="@string/onscreenHoldText" />
+                <!-- "Swap" (or "Manage calls" in some CDMA states) -->
+                <ImageButton
+                    android:id="@+id/swapButton"
+                    android:layout_width="0dp"
+                    android:layout_weight="1"
+                    android:layout_height="match_parent"
+                    style="@style/InCallButton"
+                    android:src="@drawable/ic_incall_switch_holo_dark"
+                    android:contentDescription="@string/onscreenSwapCallsText" />
+            </LinearLayout>
+
+            <View
+                android:layout_height="@dimen/dialpad_button_margin"
+                android:layout_width="match_parent"
+                android:background="#66000000" />
+
+            <LinearLayout
+                android:layout_height="0dp"
+                android:layout_weight="1"
+                android:layout_width="match_parent">
+                <ToggleButton
+                    android:id="@+id/dialpadButton"
+                    android:layout_width="0dp"
+                    android:layout_weight="1"
+                    android:layout_height="match_parent"
+                    style="@style/InCallCompoundButton"
+                    android:background="@drawable/btn_compound_dialpad"
+                    android:contentDescription="@string/onscreenShowDialpadText" />
+                <View
+                    android:layout_width="@dimen/dialpad_button_margin"
+                    android:layout_height="match_parent"
+                    android:background="#66000000" />
+                <!-- This slot is either "Add" or "Merge", depending on
+                     the state of the call.  One or the other of these
+                     must always be set to GONE. -->
+                <!-- "Add Call" -->
+                <ImageButton
+                    android:id="@+id/addButton"
+                    android:layout_width="0dp"
+                    android:layout_weight="1"
+                    android:layout_height="match_parent"
+                    style="@style/InCallButton"
+                    android:src="@drawable/ic_add_contact_holo_dark"
+                    android:contentDescription="@string/onscreenAddCallText" />
+                <!-- "Merge calls" -->
+                <!-- This button is used only on GSM devices, where we know
+                     that "Add" and "Merge" are never available at the same time.
+                     The "Merge" button for CDMA devices is "cdmaMergeButton" above. -->
+                <ImageButton
+                    android:id="@+id/mergeButton"
+                    android:layout_width="0dp"
+                    android:layout_weight="1"
+                    android:layout_height="match_parent"
+                    style="@style/InCallButton"
+                    android:src="@drawable/ic_merge_holo_dark"
+                    android:contentDescription="@string/onscreenMergeCallsText" />
+            </LinearLayout>
+
+            <!-- This spacer is not used in GSM, so it has 0 width and height. The CDMA
+                 incall_touch_ui_cdma uses it as a spacer when a 5th button is shown. -->
+            <View
+                android:id="@+id/holdSwapSpacer"
+                android:layout_width="0dp"
+                android:layout_height="0dp" />
+            <View
+                android:layout_height="@dimen/dialpad_button_margin"
+                android:layout_width="match_parent"
+                android:background="#66000000" />
+            <ImageButton
+                android:id="@+id/endButton"
+                android:layout_height="@dimen/in_call_end_button_height"
+                android:layout_width="match_parent"
+                android:src="@drawable/ic_dial_end_call"
+                android:background="@drawable/end_call_background"
+                android:contentDescription="@string/onscreenEndCallText" />
+        </LinearLayout>
+    </LinearLayout>
+
+    <!--
+        (2) incomingCallWidget: the UI displayed while an incoming call is ringing.
+            See InCallTouchUi.showIncomingCallWidget().
+
+            Layout notes:
+            - Use an opaque black background since we need to cover up
+              a bit of the bottom of the contact photo
+            - The verticalOffset value gets us a little extra space above
+              the topmost "Respond by SMS" icon
+            - The negative layout_marginBottom shifts us slightly downward;
+              we're already aligned with the bottom of the screen, but we
+              don't have an icon in the downward direction so the whole
+              bottom area of this widget is just wasted space.
+    -->
+    <com.android.internal.widget.multiwaveview.GlowPadView
+        android:id="@+id/incomingCallWidget"
+        android:layout_width="wrap_content"
+        android:layout_height="match_parent"
+        android:layout_gravity="right"
+        android:background="@android:color/black"
+        android:visibility="gone"
+        android:gravity="top"
+
+        prvandroid:targetDrawables="@array/incoming_call_widget_3way_targets"
+        prvandroid:targetDescriptions="@array/incoming_call_widget_3way_target_descriptions"
+        prvandroid:directionDescriptions="@array/incoming_call_widget_3way_direction_descriptions"
+        prvandroid:handleDrawable="@drawable/ic_in_call_touch_handle"
+        prvandroid:innerRadius="@*android:dimen/glowpadview_inner_radius"
+        prvandroid:outerRadius="@*android:dimen/glowpadview_target_placement_radius"
+        prvandroid:outerRingDrawable="@*android:drawable/ic_lockscreen_outerring"
+        prvandroid:snapMargin="@*android:dimen/glowpadview_snap_margin"
+        prvandroid:vibrationDuration="20"
+        prvandroid:feedbackCount="1"
+        prvandroid:glowRadius="@*android:dimen/glowpadview_glow_radius"
+        prvandroid:pointDrawable="@*android:drawable/ic_lockscreen_glowdot"
+        />
+
+</com.android.phone.InCallTouchUi>
diff --git a/res/layout-land/incall_touch_ui_cdma.xml b/res/layout-land/incall_touch_ui_cdma.xml
new file mode 100644
index 0000000..ce96612
--- /dev/null
+++ b/res/layout-land/incall_touch_ui_cdma.xml
@@ -0,0 +1,248 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2012 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.
+-->
+
+<!-- In-call onscreen touch UI elements, used on some platforms.
+
+     This layout is a fullscreen overlay, drawn on top of the
+     non-touch-sensitive parts of the in-call UI (i.e. the call card).
+
+     The top-level View here is a InCallTouchUi (FrameLayout) with 2 children:
+       (1) inCallControls: the widgets visible while a regular call (or calls) is in progress
+       (2) incomingCallWidget: the UI displayed while an incoming call is ringing
+     In usual cases, one of these is visible at any given moment.
+     One exception is when incomingCallWidget is fading-out. At that moment, we show
+     inCallControls beneath incomingCallWidget for smoother transition.
+     -->
+<com.android.phone.InCallTouchUi xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:prvandroid="http://schemas.android.com/apk/prv/res/android"
+    android:id="@+id/inCallTouchUi"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent">
+
+    <!--
+        (1) inCallControls: the widgets visible while a regular call
+        (or calls) is in progress
+    -->
+    <LinearLayout
+        android:id="@+id/inCallControls"
+        android:layout_width="match_parent"
+        android:layout_height="match_parent"
+        android:visibility="gone">
+
+        <!-- DTMF dialpad shown in the left part of the screen.
+             This is wrapped in a FrameLayout because otherwise the ViewStub has no width,
+             causing the other buttons to span the full width of the screen -->
+        <FrameLayout
+            android:layout_width="0dp"
+            android:layout_weight="3"
+            android:layout_height="match_parent">
+            <ViewStub
+                android:id="@+id/dtmf_twelve_key_dialer_stub"
+                android:layout="@layout/dtmf_twelve_key_dialer_view"
+                android:layout_width="match_parent"
+                android:layout_height="match_parent" />
+
+            <!-- The "extra button row": Rare button used for statues such as conference
+                 calls (GSM). Refer to layout(portrait)/incall_touch_ui for more details.
+                 When shown, this extra button row hovers over the call card, just above
+                 the primary_call_banner of layout-land/primary_call_info.
+                 I believe, since this is the CDMA layout, that the button might not be shown. -->
+            <ViewStub
+                android:id="@+id/extraButtonRow"
+                android:layout_gravity="bottom"
+                android:layout_marginBottom="@dimen/call_banner_height"
+                android:layout="@layout/extra_button_row"
+                android:layout_width="match_parent"
+                android:layout_height="wrap_content" />
+        </FrameLayout>
+
+        <!-- Note: This center margin is repeated in layout-land/incall_screen -->
+        <View
+            android:layout_width="@dimen/dialpad_center_margin"
+            android:layout_height="match_parent"
+            android:background="#66000000" />
+
+        <!-- Cluster of buttons on the right part of the screen.
+             It is named id/bottomButtons from the naming when in portrait layout. -->
+        <LinearLayout
+            android:id="@+id/bottomButtons"
+            android:background="@drawable/dialpad_background"
+            android:orientation="vertical"
+            android:layout_width="0dp"
+            android:layout_weight="2"
+            android:layout_height="match_parent">
+
+            <!-- This slot is either "Hold" or "Swap", depending on
+                 the state of the call.   One or the other of these
+                 must always be set to GONE. -->
+            <!-- "Hold" -->
+            <!-- This is a "compound button": it has checked and unchecked states. -->
+            <ToggleButton
+                android:id="@+id/holdButton"
+                android:layout_height="0dp"
+                android:layout_weight="1"
+                android:layout_width="match_parent"
+                style="@style/InCallCompoundButton"
+                android:background="@drawable/btn_compound_hold"
+                android:contentDescription="@string/onscreenHoldText" />
+            <!-- "Swap" (or "Manage calls" in some CDMA states) -->
+            <ImageButton
+                android:id="@+id/swapButton"
+                android:layout_height="0dp"
+                android:layout_weight="1"
+                android:layout_width="match_parent"
+                style="@style/InCallButton"
+                android:src="@drawable/ic_incall_switch_holo_dark"
+                android:contentDescription="@string/onscreenSwapCallsText" />
+
+
+            <View
+                android:id="@+id/holdSwapSpacer"
+                android:layout_height="@dimen/dialpad_button_margin"
+                android:layout_width="match_parent"
+                android:background="#66000000" />
+
+            <LinearLayout
+                android:layout_height="0dp"
+                android:layout_weight="1"
+                android:layout_width="match_parent">
+                <ToggleButton
+                    android:id="@+id/muteButton"
+                    android:layout_width="0dp"
+                    android:layout_weight="1"
+                    android:layout_height="match_parent"
+                    style="@style/InCallCompoundButton"
+                    android:background="@drawable/btn_compound_mute"
+                    android:contentDescription="@string/onscreenMuteText" />
+                <View
+                    android:layout_width="@dimen/dialpad_button_margin"
+                    android:layout_height="match_parent"
+                    android:background="#66000000" />
+                <!-- "Audio mode" -->
+                <!-- This is a multi-mode button that can behave either like a
+                     simple "compound button" with two states *or* like an
+                     action button that brings up a popup menu; see
+                     btn_compound_audio.xml and InCallTouchUi.updateAudioButton()
+                     for the full details. -->
+                <ToggleButton
+                    android:id="@+id/audioButton"
+                    android:layout_width="0dp"
+                    android:layout_weight="1"
+                    android:layout_height="match_parent"
+                    style="@style/InCallCompoundButton"
+                    android:background="@drawable/btn_compound_audio"
+                    android:contentDescription="@string/onscreenAudioText" />
+            </LinearLayout>
+
+            <View
+                android:layout_height="@dimen/dialpad_button_margin"
+                android:layout_width="match_parent"
+                android:background="#66000000" />
+
+            <LinearLayout
+                android:layout_height="0dp"
+                android:layout_weight="1"
+                android:layout_width="match_parent">
+                <ToggleButton
+                    android:id="@+id/dialpadButton"
+                    android:layout_width="0dp"
+                    android:layout_weight="1"
+                    android:layout_height="match_parent"
+                    style="@style/InCallCompoundButton"
+                    android:background="@drawable/btn_compound_dialpad"
+                    android:contentDescription="@string/onscreenShowDialpadText" />
+                <View
+                    android:layout_width="@dimen/dialpad_button_margin"
+                    android:layout_height="match_parent"
+                    android:background="#66000000" />
+                <!-- This slot is either "Add" or "Merge", depending on
+                     the state of the call.  One or the other of these
+                     must always be set to GONE. -->
+                <!-- "Add Call" -->
+                <ImageButton
+                    android:id="@+id/addButton"
+                    android:layout_width="0dp"
+                    android:layout_weight="1"
+                    android:layout_height="match_parent"
+                    style="@style/InCallButton"
+                    android:src="@drawable/ic_add_contact_holo_dark"
+                    android:contentDescription="@string/onscreenAddCallText" />
+                <!-- "Merge calls" -->
+                <!-- This button is used only on GSM devices, where we know
+                     that "Add" and "Merge" are never available at the same time.
+                     The "Merge" button for CDMA devices is "cdmaMergeButton" above. -->
+                <ImageButton
+                    android:id="@+id/mergeButton"
+                    android:layout_width="0dp"
+                    android:layout_weight="1"
+                    android:layout_height="match_parent"
+                    style="@style/InCallButton"
+                    android:src="@drawable/ic_merge_holo_dark"
+                    android:contentDescription="@string/onscreenMergeCallsText" />
+            </LinearLayout>
+
+            <View
+                android:layout_height="@dimen/dialpad_button_margin"
+                android:layout_width="match_parent"
+                android:background="#66000000" />
+            <ImageButton
+                android:id="@+id/endButton"
+                android:layout_height="@dimen/in_call_end_button_height"
+                android:layout_width="match_parent"
+                android:src="@drawable/ic_dial_end_call"
+                android:background="@drawable/end_call_background"
+                android:contentDescription="@string/onscreenEndCallText" />
+        </LinearLayout>
+    </LinearLayout>
+
+    <!--
+        (2) incomingCallWidget: the UI displayed while an incoming call is ringing.
+            See InCallTouchUi.showIncomingCallWidget().
+
+            Layout notes:
+            - Use an opaque black background since we need to cover up
+              a bit of the bottom of the contact photo
+            - The verticalOffset value gets us a little extra space above
+              the topmost "Respond by SMS" icon
+            - The negative layout_marginBottom shifts us slightly downward;
+              we're already aligned with the bottom of the screen, but we
+              don't have an icon in the downward direction so the whole
+              bottom area of this widget is just wasted space.
+    -->
+    <com.android.internal.widget.multiwaveview.GlowPadView
+        android:id="@+id/incomingCallWidget"
+        android:layout_width="wrap_content"
+        android:layout_height="match_parent"
+        android:layout_gravity="right"
+        android:background="@android:color/black"
+        android:visibility="gone"
+        android:gravity="top"
+
+        prvandroid:targetDrawables="@array/incoming_call_widget_3way_targets"
+        prvandroid:targetDescriptions="@array/incoming_call_widget_3way_target_descriptions"
+        prvandroid:directionDescriptions="@array/incoming_call_widget_3way_direction_descriptions"
+        prvandroid:handleDrawable="@drawable/ic_in_call_touch_handle"
+        prvandroid:innerRadius="@*android:dimen/glowpadview_inner_radius"
+        prvandroid:outerRadius="@*android:dimen/glowpadview_target_placement_radius"
+        prvandroid:outerRingDrawable="@*android:drawable/ic_lockscreen_outerring"
+        prvandroid:snapMargin="@*android:dimen/glowpadview_snap_margin"
+        prvandroid:vibrationDuration="20"
+        prvandroid:feedbackCount="1"
+        prvandroid:glowRadius="@*android:dimen/glowpadview_glow_radius"
+        prvandroid:pointDrawable="@*android:drawable/ic_lockscreen_glowdot"
+        />
+
+</com.android.phone.InCallTouchUi>
diff --git a/res/layout/incall_screen.xml b/res/layout/incall_screen.xml
index da9a509..64df29a 100644
--- a/res/layout/incall_screen.xml
+++ b/res/layout/incall_screen.xml
@@ -38,7 +38,6 @@
          of the in-call screen, and also the DTMF dialpad (which, when
          visible, covers the upper part of the screen too.) -->
     <include layout="@layout/incall_touch_ui"
-        android:id="@+id/inCallTouchUi"
         android:layout_width="match_parent"
         android:layout_height="match_parent"
         />
diff --git a/res/layout/incall_touch_ui.xml b/res/layout/incall_touch_ui.xml
index c070782..8dd8b61 100644
--- a/res/layout/incall_touch_ui.xml
+++ b/res/layout/incall_touch_ui.xml
@@ -28,6 +28,7 @@
      -->
 <com.android.phone.InCallTouchUi xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:prvandroid="http://schemas.android.com/apk/prv/res/android"
+    android:id="@+id/inCallTouchUi"
     android:layout_width="match_parent"
     android:layout_height="match_parent"
     >
diff --git a/res/layout/manage_conference_panel.xml b/res/layout/manage_conference_panel.xml
index 7baf09b..f1fbfdf 100644
--- a/res/layout/manage_conference_panel.xml
+++ b/res/layout/manage_conference_panel.xml
@@ -19,6 +19,7 @@
      button while on a conference call. -->
 <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
                 android:id="@+id/manageConferencePanel"
+                android:background="#FF000000"
                 android:layout_width="match_parent"
                 android:layout_height="match_parent"
                 android:visibility="gone"
diff --git a/res/layout/primary_call_info.xml b/res/layout/primary_call_info.xml
index 73718ee..099f19e 100644
--- a/res/layout/primary_call_info.xml
+++ b/res/layout/primary_call_info.xml
@@ -68,7 +68,7 @@
          and other status info.  This info is shown as a "banner"
          overlaid across the top of contact photo. -->
     <RelativeLayout android:id="@+id/primary_call_banner"
-        android:layout_alignParentTop="true"
+        style="@style/PrimaryCallInfoPrimaryCallBanner"
         android:layout_width="match_parent"
         android:layout_height="wrap_content"
         android:minHeight="@dimen/call_banner_height"
@@ -137,7 +137,7 @@
     </RelativeLayout>  <!-- End of call_banner -->
 
     <LinearLayout android:id="@+id/secondary_info_container"
-        android:layout_below="@id/primary_call_banner"
+        style="@style/PrimaryCallInfoSecondaryInfoContainer"
         android:layout_width="match_parent"
         android:layout_height="wrap_content"
         android:layout_gravity="center_vertical|right"
diff --git a/res/layout/secondary_call_info.xml b/res/layout/secondary_call_info.xml
index 0e6e65f..516b615 100644
--- a/res/layout/secondary_call_info.xml
+++ b/res/layout/secondary_call_info.xml
@@ -25,8 +25,6 @@
 
     <!-- Contact photo for call_info #2 -->
     <ImageView android:id="@+id/secondaryCallPhoto"
-        android:layout_alignParentLeft="true"
-        android:layout_alignParentTop="true"
         android:layout_width="match_parent"
         android:layout_height="match_parent"
         android:gravity="top|center_horizontal"
@@ -37,8 +35,6 @@
 
          TODO: We could do better. See equivalent in primary xml. -->
     <View android:id="@+id/dim_effect_for_secondary_photo"
-         android:layout_alignParentLeft="true"
-         android:layout_alignParentTop="true"
          android:layout_width="match_parent"
          android:layout_height="match_parent"
          android:background="@drawable/clickable_dim_effect"
@@ -46,6 +42,7 @@
 
     <!-- Name (or the phone number, if we don't have a name to display). -->
     <TextView android:id="@+id/secondaryCallName"
+        style="@style/SecondaryCallInfoSecondaryCallName"
         android:layout_width="match_parent"
         android:layout_height="@dimen/call_banner_height"
         android:gravity="top|left"
@@ -60,9 +57,9 @@
 
     <!-- Call status of the background call, usually the string "On hold". -->
     <TextView android:id="@+id/secondaryCallStatus"
+        style="@style/SecondaryCallInfoSecondaryCallStatus"
         android:layout_width="wrap_content"
         android:layout_height="@dimen/call_banner_height"
-        android:layout_gravity="top|right"
         android:gravity="top|right"
         android:paddingLeft="@dimen/call_banner_side_padding"
         android:paddingRight="@dimen/call_banner_side_padding"
diff --git a/res/mipmap-hdpi/ic_launcher_phone.png b/res/mipmap-hdpi/ic_launcher_phone.png
new file mode 100644
index 0000000..47d7894
--- /dev/null
+++ b/res/mipmap-hdpi/ic_launcher_phone.png
Binary files differ
diff --git a/res/mipmap-mdpi/ic_launcher_phone.png b/res/mipmap-mdpi/ic_launcher_phone.png
new file mode 100644
index 0000000..3b333cf
--- /dev/null
+++ b/res/mipmap-mdpi/ic_launcher_phone.png
Binary files differ
diff --git a/res/mipmap-xhdpi/ic_launcher_phone.png b/res/mipmap-xhdpi/ic_launcher_phone.png
new file mode 100644
index 0000000..020c2fa
--- /dev/null
+++ b/res/mipmap-xhdpi/ic_launcher_phone.png
Binary files differ
diff --git a/res/mipmap-xxhdpi/ic_launcher_contacts.png b/res/mipmap-xxhdpi/ic_launcher_contacts.png
new file mode 100644
index 0000000..99b403b
--- /dev/null
+++ b/res/mipmap-xxhdpi/ic_launcher_contacts.png
Binary files differ
diff --git a/res/mipmap-xxhdpi/ic_launcher_phone.png b/res/mipmap-xxhdpi/ic_launcher_phone.png
new file mode 100644
index 0000000..1594e4e
--- /dev/null
+++ b/res/mipmap-xxhdpi/ic_launcher_phone.png
Binary files differ
diff --git a/res/values-af/strings.xml b/res/values-af/strings.xml
index 0bfd714..ef82556 100644
--- a/res/values-af/strings.xml
+++ b/res/values-af/strings.xml
@@ -399,6 +399,7 @@
     <string name="card_title_hanging_up" msgid="3999101620995182450">"Lui af"</string>
     <string name="card_title_in_call" msgid="6346543933068225205">"In oproep"</string>
     <string name="card_title_my_phone_number" msgid="112428362494434191">"My nommer is <xliff:g id="MY_PHONE_NUMBER">%s</xliff:g>"</string>
+    <string name="notification_dialing" msgid="2107666444937350731">"Bel"</string>
     <string name="notification_missedCallTitle" msgid="7554385905572364535">"Gemiste oproep"</string>
     <string name="notification_missedCallsTitle" msgid="1361677948941502522">"Gemiste oproepe"</string>
     <string name="notification_missedCallsMsg" msgid="4575787816055205600">"<xliff:g id="NUM_MISSED_CALLS">%s</xliff:g> gemiste oproepe"</string>
diff --git a/res/values-am/strings.xml b/res/values-am/strings.xml
index a0da9d3..f068ba4 100644
--- a/res/values-am/strings.xml
+++ b/res/values-am/strings.xml
@@ -395,6 +395,7 @@
     <string name="card_title_hanging_up" msgid="3999101620995182450">"በመዝጋት ላይ"</string>
     <string name="card_title_in_call" msgid="6346543933068225205">"ጥሪ ላይ"</string>
     <string name="card_title_my_phone_number" msgid="112428362494434191">"ቁጥሬ<xliff:g id="MY_PHONE_NUMBER">%s</xliff:g> ነው"</string>
+    <string name="notification_dialing" msgid="2107666444937350731">"በመደወል ላይ"</string>
     <string name="notification_missedCallTitle" msgid="7554385905572364535">"ያመለጠጥሪ"</string>
     <string name="notification_missedCallsTitle" msgid="1361677948941502522">"ያመለጡ ጥሪዎች"</string>
     <string name="notification_missedCallsMsg" msgid="4575787816055205600">"<xliff:g id="NUM_MISSED_CALLS">%s</xliff:g> ያመለጡ ጥሪዎች"</string>
diff --git a/res/values-ar/strings.xml b/res/values-ar/strings.xml
index 0990b24..e04a955 100644
--- a/res/values-ar/strings.xml
+++ b/res/values-ar/strings.xml
@@ -395,6 +395,7 @@
     <string name="card_title_hanging_up" msgid="3999101620995182450">"إنهاء المكالمة"</string>
     <string name="card_title_in_call" msgid="6346543933068225205">"قيد الاتصال"</string>
     <string name="card_title_my_phone_number" msgid="112428362494434191">"رقمي هو <xliff:g id="MY_PHONE_NUMBER">%s</xliff:g>"</string>
+    <string name="notification_dialing" msgid="2107666444937350731">"جارٍ الطلب"</string>
     <string name="notification_missedCallTitle" msgid="7554385905572364535">"مكالمة فائتة"</string>
     <string name="notification_missedCallsTitle" msgid="1361677948941502522">"المكالمات الفائتة"</string>
     <string name="notification_missedCallsMsg" msgid="4575787816055205600">"<xliff:g id="NUM_MISSED_CALLS">%s</xliff:g> من المكالمات الفائتة"</string>
diff --git a/res/values-be/strings.xml b/res/values-be/strings.xml
index 5b1d820..9cf2c0a 100644
--- a/res/values-be/strings.xml
+++ b/res/values-be/strings.xml
@@ -395,6 +395,7 @@
     <string name="card_title_hanging_up" msgid="3999101620995182450">"Завяршэнне"</string>
     <string name="card_title_in_call" msgid="6346543933068225205">"У выкліку"</string>
     <string name="card_title_my_phone_number" msgid="112428362494434191">"Мой нумар – <xliff:g id="MY_PHONE_NUMBER">%s</xliff:g>"</string>
+    <string name="notification_dialing" msgid="2107666444937350731">"Набор"</string>
     <string name="notification_missedCallTitle" msgid="7554385905572364535">"Прапушчаны выклік"</string>
     <string name="notification_missedCallsTitle" msgid="1361677948941502522">"Прапушчаныя выклікі"</string>
     <string name="notification_missedCallsMsg" msgid="4575787816055205600">"Прапушчаных выклікаў: <xliff:g id="NUM_MISSED_CALLS">%s</xliff:g>"</string>
diff --git a/res/values-bg/strings.xml b/res/values-bg/strings.xml
index e859348..79f37ae 100644
--- a/res/values-bg/strings.xml
+++ b/res/values-bg/strings.xml
@@ -395,6 +395,7 @@
     <string name="card_title_hanging_up" msgid="3999101620995182450">"Приключване на разговора"</string>
     <string name="card_title_in_call" msgid="6346543933068225205">"Вх. обаждане"</string>
     <string name="card_title_my_phone_number" msgid="112428362494434191">"Моят номер е <xliff:g id="MY_PHONE_NUMBER">%s</xliff:g>"</string>
+    <string name="notification_dialing" msgid="2107666444937350731">"Набира се"</string>
     <string name="notification_missedCallTitle" msgid="7554385905572364535">"Пропуснато обаждане"</string>
     <string name="notification_missedCallsTitle" msgid="1361677948941502522">"Пропуснати обаждания"</string>
     <string name="notification_missedCallsMsg" msgid="4575787816055205600">"<xliff:g id="NUM_MISSED_CALLS">%s</xliff:g> пропуснати обаждания"</string>
diff --git a/res/values-ca/strings.xml b/res/values-ca/strings.xml
index 072b610..6a9aa2d 100644
--- a/res/values-ca/strings.xml
+++ b/res/values-ca/strings.xml
@@ -395,6 +395,7 @@
     <string name="card_title_hanging_up" msgid="3999101620995182450">"S\'està penjant"</string>
     <string name="card_title_in_call" msgid="6346543933068225205">"En una trucada"</string>
     <string name="card_title_my_phone_number" msgid="112428362494434191">"El meu número és <xliff:g id="MY_PHONE_NUMBER">%s</xliff:g>"</string>
+    <string name="notification_dialing" msgid="2107666444937350731">"Marcatge"</string>
     <string name="notification_missedCallTitle" msgid="7554385905572364535">"Trucada perduda"</string>
     <string name="notification_missedCallsTitle" msgid="1361677948941502522">"Trucades perdudes"</string>
     <string name="notification_missedCallsMsg" msgid="4575787816055205600">"<xliff:g id="NUM_MISSED_CALLS">%s</xliff:g> trucades perdudes"</string>
diff --git a/res/values-cs/strings.xml b/res/values-cs/strings.xml
index 587ea69..af013e2 100644
--- a/res/values-cs/strings.xml
+++ b/res/values-cs/strings.xml
@@ -395,6 +395,7 @@
     <string name="card_title_hanging_up" msgid="3999101620995182450">"Zavěšování"</string>
     <string name="card_title_in_call" msgid="6346543933068225205">"Probíhá hovor"</string>
     <string name="card_title_my_phone_number" msgid="112428362494434191">"Moje číslo je <xliff:g id="MY_PHONE_NUMBER">%s</xliff:g>"</string>
+    <string name="notification_dialing" msgid="2107666444937350731">"Vytáčení"</string>
     <string name="notification_missedCallTitle" msgid="7554385905572364535">"Zmeškaný hovor"</string>
     <string name="notification_missedCallsTitle" msgid="1361677948941502522">"Zmeškané hovory"</string>
     <string name="notification_missedCallsMsg" msgid="4575787816055205600">"Zmeškané hovory: <xliff:g id="NUM_MISSED_CALLS">%s</xliff:g>."</string>
diff --git a/res/values-da/strings.xml b/res/values-da/strings.xml
index 8cbbd12..ac2441b 100644
--- a/res/values-da/strings.xml
+++ b/res/values-da/strings.xml
@@ -401,6 +401,7 @@
     <string name="card_title_hanging_up" msgid="3999101620995182450">"Lægger på"</string>
     <string name="card_title_in_call" msgid="6346543933068225205">"Opkald i gang"</string>
     <string name="card_title_my_phone_number" msgid="112428362494434191">"Mit nummer er <xliff:g id="MY_PHONE_NUMBER">%s</xliff:g>"</string>
+    <string name="notification_dialing" msgid="2107666444937350731">"Ringer op"</string>
     <string name="notification_missedCallTitle" msgid="7554385905572364535">"Ubesvarede opkald"</string>
     <string name="notification_missedCallsTitle" msgid="1361677948941502522">"Ubesvarede opkald"</string>
     <string name="notification_missedCallsMsg" msgid="4575787816055205600">"<xliff:g id="NUM_MISSED_CALLS">%s</xliff:g> ubesvarede opkald"</string>
diff --git a/res/values-de/strings.xml b/res/values-de/strings.xml
index b638884..74e8596 100644
--- a/res/values-de/strings.xml
+++ b/res/values-de/strings.xml
@@ -399,6 +399,7 @@
     <string name="card_title_hanging_up" msgid="3999101620995182450">"Auflegen"</string>
     <string name="card_title_in_call" msgid="6346543933068225205">"Anruf"</string>
     <string name="card_title_my_phone_number" msgid="112428362494434191">"Meine Nummer lautet <xliff:g id="MY_PHONE_NUMBER">%s</xliff:g>."</string>
+    <string name="notification_dialing" msgid="2107666444937350731">"Verbindung wird aufgebaut..."</string>
     <string name="notification_missedCallTitle" msgid="7554385905572364535">"Entgangener Anruf"</string>
     <string name="notification_missedCallsTitle" msgid="1361677948941502522">"Entgangene Anrufe"</string>
     <string name="notification_missedCallsMsg" msgid="4575787816055205600">"<xliff:g id="NUM_MISSED_CALLS">%s</xliff:g> entgangene Anrufe"</string>
diff --git a/res/values-el/strings.xml b/res/values-el/strings.xml
index 78679e1..6bf050b 100644
--- a/res/values-el/strings.xml
+++ b/res/values-el/strings.xml
@@ -395,6 +395,7 @@
     <string name="card_title_hanging_up" msgid="3999101620995182450">"Κλείσιμο γραμμής"</string>
     <string name="card_title_in_call" msgid="6346543933068225205">"Σε κλήση"</string>
     <string name="card_title_my_phone_number" msgid="112428362494434191">"Ο αριθμός μου είναι <xliff:g id="MY_PHONE_NUMBER">%s</xliff:g>"</string>
+    <string name="notification_dialing" msgid="2107666444937350731">"Κλήση"</string>
     <string name="notification_missedCallTitle" msgid="7554385905572364535">"Αναπάντητη κλήση"</string>
     <string name="notification_missedCallsTitle" msgid="1361677948941502522">"Αναπάντητες κλήσεις"</string>
     <string name="notification_missedCallsMsg" msgid="4575787816055205600">"<xliff:g id="NUM_MISSED_CALLS">%s</xliff:g> αναπάντητες κλήσεις"</string>
diff --git a/res/values-en-rGB/strings.xml b/res/values-en-rGB/strings.xml
index ac52314..27a116d 100644
--- a/res/values-en-rGB/strings.xml
+++ b/res/values-en-rGB/strings.xml
@@ -395,6 +395,7 @@
     <string name="card_title_hanging_up" msgid="3999101620995182450">"Hanging up"</string>
     <string name="card_title_in_call" msgid="6346543933068225205">"In call"</string>
     <string name="card_title_my_phone_number" msgid="112428362494434191">"My number is <xliff:g id="MY_PHONE_NUMBER">%s</xliff:g>"</string>
+    <string name="notification_dialing" msgid="2107666444937350731">"Dialling"</string>
     <string name="notification_missedCallTitle" msgid="7554385905572364535">"Missed call"</string>
     <string name="notification_missedCallsTitle" msgid="1361677948941502522">"Missed calls"</string>
     <string name="notification_missedCallsMsg" msgid="4575787816055205600">"<xliff:g id="NUM_MISSED_CALLS">%s</xliff:g> missed calls"</string>
diff --git a/res/values-es-rUS/strings.xml b/res/values-es-rUS/strings.xml
index 6db20ee..316e086 100644
--- a/res/values-es-rUS/strings.xml
+++ b/res/values-es-rUS/strings.xml
@@ -395,6 +395,7 @@
     <string name="card_title_hanging_up" msgid="3999101620995182450">"Colgando"</string>
     <string name="card_title_in_call" msgid="6346543933068225205">"En llamada"</string>
     <string name="card_title_my_phone_number" msgid="112428362494434191">"Mi número es <xliff:g id="MY_PHONE_NUMBER">%s</xliff:g>"</string>
+    <string name="notification_dialing" msgid="2107666444937350731">"Marcando"</string>
     <string name="notification_missedCallTitle" msgid="7554385905572364535">"Llamada perdida"</string>
     <string name="notification_missedCallsTitle" msgid="1361677948941502522">"Llamadas perdidas"</string>
     <string name="notification_missedCallsMsg" msgid="4575787816055205600">"<xliff:g id="NUM_MISSED_CALLS">%s</xliff:g> llamadas perdidas"</string>
diff --git a/res/values-es/strings.xml b/res/values-es/strings.xml
index bd6946d..21fb011 100644
--- a/res/values-es/strings.xml
+++ b/res/values-es/strings.xml
@@ -399,6 +399,7 @@
     <string name="card_title_hanging_up" msgid="3999101620995182450">"Colgando"</string>
     <string name="card_title_in_call" msgid="6346543933068225205">"Llamada entrante"</string>
     <string name="card_title_my_phone_number" msgid="112428362494434191">"Mi número es <xliff:g id="MY_PHONE_NUMBER">%s</xliff:g>."</string>
+    <string name="notification_dialing" msgid="2107666444937350731">"Llamando..."</string>
     <string name="notification_missedCallTitle" msgid="7554385905572364535">"Llamada perdida"</string>
     <string name="notification_missedCallsTitle" msgid="1361677948941502522">"Llamadas perdidas"</string>
     <string name="notification_missedCallsMsg" msgid="4575787816055205600">"<xliff:g id="NUM_MISSED_CALLS">%s</xliff:g> llamadas perdidas"</string>
diff --git a/res/values-et/strings.xml b/res/values-et/strings.xml
index 7f934d0..1755314 100644
--- a/res/values-et/strings.xml
+++ b/res/values-et/strings.xml
@@ -395,6 +395,7 @@
     <string name="card_title_hanging_up" msgid="3999101620995182450">"Lõpetamisel"</string>
     <string name="card_title_in_call" msgid="6346543933068225205">"Kõne"</string>
     <string name="card_title_my_phone_number" msgid="112428362494434191">"Minu number on <xliff:g id="MY_PHONE_NUMBER">%s</xliff:g>"</string>
+    <string name="notification_dialing" msgid="2107666444937350731">"Valimine"</string>
     <string name="notification_missedCallTitle" msgid="7554385905572364535">"Vastamata kõne"</string>
     <string name="notification_missedCallsTitle" msgid="1361677948941502522">"Vastamata kõned"</string>
     <string name="notification_missedCallsMsg" msgid="4575787816055205600">"<xliff:g id="NUM_MISSED_CALLS">%s</xliff:g> vastamata kõnet"</string>
diff --git a/res/values-fa/strings.xml b/res/values-fa/strings.xml
index 1163ebc..26da88e 100644
--- a/res/values-fa/strings.xml
+++ b/res/values-fa/strings.xml
@@ -395,6 +395,7 @@
     <string name="card_title_hanging_up" msgid="3999101620995182450">"قطع تماس"</string>
     <string name="card_title_in_call" msgid="6346543933068225205">"در تماس"</string>
     <string name="card_title_my_phone_number" msgid="112428362494434191">"شماره من <xliff:g id="MY_PHONE_NUMBER">%s</xliff:g> است"</string>
+    <string name="notification_dialing" msgid="2107666444937350731">"شماره‌گیری"</string>
     <string name="notification_missedCallTitle" msgid="7554385905572364535">"تماس بی پاسخ"</string>
     <string name="notification_missedCallsTitle" msgid="1361677948941502522">"تماس‌های بی پاسخ"</string>
     <string name="notification_missedCallsMsg" msgid="4575787816055205600">"<xliff:g id="NUM_MISSED_CALLS">%s</xliff:g> تماس بی پاسخ"</string>
diff --git a/res/values-fi/strings.xml b/res/values-fi/strings.xml
index 1587076..be763c4 100644
--- a/res/values-fi/strings.xml
+++ b/res/values-fi/strings.xml
@@ -399,6 +399,7 @@
     <string name="card_title_hanging_up" msgid="3999101620995182450">"Katkaistaan"</string>
     <string name="card_title_in_call" msgid="6346543933068225205">"Puhelun aikana"</string>
     <string name="card_title_my_phone_number" msgid="112428362494434191">"Numeroni on <xliff:g id="MY_PHONE_NUMBER">%s</xliff:g>"</string>
+    <string name="notification_dialing" msgid="2107666444937350731">"Soitetaan"</string>
     <string name="notification_missedCallTitle" msgid="7554385905572364535">"Vastaamatta jäänyt puhelu"</string>
     <string name="notification_missedCallsTitle" msgid="1361677948941502522">"Vastaamattomat puhelut"</string>
     <string name="notification_missedCallsMsg" msgid="4575787816055205600">"<xliff:g id="NUM_MISSED_CALLS">%s</xliff:g> vastaamatonta puhelua"</string>
diff --git a/res/values-fr/strings.xml b/res/values-fr/strings.xml
index 953a44e..4f96455 100644
--- a/res/values-fr/strings.xml
+++ b/res/values-fr/strings.xml
@@ -395,6 +395,7 @@
     <string name="card_title_hanging_up" msgid="3999101620995182450">"Fin de l\'appel.."</string>
     <string name="card_title_in_call" msgid="6346543933068225205">"Appel en cours"</string>
     <string name="card_title_my_phone_number" msgid="112428362494434191">"Mon numéro est le <xliff:g id="MY_PHONE_NUMBER">%s</xliff:g>"</string>
+    <string name="notification_dialing" msgid="2107666444937350731">"Numérotation en cours…"</string>
     <string name="notification_missedCallTitle" msgid="7554385905572364535">"Appel manqué"</string>
     <string name="notification_missedCallsTitle" msgid="1361677948941502522">"Appels manqués"</string>
     <string name="notification_missedCallsMsg" msgid="4575787816055205600">"<xliff:g id="NUM_MISSED_CALLS">%s</xliff:g> appels manqués"</string>
diff --git a/res/values-hi/strings.xml b/res/values-hi/strings.xml
index 0880230..86de7d3 100644
--- a/res/values-hi/strings.xml
+++ b/res/values-hi/strings.xml
@@ -395,6 +395,7 @@
     <string name="card_title_hanging_up" msgid="3999101620995182450">"बंद कर रहा है"</string>
     <string name="card_title_in_call" msgid="6346543933068225205">"कॉल में"</string>
     <string name="card_title_my_phone_number" msgid="112428362494434191">"मेरा नंबर <xliff:g id="MY_PHONE_NUMBER">%s</xliff:g> है"</string>
+    <string name="notification_dialing" msgid="2107666444937350731">"डायल हो रहा है"</string>
     <string name="notification_missedCallTitle" msgid="7554385905572364535">"छूटी कॉल"</string>
     <string name="notification_missedCallsTitle" msgid="1361677948941502522">"छूटी कॉल"</string>
     <string name="notification_missedCallsMsg" msgid="4575787816055205600">"<xliff:g id="NUM_MISSED_CALLS">%s</xliff:g> छूटी कॉल"</string>
diff --git a/res/values-hr/strings.xml b/res/values-hr/strings.xml
index eda2ac7..e3f6d31 100644
--- a/res/values-hr/strings.xml
+++ b/res/values-hr/strings.xml
@@ -395,6 +395,7 @@
     <string name="card_title_hanging_up" msgid="3999101620995182450">"Prekidanje veze"</string>
     <string name="card_title_in_call" msgid="6346543933068225205">"Poziv u tijeku"</string>
     <string name="card_title_my_phone_number" msgid="112428362494434191">"Moj broj je <xliff:g id="MY_PHONE_NUMBER">%s</xliff:g>"</string>
+    <string name="notification_dialing" msgid="2107666444937350731">"Biranje broja"</string>
     <string name="notification_missedCallTitle" msgid="7554385905572364535">"Propušteni poziv"</string>
     <string name="notification_missedCallsTitle" msgid="1361677948941502522">"Propušteni pozivi"</string>
     <string name="notification_missedCallsMsg" msgid="4575787816055205600">"Broj propuštenih poziva: <xliff:g id="NUM_MISSED_CALLS">%s</xliff:g>"</string>
diff --git a/res/values-hu/strings.xml b/res/values-hu/strings.xml
index 4319e01..261dba2 100644
--- a/res/values-hu/strings.xml
+++ b/res/values-hu/strings.xml
@@ -395,6 +395,7 @@
     <string name="card_title_hanging_up" msgid="3999101620995182450">"Megszakítás"</string>
     <string name="card_title_in_call" msgid="6346543933068225205">"Hívásban"</string>
     <string name="card_title_my_phone_number" msgid="112428362494434191">"A számom: <xliff:g id="MY_PHONE_NUMBER">%s</xliff:g>"</string>
+    <string name="notification_dialing" msgid="2107666444937350731">"Tárcsázás"</string>
     <string name="notification_missedCallTitle" msgid="7554385905572364535">"Nem fogadott hívás"</string>
     <string name="notification_missedCallsTitle" msgid="1361677948941502522">"Nem fogadott hívások"</string>
     <string name="notification_missedCallsMsg" msgid="4575787816055205600">"<xliff:g id="NUM_MISSED_CALLS">%s</xliff:g> nem fogadott hívás"</string>
diff --git a/res/values-in/strings.xml b/res/values-in/strings.xml
index e0c4af8..b660a3e 100644
--- a/res/values-in/strings.xml
+++ b/res/values-in/strings.xml
@@ -395,6 +395,7 @@
     <string name="card_title_hanging_up" msgid="3999101620995182450">"Menutup panggilan"</string>
     <string name="card_title_in_call" msgid="6346543933068225205">"Sedang dalam panggilan"</string>
     <string name="card_title_my_phone_number" msgid="112428362494434191">"Nomor saya <xliff:g id="MY_PHONE_NUMBER">%s</xliff:g>"</string>
+    <string name="notification_dialing" msgid="2107666444937350731">"Memanggil"</string>
     <string name="notification_missedCallTitle" msgid="7554385905572364535">"Panggilan tak terjawab"</string>
     <string name="notification_missedCallsTitle" msgid="1361677948941502522">"Panggilan tak terjawab"</string>
     <string name="notification_missedCallsMsg" msgid="4575787816055205600">"<xliff:g id="NUM_MISSED_CALLS">%s</xliff:g> panggilan tak terjawab"</string>
diff --git a/res/values-it/strings.xml b/res/values-it/strings.xml
index c792049..442aceb 100644
--- a/res/values-it/strings.xml
+++ b/res/values-it/strings.xml
@@ -399,6 +399,7 @@
     <string name="card_title_hanging_up" msgid="3999101620995182450">"In fase di chiusura"</string>
     <string name="card_title_in_call" msgid="6346543933068225205">"Chiamata"</string>
     <string name="card_title_my_phone_number" msgid="112428362494434191">"Il mio numero è <xliff:g id="MY_PHONE_NUMBER">%s</xliff:g>"</string>
+    <string name="notification_dialing" msgid="2107666444937350731">"Chiamata in corso"</string>
     <string name="notification_missedCallTitle" msgid="7554385905572364535">"Chiamata senza risposta"</string>
     <string name="notification_missedCallsTitle" msgid="1361677948941502522">"Chiamate senza risposta"</string>
     <string name="notification_missedCallsMsg" msgid="4575787816055205600">"<xliff:g id="NUM_MISSED_CALLS">%s</xliff:g> chiamate senza risposta"</string>
diff --git a/res/values-iw/strings.xml b/res/values-iw/strings.xml
index 3bf8f95..193ebe6 100644
--- a/res/values-iw/strings.xml
+++ b/res/values-iw/strings.xml
@@ -395,6 +395,7 @@
     <string name="card_title_hanging_up" msgid="3999101620995182450">"מנתק"</string>
     <string name="card_title_in_call" msgid="6346543933068225205">"בשיחה"</string>
     <string name="card_title_my_phone_number" msgid="112428362494434191">"המספר שלי הוא <xliff:g id="MY_PHONE_NUMBER">%s</xliff:g>"</string>
+    <string name="notification_dialing" msgid="2107666444937350731">"מחייג"</string>
     <string name="notification_missedCallTitle" msgid="7554385905572364535">"שיחה שלא נענתה"</string>
     <string name="notification_missedCallsTitle" msgid="1361677948941502522">"שיחות שלא נענו"</string>
     <string name="notification_missedCallsMsg" msgid="4575787816055205600">"<xliff:g id="NUM_MISSED_CALLS">%s</xliff:g> שיחות שלא נענו"</string>
diff --git a/res/values-ja/strings.xml b/res/values-ja/strings.xml
index fd97dcf..daf0844 100644
--- a/res/values-ja/strings.xml
+++ b/res/values-ja/strings.xml
@@ -395,6 +395,7 @@
     <string name="card_title_hanging_up" msgid="3999101620995182450">"通話終了"</string>
     <string name="card_title_in_call" msgid="6346543933068225205">"着信"</string>
     <string name="card_title_my_phone_number" msgid="112428362494434191">"この電話の番号: <xliff:g id="MY_PHONE_NUMBER">%s</xliff:g>"</string>
+    <string name="notification_dialing" msgid="2107666444937350731">"発信中"</string>
     <string name="notification_missedCallTitle" msgid="7554385905572364535">"不在着信"</string>
     <string name="notification_missedCallsTitle" msgid="1361677948941502522">"不在着信"</string>
     <string name="notification_missedCallsMsg" msgid="4575787816055205600">"不在着信<xliff:g id="NUM_MISSED_CALLS">%s</xliff:g>件"</string>
diff --git a/res/values-ko/strings.xml b/res/values-ko/strings.xml
index 9ed70a3..982b863 100644
--- a/res/values-ko/strings.xml
+++ b/res/values-ko/strings.xml
@@ -395,6 +395,7 @@
     <string name="card_title_hanging_up" msgid="3999101620995182450">"전화 끊는 중"</string>
     <string name="card_title_in_call" msgid="6346543933068225205">"통화 상태"</string>
     <string name="card_title_my_phone_number" msgid="112428362494434191">"내 전화번호는 <xliff:g id="MY_PHONE_NUMBER">%s</xliff:g>입니다."</string>
+    <string name="notification_dialing" msgid="2107666444937350731">"전화 거는 중"</string>
     <string name="notification_missedCallTitle" msgid="7554385905572364535">"부재중 전화"</string>
     <string name="notification_missedCallsTitle" msgid="1361677948941502522">"부재중 통화"</string>
     <string name="notification_missedCallsMsg" msgid="4575787816055205600">"부재중 통화 <xliff:g id="NUM_MISSED_CALLS">%s</xliff:g>통"</string>
diff --git a/res/values-land/dimens.xml b/res/values-land/dimens.xml
index 56ad159..9eb531d 100644
--- a/res/values-land/dimens.xml
+++ b/res/values-land/dimens.xml
@@ -15,4 +15,7 @@
 -->
 <resources>
     <dimen name="emergency_dialer_digits_height">66dip</dimen>
+
+    <!-- Height of the "call banner" overlay on bottom of the call_card -->
+    <dimen name="call_banner_height">@dimen/in_call_end_button_height</dimen>
 </resources>
diff --git a/res/values-land/styles.xml b/res/values-land/styles.xml
new file mode 100644
index 0000000..0626a15
--- /dev/null
+++ b/res/values-land/styles.xml
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2012 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.
+-->
+
+<resources>
+    <style name="PrimaryCallInfoPrimaryCallBanner">
+        <item name="android:layout_alignParentBottom">true</item>
+    </style>
+    <style name="PrimaryCallInfoSecondaryInfoContainer">
+        <item name="android:layout_above">@id/primary_call_banner</item>
+    </style>
+
+    <style name="SecondaryCallInfoSecondaryCallName">
+        <item name="android:layout_gravity">bottom|left</item>
+    </style>
+    <style name="SecondaryCallInfoSecondaryCallStatus">
+        <item name="android:layout_gravity">bottom|right</item>
+    </style>
+</resources>
diff --git a/res/values-lt/strings.xml b/res/values-lt/strings.xml
index 67c7e61..b4d8269 100644
--- a/res/values-lt/strings.xml
+++ b/res/values-lt/strings.xml
@@ -395,6 +395,7 @@
     <string name="card_title_hanging_up" msgid="3999101620995182450">"Baigiamas pokalbis"</string>
     <string name="card_title_in_call" msgid="6346543933068225205">"Skambinant"</string>
     <string name="card_title_my_phone_number" msgid="112428362494434191">"Mano numeris: <xliff:g id="MY_PHONE_NUMBER">%s</xliff:g>"</string>
+    <string name="notification_dialing" msgid="2107666444937350731">"Renkamas numeris"</string>
     <string name="notification_missedCallTitle" msgid="7554385905572364535">"Praleistas skambutis"</string>
     <string name="notification_missedCallsTitle" msgid="1361677948941502522">"Praleisti skambučiai"</string>
     <string name="notification_missedCallsMsg" msgid="4575787816055205600">"<xliff:g id="NUM_MISSED_CALLS">%s</xliff:g> praleisti (-ų) skambučiai (-ų)"</string>
diff --git a/res/values-lv/strings.xml b/res/values-lv/strings.xml
index c2c8594..9893974 100644
--- a/res/values-lv/strings.xml
+++ b/res/values-lv/strings.xml
@@ -397,6 +397,7 @@
     <string name="card_title_hanging_up" msgid="3999101620995182450">"Notiek klausules nolikšana"</string>
     <string name="card_title_in_call" msgid="6346543933068225205">"Notiek saruna"</string>
     <string name="card_title_my_phone_number" msgid="112428362494434191">"Mans tālruņa numurs: <xliff:g id="MY_PHONE_NUMBER">%s</xliff:g>"</string>
+    <string name="notification_dialing" msgid="2107666444937350731">"Notiek numura sastādīšana"</string>
     <string name="notification_missedCallTitle" msgid="7554385905572364535">"Neatbildēts zvans"</string>
     <string name="notification_missedCallsTitle" msgid="1361677948941502522">"Neatbildētie zvani"</string>
     <string name="notification_missedCallsMsg" msgid="4575787816055205600">"<xliff:g id="NUM_MISSED_CALLS">%s</xliff:g> neatbildēts(-i) zvans(-i)"</string>
diff --git a/res/values-ms/strings.xml b/res/values-ms/strings.xml
index 7cdb49f..92536c2 100644
--- a/res/values-ms/strings.xml
+++ b/res/values-ms/strings.xml
@@ -395,6 +395,7 @@
     <string name="card_title_hanging_up" msgid="3999101620995182450">"Menamatkan panggilan"</string>
     <string name="card_title_in_call" msgid="6346543933068225205">"Dalam panggilan"</string>
     <string name="card_title_my_phone_number" msgid="112428362494434191">"Nombor saya ialah <xliff:g id="MY_PHONE_NUMBER">%s</xliff:g>"</string>
+    <string name="notification_dialing" msgid="2107666444937350731">"Mendail"</string>
     <string name="notification_missedCallTitle" msgid="7554385905572364535">"Panggilan tidak dijawab"</string>
     <string name="notification_missedCallsTitle" msgid="1361677948941502522">"Panggilan tidak dijawab"</string>
     <string name="notification_missedCallsMsg" msgid="4575787816055205600">"<xliff:g id="NUM_MISSED_CALLS">%s</xliff:g> panggilan tidak dijawab"</string>
diff --git a/res/values-nb/strings.xml b/res/values-nb/strings.xml
index a706730..4cd6ee4 100644
--- a/res/values-nb/strings.xml
+++ b/res/values-nb/strings.xml
@@ -401,6 +401,7 @@
     <string name="card_title_hanging_up" msgid="3999101620995182450">"Legger på"</string>
     <string name="card_title_in_call" msgid="6346543933068225205">"Samtale pågår"</string>
     <string name="card_title_my_phone_number" msgid="112428362494434191">"Nummeret mitt er <xliff:g id="MY_PHONE_NUMBER">%s</xliff:g>"</string>
+    <string name="notification_dialing" msgid="2107666444937350731">"Slår nummeret"</string>
     <string name="notification_missedCallTitle" msgid="7554385905572364535">"Tapt anrop"</string>
     <string name="notification_missedCallsTitle" msgid="1361677948941502522">"Tapte anrop"</string>
     <string name="notification_missedCallsMsg" msgid="4575787816055205600">"<xliff:g id="NUM_MISSED_CALLS">%s</xliff:g> tapte anrop"</string>
diff --git a/res/values-nl/strings.xml b/res/values-nl/strings.xml
index 3b981dc..efe72ba 100644
--- a/res/values-nl/strings.xml
+++ b/res/values-nl/strings.xml
@@ -395,6 +395,7 @@
     <string name="card_title_hanging_up" msgid="3999101620995182450">"Ophangen"</string>
     <string name="card_title_in_call" msgid="6346543933068225205">"Actieve oproep"</string>
     <string name="card_title_my_phone_number" msgid="112428362494434191">"Mijn nummer is <xliff:g id="MY_PHONE_NUMBER">%s</xliff:g>"</string>
+    <string name="notification_dialing" msgid="2107666444937350731">"Kiezen"</string>
     <string name="notification_missedCallTitle" msgid="7554385905572364535">"Gemiste oproep"</string>
     <string name="notification_missedCallsTitle" msgid="1361677948941502522">"Gemiste oproepen"</string>
     <string name="notification_missedCallsMsg" msgid="4575787816055205600">"<xliff:g id="NUM_MISSED_CALLS">%s</xliff:g> gemiste oproepen"</string>
diff --git a/res/values-pl/strings.xml b/res/values-pl/strings.xml
index 0a65331..15deb2e 100644
--- a/res/values-pl/strings.xml
+++ b/res/values-pl/strings.xml
@@ -395,6 +395,7 @@
     <string name="card_title_hanging_up" msgid="3999101620995182450">"Trwa rozłączanie"</string>
     <string name="card_title_in_call" msgid="6346543933068225205">"Trwa połączenie"</string>
     <string name="card_title_my_phone_number" msgid="112428362494434191">"Mój numer to <xliff:g id="MY_PHONE_NUMBER">%s</xliff:g>"</string>
+    <string name="notification_dialing" msgid="2107666444937350731">"Trwa wybieranie numeru"</string>
     <string name="notification_missedCallTitle" msgid="7554385905572364535">"Nieodebrane połączenie"</string>
     <string name="notification_missedCallsTitle" msgid="1361677948941502522">"Połączenia nieodebrane"</string>
     <string name="notification_missedCallsMsg" msgid="4575787816055205600">"<xliff:g id="NUM_MISSED_CALLS">%s</xliff:g> nieodebranych połączeń"</string>
diff --git a/res/values-pt-rPT/strings.xml b/res/values-pt-rPT/strings.xml
index e9a16ec..34fdc61 100644
--- a/res/values-pt-rPT/strings.xml
+++ b/res/values-pt-rPT/strings.xml
@@ -395,6 +395,7 @@
     <string name="card_title_hanging_up" msgid="3999101620995182450">"A desligar"</string>
     <string name="card_title_in_call" msgid="6346543933068225205">"A chamar"</string>
     <string name="card_title_my_phone_number" msgid="112428362494434191">"O meu número é <xliff:g id="MY_PHONE_NUMBER">%s</xliff:g>"</string>
+    <string name="notification_dialing" msgid="2107666444937350731">"A marcar"</string>
     <string name="notification_missedCallTitle" msgid="7554385905572364535">"Chamada não atendida"</string>
     <string name="notification_missedCallsTitle" msgid="1361677948941502522">"Chamadas não atendidas"</string>
     <string name="notification_missedCallsMsg" msgid="4575787816055205600">"<xliff:g id="NUM_MISSED_CALLS">%s</xliff:g> chamadas não atendidas"</string>
diff --git a/res/values-pt/strings.xml b/res/values-pt/strings.xml
index 05dc83f..177ba64 100644
--- a/res/values-pt/strings.xml
+++ b/res/values-pt/strings.xml
@@ -395,6 +395,7 @@
     <string name="card_title_hanging_up" msgid="3999101620995182450">"Desligando"</string>
     <string name="card_title_in_call" msgid="6346543933068225205">"Em chamada"</string>
     <string name="card_title_my_phone_number" msgid="112428362494434191">"Meu número é <xliff:g id="MY_PHONE_NUMBER">%s</xliff:g>"</string>
+    <string name="notification_dialing" msgid="2107666444937350731">"Discando"</string>
     <string name="notification_missedCallTitle" msgid="7554385905572364535">"Chamada perdida"</string>
     <string name="notification_missedCallsTitle" msgid="1361677948941502522">"Chamadas perdidas"</string>
     <string name="notification_missedCallsMsg" msgid="4575787816055205600">"<xliff:g id="NUM_MISSED_CALLS">%s</xliff:g> chamadas perdidas"</string>
diff --git a/res/values-rm/strings.xml b/res/values-rm/strings.xml
index 422022d..31002f9 100644
--- a/res/values-rm/strings.xml
+++ b/res/values-rm/strings.xml
@@ -463,6 +463,8 @@
     <string name="card_title_in_call" msgid="6346543933068225205">"Clom"</string>
     <!-- no translation found for card_title_my_phone_number (112428362494434191) -->
     <skip />
+    <!-- no translation found for notification_dialing (2107666444937350731) -->
+    <skip />
     <string name="notification_missedCallTitle" msgid="7554385905572364535">"Clom manchentà"</string>
     <string name="notification_missedCallsTitle" msgid="1361677948941502522">"Cloms manchentads"</string>
     <string name="notification_missedCallsMsg" msgid="4575787816055205600">"<xliff:g id="NUM_MISSED_CALLS">%s</xliff:g> cloms manchentads"</string>
diff --git a/res/values-ro/strings.xml b/res/values-ro/strings.xml
index 6840427..3611653 100644
--- a/res/values-ro/strings.xml
+++ b/res/values-ro/strings.xml
@@ -395,6 +395,7 @@
     <string name="card_title_hanging_up" msgid="3999101620995182450">"Se închide telefonul"</string>
     <string name="card_title_in_call" msgid="6346543933068225205">"În timpul apelului"</string>
     <string name="card_title_my_phone_number" msgid="112428362494434191">"Numărul meu este <xliff:g id="MY_PHONE_NUMBER">%s</xliff:g>"</string>
+    <string name="notification_dialing" msgid="2107666444937350731">"Apelează"</string>
     <string name="notification_missedCallTitle" msgid="7554385905572364535">"Apel nepreluat"</string>
     <string name="notification_missedCallsTitle" msgid="1361677948941502522">"Apeluri nepreluate"</string>
     <string name="notification_missedCallsMsg" msgid="4575787816055205600">"<xliff:g id="NUM_MISSED_CALLS">%s</xliff:g> (de) apeluri nepreluate"</string>
diff --git a/res/values-ru/strings.xml b/res/values-ru/strings.xml
index 8909248..ef165ee 100644
--- a/res/values-ru/strings.xml
+++ b/res/values-ru/strings.xml
@@ -397,6 +397,7 @@
     <string name="card_title_hanging_up" msgid="3999101620995182450">"Завершение разговора"</string>
     <string name="card_title_in_call" msgid="6346543933068225205">"Поступающий вызов"</string>
     <string name="card_title_my_phone_number" msgid="112428362494434191">"Мой номер: <xliff:g id="MY_PHONE_NUMBER">%s</xliff:g>"</string>
+    <string name="notification_dialing" msgid="2107666444937350731">"Набор номера"</string>
     <string name="notification_missedCallTitle" msgid="7554385905572364535">"Пропущенный вызов"</string>
     <string name="notification_missedCallsTitle" msgid="1361677948941502522">"Пропущенные вызовы"</string>
     <string name="notification_missedCallsMsg" msgid="4575787816055205600">"Пропущенных вызовов: <xliff:g id="NUM_MISSED_CALLS">%s</xliff:g>"</string>
diff --git a/res/values-sk/strings.xml b/res/values-sk/strings.xml
index 112e3bb..080a0b3 100644
--- a/res/values-sk/strings.xml
+++ b/res/values-sk/strings.xml
@@ -395,6 +395,7 @@
     <string name="card_title_hanging_up" msgid="3999101620995182450">"Ukončovanie hovoru"</string>
     <string name="card_title_in_call" msgid="6346543933068225205">"Prebieha hovor"</string>
     <string name="card_title_my_phone_number" msgid="112428362494434191">"Moje číslo je <xliff:g id="MY_PHONE_NUMBER">%s</xliff:g>"</string>
+    <string name="notification_dialing" msgid="2107666444937350731">"Vytáčanie"</string>
     <string name="notification_missedCallTitle" msgid="7554385905572364535">"Zmeškaný hovor"</string>
     <string name="notification_missedCallsTitle" msgid="1361677948941502522">"Zmeškané hovory"</string>
     <string name="notification_missedCallsMsg" msgid="4575787816055205600">"Zmeškané hovory: <xliff:g id="NUM_MISSED_CALLS">%s</xliff:g>."</string>
diff --git a/res/values-sl/strings.xml b/res/values-sl/strings.xml
index 368b43e..057993d 100644
--- a/res/values-sl/strings.xml
+++ b/res/values-sl/strings.xml
@@ -395,6 +395,7 @@
     <string name="card_title_hanging_up" msgid="3999101620995182450">"Prekinitev"</string>
     <string name="card_title_in_call" msgid="6346543933068225205">"Dohodni klic"</string>
     <string name="card_title_my_phone_number" msgid="112428362494434191">"Moja številka je <xliff:g id="MY_PHONE_NUMBER">%s</xliff:g>"</string>
+    <string name="notification_dialing" msgid="2107666444937350731">"Klicanje"</string>
     <string name="notification_missedCallTitle" msgid="7554385905572364535">"Neodgovorjeni klic"</string>
     <string name="notification_missedCallsTitle" msgid="1361677948941502522">"Neodgovorjeni klici"</string>
     <string name="notification_missedCallsMsg" msgid="4575787816055205600">"<xliff:g id="NUM_MISSED_CALLS">%s</xliff:g> neodgovorjenih klicev"</string>
diff --git a/res/values-sr/strings.xml b/res/values-sr/strings.xml
index a5a0f2c..6c47923 100644
--- a/res/values-sr/strings.xml
+++ b/res/values-sr/strings.xml
@@ -395,6 +395,7 @@
     <string name="card_title_hanging_up" msgid="3999101620995182450">"Прекид везе"</string>
     <string name="card_title_in_call" msgid="6346543933068225205">"Има позив"</string>
     <string name="card_title_my_phone_number" msgid="112428362494434191">"Мој број је <xliff:g id="MY_PHONE_NUMBER">%s</xliff:g>"</string>
+    <string name="notification_dialing" msgid="2107666444937350731">"Бирање"</string>
     <string name="notification_missedCallTitle" msgid="7554385905572364535">"Пропуштен позив"</string>
     <string name="notification_missedCallsTitle" msgid="1361677948941502522">"Пропуштени позиви"</string>
     <string name="notification_missedCallsMsg" msgid="4575787816055205600">"Број пропуштених позива: <xliff:g id="NUM_MISSED_CALLS">%s</xliff:g>"</string>
diff --git a/res/values-sv/strings.xml b/res/values-sv/strings.xml
index 1bc649e..e8366a4 100644
--- a/res/values-sv/strings.xml
+++ b/res/values-sv/strings.xml
@@ -401,6 +401,7 @@
     <string name="card_title_hanging_up" msgid="3999101620995182450">"Lägger på"</string>
     <string name="card_title_in_call" msgid="6346543933068225205">"I samtal"</string>
     <string name="card_title_my_phone_number" msgid="112428362494434191">"Mitt nummer är <xliff:g id="MY_PHONE_NUMBER">%s</xliff:g>"</string>
+    <string name="notification_dialing" msgid="2107666444937350731">"Ringer"</string>
     <string name="notification_missedCallTitle" msgid="7554385905572364535">"Missat samtal"</string>
     <string name="notification_missedCallsTitle" msgid="1361677948941502522">"Missade samtal"</string>
     <string name="notification_missedCallsMsg" msgid="4575787816055205600">"<xliff:g id="NUM_MISSED_CALLS">%s</xliff:g> missade samtal"</string>
diff --git a/res/values-sw/strings.xml b/res/values-sw/strings.xml
index 8de488f..f38b2a0 100644
--- a/res/values-sw/strings.xml
+++ b/res/values-sw/strings.xml
@@ -395,6 +395,7 @@
     <string name="card_title_hanging_up" msgid="3999101620995182450">"Kukata simu"</string>
     <string name="card_title_in_call" msgid="6346543933068225205">"Katika simu"</string>
     <string name="card_title_my_phone_number" msgid="112428362494434191">"Nambari yangu ni <xliff:g id="MY_PHONE_NUMBER">%s</xliff:g>"</string>
+    <string name="notification_dialing" msgid="2107666444937350731">"Inapiga"</string>
     <string name="notification_missedCallTitle" msgid="7554385905572364535">"Simu isiyojibiwa"</string>
     <string name="notification_missedCallsTitle" msgid="1361677948941502522">"Simu zisizojibiwa"</string>
     <string name="notification_missedCallsMsg" msgid="4575787816055205600">"<xliff:g id="NUM_MISSED_CALLS">%s</xliff:g> simu ambazo hazijajibiwa"</string>
diff --git a/res/values-th/strings.xml b/res/values-th/strings.xml
index a1b2dee..78f593d 100644
--- a/res/values-th/strings.xml
+++ b/res/values-th/strings.xml
@@ -395,6 +395,7 @@
     <string name="card_title_hanging_up" msgid="3999101620995182450">"กำลังวางสาย"</string>
     <string name="card_title_in_call" msgid="6346543933068225205">"กำลังใช้สาย"</string>
     <string name="card_title_my_phone_number" msgid="112428362494434191">"หมายเลขของฉันคือ <xliff:g id="MY_PHONE_NUMBER">%s</xliff:g>"</string>
+    <string name="notification_dialing" msgid="2107666444937350731">"กำลังโทรออก"</string>
     <string name="notification_missedCallTitle" msgid="7554385905572364535">"สายที่ไม่ได้รับ"</string>
     <string name="notification_missedCallsTitle" msgid="1361677948941502522">"สายที่ไม่ได้รับ"</string>
     <string name="notification_missedCallsMsg" msgid="4575787816055205600">"<xliff:g id="NUM_MISSED_CALLS">%s</xliff:g> สายที่ไม่ได้รับ"</string>
diff --git a/res/values-tl/strings.xml b/res/values-tl/strings.xml
index 2919f3d..eaa1968 100644
--- a/res/values-tl/strings.xml
+++ b/res/values-tl/strings.xml
@@ -395,6 +395,7 @@
     <string name="card_title_hanging_up" msgid="3999101620995182450">"Binababa"</string>
     <string name="card_title_in_call" msgid="6346543933068225205">"Nasa tawag"</string>
     <string name="card_title_my_phone_number" msgid="112428362494434191">"Ang aking numero ay <xliff:g id="MY_PHONE_NUMBER">%s</xliff:g>"</string>
+    <string name="notification_dialing" msgid="2107666444937350731">"Dina-dial"</string>
     <string name="notification_missedCallTitle" msgid="7554385905572364535">"Hindi nasagot na tawag"</string>
     <string name="notification_missedCallsTitle" msgid="1361677948941502522">"Mga hindi nasagot na tawag"</string>
     <string name="notification_missedCallsMsg" msgid="4575787816055205600">"<xliff:g id="NUM_MISSED_CALLS">%s</xliff:g> (na) hindi nasagot na tawag"</string>
diff --git a/res/values-tr/strings.xml b/res/values-tr/strings.xml
index 1567c0d..7f014a8 100644
--- a/res/values-tr/strings.xml
+++ b/res/values-tr/strings.xml
@@ -395,6 +395,7 @@
     <string name="card_title_hanging_up" msgid="3999101620995182450">"Sonlandırılıyor"</string>
     <string name="card_title_in_call" msgid="6346543933068225205">"Çağrı halinde"</string>
     <string name="card_title_my_phone_number" msgid="112428362494434191">"Numaram: <xliff:g id="MY_PHONE_NUMBER">%s</xliff:g>"</string>
+    <string name="notification_dialing" msgid="2107666444937350731">"Çevriliyor"</string>
     <string name="notification_missedCallTitle" msgid="7554385905572364535">"Cevapsız çağrı"</string>
     <string name="notification_missedCallsTitle" msgid="1361677948941502522">"Cevapsız çağrılar"</string>
     <string name="notification_missedCallsMsg" msgid="4575787816055205600">"<xliff:g id="NUM_MISSED_CALLS">%s</xliff:g> cevapsız çağrı"</string>
diff --git a/res/values-uk/strings.xml b/res/values-uk/strings.xml
index f92f403..068ba9e 100644
--- a/res/values-uk/strings.xml
+++ b/res/values-uk/strings.xml
@@ -395,6 +395,7 @@
     <string name="card_title_hanging_up" msgid="3999101620995182450">"Класти слухавку"</string>
     <string name="card_title_in_call" msgid="6346543933068225205">"Вхід. викл."</string>
     <string name="card_title_my_phone_number" msgid="112428362494434191">"Мій номер: <xliff:g id="MY_PHONE_NUMBER">%s</xliff:g>"</string>
+    <string name="notification_dialing" msgid="2107666444937350731">"Набір"</string>
     <string name="notification_missedCallTitle" msgid="7554385905572364535">"Пропущ. виклик"</string>
     <string name="notification_missedCallsTitle" msgid="1361677948941502522">"Пропущ. дзвінки"</string>
     <string name="notification_missedCallsMsg" msgid="4575787816055205600">"Пропущ. дзвінк: <xliff:g id="NUM_MISSED_CALLS">%s</xliff:g>"</string>
diff --git a/res/values-vi/strings.xml b/res/values-vi/strings.xml
index 5881f64..348819c 100644
--- a/res/values-vi/strings.xml
+++ b/res/values-vi/strings.xml
@@ -395,6 +395,7 @@
     <string name="card_title_hanging_up" msgid="3999101620995182450">"Kết thúc cuộc gọi"</string>
     <string name="card_title_in_call" msgid="6346543933068225205">"Đang trong cuộc gọi"</string>
     <string name="card_title_my_phone_number" msgid="112428362494434191">"Số điện thoại của tôi là <xliff:g id="MY_PHONE_NUMBER">%s</xliff:g>"</string>
+    <string name="notification_dialing" msgid="2107666444937350731">"Đang gọi"</string>
     <string name="notification_missedCallTitle" msgid="7554385905572364535">"Cuộc gọi nhỡ"</string>
     <string name="notification_missedCallsTitle" msgid="1361677948941502522">"Cuộc gọi nhỡ"</string>
     <string name="notification_missedCallsMsg" msgid="4575787816055205600">"<xliff:g id="NUM_MISSED_CALLS">%s</xliff:g> cuộc gọi nhỡ"</string>
diff --git a/res/values-zh-rCN/strings.xml b/res/values-zh-rCN/strings.xml
index 8896425..1d3aafa 100644
--- a/res/values-zh-rCN/strings.xml
+++ b/res/values-zh-rCN/strings.xml
@@ -395,6 +395,7 @@
     <string name="card_title_hanging_up" msgid="3999101620995182450">"正在挂断"</string>
     <string name="card_title_in_call" msgid="6346543933068225205">"正在通话"</string>
     <string name="card_title_my_phone_number" msgid="112428362494434191">"我的手机号码：<xliff:g id="MY_PHONE_NUMBER">%s</xliff:g>"</string>
+    <string name="notification_dialing" msgid="2107666444937350731">"正在拨号"</string>
     <string name="notification_missedCallTitle" msgid="7554385905572364535">"未接电话"</string>
     <string name="notification_missedCallsTitle" msgid="1361677948941502522">"未接电话"</string>
     <string name="notification_missedCallsMsg" msgid="4575787816055205600">"<xliff:g id="NUM_MISSED_CALLS">%s</xliff:g> 个未接电话"</string>
diff --git a/res/values-zh-rTW/strings.xml b/res/values-zh-rTW/strings.xml
index c0d1ae1..f17a251 100644
--- a/res/values-zh-rTW/strings.xml
+++ b/res/values-zh-rTW/strings.xml
@@ -401,6 +401,7 @@
     <string name="card_title_hanging_up" msgid="3999101620995182450">"掛斷電話"</string>
     <string name="card_title_in_call" msgid="6346543933068225205">"通話中"</string>
     <string name="card_title_my_phone_number" msgid="112428362494434191">"我的電話號碼：<xliff:g id="MY_PHONE_NUMBER">%s</xliff:g>"</string>
+    <string name="notification_dialing" msgid="2107666444937350731">"撥號中"</string>
     <string name="notification_missedCallTitle" msgid="7554385905572364535">"未接來電"</string>
     <string name="notification_missedCallsTitle" msgid="1361677948941502522">"未接來電"</string>
     <string name="notification_missedCallsMsg" msgid="4575787816055205600">"<xliff:g id="NUM_MISSED_CALLS">%s</xliff:g> 通未接來電"</string>
diff --git a/res/values-zu/strings.xml b/res/values-zu/strings.xml
index 518d029..d2db86f 100644
--- a/res/values-zu/strings.xml
+++ b/res/values-zu/strings.xml
@@ -399,6 +399,7 @@
     <string name="card_title_hanging_up" msgid="3999101620995182450">"Iyavala"</string>
     <string name="card_title_in_call" msgid="6346543933068225205">"Isecingweni"</string>
     <string name="card_title_my_phone_number" msgid="112428362494434191">"Inombolo yami ngu <xliff:g id="MY_PHONE_NUMBER">%s</xliff:g>"</string>
+    <string name="notification_dialing" msgid="2107666444937350731">"Iyadayela"</string>
     <string name="notification_missedCallTitle" msgid="7554385905572364535">"Ikholi ekulahlekele"</string>
     <string name="notification_missedCallsTitle" msgid="1361677948941502522">"Izincingo ezikulahlekele"</string>
     <string name="notification_missedCallsMsg" msgid="4575787816055205600">"<xliff:g id="NUM_MISSED_CALLS">%s</xliff:g> amakholi akulahlekele"</string>
diff --git a/res/values/dimens.xml b/res/values/dimens.xml
index 97a1496..5adfe52 100644
--- a/res/values/dimens.xml
+++ b/res/values/dimens.xml
@@ -41,7 +41,7 @@
     <!-- Height of the main row of in-call buttons. -->
     <dimen name="in_call_button_height">76dp</dimen>
 
-    <!-- Height of the in-call "End" button. -->
+    <!-- Height of the in-call "End" button. Match with Contact's dimens/call_button_height -->
     <dimen name="in_call_end_button_height">74dp</dimen>
 
     <!-- Width of buttons in the extra button row. -->
@@ -69,8 +69,12 @@
     <dimen name="dialpad_horizontal_margin">4dp</dimen>
     <dimen name="dialpad_vertical_margin">2dp</dimen>
     <dimen name="dialpad_digits_text_size">35sp</dimen>
+
     <!-- Just used in landscape mode -->
     <dimen name="emergency_dialer_digits_height">0px</dimen>
+    <dimen name="dialpad_center_margin">3dp</dimen>
+    <dimen name="dialpad_button_margin">3dp</dimen>
+
 
     <!-- Layout weight values for dialpad screen. These layouts will be used in one
          LinearLayout (dialpad_fragment.xml), configuring dialpad screen's vertical
diff --git a/res/values/strings.xml b/res/values/strings.xml
index fe0c5d6..a051173 100755
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -786,6 +786,9 @@
     <string name="card_title_my_phone_number">My number is <xliff:g id="my_phone_number">%s</xliff:g></string>
 
     <!-- Notification strings -->
+    <!-- The "label" of the in-call Notification for a dialing call, used
+         as the format string for a Chronometer widget. [CHAR LIMIT=60] -->
+    <string name="notification_dialing">Dialing</string>
     <!-- Missed call notification label, used when there's exactly one missed call -->
     <string name="notification_missedCallTitle">Missed call</string>
     <!-- Missed call notification label, used when there are two or more missed calls -->
diff --git a/res/values/styles.xml b/res/values/styles.xml
index 798cf07..28fb8f2 100644
--- a/res/values/styles.xml
+++ b/res/values/styles.xml
@@ -238,4 +238,18 @@
         <item name="android:editable">true</item>
         <item name="android:cursorVisible">false</item>
     </style>
+
+    <style name="PrimaryCallInfoPrimaryCallBanner">
+        <item name="android:layout_alignParentTop">true</item>
+    </style>
+    <style name="PrimaryCallInfoSecondaryInfoContainer">
+        <item name="android:layout_below">@id/primary_call_banner</item>
+    </style>
+
+    <style name="SecondaryCallInfoSecondaryCallName">
+        <item name="android:layout_gravity">top|left</item>
+    </style>
+    <style name="SecondaryCallInfoSecondaryCallStatus">
+        <item name="android:layout_gravity">top|right</item>
+    </style>
 </resources>
diff --git a/src/com/android/phone/BitmapUtils.java b/src/com/android/phone/BitmapUtils.java
index 0b8ba99..94d4bf9 100644
--- a/src/com/android/phone/BitmapUtils.java
+++ b/src/com/android/phone/BitmapUtils.java
@@ -28,7 +28,7 @@
 public class BitmapUtils {
     private static final String TAG = "BitmapUtils";
     private static final boolean DBG =
-            (PhoneApp.DBG_LEVEL >= 1) && (SystemProperties.getInt("ro.debuggable", 0) == 1);
+            (PhoneGlobals.DBG_LEVEL >= 1) && (SystemProperties.getInt("ro.debuggable", 0) == 1);
 
     /** This class is never instantiated. */
     private BitmapUtils() {
diff --git a/src/com/android/phone/BluetoothAtPhonebook.java b/src/com/android/phone/BluetoothAtPhonebook.java
deleted file mode 100644
index c9669c4..0000000
--- a/src/com/android/phone/BluetoothAtPhonebook.java
+++ /dev/null
@@ -1,529 +0,0 @@
-/*
- * Copyright (C) 2008 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 com.android.internal.telephony.GsmAlphabet;
-
-import android.bluetooth.AtCommandHandler;
-import android.bluetooth.AtCommandResult;
-import android.bluetooth.AtParser;
-import android.bluetooth.BluetoothDevice;
-import android.bluetooth.HeadsetBase;
-import android.content.Context;
-import android.content.Intent;
-import android.database.Cursor;
-import android.net.Uri;
-import android.provider.CallLog.Calls;
-import android.provider.ContactsContract.CommonDataKinds.Phone;
-import android.provider.ContactsContract.PhoneLookup;
-import android.telephony.PhoneNumberUtils;
-import android.util.Log;
-
-import java.util.HashMap;
-
-/**
- * Helper for managing phonebook presentation over AT commands
- * @hide
- */
-public class BluetoothAtPhonebook {
-    private static final String TAG = "BluetoothAtPhonebook";
-    private static final boolean DBG = false;
-
-    /** The projection to use when querying the call log database in response
-     *  to AT+CPBR for the MC, RC, and DC phone books (missed, received, and
-     *   dialed calls respectively)
-     */
-    private static final String[] CALLS_PROJECTION = new String[] {
-        Calls._ID, Calls.NUMBER
-    };
-
-    /** The projection to use when querying the contacts database in response
-     *   to AT+CPBR for the ME phonebook (saved phone numbers).
-     */
-    private static final String[] PHONES_PROJECTION = new String[] {
-        Phone._ID, Phone.DISPLAY_NAME, Phone.NUMBER, Phone.TYPE
-    };
-
-    /** Android supports as many phonebook entries as the flash can hold, but
-     *  BT periphals don't. Limit the number we'll report. */
-    private static final int MAX_PHONEBOOK_SIZE = 16384;
-
-    private static final String OUTGOING_CALL_WHERE = Calls.TYPE + "=" + Calls.OUTGOING_TYPE;
-    private static final String INCOMING_CALL_WHERE = Calls.TYPE + "=" + Calls.INCOMING_TYPE;
-    private static final String MISSED_CALL_WHERE = Calls.TYPE + "=" + Calls.MISSED_TYPE;
-    private static final String VISIBLE_PHONEBOOK_WHERE = Phone.IN_VISIBLE_GROUP + "=1";
-
-    private class PhonebookResult {
-        public Cursor  cursor; // result set of last query
-        public int     numberColumn;
-        public int     typeColumn;
-        public int     nameColumn;
-    };
-
-    private final Context mContext;
-    private final BluetoothHandsfree mHandsfree;
-
-    private String mCurrentPhonebook;
-    private String mCharacterSet = "UTF-8";
-
-    private int mCpbrIndex1, mCpbrIndex2;
-    private boolean mCheckingAccessPermission;
-
-    // package and class name to which we send intent to check phone book access permission
-    private static final String ACCESS_AUTHORITY_PACKAGE = "com.android.settings";
-    private static final String ACCESS_AUTHORITY_CLASS =
-        "com.android.settings.bluetooth.BluetoothPermissionRequest";
-    private static final String BLUETOOTH_ADMIN_PERM = android.Manifest.permission.BLUETOOTH_ADMIN;
-
-    private final HashMap<String, PhonebookResult> mPhonebooks =
-            new HashMap<String, PhonebookResult>(4);
-
-    public BluetoothAtPhonebook(Context context, BluetoothHandsfree handsfree) {
-        mContext = context;
-        mHandsfree = handsfree;
-        mPhonebooks.put("DC", new PhonebookResult());  // dialled calls
-        mPhonebooks.put("RC", new PhonebookResult());  // received calls
-        mPhonebooks.put("MC", new PhonebookResult());  // missed calls
-        mPhonebooks.put("ME", new PhonebookResult());  // mobile phonebook
-
-        mCurrentPhonebook = "ME";  // default to mobile phonebook
-
-        mCpbrIndex1 = mCpbrIndex2 = -1;
-        mCheckingAccessPermission = false;
-    }
-
-    /** Returns the last dialled number, or null if no numbers have been called */
-    public String getLastDialledNumber() {
-        String[] projection = {Calls.NUMBER};
-        Cursor cursor = mContext.getContentResolver().query(Calls.CONTENT_URI, projection,
-                Calls.TYPE + "=" + Calls.OUTGOING_TYPE, null, Calls.DEFAULT_SORT_ORDER +
-                " LIMIT 1");
-        if (cursor == null) return null;
-
-        if (cursor.getCount() < 1) {
-            cursor.close();
-            return null;
-        }
-        cursor.moveToNext();
-        int column = cursor.getColumnIndexOrThrow(Calls.NUMBER);
-        String number = cursor.getString(column);
-        cursor.close();
-        return number;
-    }
-
-    public void register(AtParser parser) {
-        // Select Character Set
-        parser.register("+CSCS", new AtCommandHandler() {
-            @Override
-            public AtCommandResult handleReadCommand() {
-                String result = "+CSCS: \"" + mCharacterSet + "\"";
-                return new AtCommandResult(result);
-            }
-            @Override
-            public AtCommandResult handleSetCommand(Object[] args) {
-                if (args.length < 1) {
-                    return new AtCommandResult(AtCommandResult.ERROR);
-                }
-                String characterSet = (String)args[0];
-                characterSet = characterSet.replace("\"", "");
-                if (characterSet.equals("GSM") || characterSet.equals("IRA") ||
-                    characterSet.equals("UTF-8") || characterSet.equals("UTF8")) {
-                    mCharacterSet = characterSet;
-                    return new AtCommandResult(AtCommandResult.OK);
-                } else {
-                    return mHandsfree.reportCmeError(BluetoothCmeError.OPERATION_NOT_SUPPORTED);
-                }
-            }
-            @Override
-            public AtCommandResult handleTestCommand() {
-                return new AtCommandResult( "+CSCS: (\"UTF-8\",\"IRA\",\"GSM\")");
-            }
-        });
-
-        // Select PhoneBook memory Storage
-        parser.register("+CPBS", new AtCommandHandler() {
-            @Override
-            public AtCommandResult handleReadCommand() {
-                // Return current size and max size
-                if ("SM".equals(mCurrentPhonebook)) {
-                    return new AtCommandResult("+CPBS: \"SM\",0," + getMaxPhoneBookSize(0));
-                }
-
-                PhonebookResult pbr = getPhonebookResult(mCurrentPhonebook, true);
-                if (pbr == null) {
-                    return mHandsfree.reportCmeError(BluetoothCmeError.OPERATION_NOT_ALLOWED);
-                }
-                int size = pbr.cursor.getCount();
-                return new AtCommandResult("+CPBS: \"" + mCurrentPhonebook + "\"," +
-                        size + "," + getMaxPhoneBookSize(size));
-            }
-            @Override
-            public AtCommandResult handleSetCommand(Object[] args) {
-                // Select phonebook memory
-                if (args.length < 1 || !(args[0] instanceof String)) {
-                    return new AtCommandResult(AtCommandResult.ERROR);
-                }
-                String pb = ((String)args[0]).trim();
-                while (pb.endsWith("\"")) pb = pb.substring(0, pb.length() - 1);
-                while (pb.startsWith("\"")) pb = pb.substring(1, pb.length());
-                if (getPhonebookResult(pb, false) == null && !"SM".equals(pb)) {
-                    if (DBG) log("Dont know phonebook: '" + pb + "'");
-                    return mHandsfree.reportCmeError(BluetoothCmeError.OPERATION_NOT_SUPPORTED);
-                }
-                mCurrentPhonebook = pb;
-                return new AtCommandResult(AtCommandResult.OK);
-            }
-            @Override
-            public AtCommandResult handleTestCommand() {
-                return new AtCommandResult("+CPBS: (\"ME\",\"SM\",\"DC\",\"RC\",\"MC\")");
-            }
-        });
-
-        // Read PhoneBook Entries
-        parser.register("+CPBR", new AtCommandHandler() {
-            @Override
-            public AtCommandResult handleSetCommand(Object[] args) {
-                // Phone Book Read Request
-                // AT+CPBR=<index1>[,<index2>]
-
-                if (mCpbrIndex1 != -1) {
-                    /* handling a CPBR at the moment, reject this CPBR command */
-                    return mHandsfree.reportCmeError(BluetoothCmeError.OPERATION_NOT_ALLOWED);
-                }
-
-                // Parse indexes
-                int index1;
-                int index2;
-                if (args.length < 1 || !(args[0] instanceof Integer)) {
-                    return new AtCommandResult(AtCommandResult.ERROR);
-                } else {
-                    index1 = (Integer)args[0];
-                }
-
-                if (args.length == 1) {
-                    index2 = index1;
-                } else if (!(args[1] instanceof Integer)) {
-                    return mHandsfree.reportCmeError(BluetoothCmeError.TEXT_HAS_INVALID_CHARS);
-                } else {
-                    index2 = (Integer)args[1];
-                }
-
-                mCpbrIndex1 = index1;
-                mCpbrIndex2 = index2;
-                mCheckingAccessPermission = true;
-
-                if (checkAccessPermission()) {
-                    mCheckingAccessPermission = false;
-                    AtCommandResult atResult = processCpbrCommand();
-                    mCpbrIndex1 = mCpbrIndex2 = -1;
-                    return atResult;
-                }
-
-                // no reponse here, will continue the process in handleAccessPermissionResult
-                return new AtCommandResult(AtCommandResult.UNSOLICITED);
-            };
-
-            @Override
-            public AtCommandResult handleTestCommand() {
-                /* Ideally we should return the maximum range of valid index's
-                 * for the selected phone book, but this causes problems for the
-                 * Parrot CK3300. So instead send just the range of currently
-                 * valid index's.
-                 */
-                int size;
-                if ("SM".equals(mCurrentPhonebook)) {
-                    size = 0;
-                } else {
-                    PhonebookResult pbr = getPhonebookResult(mCurrentPhonebook, false);
-                    if (pbr == null) {
-                        return mHandsfree.reportCmeError(BluetoothCmeError.OPERATION_NOT_ALLOWED);
-                    }
-                    size = pbr.cursor.getCount();
-                }
-
-                if (size == 0) {
-                    /* Sending "+CPBR: (1-0)" can confused some carkits, send "1-1"
-                     * instead */
-                    size = 1;
-                }
-                return new AtCommandResult("+CPBR: (1-" + size + "),30,30");
-            }
-        });
-    }
-
-    /* package */ void handleAccessPermissionResult(Intent intent) {
-        if (!mCheckingAccessPermission) {
-            return;
-        }
-
-        HeadsetBase headset = mHandsfree.getHeadset();
-        // ASSERT: (headset != null) && headSet.isConnected()
-        // REASON: mCheckingAccessPermission is true, otherwise resetAtState
-        //         has set mCheckingAccessPermission to false
-
-        if (intent.getAction().equals(BluetoothDevice.ACTION_CONNECTION_ACCESS_REPLY)) {
-
-            if (intent.getIntExtra(BluetoothDevice.EXTRA_CONNECTION_ACCESS_RESULT,
-                                   BluetoothDevice.CONNECTION_ACCESS_NO) ==
-                BluetoothDevice.CONNECTION_ACCESS_YES) {
-                BluetoothDevice remoteDevice = headset.getRemoteDevice();
-                if (intent.getBooleanExtra(BluetoothDevice.EXTRA_ALWAYS_ALLOWED, false)) {
-                    remoteDevice.setTrust(true);
-                }
-
-                AtCommandResult cpbrResult = processCpbrCommand();
-                headset.sendURC(cpbrResult.toString());
-            } else {
-                headset.sendURC("ERROR");
-            }
-        }
-        mCpbrIndex1 = mCpbrIndex2 = -1;
-        mCheckingAccessPermission = false;
-    }
-
-    /** Get the most recent result for the given phone book,
-     *  with the cursor ready to go.
-     *  If force then re-query that phonebook
-     *  Returns null if the cursor is not ready
-     */
-    private synchronized PhonebookResult getPhonebookResult(String pb, boolean force) {
-        if (pb == null) {
-            return null;
-        }
-        PhonebookResult pbr = mPhonebooks.get(pb);
-        if (pbr == null) {
-            pbr = new PhonebookResult();
-        }
-        if (force || pbr.cursor == null) {
-            if (!queryPhonebook(pb, pbr)) {
-                return null;
-            }
-        }
-
-        return pbr;
-    }
-
-    private synchronized boolean queryPhonebook(String pb, PhonebookResult pbr) {
-        String where;
-        boolean ancillaryPhonebook = true;
-
-        if (pb.equals("ME")) {
-            ancillaryPhonebook = false;
-            where = VISIBLE_PHONEBOOK_WHERE;
-        } else if (pb.equals("DC")) {
-            where = OUTGOING_CALL_WHERE;
-        } else if (pb.equals("RC")) {
-            where = INCOMING_CALL_WHERE;
-        } else if (pb.equals("MC")) {
-            where = MISSED_CALL_WHERE;
-        } else {
-            return false;
-        }
-
-        if (pbr.cursor != null) {
-            pbr.cursor.close();
-            pbr.cursor = null;
-        }
-
-        if (ancillaryPhonebook) {
-            pbr.cursor = mContext.getContentResolver().query(
-                    Calls.CONTENT_URI, CALLS_PROJECTION, where, null,
-                    Calls.DEFAULT_SORT_ORDER + " LIMIT " + MAX_PHONEBOOK_SIZE);
-            if (pbr.cursor == null) return false;
-
-            pbr.numberColumn = pbr.cursor.getColumnIndexOrThrow(Calls.NUMBER);
-            pbr.typeColumn = -1;
-            pbr.nameColumn = -1;
-        } else {
-            pbr.cursor = mContext.getContentResolver().query(Phone.CONTENT_URI, PHONES_PROJECTION,
-                    where, null, Phone.NUMBER + " LIMIT " + MAX_PHONEBOOK_SIZE);
-            if (pbr.cursor == null) return false;
-
-            pbr.numberColumn = pbr.cursor.getColumnIndex(Phone.NUMBER);
-            pbr.typeColumn = pbr.cursor.getColumnIndex(Phone.TYPE);
-            pbr.nameColumn = pbr.cursor.getColumnIndex(Phone.DISPLAY_NAME);
-        }
-        Log.i(TAG, "Refreshed phonebook " + pb + " with " + pbr.cursor.getCount() + " results");
-        return true;
-    }
-
-    synchronized void resetAtState() {
-        mCharacterSet = "UTF-8";
-        mCpbrIndex1 = mCpbrIndex2 = -1;
-        mCheckingAccessPermission = false;
-    }
-
-    private synchronized int getMaxPhoneBookSize(int currSize) {
-        // some car kits ignore the current size and request max phone book
-        // size entries. Thus, it takes a long time to transfer all the
-        // entries. Use a heuristic to calculate the max phone book size
-        // considering future expansion.
-        // maxSize = currSize + currSize / 2 rounded up to nearest power of 2
-        // If currSize < 100, use 100 as the currSize
-
-        int maxSize = (currSize < 100) ? 100 : currSize;
-        maxSize += maxSize / 2;
-        return roundUpToPowerOfTwo(maxSize);
-    }
-
-    private int roundUpToPowerOfTwo(int x) {
-        x |= x >> 1;
-        x |= x >> 2;
-        x |= x >> 4;
-        x |= x >> 8;
-        x |= x >> 16;
-        return x + 1;
-    }
-
-    // process CPBR command after permission check
-    private AtCommandResult processCpbrCommand()
-    {
-        // Shortcut SM phonebook
-        if ("SM".equals(mCurrentPhonebook)) {
-            return new AtCommandResult(AtCommandResult.OK);
-        }
-
-        // Check phonebook
-        PhonebookResult pbr = getPhonebookResult(mCurrentPhonebook, false);
-        if (pbr == null) {
-            return mHandsfree.reportCmeError(BluetoothCmeError.OPERATION_NOT_ALLOWED);
-        }
-
-        // More sanity checks
-        // Send OK instead of ERROR if these checks fail.
-        // When we send error, certain kits like BMW disconnect the
-        // Handsfree connection.
-        if (pbr.cursor.getCount() == 0 || mCpbrIndex1 <= 0 || mCpbrIndex2 < mCpbrIndex1  ||
-            mCpbrIndex2 > pbr.cursor.getCount() || mCpbrIndex1 > pbr.cursor.getCount()) {
-            return new AtCommandResult(AtCommandResult.OK);
-        }
-
-        // Process
-        AtCommandResult result = new AtCommandResult(AtCommandResult.OK);
-        int errorDetected = -1; // no error
-        pbr.cursor.moveToPosition(mCpbrIndex1 - 1);
-        for (int index = mCpbrIndex1; index <= mCpbrIndex2; index++) {
-            String number = pbr.cursor.getString(pbr.numberColumn);
-            String name = null;
-            int type = -1;
-            if (pbr.nameColumn == -1) {
-                // try caller id lookup
-                // TODO: This code is horribly inefficient. I saw it
-                // take 7 seconds to process 100 missed calls.
-                Cursor c = mContext.getContentResolver().
-                    query(Uri.withAppendedPath(PhoneLookup.CONTENT_FILTER_URI, number),
-                          new String[] {PhoneLookup.DISPLAY_NAME, PhoneLookup.TYPE},
-                          null, null, null);
-                if (c != null) {
-                    if (c.moveToFirst()) {
-                        name = c.getString(0);
-                        type = c.getInt(1);
-                    }
-                    c.close();
-                }
-                if (DBG && name == null) log("Caller ID lookup failed for " + number);
-
-            } else {
-                name = pbr.cursor.getString(pbr.nameColumn);
-            }
-            if (name == null) name = "";
-            name = name.trim();
-            if (name.length() > 28) name = name.substring(0, 28);
-
-            if (pbr.typeColumn != -1) {
-                type = pbr.cursor.getInt(pbr.typeColumn);
-                name = name + "/" + getPhoneType(type);
-            }
-
-            if (number == null) number = "";
-            int regionType = PhoneNumberUtils.toaFromString(number);
-
-            number = number.trim();
-            number = PhoneNumberUtils.stripSeparators(number);
-            if (number.length() > 30) number = number.substring(0, 30);
-            if (number.equals("-1")) {
-                // unknown numbers are stored as -1 in our database
-                number = "";
-                name = mContext.getString(R.string.unknown);
-            }
-
-            // TODO(): Handle IRA commands. It's basically
-            // a 7 bit ASCII character set.
-            if (!name.equals("") && mCharacterSet.equals("GSM")) {
-                byte[] nameByte = GsmAlphabet.stringToGsm8BitPacked(name);
-                if (nameByte == null) {
-                    name = mContext.getString(R.string.unknown);
-                } else {
-                    name = new String(nameByte);
-                }
-            }
-
-            result.addResponse("+CPBR: " + index + ",\"" + number + "\"," +
-                               regionType + ",\"" + name + "\"");
-            if (!pbr.cursor.moveToNext()) {
-                break;
-            }
-        }
-        return result;
-    }
-
-    // Check if the remote device has premission to read our phone book
-    // Return true if it has the permission
-    //        false if not known and we have sent our Intent to check
-    private boolean checkAccessPermission() {
-        BluetoothDevice remoteDevice = mHandsfree.getHeadset().getRemoteDevice();
-
-        boolean trust = remoteDevice.getTrustState();
-
-        if (trust) {
-            return true;
-        }
-
-        Intent intent = new Intent(BluetoothDevice.ACTION_CONNECTION_ACCESS_REQUEST);
-        intent.setClassName(ACCESS_AUTHORITY_PACKAGE, ACCESS_AUTHORITY_CLASS);
-        intent.putExtra(BluetoothDevice.EXTRA_ACCESS_REQUEST_TYPE,
-                        BluetoothDevice.REQUEST_TYPE_PHONEBOOK_ACCESS);
-        intent.putExtra(BluetoothDevice.EXTRA_DEVICE, remoteDevice);
-        // Leave EXTRA_PACKAGE_NAME and EXTRA_CLASS_NAME field empty
-        // BluetoothHandsfree's broadcast receiver is anonymous, cannot be targeted
-        mContext.sendBroadcast(intent, BLUETOOTH_ADMIN_PERM);
-
-        return false;
-    }
-
-    private static String getPhoneType(int type) {
-        switch (type) {
-            case Phone.TYPE_HOME:
-                return "H";
-            case Phone.TYPE_MOBILE:
-                return "M";
-            case Phone.TYPE_WORK:
-                return "W";
-            case Phone.TYPE_FAX_HOME:
-            case Phone.TYPE_FAX_WORK:
-                return "F";
-            case Phone.TYPE_OTHER:
-            case Phone.TYPE_CUSTOM:
-            default:
-                return "O";
-        }
-    }
-
-    private static void log(String msg) {
-        Log.d(TAG, msg);
-    }
-}
diff --git a/src/com/android/phone/BluetoothCmeError.java b/src/com/android/phone/BluetoothCmeError.java
deleted file mode 100644
index aa5e887..0000000
--- a/src/com/android/phone/BluetoothCmeError.java
+++ /dev/null
@@ -1,43 +0,0 @@
-/*
- * Copyright (C) 2008 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;
-
-/* Constants for extended AT error codes specified by the Handsfree profile. */
-public class BluetoothCmeError {
-    public static final int AG_FAILURE = 0;
-    public static final int NO_CONNECTION_TO_PHONE = 1;
-    public static final int OPERATION_NOT_ALLOWED = 3;
-    public static final int OPERATION_NOT_SUPPORTED = 4;
-    public static final int PIN_REQUIRED = 5;
-    public static final int SIM_MISSING = 10;
-    public static final int SIM_PIN_REQUIRED = 11;
-    public static final int SIM_PUK_REQUIRED = 12;
-    public static final int SIM_FAILURE = 13;
-    public static final int SIM_BUSY = 14;
-    public static final int WRONG_PASSWORD = 16;
-    public static final int SIM_PIN2_REQUIRED = 17;
-    public static final int SIM_PUK2_REQUIRED = 18;
-    public static final int MEMORY_FULL = 20;
-    public static final int INVALID_INDEX = 21;
-    public static final int MEMORY_FAILURE = 23;
-    public static final int TEXT_TOO_LONG = 24;
-    public static final int TEXT_HAS_INVALID_CHARS = 25;
-    public static final int DIAL_STRING_TOO_LONG = 26;
-    public static final int DIAL_STRING_HAS_INVALID_CHARS = 27;
-    public static final int NO_SERVICE = 30;
-    public static final int ONLY_911_ALLOWED = 32;
-}
diff --git a/src/com/android/phone/BluetoothHandsfree.java b/src/com/android/phone/BluetoothHandsfree.java
deleted file mode 100755
index 5845397..0000000
--- a/src/com/android/phone/BluetoothHandsfree.java
+++ /dev/null
@@ -1,3071 +0,0 @@
-/*
- * Copyright (C) 2008 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.bluetooth.AtCommandHandler;
-import android.bluetooth.AtCommandResult;
-import android.bluetooth.AtParser;
-import android.bluetooth.BluetoothA2dp;
-import android.bluetooth.BluetoothAssignedNumbers;
-import android.bluetooth.BluetoothAdapter;
-import android.bluetooth.BluetoothDevice;
-import android.bluetooth.BluetoothHeadset;
-import android.bluetooth.BluetoothProfile;
-import android.bluetooth.BluetoothServerSocket;
-import android.bluetooth.BluetoothSocket;
-import android.bluetooth.HeadsetBase;
-import android.content.ActivityNotFoundException;
-import android.content.BroadcastReceiver;
-import android.content.Context;
-import android.content.Intent;
-import android.content.IntentFilter;
-import android.media.AudioManager;
-import android.net.Uri;
-import android.os.AsyncResult;
-import android.os.Bundle;
-import android.os.Handler;
-import android.os.HandlerThread;
-import android.os.Looper;
-import android.os.Message;
-import android.os.PowerManager;
-import android.os.PowerManager.WakeLock;
-import android.os.SystemProperties;
-import android.telephony.PhoneNumberUtils;
-import android.telephony.ServiceState;
-import android.telephony.SignalStrength;
-import android.telephony.TelephonyManager;
-import android.util.Log;
-
-import com.android.internal.telephony.Call;
-import com.android.internal.telephony.Connection;
-import com.android.internal.telephony.Phone;
-import com.android.internal.telephony.PhoneConstants;
-import com.android.internal.telephony.TelephonyIntents;
-import com.android.internal.telephony.CallManager;
-
-import java.io.IOException;
-import java.io.InputStream;
-import java.util.LinkedList;
-
-/**
- * Bluetooth headset manager for the Phone app.
- * @hide
- */
-public class BluetoothHandsfree {
-    private static final String TAG = "Bluetooth HS/HF";
-    private static final boolean DBG = (PhoneApp.DBG_LEVEL >= 1)
-            && (SystemProperties.getInt("ro.debuggable", 0) == 1);
-    private static final boolean VDBG = (PhoneApp.DBG_LEVEL >= 2);  // even more logging
-
-    public static final int TYPE_UNKNOWN           = 0;
-    public static final int TYPE_HEADSET           = 1;
-    public static final int TYPE_HANDSFREE         = 2;
-
-    /** The singleton instance. */
-    private static BluetoothHandsfree sInstance;
-
-    private final Context mContext;
-    private final BluetoothAdapter mAdapter;
-    private final CallManager mCM;
-    private BluetoothA2dp mA2dp;
-
-    private BluetoothDevice mA2dpDevice;
-    private int mA2dpState;
-    private boolean mPendingAudioState;
-    private int mAudioState;
-
-    private ServiceState mServiceState;
-    private HeadsetBase mHeadset;
-    private BluetoothHeadset mBluetoothHeadset;
-    private int mHeadsetType;   // TYPE_UNKNOWN when not connected
-    private boolean mAudioPossible;
-    private BluetoothSocket mConnectedSco;
-
-    private IncomingScoAcceptThread mIncomingScoThread = null;
-    private ScoSocketConnectThread mConnectScoThread = null;
-    private SignalScoCloseThread mSignalScoCloseThread = null;
-
-    private AudioManager mAudioManager;
-    private PowerManager mPowerManager;
-
-    private boolean mPendingSco;  // waiting for a2dp sink to suspend before establishing SCO
-    private boolean mA2dpSuspended;
-    private boolean mUserWantsAudio;
-    private WakeLock mStartCallWakeLock;  // held while waiting for the intent to start call
-    private WakeLock mStartVoiceRecognitionWakeLock;  // held while waiting for voice recognition
-
-    // AT command state
-    private static final int GSM_MAX_CONNECTIONS = 6;  // Max connections allowed by GSM
-    private static final int CDMA_MAX_CONNECTIONS = 2;  // Max connections allowed by CDMA
-
-    private long mBgndEarliestConnectionTime = 0;
-    private boolean mClip = false;  // Calling Line Information Presentation
-    private boolean mIndicatorsEnabled = false;
-    private boolean mCmee = false;  // Extended Error reporting
-    private long[] mClccTimestamps; // Timestamps associated with each clcc index
-    private boolean[] mClccUsed;     // Is this clcc index in use
-    private boolean mWaitingForCallStart;
-    private boolean mWaitingForVoiceRecognition;
-    // do not connect audio until service connection is established
-    // for 3-way supported devices, this is after AT+CHLD
-    // for non-3-way supported devices, this is after AT+CMER (see spec)
-    private boolean mServiceConnectionEstablished;
-
-    private final BluetoothPhoneState mBluetoothPhoneState;  // for CIND and CIEV updates
-    private final BluetoothAtPhonebook mPhonebook;
-    private PhoneConstants.State mPhoneState = PhoneConstants.State.IDLE;
-    CdmaPhoneCallState.PhoneCallState mCdmaThreeWayCallState =
-                                            CdmaPhoneCallState.PhoneCallState.IDLE;
-
-    private DebugThread mDebugThread;
-    private int mScoGain = Integer.MIN_VALUE;
-
-    private static Intent sVoiceCommandIntent;
-
-    // Audio parameters
-    private static final String HEADSET_NREC = "bt_headset_nrec";
-    private static final String HEADSET_NAME = "bt_headset_name";
-
-    private int mRemoteBrsf = 0;
-    private int mLocalBrsf = 0;
-
-    // CDMA specific flag used in context with BT devices having display capabilities
-    // to show which Caller is active. This state might not be always true as in CDMA
-    // networks if a caller drops off no update is provided to the Phone.
-    // This flag is just used as a toggle to provide a update to the BT device to specify
-    // which caller is active.
-    private boolean mCdmaIsSecondCallActive = false;
-    private boolean mCdmaCallsSwapped = false;
-
-    /* Constants from Bluetooth Specification Hands-Free profile version 1.5 */
-    private static final int BRSF_AG_THREE_WAY_CALLING = 1 << 0;
-    private static final int BRSF_AG_EC_NR = 1 << 1;
-    private static final int BRSF_AG_VOICE_RECOG = 1 << 2;
-    private static final int BRSF_AG_IN_BAND_RING = 1 << 3;
-    private static final int BRSF_AG_VOICE_TAG_NUMBE = 1 << 4;
-    private static final int BRSF_AG_REJECT_CALL = 1 << 5;
-    private static final int BRSF_AG_ENHANCED_CALL_STATUS = 1 <<  6;
-    private static final int BRSF_AG_ENHANCED_CALL_CONTROL = 1 << 7;
-    private static final int BRSF_AG_ENHANCED_ERR_RESULT_CODES = 1 << 8;
-
-    private static final int BRSF_HF_EC_NR = 1 << 0;
-    private static final int BRSF_HF_CW_THREE_WAY_CALLING = 1 << 1;
-    private static final int BRSF_HF_CLIP = 1 << 2;
-    private static final int BRSF_HF_VOICE_REG_ACT = 1 << 3;
-    private static final int BRSF_HF_REMOTE_VOL_CONTROL = 1 << 4;
-    private static final int BRSF_HF_ENHANCED_CALL_STATUS = 1 <<  5;
-    private static final int BRSF_HF_ENHANCED_CALL_CONTROL = 1 << 6;
-
-    // VirtualCall - true if Virtual Call is active, false otherwise
-    private boolean mVirtualCallStarted = false;
-
-    // Voice Recognition - true if Voice Recognition is active, false otherwise
-    private boolean mVoiceRecognitionStarted;
-
-    private HandsfreeMessageHandler mHandler;
-
-    public static String typeToString(int type) {
-        switch (type) {
-        case TYPE_UNKNOWN:
-            return "unknown";
-        case TYPE_HEADSET:
-            return "headset";
-        case TYPE_HANDSFREE:
-            return "handsfree";
-        }
-        return null;
-    }
-
-    /**
-     * Initialize the singleton BluetoothHandsfree instance.
-     * This is only done once, at startup, from PhoneApp.onCreate().
-     */
-    /* package */ static BluetoothHandsfree init(Context context, CallManager cm) {
-        synchronized (BluetoothHandsfree.class) {
-            if (sInstance == null) {
-                sInstance = new BluetoothHandsfree(context, cm);
-            } else {
-                Log.wtf(TAG, "init() called multiple times!  sInstance = " + sInstance);
-            }
-            return sInstance;
-        }
-    }
-
-    /** Private constructor; @see init() */
-    private BluetoothHandsfree(Context context, CallManager cm) {
-        mCM = cm;
-        mContext = context;
-        mAdapter = BluetoothAdapter.getDefaultAdapter();
-        boolean bluetoothCapable = (mAdapter != null);
-        mHeadset = null;
-        mHeadsetType = TYPE_UNKNOWN; // nothing connected yet
-        if (bluetoothCapable) {
-            mAdapter.getProfileProxy(mContext, mProfileListener,
-                                     BluetoothProfile.A2DP);
-        }
-        mA2dpState = BluetoothA2dp.STATE_DISCONNECTED;
-        mA2dpDevice = null;
-        mA2dpSuspended = false;
-
-        mPowerManager = (PowerManager) context.getSystemService(Context.POWER_SERVICE);
-        mStartCallWakeLock = mPowerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK,
-                                                       TAG + ":StartCall");
-        mStartCallWakeLock.setReferenceCounted(false);
-        mStartVoiceRecognitionWakeLock = mPowerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK,
-                                                       TAG + ":VoiceRecognition");
-        mStartVoiceRecognitionWakeLock.setReferenceCounted(false);
-
-        mLocalBrsf = BRSF_AG_THREE_WAY_CALLING |
-                     BRSF_AG_EC_NR |
-                     BRSF_AG_REJECT_CALL |
-                     BRSF_AG_ENHANCED_CALL_STATUS;
-
-        if (sVoiceCommandIntent == null) {
-            sVoiceCommandIntent = new Intent(Intent.ACTION_VOICE_COMMAND);
-            sVoiceCommandIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
-        }
-        if (mContext.getPackageManager().resolveActivity(sVoiceCommandIntent, 0) != null &&
-                BluetoothHeadset.isBluetoothVoiceDialingEnabled(mContext)) {
-            mLocalBrsf |= BRSF_AG_VOICE_RECOG;
-        }
-
-        HandlerThread thread = new HandlerThread("BluetoothHandsfreeHandler");
-        thread.start();
-        Looper looper = thread.getLooper();
-        mHandler = new HandsfreeMessageHandler(looper);
-        mBluetoothPhoneState = new BluetoothPhoneState();
-        mUserWantsAudio = true;
-        mVirtualCallStarted = false;
-        mVoiceRecognitionStarted = false;
-        mPhonebook = new BluetoothAtPhonebook(mContext, this);
-        mAudioManager = (AudioManager) context.getSystemService(Context.AUDIO_SERVICE);
-        cdmaSetSecondCallState(false);
-
-        if (bluetoothCapable) {
-            resetAtState();
-        }
-
-    }
-
-    /**
-     * A thread that runs in the background waiting for a Sco Server Socket to
-     * accept a connection. Even after a connection has been accepted, the Sco Server
-     * continues to listen for new connections.
-     */
-    private class IncomingScoAcceptThread extends Thread{
-        private final BluetoothServerSocket mIncomingServerSocket;
-        private BluetoothSocket mIncomingSco;
-        private boolean stopped = false;
-
-        public IncomingScoAcceptThread() {
-            BluetoothServerSocket serverSocket = null;
-            try {
-                serverSocket = BluetoothAdapter.listenUsingScoOn();
-            } catch (IOException e) {
-                Log.e(TAG, "Could not create BluetoothServerSocket");
-                stopped = true;
-            }
-            mIncomingServerSocket = serverSocket;
-        }
-
-        @Override
-        public void run() {
-            while (!stopped) {
-                try {
-                    mIncomingSco = mIncomingServerSocket.accept();
-                } catch (IOException e) {
-                    Log.e(TAG, "BluetoothServerSocket could not accept connection");
-                }
-
-                if (mIncomingSco != null) {
-                    connectSco();
-                }
-            }
-        }
-
-        private void connectSco() {
-            synchronized (BluetoothHandsfree.this) {
-                if (!Thread.interrupted() && isHeadsetConnected() &&
-                    (mAudioPossible || allowAudioAnytime()) &&
-                    mConnectedSco == null) {
-                    Log.i(TAG, "Routing audio for incoming SCO connection");
-                    mConnectedSco = mIncomingSco;
-                    mAudioManager.setBluetoothScoOn(true);
-                    setAudioState(BluetoothHeadset.STATE_AUDIO_CONNECTED,
-                        mHeadset.getRemoteDevice());
-
-                    if (mSignalScoCloseThread == null) {
-                        mSignalScoCloseThread = new SignalScoCloseThread();
-                        mSignalScoCloseThread.setName("SignalScoCloseThread");
-                        mSignalScoCloseThread.start();
-                    }
-                } else {
-                    Log.i(TAG, "Rejecting incoming SCO connection");
-                    try {
-                        mIncomingSco.close();
-                    }catch (IOException e) {
-                        Log.e(TAG, "Error when closing incoming Sco socket");
-                    }
-                    mIncomingSco = null;
-                }
-            }
-        }
-
-        // must be called with BluetoothHandsfree locked
-        void shutdown() {
-            try {
-                mIncomingServerSocket.close();
-            } catch (IOException e) {
-                Log.w(TAG, "Error when closing server socket");
-            }
-            stopped = true;
-            interrupt();
-        }
-    }
-
-    /**
-     * A thread that runs in the background waiting for a Sco Socket to
-     * connect.Once the socket is connected, this thread shall be
-     * shutdown.
-     */
-    private class ScoSocketConnectThread extends Thread{
-        private BluetoothSocket mOutgoingSco;
-
-        public ScoSocketConnectThread(BluetoothDevice device) {
-            try {
-                mOutgoingSco = device.createScoSocket();
-            } catch (IOException e) {
-                Log.w(TAG, "Could not create BluetoothSocket");
-                failedScoConnect();
-            }
-        }
-
-        @Override
-        public void run() {
-            try {
-                mOutgoingSco.connect();
-            }catch (IOException connectException) {
-                Log.e(TAG, "BluetoothSocket could not connect");
-                mOutgoingSco = null;
-                failedScoConnect();
-            }
-
-            if (mOutgoingSco != null) {
-                connectSco();
-            }
-        }
-
-        private void connectSco() {
-            synchronized (BluetoothHandsfree.this) {
-                if (!Thread.interrupted() && isHeadsetConnected() && mConnectedSco == null) {
-                    if (VDBG) log("Routing audio for outgoing SCO conection");
-                    mConnectedSco = mOutgoingSco;
-                    mAudioManager.setBluetoothScoOn(true);
-
-                    setAudioState(BluetoothHeadset.STATE_AUDIO_CONNECTED,
-                      mHeadset.getRemoteDevice());
-
-                    if (mSignalScoCloseThread == null) {
-                        mSignalScoCloseThread = new SignalScoCloseThread();
-                        mSignalScoCloseThread.setName("SignalScoCloseThread");
-                        mSignalScoCloseThread.start();
-                    }
-                } else {
-                    if (VDBG) log("Rejecting new connected outgoing SCO socket");
-                    try {
-                        mOutgoingSco.close();
-                    }catch (IOException e) {
-                        Log.e(TAG, "Error when closing Sco socket");
-                    }
-                    mOutgoingSco = null;
-                    failedScoConnect();
-                }
-            }
-        }
-
-        private void failedScoConnect() {
-            // Wait for couple of secs before sending AUDIO_STATE_DISCONNECTED,
-            // since an incoming SCO connection can happen immediately with
-            // certain headsets.
-            Message msg = Message.obtain(mHandler, SCO_AUDIO_STATE);
-            msg.obj = mHeadset.getRemoteDevice();
-            mHandler.sendMessageDelayed(msg, 2000);
-
-            // Sync with interrupt() statement of shutdown method
-            // This prevents resetting of a valid mConnectScoThread.
-            // If this thread has been interrupted, it has been shutdown and
-            // mConnectScoThread is/will be reset by the outer class.
-            // We do not want to do it here since mConnectScoThread could be
-            // assigned with a new object.
-            synchronized (ScoSocketConnectThread.this) {
-                if (!isInterrupted()) {
-                    resetConnectScoThread();
-                }
-            }
-        }
-
-        // must be called with BluetoothHandsfree locked
-        void shutdown() {
-            closeConnectedSco();
-
-            // sync with isInterrupted() check in failedScoConnect method
-            // see explanation there
-            synchronized (ScoSocketConnectThread.this) {
-                interrupt();
-            }
-        }
-    }
-
-    /*
-     * Signals when a Sco connection has been closed
-     */
-    private class SignalScoCloseThread extends Thread{
-        private boolean stopped = false;
-
-        @Override
-        public void run() {
-            while (!stopped) {
-                BluetoothSocket connectedSco = null;
-                synchronized (BluetoothHandsfree.this) {
-                    connectedSco = mConnectedSco;
-                }
-                if (connectedSco != null) {
-                    byte b[] = new byte[1];
-                    InputStream inStream = null;
-                    try {
-                        inStream = connectedSco.getInputStream();
-                    } catch (IOException e) {}
-
-                    if (inStream != null) {
-                        try {
-                            // inStream.read is a blocking call that won't ever
-                            // return anything, but will throw an exception if the
-                            // connection is closed
-                            int ret = inStream.read(b, 0, 1);
-                        }catch (IOException connectException) {
-                            // call a message to close this thread and turn off audio
-                            // we can't call audioOff directly because then
-                            // the thread would try to close itself
-                            Message msg = Message.obtain(mHandler, SCO_CLOSED);
-                            mHandler.sendMessage(msg);
-                            break;
-                        }
-                    }
-                }
-            }
-        }
-
-        // must be called with BluetoothHandsfree locked
-        void shutdown() {
-            stopped = true;
-            closeConnectedSco();
-            interrupt();
-        }
-    }
-
-    private void connectScoThread(){
-        // Sync with setting mConnectScoThread to null to assure the validity of
-        // the condition
-        synchronized (ScoSocketConnectThread.class) {
-            if (mConnectScoThread == null) {
-                BluetoothDevice device = mHeadset.getRemoteDevice();
-                if (getAudioState(device) == BluetoothHeadset.STATE_AUDIO_DISCONNECTED) {
-                    setAudioState(BluetoothHeadset.STATE_AUDIO_CONNECTING, device);
-                }
-
-                mConnectScoThread = new ScoSocketConnectThread(mHeadset.getRemoteDevice());
-                mConnectScoThread.setName("HandsfreeScoSocketConnectThread");
-
-                mConnectScoThread.start();
-            }
-        }
-    }
-
-    private void resetConnectScoThread() {
-        // Sync with if (mConnectScoThread == null) check
-        synchronized (ScoSocketConnectThread.class) {
-            mConnectScoThread = null;
-        }
-    }
-
-    // must be called with BluetoothHandsfree locked
-    private void closeConnectedSco() {
-        if (mConnectedSco != null) {
-            try {
-                mConnectedSco.close();
-            } catch (IOException e) {
-                Log.e(TAG, "Error when closing Sco socket");
-            }
-
-            BluetoothDevice device = null;
-            if (mHeadset != null) {
-                device = mHeadset.getRemoteDevice();
-            }
-            mAudioManager.setBluetoothScoOn(false);
-            setAudioState(BluetoothHeadset.STATE_AUDIO_DISCONNECTED, device);
-
-            mConnectedSco = null;
-        }
-    }
-
-    /* package */ synchronized void onBluetoothEnabled() {
-        /* Bluez has a bug where it will always accept and then orphan
-         * incoming SCO connections, regardless of whether we have a listening
-         * SCO socket. So the best thing to do is always run a listening socket
-         * while bluetooth is on so that at least we can disconnect it
-         * immediately when we don't want it.
-         */
-
-        if (mIncomingScoThread == null) {
-            mIncomingScoThread = new IncomingScoAcceptThread();
-            mIncomingScoThread.setName("incomingScoAcceptThread");
-            mIncomingScoThread.start();
-        }
-    }
-
-    /* package */ synchronized void onBluetoothDisabled() {
-        // Close off the SCO sockets
-        audioOff();
-
-        if (mIncomingScoThread != null) {
-            mIncomingScoThread.shutdown();
-            mIncomingScoThread = null;
-        }
-    }
-
-    private boolean isHeadsetConnected() {
-        if (mHeadset == null || mHeadsetType == TYPE_UNKNOWN) {
-            return false;
-        }
-        return mHeadset.isConnected();
-    }
-
-    /* package */ synchronized void connectHeadset(HeadsetBase headset, int headsetType) {
-        mHeadset = headset;
-        mHeadsetType = headsetType;
-        if (mHeadsetType == TYPE_HEADSET) {
-            initializeHeadsetAtParser();
-        } else {
-            initializeHandsfreeAtParser();
-        }
-
-        // Headset vendor-specific commands
-        registerAllVendorSpecificCommands();
-
-        headset.startEventThread();
-        configAudioParameters();
-
-        if (inDebug()) {
-            startDebug();
-        }
-
-        if (isIncallAudio()) {
-            audioOn();
-        } else if ( mCM.getFirstActiveRingingCall().isRinging()) {
-            // need to update HS with RING when single ringing call exist
-            mBluetoothPhoneState.ring();
-        }
-    }
-
-    /* returns true if there is some kind of in-call audio we may wish to route
-     * bluetooth to */
-    private boolean isIncallAudio() {
-        Call.State state = mCM.getActiveFgCallState();
-
-        return (state == Call.State.ACTIVE || state == Call.State.ALERTING);
-    }
-
-    /* package */ synchronized void disconnectHeadset() {
-        audioOff();
-
-        // No need to check if isVirtualCallInProgress()
-        // terminateScoUsingVirtualVoiceCall() does the check
-        terminateScoUsingVirtualVoiceCall();
-
-        mHeadsetType = TYPE_UNKNOWN;
-        stopDebug();
-        resetAtState();
-    }
-
-    /* package */ synchronized void resetAtState() {
-        mClip = false;
-        mIndicatorsEnabled = false;
-        mServiceConnectionEstablished = false;
-        mCmee = false;
-        mClccTimestamps = new long[GSM_MAX_CONNECTIONS];
-        mClccUsed = new boolean[GSM_MAX_CONNECTIONS];
-        for (int i = 0; i < GSM_MAX_CONNECTIONS; i++) {
-            mClccUsed[i] = false;
-        }
-        mRemoteBrsf = 0;
-        mPhonebook.resetAtState();
-    }
-
-    /* package */ HeadsetBase getHeadset() {
-        return mHeadset;
-    }
-
-    private void configAudioParameters() {
-        String name = mHeadset.getRemoteDevice().getName();
-        if (name == null) {
-            name = "<unknown>";
-        }
-        mAudioManager.setParameters(HEADSET_NAME+"="+name+";"+HEADSET_NREC+"=on");
-    }
-
-
-    /** Represents the data that we send in a +CIND or +CIEV command to the HF
-     */
-    private class BluetoothPhoneState {
-        // 0: no service
-        // 1: service
-        private int mService;
-
-        // 0: no active call
-        // 1: active call (where active means audio is routed - not held call)
-        private int mCall;
-
-        // 0: not in call setup
-        // 1: incoming call setup
-        // 2: outgoing call setup
-        // 3: remote party being alerted in an outgoing call setup
-        private int mCallsetup;
-
-        // 0: no calls held
-        // 1: held call and active call
-        // 2: held call only
-        private int mCallheld;
-
-        // cellular signal strength of AG: 0-5
-        private int mSignal;
-
-        // cellular signal strength in CSQ rssi scale
-        private int mRssi;  // for CSQ
-
-        // 0: roaming not active (home)
-        // 1: roaming active
-        private int mRoam;
-
-        // battery charge of AG: 0-5
-        private int mBattchg;
-
-        // 0: not registered
-        // 1: registered, home network
-        // 5: registered, roaming
-        private int mStat;  // for CREG
-
-        private String mRingingNumber;  // Context for in-progress RING's
-        private int    mRingingType;
-        private boolean mIgnoreRing = false;
-        private boolean mStopRing = false;
-
-        // current or last call start timestamp
-        private long mCallStartTime = 0;
-        // time window to reconnect remotely-disconnected SCO
-        // in mili-seconds
-        private static final int RETRY_SCO_TIME_WINDOW = 1000;
-
-        private static final int SERVICE_STATE_CHANGED = 1;
-        private static final int PRECISE_CALL_STATE_CHANGED = 2;
-        private static final int RING = 3;
-        private static final int PHONE_CDMA_CALL_WAITING = 4;
-
-        private Handler mStateChangeHandler = new Handler() {
-            @Override
-            public void handleMessage(Message msg) {
-                switch(msg.what) {
-                case RING:
-                    AtCommandResult result = ring();
-                    if (result != null) {
-                        sendURC(result.toString());
-                    }
-                    break;
-                case SERVICE_STATE_CHANGED:
-                    ServiceState state = (ServiceState) ((AsyncResult) msg.obj).result;
-                    updateServiceState(sendUpdate(), state);
-                    break;
-                case PRECISE_CALL_STATE_CHANGED:
-                case PHONE_CDMA_CALL_WAITING:
-                    Connection connection = null;
-                    if (((AsyncResult) msg.obj).result instanceof Connection) {
-                        connection = (Connection) ((AsyncResult) msg.obj).result;
-                    }
-                    handlePreciseCallStateChange(sendUpdate(), connection);
-                    break;
-                }
-            }
-        };
-
-        private BluetoothPhoneState() {
-            // init members
-            // TODO May consider to repalce the default phone's state and signal
-            //      by CallManagter's state and signal
-            updateServiceState(false, mCM.getDefaultPhone().getServiceState());
-            handlePreciseCallStateChange(false, null);
-            mBattchg = 5;  // There is currently no API to get battery level
-                           // on demand, so set to 5 and wait for an update
-            mSignal = asuToSignal(mCM.getDefaultPhone().getSignalStrength());
-
-            // register for updates
-            // Use the service state of default phone as BT service state to
-            // avoid situation such as no cell or wifi connection but still
-            // reporting in service (since SipPhone always reports in service).
-            mCM.getDefaultPhone().registerForServiceStateChanged(mStateChangeHandler,
-                                                  SERVICE_STATE_CHANGED, null);
-            mCM.registerForPreciseCallStateChanged(mStateChangeHandler,
-                    PRECISE_CALL_STATE_CHANGED, null);
-            mCM.registerForCallWaiting(mStateChangeHandler,
-                PHONE_CDMA_CALL_WAITING, null);
-
-            IntentFilter filter = new IntentFilter(Intent.ACTION_BATTERY_CHANGED);
-            filter.addAction(TelephonyIntents.ACTION_SIGNAL_STRENGTH_CHANGED);
-            filter.addAction(BluetoothA2dp.ACTION_CONNECTION_STATE_CHANGED);
-            filter.addAction(BluetoothDevice.ACTION_CONNECTION_ACCESS_REPLY);
-            mContext.registerReceiver(mStateReceiver, filter);
-        }
-
-        private void updateBtPhoneStateAfterRadioTechnologyChange() {
-            if(VDBG) Log.d(TAG, "updateBtPhoneStateAfterRadioTechnologyChange...");
-
-            //Unregister all events from the old obsolete phone
-            mCM.getDefaultPhone().unregisterForServiceStateChanged(mStateChangeHandler);
-            mCM.unregisterForPreciseCallStateChanged(mStateChangeHandler);
-            mCM.unregisterForCallWaiting(mStateChangeHandler);
-
-            //Register all events new to the new active phone
-            mCM.getDefaultPhone().registerForServiceStateChanged(mStateChangeHandler,
-                                                  SERVICE_STATE_CHANGED, null);
-            mCM.registerForPreciseCallStateChanged(mStateChangeHandler,
-                    PRECISE_CALL_STATE_CHANGED, null);
-            mCM.registerForCallWaiting(mStateChangeHandler,
-                PHONE_CDMA_CALL_WAITING, null);
-        }
-
-        private boolean sendUpdate() {
-            return isHeadsetConnected() && mHeadsetType == TYPE_HANDSFREE && mIndicatorsEnabled
-                   && mServiceConnectionEstablished;
-        }
-
-        private boolean sendClipUpdate() {
-            return isHeadsetConnected() && mHeadsetType == TYPE_HANDSFREE && mClip &&
-                   mServiceConnectionEstablished;
-        }
-
-        private boolean sendRingUpdate() {
-            if (isHeadsetConnected() && !mIgnoreRing && !mStopRing &&
-                    mCM.getFirstActiveRingingCall().isRinging()) {
-                if (mHeadsetType == TYPE_HANDSFREE) {
-                    return mServiceConnectionEstablished ? true : false;
-                }
-                return true;
-            }
-            return false;
-        }
-
-        private void stopRing() {
-            mStopRing = true;
-        }
-
-        /* convert [0,31] ASU signal strength to the [0,5] expected by
-         * bluetooth devices. Scale is similar to status bar policy
-         */
-        private int gsmAsuToSignal(SignalStrength signalStrength) {
-            int asu = signalStrength.getGsmSignalStrength();
-            if      (asu >= 16) return 5;
-            else if (asu >= 8)  return 4;
-            else if (asu >= 4)  return 3;
-            else if (asu >= 2)  return 2;
-            else if (asu >= 1)  return 1;
-            else                return 0;
-        }
-
-        /**
-         * Convert the cdma / evdo db levels to appropriate icon level.
-         * The scale is similar to the one used in status bar policy.
-         *
-         * @param signalStrength
-         * @return the icon level
-         */
-        private int cdmaDbmEcioToSignal(SignalStrength signalStrength) {
-            int levelDbm = 0;
-            int levelEcio = 0;
-            int cdmaIconLevel = 0;
-            int evdoIconLevel = 0;
-            int cdmaDbm = signalStrength.getCdmaDbm();
-            int cdmaEcio = signalStrength.getCdmaEcio();
-
-            if (cdmaDbm >= -75) levelDbm = 4;
-            else if (cdmaDbm >= -85) levelDbm = 3;
-            else if (cdmaDbm >= -95) levelDbm = 2;
-            else if (cdmaDbm >= -100) levelDbm = 1;
-            else levelDbm = 0;
-
-            // Ec/Io are in dB*10
-            if (cdmaEcio >= -90) levelEcio = 4;
-            else if (cdmaEcio >= -110) levelEcio = 3;
-            else if (cdmaEcio >= -130) levelEcio = 2;
-            else if (cdmaEcio >= -150) levelEcio = 1;
-            else levelEcio = 0;
-
-            cdmaIconLevel = (levelDbm < levelEcio) ? levelDbm : levelEcio;
-
-            if (mServiceState != null &&
-                  (mServiceState.getNetworkType() == TelephonyManager.NETWORK_TYPE_EVDO_0 ||
-                   mServiceState.getNetworkType() == TelephonyManager.NETWORK_TYPE_EVDO_A)) {
-                  int evdoEcio = signalStrength.getEvdoEcio();
-                  int evdoSnr = signalStrength.getEvdoSnr();
-                  int levelEvdoEcio = 0;
-                  int levelEvdoSnr = 0;
-
-                  // Ec/Io are in dB*10
-                  if (evdoEcio >= -650) levelEvdoEcio = 4;
-                  else if (evdoEcio >= -750) levelEvdoEcio = 3;
-                  else if (evdoEcio >= -900) levelEvdoEcio = 2;
-                  else if (evdoEcio >= -1050) levelEvdoEcio = 1;
-                  else levelEvdoEcio = 0;
-
-                  if (evdoSnr > 7) levelEvdoSnr = 4;
-                  else if (evdoSnr > 5) levelEvdoSnr = 3;
-                  else if (evdoSnr > 3) levelEvdoSnr = 2;
-                  else if (evdoSnr > 1) levelEvdoSnr = 1;
-                  else levelEvdoSnr = 0;
-
-                  evdoIconLevel = (levelEvdoEcio < levelEvdoSnr) ? levelEvdoEcio : levelEvdoSnr;
-            }
-            // TODO(): There is a bug open regarding what should be sent.
-            return (cdmaIconLevel > evdoIconLevel) ?  cdmaIconLevel : evdoIconLevel;
-
-        }
-
-
-        private int asuToSignal(SignalStrength signalStrength) {
-            if (signalStrength.isGsm()) {
-                return gsmAsuToSignal(signalStrength);
-            } else {
-                return cdmaDbmEcioToSignal(signalStrength);
-            }
-        }
-
-
-        /* convert [0,5] signal strength to a rssi signal strength for CSQ
-         * which is [0,31]. Despite the same scale, this is not the same value
-         * as ASU.
-         */
-        private int signalToRssi(int signal) {
-            // using C4A suggested values
-            switch (signal) {
-            case 0: return 0;
-            case 1: return 4;
-            case 2: return 8;
-            case 3: return 13;
-            case 4: return 19;
-            case 5: return 31;
-            }
-            return 0;
-        }
-
-
-        private final BroadcastReceiver mStateReceiver = new BroadcastReceiver() {
-            @Override
-            public void onReceive(Context context, Intent intent) {
-                if (intent.getAction().equals(Intent.ACTION_BATTERY_CHANGED)) {
-                    Message msg = mHandler.obtainMessage(BATTERY_CHANGED, intent);
-                    mHandler.sendMessage(msg);
-                } else if (intent.getAction().equals(
-                            TelephonyIntents.ACTION_SIGNAL_STRENGTH_CHANGED)) {
-                    Message msg = mHandler.obtainMessage(SIGNAL_STRENGTH_CHANGED,
-                                                                    intent);
-                    mHandler.sendMessage(msg);
-                } else if (intent.getAction().equals(
-                    BluetoothA2dp.ACTION_CONNECTION_STATE_CHANGED)) {
-                    int state = intent.getIntExtra(BluetoothProfile.EXTRA_STATE,
-                        BluetoothProfile.STATE_DISCONNECTED);
-                    int oldState = intent.getIntExtra(BluetoothProfile.EXTRA_PREVIOUS_STATE,
-                        BluetoothProfile.STATE_DISCONNECTED);
-                    BluetoothDevice device =
-                            intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
-
-
-                    // We are only concerned about Connected sinks to suspend and resume
-                    // them. We can safely ignore SINK_STATE_CHANGE for other devices.
-                    if (device == null || (mA2dpDevice != null && !device.equals(mA2dpDevice))) {
-                        return;
-                    }
-
-                    synchronized (BluetoothHandsfree.this) {
-                        mA2dpState = state;
-                        if (state == BluetoothProfile.STATE_DISCONNECTED) {
-                            mA2dpDevice = null;
-                        } else {
-                            mA2dpDevice = device;
-                        }
-                        if (oldState == BluetoothA2dp.STATE_PLAYING &&
-                            mA2dpState == BluetoothProfile.STATE_CONNECTED) {
-                            if (mA2dpSuspended) {
-                                if (mPendingSco) {
-                                    mHandler.removeMessages(MESSAGE_CHECK_PENDING_SCO);
-                                    if (DBG) log("A2DP suspended, completing SCO");
-                                    connectScoThread();
-                                    mPendingSco = false;
-                                }
-                            }
-                        }
-                    }
-                } else if (intent.getAction().
-                           equals(BluetoothDevice.ACTION_CONNECTION_ACCESS_REPLY)) {
-                    mPhonebook.handleAccessPermissionResult(intent);
-                }
-            }
-        };
-
-        private synchronized void updateBatteryState(Intent intent) {
-            int batteryLevel = intent.getIntExtra("level", -1);
-            int scale = intent.getIntExtra("scale", -1);
-            if (batteryLevel == -1 || scale == -1) {
-                return;  // ignore
-            }
-            batteryLevel = batteryLevel * 5 / scale;
-            if (mBattchg != batteryLevel) {
-                mBattchg = batteryLevel;
-                if (sendUpdate()) {
-                    sendURC("+CIEV: 7," + mBattchg);
-                }
-            }
-        }
-
-        private synchronized void updateSignalState(Intent intent) {
-            // NOTE this function is called by the BroadcastReceiver mStateReceiver after intent
-            // ACTION_SIGNAL_STRENGTH_CHANGED and by the DebugThread mDebugThread
-            if (!isHeadsetConnected()) {
-                return;
-            }
-
-            SignalStrength signalStrength = SignalStrength.newFromBundle(intent.getExtras());
-            int signal;
-
-            if (signalStrength != null) {
-                signal = asuToSignal(signalStrength);
-                mRssi = signalToRssi(signal);  // no unsolicited CSQ
-                if (signal != mSignal) {
-                    mSignal = signal;
-                    if (sendUpdate()) {
-                        sendURC("+CIEV: 5," + mSignal);
-                    }
-                }
-            } else {
-                Log.e(TAG, "Signal Strength null");
-            }
-        }
-
-        private synchronized void updateServiceState(boolean sendUpdate, ServiceState state) {
-            int service = state.getState() == ServiceState.STATE_IN_SERVICE ? 1 : 0;
-            int roam = state.getRoaming() ? 1 : 0;
-            int stat;
-            AtCommandResult result = new AtCommandResult(AtCommandResult.UNSOLICITED);
-            mServiceState = state;
-            if (service == 0) {
-                stat = 0;
-            } else {
-                stat = (roam == 1) ? 5 : 1;
-            }
-
-            if (service != mService) {
-                mService = service;
-                if (sendUpdate) {
-                    result.addResponse("+CIEV: 1," + mService);
-                }
-            }
-            if (roam != mRoam) {
-                mRoam = roam;
-                if (sendUpdate) {
-                    result.addResponse("+CIEV: 6," + mRoam);
-                }
-            }
-            if (stat != mStat) {
-                mStat = stat;
-                if (sendUpdate) {
-                    result.addResponse(toCregString());
-                }
-            }
-
-            sendURC(result.toString());
-        }
-
-        private synchronized void handlePreciseCallStateChange(boolean sendUpdate,
-                Connection connection) {
-            int call = 0;
-            int callsetup = 0;
-            int callheld = 0;
-            int prevCallsetup = mCallsetup;
-            AtCommandResult result = new AtCommandResult(AtCommandResult.UNSOLICITED);
-            Call foregroundCall = mCM.getActiveFgCall();
-            Call backgroundCall = mCM.getFirstActiveBgCall();
-            Call ringingCall = mCM.getFirstActiveRingingCall();
-
-            if (VDBG) log("updatePhoneState()");
-
-            // This function will get called when the Precise Call State
-            // {@link Call.State} changes. Hence, we might get this update
-            // even if the {@link PhoneConstants.state} is same as before.
-            // Check for the same.
-
-            PhoneConstants.State newState = mCM.getState();
-            if (newState != mPhoneState) {
-                mPhoneState = newState;
-                switch (mPhoneState) {
-                case IDLE:
-                    mUserWantsAudio = true;  // out of call - reset state
-                    audioOff();
-                    break;
-                default:
-                    callStarted();
-                }
-            }
-
-            switch(foregroundCall.getState()) {
-            case ACTIVE:
-                call = 1;
-                mAudioPossible = true;
-                break;
-            case DIALING:
-                callsetup = 2;
-                mAudioPossible = true;
-                // We also need to send a Call started indication
-                // for cases where the 2nd MO was initiated was
-                // from a *BT hands free* and is waiting for a
-                // +BLND: OK response
-                // There is a special case handling of the same case
-                // for CDMA below
-                if (mCM.getFgPhone().getPhoneType() == PhoneConstants.PHONE_TYPE_GSM) {
-                    callStarted();
-                }
-                break;
-            case ALERTING:
-                callsetup = 3;
-                // Open the SCO channel for the outgoing call.
-                mCallStartTime = System.currentTimeMillis();
-                audioOn();
-                mAudioPossible = true;
-                break;
-            case DISCONNECTING:
-                // This is a transient state, we don't want to send
-                // any AT commands during this state.
-                call = mCall;
-                callsetup = mCallsetup;
-                callheld = mCallheld;
-                break;
-            default:
-                mAudioPossible = false;
-            }
-
-            switch(ringingCall.getState()) {
-            case INCOMING:
-            case WAITING:
-                callsetup = 1;
-                break;
-            case DISCONNECTING:
-                // This is a transient state, we don't want to send
-                // any AT commands during this state.
-                call = mCall;
-                callsetup = mCallsetup;
-                callheld = mCallheld;
-                break;
-            }
-
-            switch(backgroundCall.getState()) {
-            case HOLDING:
-                if (call == 1) {
-                    callheld = 1;
-                } else {
-                    call = 1;
-                    callheld = 2;
-                }
-                break;
-            case DISCONNECTING:
-                // This is a transient state, we don't want to send
-                // any AT commands during this state.
-                call = mCall;
-                callsetup = mCallsetup;
-                callheld = mCallheld;
-                break;
-            }
-
-            if (mCall != call) {
-                if (call == 1) {
-                    // This means that a call has transitioned from NOT ACTIVE to ACTIVE.
-                    // Switch on audio.
-                    mCallStartTime = System.currentTimeMillis();
-                    audioOn();
-                }
-                mCall = call;
-                if (sendUpdate) {
-                    result.addResponse("+CIEV: 2," + mCall);
-                }
-            }
-            if (mCallsetup != callsetup) {
-                mCallsetup = callsetup;
-                if (sendUpdate) {
-                    // If mCall = 0, send CIEV
-                    // mCall = 1, mCallsetup = 0, send CIEV
-                    // mCall = 1, mCallsetup = 1, send CIEV after CCWA,
-                    // if 3 way supported.
-                    // mCall = 1, mCallsetup = 2 / 3 -> send CIEV,
-                    // if 3 way is supported
-                    if (mCall != 1 || mCallsetup == 0 ||
-                        mCallsetup != 1 && (mRemoteBrsf & BRSF_HF_CW_THREE_WAY_CALLING) != 0x0) {
-                        result.addResponse("+CIEV: 3," + mCallsetup);
-                    }
-                }
-            }
-
-            if (mCM.getDefaultPhone().getPhoneType() == PhoneConstants.PHONE_TYPE_CDMA) {
-                PhoneApp app = PhoneApp.getInstance();
-                if (app.cdmaPhoneCallState != null) {
-                    CdmaPhoneCallState.PhoneCallState currCdmaThreeWayCallState =
-                            app.cdmaPhoneCallState.getCurrentCallState();
-                    CdmaPhoneCallState.PhoneCallState prevCdmaThreeWayCallState =
-                        app.cdmaPhoneCallState.getPreviousCallState();
-
-                    log("CDMA call state: " + currCdmaThreeWayCallState + " prev state:" +
-                        prevCdmaThreeWayCallState);
-                    callheld = getCdmaCallHeldStatus(currCdmaThreeWayCallState,
-                                                     prevCdmaThreeWayCallState);
-
-                    if (mCdmaThreeWayCallState != currCdmaThreeWayCallState) {
-                        // In CDMA, the network does not provide any feedback
-                        // to the phone when the 2nd MO call goes through the
-                        // stages of DIALING > ALERTING -> ACTIVE we fake the
-                        // sequence
-                        if ((currCdmaThreeWayCallState ==
-                                CdmaPhoneCallState.PhoneCallState.THRWAY_ACTIVE)
-                                    && app.cdmaPhoneCallState.IsThreeWayCallOrigStateDialing()) {
-                            mAudioPossible = true;
-                            if (sendUpdate) {
-                                if ((mRemoteBrsf & BRSF_HF_CW_THREE_WAY_CALLING) != 0x0) {
-                                    result.addResponse("+CIEV: 3,2");
-                                    // Mimic putting the call on hold
-                                    result.addResponse("+CIEV: 4,1");
-                                    mCallheld = callheld;
-                                    result.addResponse("+CIEV: 3,3");
-                                    result.addResponse("+CIEV: 3,0");
-                                }
-                            }
-                            // We also need to send a Call started indication
-                            // for cases where the 2nd MO was initiated was
-                            // from a *BT hands free* and is waiting for a
-                            // +BLND: OK response
-                            callStarted();
-                        }
-
-                        // In CDMA, the network does not provide any feedback to
-                        // the phone when a user merges a 3way call or swaps
-                        // between two calls we need to send a CIEV response
-                        // indicating that a call state got changed which should
-                        // trigger a CLCC update request from the BT client.
-                        if (currCdmaThreeWayCallState ==
-                                CdmaPhoneCallState.PhoneCallState.CONF_CALL &&
-                                prevCdmaThreeWayCallState ==
-                                  CdmaPhoneCallState.PhoneCallState.THRWAY_ACTIVE) {
-                            mAudioPossible = true;
-                            if (sendUpdate) {
-                                if ((mRemoteBrsf & BRSF_HF_CW_THREE_WAY_CALLING) != 0x0) {
-                                    result.addResponse("+CIEV: 2,1");
-                                    result.addResponse("+CIEV: 3,0");
-                                }
-                            }
-                        }
-                    }
-                    mCdmaThreeWayCallState = currCdmaThreeWayCallState;
-                }
-            }
-
-            boolean callsSwitched;
-
-            if (mCM.getDefaultPhone().getPhoneType() == PhoneConstants.PHONE_TYPE_CDMA &&
-                mCdmaThreeWayCallState == CdmaPhoneCallState.PhoneCallState.CONF_CALL) {
-                callsSwitched = mCdmaCallsSwapped;
-            } else {
-                callsSwitched =
-                    (callheld == 1 && ! (backgroundCall.getEarliestConnectTime() ==
-                        mBgndEarliestConnectionTime));
-                mBgndEarliestConnectionTime = backgroundCall.getEarliestConnectTime();
-            }
-
-
-            if (mCallheld != callheld || callsSwitched) {
-                mCallheld = callheld;
-                if (sendUpdate) {
-                    result.addResponse("+CIEV: 4," + mCallheld);
-                }
-            }
-
-            if (callsetup == 1 && callsetup != prevCallsetup) {
-                // new incoming call
-                String number = null;
-                int type = 128;
-                // find incoming phone number and type
-                if (connection == null) {
-                    connection = ringingCall.getEarliestConnection();
-                    if (connection == null) {
-                        Log.e(TAG, "Could not get a handle on Connection object for new " +
-                              "incoming call");
-                    }
-                }
-                if (connection != null) {
-                    number = connection.getAddress();
-                    if (number != null) {
-                        type = PhoneNumberUtils.toaFromString(number);
-                    }
-                }
-                if (number == null) {
-                    number = "";
-                }
-                if ((call != 0 || callheld != 0) && sendUpdate) {
-                    // call waiting
-                    if ((mRemoteBrsf & BRSF_HF_CW_THREE_WAY_CALLING) != 0x0) {
-                        result.addResponse("+CCWA: \"" + number + "\"," + type);
-                        result.addResponse("+CIEV: 3," + callsetup);
-                    }
-                } else {
-                    // regular new incoming call
-                    mRingingNumber = number;
-                    mRingingType = type;
-                    mIgnoreRing = false;
-                    mStopRing = false;
-
-                    if ((mLocalBrsf & BRSF_AG_IN_BAND_RING) != 0x0) {
-                        mCallStartTime = System.currentTimeMillis();
-                        audioOn();
-                    }
-                    result.addResult(ring());
-                }
-            }
-            sendURC(result.toString());
-        }
-
-        private int getCdmaCallHeldStatus(CdmaPhoneCallState.PhoneCallState currState,
-                                  CdmaPhoneCallState.PhoneCallState prevState) {
-            int callheld;
-            // Update the Call held information
-            if (currState == CdmaPhoneCallState.PhoneCallState.CONF_CALL) {
-                if (prevState == CdmaPhoneCallState.PhoneCallState.THRWAY_ACTIVE) {
-                    callheld = 0; //0: no calls held, as now *both* the caller are active
-                } else {
-                    callheld = 1; //1: held call and active call, as on answering a
-                            // Call Waiting, one of the caller *is* put on hold
-                }
-            } else if (currState == CdmaPhoneCallState.PhoneCallState.THRWAY_ACTIVE) {
-                callheld = 1; //1: held call and active call, as on make a 3 Way Call
-                        // the first caller *is* put on hold
-            } else {
-                callheld = 0; //0: no calls held as this is a SINGLE_ACTIVE call
-            }
-            return callheld;
-        }
-
-
-        private AtCommandResult ring() {
-            if (sendRingUpdate()) {
-                AtCommandResult result = new AtCommandResult(AtCommandResult.UNSOLICITED);
-                result.addResponse("RING");
-                if (sendClipUpdate()) {
-                    result.addResponse("+CLIP: \"" + mRingingNumber + "\"," + mRingingType);
-                }
-
-                Message msg = mStateChangeHandler.obtainMessage(RING);
-                mStateChangeHandler.sendMessageDelayed(msg, 3000);
-                return result;
-            }
-            return null;
-        }
-
-        private synchronized String toCregString() {
-            return new String("+CREG: 1," + mStat);
-        }
-
-        private synchronized void updateCallHeld() {
-            if (mCallheld != 0) {
-                mCallheld = 0;
-                sendURC("+CIEV: 4,0");
-            }
-        }
-
-        private synchronized AtCommandResult toCindResult() {
-            AtCommandResult result = new AtCommandResult(AtCommandResult.OK);
-            int call, call_setup;
-
-            // Handsfree carkits expect that +CIND is properly responded to.
-            // Hence we ensure that a proper response is sent for the virtual call too.
-            if (isVirtualCallInProgress()) {
-                call = 1;
-                call_setup = 0;
-            } else {
-                // regular phone call
-                call = mCall;
-                call_setup = mCallsetup;
-            }
-
-            mSignal = asuToSignal(mCM.getDefaultPhone().getSignalStrength());
-            String status = "+CIND: " + mService + "," + call + "," + call_setup + "," +
-                            mCallheld + "," + mSignal + "," + mRoam + "," + mBattchg;
-            result.addResponse(status);
-            return result;
-        }
-
-        private synchronized AtCommandResult toCsqResult() {
-            AtCommandResult result = new AtCommandResult(AtCommandResult.OK);
-            String status = "+CSQ: " + mRssi + ",99";
-            result.addResponse(status);
-            return result;
-        }
-
-
-        private synchronized AtCommandResult getCindTestResult() {
-            return new AtCommandResult("+CIND: (\"service\",(0-1))," + "(\"call\",(0-1))," +
-                        "(\"callsetup\",(0-3)),(\"callheld\",(0-2)),(\"signal\",(0-5))," +
-                        "(\"roam\",(0-1)),(\"battchg\",(0-5))");
-        }
-
-        private synchronized void ignoreRing() {
-            mCallsetup = 0;
-            mIgnoreRing = true;
-            if (sendUpdate()) {
-                sendURC("+CIEV: 3," + mCallsetup);
-            }
-        }
-
-        private void scoClosed() {
-            // sync on mUserWantsAudio change
-            synchronized(BluetoothHandsfree.this) {
-                if (mUserWantsAudio &&
-                    System.currentTimeMillis() - mCallStartTime < RETRY_SCO_TIME_WINDOW) {
-                    Message msg = mHandler.obtainMessage(SCO_CONNECTION_CHECK);
-                    mHandler.sendMessage(msg);
-                }
-            }
-        }
-    };
-
-    private static final int SCO_CLOSED = 3;
-    private static final int CHECK_CALL_STARTED = 4;
-    private static final int CHECK_VOICE_RECOGNITION_STARTED = 5;
-    private static final int MESSAGE_CHECK_PENDING_SCO = 6;
-    private static final int SCO_AUDIO_STATE = 7;
-    private static final int SCO_CONNECTION_CHECK = 8;
-    private static final int BATTERY_CHANGED = 9;
-    private static final int SIGNAL_STRENGTH_CHANGED = 10;
-
-    private final class HandsfreeMessageHandler extends Handler {
-        private HandsfreeMessageHandler(Looper looper) {
-            super(looper);
-        }
-
-        @Override
-        public void handleMessage(Message msg) {
-            switch (msg.what) {
-            case SCO_CLOSED:
-                synchronized (BluetoothHandsfree.this) {
-                    // synchronized
-                    // Make atomic against audioOn, userWantsAudioOn
-                    // TODO finer lock to decouple from other call flow such as
-                    //      mWaitingForCallStart change
-
-                    audioOff();
-                    // notify mBluetoothPhoneState that the SCO channel has closed
-                    mBluetoothPhoneState.scoClosed();
-                }
-                break;
-            case CHECK_CALL_STARTED:
-                synchronized (BluetoothHandsfree.this) {
-                    // synchronized
-                    // Protect test/change of mWaitingForCallStart
-                    if (mWaitingForCallStart) {
-                        mWaitingForCallStart = false;
-                        Log.e(TAG, "Timeout waiting for call to start");
-                        sendURC("ERROR");
-                        if (mStartCallWakeLock.isHeld()) {
-                            mStartCallWakeLock.release();
-                        }
-                    }
-                }
-                break;
-            case CHECK_VOICE_RECOGNITION_STARTED:
-                synchronized (BluetoothHandsfree.this) {
-                    // synchronized
-                    // Protect test/change of mWaitingForVoiceRecognition
-                    if (mWaitingForVoiceRecognition) {
-                        mWaitingForVoiceRecognition = false;
-                        Log.e(TAG, "Timeout waiting for voice recognition to start");
-                        sendURC("ERROR");
-                    }
-                }
-                break;
-            case MESSAGE_CHECK_PENDING_SCO:
-                synchronized (BluetoothHandsfree.this) {
-                    // synchronized
-                    // Protect test/change of mPendingSco
-                    if (mPendingSco && isA2dpMultiProfile()) {
-                        Log.w(TAG, "Timeout suspending A2DP for SCO (mA2dpState = " +
-                                mA2dpState + "). Starting SCO anyway");
-                        connectScoThread();
-                        mPendingSco = false;
-                    }
-                }
-                break;
-            case SCO_AUDIO_STATE:
-                BluetoothDevice device = (BluetoothDevice) msg.obj;
-                if (getAudioState(device) == BluetoothHeadset.STATE_AUDIO_CONNECTING) {
-                    setAudioState(BluetoothHeadset.STATE_AUDIO_DISCONNECTED, device);
-                }
-                break;
-            case SCO_CONNECTION_CHECK:
-                synchronized (mBluetoothPhoneState) {
-                    // synchronized on mCall change
-                    if (mBluetoothPhoneState.mCall == 1) {
-                        // Sometimes, the SCO channel is torn down by HF with no reason.
-                        // Because we are still in active call, reconnect SCO.
-                        // audioOn does nothing if the SCO is already on.
-                        audioOn();
-                    }
-                }
-                break;
-            case BATTERY_CHANGED:
-                mBluetoothPhoneState.updateBatteryState((Intent) msg.obj);
-                break;
-            case SIGNAL_STRENGTH_CHANGED:
-                mBluetoothPhoneState.updateSignalState((Intent) msg.obj);
-                break;
-            }
-        }
-    }
-
-    private synchronized void setAudioState(int state, BluetoothDevice device) {
-        if (VDBG) log("setAudioState(" + state + ")");
-        if (mBluetoothHeadset == null) {
-            mAdapter.getProfileProxy(mContext, mProfileListener, BluetoothProfile.HEADSET);
-            mPendingAudioState = true;
-            mAudioState = state;
-            return;
-        }
-        mBluetoothHeadset.setAudioState(device, state);
-    }
-
-    private synchronized int getAudioState(BluetoothDevice device) {
-        if (mBluetoothHeadset == null) return BluetoothHeadset.STATE_AUDIO_DISCONNECTED;
-        return mBluetoothHeadset.getAudioState(device);
-    }
-
-    private BluetoothProfile.ServiceListener mProfileListener =
-            new BluetoothProfile.ServiceListener() {
-        public void onServiceConnected(int profile, BluetoothProfile proxy) {
-            if (profile == BluetoothProfile.HEADSET) {
-                mBluetoothHeadset = (BluetoothHeadset) proxy;
-                synchronized(BluetoothHandsfree.this) {
-                    if (mPendingAudioState) {
-                        mBluetoothHeadset.setAudioState(mHeadset.getRemoteDevice(), mAudioState);
-                        mPendingAudioState = false;
-                    }
-                }
-            } else if (profile == BluetoothProfile.A2DP) {
-                mA2dp = (BluetoothA2dp) proxy;
-            }
-        }
-        public void onServiceDisconnected(int profile) {
-            if (profile == BluetoothProfile.HEADSET) {
-                mBluetoothHeadset = null;
-            } else if (profile == BluetoothProfile.A2DP) {
-                mA2dp = null;
-            }
-        }
-    };
-
-    /*
-     * Put the AT command, company ID, arguments, and device in an Intent and broadcast it.
-     */
-    private void broadcastVendorSpecificEventIntent(String command,
-                                                    int companyId,
-                                                    int commandType,
-                                                    Object[] arguments,
-                                                    BluetoothDevice device) {
-        if (VDBG) log("broadcastVendorSpecificEventIntent(" + command + ")");
-        Intent intent =
-                new Intent(BluetoothHeadset.ACTION_VENDOR_SPECIFIC_HEADSET_EVENT);
-        intent.putExtra(BluetoothHeadset.EXTRA_VENDOR_SPECIFIC_HEADSET_EVENT_CMD, command);
-        intent.putExtra(BluetoothHeadset.EXTRA_VENDOR_SPECIFIC_HEADSET_EVENT_CMD_TYPE,
-                        commandType);
-        // assert: all elements of args are Serializable
-        intent.putExtra(BluetoothHeadset.EXTRA_VENDOR_SPECIFIC_HEADSET_EVENT_ARGS, arguments);
-        intent.putExtra(BluetoothDevice.EXTRA_DEVICE, device);
-
-        intent.addCategory(BluetoothHeadset.VENDOR_SPECIFIC_HEADSET_EVENT_COMPANY_ID_CATEGORY
-            + "." + Integer.toString(companyId));
-
-        mContext.sendBroadcast(intent, android.Manifest.permission.BLUETOOTH);
-    }
-
-    void updateBtHandsfreeAfterRadioTechnologyChange() {
-        if (VDBG) Log.d(TAG, "updateBtHandsfreeAfterRadioTechnologyChange...");
-
-        mBluetoothPhoneState.updateBtPhoneStateAfterRadioTechnologyChange();
-    }
-
-    /** Request to establish SCO (audio) connection to bluetooth
-     * headset/handsfree, if one is connected. Does not block.
-     * Returns false if the user has requested audio off, or if there
-     * is some other immediate problem that will prevent BT audio.
-     */
-    /* package */ synchronized boolean audioOn() {
-        if (VDBG) log("audioOn()");
-        if (!isHeadsetConnected()) {
-            if (DBG) log("audioOn(): headset is not connected!");
-            return false;
-        }
-        if (mHeadsetType == TYPE_HANDSFREE && !mServiceConnectionEstablished) {
-            if (DBG) log("audioOn(): service connection not yet established!");
-            return false;
-        }
-
-        if (mConnectedSco != null) {
-            if (DBG) log("audioOn(): audio is already connected");
-            return true;
-        }
-
-        if (!mUserWantsAudio) {
-            if (DBG) log("audioOn(): user requested no audio, ignoring");
-            return false;
-        }
-
-        if (mPendingSco) {
-            if (DBG) log("audioOn(): SCO already pending");
-            return true;
-        }
-
-        mA2dpSuspended = false;
-        mPendingSco = false;
-        if (isA2dpMultiProfile() && mA2dpState == BluetoothA2dp.STATE_PLAYING) {
-            if (DBG) log("suspending A2DP stream for SCO");
-            mA2dpSuspended = mA2dp.suspendSink(mA2dpDevice);
-            if (mA2dpSuspended) {
-                mPendingSco = true;
-                Message msg = mHandler.obtainMessage(MESSAGE_CHECK_PENDING_SCO);
-                mHandler.sendMessageDelayed(msg, 2000);
-            } else {
-                Log.w(TAG, "Could not suspend A2DP stream for SCO, going ahead with SCO");
-            }
-        }
-
-        if (!mPendingSco) {
-            connectScoThread();
-        }
-
-        return true;
-    }
-
-    /** Used to indicate the user requested BT audio on.
-     *  This will establish SCO (BT audio), even if the user requested it off
-     *  previously on this call.
-     */
-    /* package */ synchronized void userWantsAudioOn() {
-        mUserWantsAudio = true;
-        audioOn();
-    }
-    /** Used to indicate the user requested BT audio off.
-     *  This will prevent us from establishing BT audio again during this call
-     *  if audioOn() is called.
-     */
-    /* package */ synchronized void userWantsAudioOff() {
-        mUserWantsAudio = false;
-        audioOff();
-    }
-
-    /** Request to disconnect SCO (audio) connection to bluetooth
-     * headset/handsfree, if one is connected. Does not block.
-     */
-    /* package */ synchronized void audioOff() {
-        if (VDBG) log("audioOff(): mPendingSco: " + mPendingSco +
-                ", mConnectedSco: " + mConnectedSco +
-                ", mA2dpState: " + mA2dpState +
-                ", mA2dpSuspended: " + mA2dpSuspended);
-
-        if (mA2dpSuspended) {
-            if (isA2dpMultiProfile()) {
-                if (DBG) log("resuming A2DP stream after disconnecting SCO");
-                mA2dp.resumeSink(mA2dpDevice);
-            }
-            mA2dpSuspended = false;
-        }
-
-        mPendingSco = false;
-
-        if (mSignalScoCloseThread != null) {
-            mSignalScoCloseThread.shutdown();
-            mSignalScoCloseThread = null;
-        }
-
-        // Sync with setting mConnectScoThread to null to assure the validity of
-        // the condition
-        synchronized (ScoSocketConnectThread.class) {
-            if (mConnectScoThread != null) {
-                mConnectScoThread.shutdown();
-                resetConnectScoThread();
-            }
-        }
-
-        closeConnectedSco();    // Should be closed already, but just in case
-    }
-
-    /* package */ boolean isAudioOn() {
-        return (mConnectedSco != null);
-    }
-
-    private boolean isA2dpMultiProfile() {
-        return mA2dp != null && mHeadset != null && mA2dpDevice != null &&
-                mA2dpDevice.equals(mHeadset.getRemoteDevice());
-    }
-
-    /* package */ void ignoreRing() {
-        mBluetoothPhoneState.ignoreRing();
-    }
-
-    private void sendURC(String urc) {
-        if (isHeadsetConnected()) {
-            mHeadset.sendURC(urc);
-        }
-    }
-
-    /** helper to redial last dialled number */
-    private AtCommandResult redial() {
-        String number = mPhonebook.getLastDialledNumber();
-        if (number == null) {
-            // spec seems to suggest sending ERROR if we dont have a
-            // number to redial
-            if (VDBG) log("Bluetooth redial requested (+BLDN), but no previous " +
-                  "outgoing calls found. Ignoring");
-            return new AtCommandResult(AtCommandResult.ERROR);
-        }
-        // Outgoing call initiated by the handsfree device
-        // Send terminateScoUsingVirtualVoiceCall
-        terminateScoUsingVirtualVoiceCall();
-        Intent intent = new Intent(Intent.ACTION_CALL_PRIVILEGED,
-                Uri.fromParts(Constants.SCHEME_TEL, number, null));
-        intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
-        mContext.startActivity(intent);
-
-        // We do not immediately respond OK, wait until we get a phone state
-        // update. If we return OK now and the handsfree immeidately requests
-        // our phone state it will say we are not in call yet which confuses
-        // some devices
-        expectCallStart();
-        return new AtCommandResult(AtCommandResult.UNSOLICITED);  // send nothing
-    }
-
-    /** Build the +CLCC result
-     *  The complexity arises from the fact that we need to maintain the same
-     *  CLCC index even as a call moves between states. */
-    private synchronized AtCommandResult gsmGetClccResult() {
-        // Collect all known connections
-        Connection[] clccConnections = new Connection[GSM_MAX_CONNECTIONS];  // indexed by CLCC index
-        LinkedList<Connection> newConnections = new LinkedList<Connection>();
-        LinkedList<Connection> connections = new LinkedList<Connection>();
-
-        Call foregroundCall = mCM.getActiveFgCall();
-        Call backgroundCall = mCM.getFirstActiveBgCall();
-        Call ringingCall = mCM.getFirstActiveRingingCall();
-
-        if (ringingCall.getState().isAlive()) {
-            connections.addAll(ringingCall.getConnections());
-        }
-        if (foregroundCall.getState().isAlive()) {
-            connections.addAll(foregroundCall.getConnections());
-        }
-        if (backgroundCall.getState().isAlive()) {
-            connections.addAll(backgroundCall.getConnections());
-        }
-
-        // Mark connections that we already known about
-        boolean clccUsed[] = new boolean[GSM_MAX_CONNECTIONS];
-        for (int i = 0; i < GSM_MAX_CONNECTIONS; i++) {
-            clccUsed[i] = mClccUsed[i];
-            mClccUsed[i] = false;
-        }
-        for (Connection c : connections) {
-            boolean found = false;
-            long timestamp = c.getCreateTime();
-            for (int i = 0; i < GSM_MAX_CONNECTIONS; i++) {
-                if (clccUsed[i] && timestamp == mClccTimestamps[i]) {
-                    mClccUsed[i] = true;
-                    found = true;
-                    clccConnections[i] = c;
-                    break;
-                }
-            }
-            if (!found) {
-                newConnections.add(c);
-            }
-        }
-
-        // Find a CLCC index for new connections
-        while (!newConnections.isEmpty()) {
-            // Find lowest empty index
-            int i = 0;
-            while (mClccUsed[i]) i++;
-            // Find earliest connection
-            long earliestTimestamp = newConnections.get(0).getCreateTime();
-            Connection earliestConnection = newConnections.get(0);
-            for (int j = 0; j < newConnections.size(); j++) {
-                long timestamp = newConnections.get(j).getCreateTime();
-                if (timestamp < earliestTimestamp) {
-                    earliestTimestamp = timestamp;
-                    earliestConnection = newConnections.get(j);
-                }
-            }
-
-            // update
-            mClccUsed[i] = true;
-            mClccTimestamps[i] = earliestTimestamp;
-            clccConnections[i] = earliestConnection;
-            newConnections.remove(earliestConnection);
-        }
-
-        // Build CLCC
-        AtCommandResult result = new AtCommandResult(AtCommandResult.OK);
-        for (int i = 0; i < clccConnections.length; i++) {
-            if (mClccUsed[i]) {
-                String clccEntry = connectionToClccEntry(i, clccConnections[i]);
-                if (clccEntry != null) {
-                    result.addResponse(clccEntry);
-                }
-            }
-        }
-
-        return result;
-    }
-
-    /** Convert a Connection object into a single +CLCC result */
-    private String connectionToClccEntry(int index, Connection c) {
-        int state;
-        switch (c.getState()) {
-        case ACTIVE:
-            state = 0;
-            break;
-        case HOLDING:
-            state = 1;
-            break;
-        case DIALING:
-            state = 2;
-            break;
-        case ALERTING:
-            state = 3;
-            break;
-        case INCOMING:
-            state = 4;
-            break;
-        case WAITING:
-            state = 5;
-            break;
-        default:
-            return null;  // bad state
-        }
-
-        int mpty = 0;
-        Call call = c.getCall();
-        if (call != null) {
-            mpty = call.isMultiparty() ? 1 : 0;
-        }
-
-        int direction = c.isIncoming() ? 1 : 0;
-
-        String number = c.getAddress();
-        int type = -1;
-        if (number != null) {
-            type = PhoneNumberUtils.toaFromString(number);
-        }
-
-        String result = "+CLCC: " + (index + 1) + "," + direction + "," + state + ",0," + mpty;
-        if (number != null) {
-            result += ",\"" + number + "\"," + type;
-        }
-        return result;
-    }
-
-    /** Build the +CLCC result for CDMA
-     *  The complexity arises from the fact that we need to maintain the same
-     *  CLCC index even as a call moves between states. */
-    private synchronized AtCommandResult cdmaGetClccResult() {
-        // In CDMA at one time a user can have only two live/active connections
-        Connection[] clccConnections = new Connection[CDMA_MAX_CONNECTIONS];// indexed by CLCC index
-        Call foregroundCall = mCM.getActiveFgCall();
-        Call ringingCall = mCM.getFirstActiveRingingCall();
-
-        Call.State ringingCallState = ringingCall.getState();
-        // If the Ringing Call state is INCOMING, that means this is the very first call
-        // hence there should not be any Foreground Call
-        if (ringingCallState == Call.State.INCOMING) {
-            if (VDBG) log("Filling clccConnections[0] for INCOMING state");
-            clccConnections[0] = ringingCall.getLatestConnection();
-        } else if (foregroundCall.getState().isAlive()) {
-            // Getting Foreground Call connection based on Call state
-            if (ringingCall.isRinging()) {
-                if (VDBG) log("Filling clccConnections[0] & [1] for CALL WAITING state");
-                clccConnections[0] = foregroundCall.getEarliestConnection();
-                clccConnections[1] = ringingCall.getLatestConnection();
-            } else {
-                if (foregroundCall.getConnections().size() <= 1) {
-                    // Single call scenario
-                    if (VDBG) log("Filling clccConnections[0] with ForgroundCall latest connection");
-                    clccConnections[0] = foregroundCall.getLatestConnection();
-                } else {
-                    // Multiple Call scenario. This would be true for both
-                    // CONF_CALL and THRWAY_ACTIVE state
-                    if (VDBG) log("Filling clccConnections[0] & [1] with ForgroundCall connections");
-                    clccConnections[0] = foregroundCall.getEarliestConnection();
-                    clccConnections[1] = foregroundCall.getLatestConnection();
-                }
-            }
-        }
-
-        // Update the mCdmaIsSecondCallActive flag based on the Phone call state
-        if (PhoneApp.getInstance().cdmaPhoneCallState.getCurrentCallState()
-                == CdmaPhoneCallState.PhoneCallState.SINGLE_ACTIVE) {
-            cdmaSetSecondCallState(false);
-        } else if (PhoneApp.getInstance().cdmaPhoneCallState.getCurrentCallState()
-                == CdmaPhoneCallState.PhoneCallState.THRWAY_ACTIVE) {
-            cdmaSetSecondCallState(true);
-        }
-
-        // Build CLCC
-        AtCommandResult result = new AtCommandResult(AtCommandResult.OK);
-        for (int i = 0; (i < clccConnections.length) && (clccConnections[i] != null); i++) {
-            String clccEntry = cdmaConnectionToClccEntry(i, clccConnections[i]);
-            if (clccEntry != null) {
-                result.addResponse(clccEntry);
-            }
-        }
-
-        return result;
-    }
-
-    /** Convert a Connection object into a single +CLCC result for CDMA phones */
-    private String cdmaConnectionToClccEntry(int index, Connection c) {
-        int state;
-        PhoneApp app = PhoneApp.getInstance();
-        CdmaPhoneCallState.PhoneCallState currCdmaCallState =
-                app.cdmaPhoneCallState.getCurrentCallState();
-        CdmaPhoneCallState.PhoneCallState prevCdmaCallState =
-                app.cdmaPhoneCallState.getPreviousCallState();
-
-        if ((prevCdmaCallState == CdmaPhoneCallState.PhoneCallState.THRWAY_ACTIVE)
-                && (currCdmaCallState == CdmaPhoneCallState.PhoneCallState.CONF_CALL)) {
-            // If the current state is reached after merging two calls
-            // we set the state of all the connections as ACTIVE
-            state = 0;
-        } else {
-            switch (c.getState()) {
-            case ACTIVE:
-                // For CDMA since both the connections are set as active by FW after accepting
-                // a Call waiting or making a 3 way call, we need to set the state specifically
-                // to ACTIVE/HOLDING based on the mCdmaIsSecondCallActive flag. This way the
-                // CLCC result will allow BT devices to enable the swap or merge options
-                if (index == 0) { // For the 1st active connection
-                    state = mCdmaIsSecondCallActive ? 1 : 0;
-                } else { // for the 2nd active connection
-                    state = mCdmaIsSecondCallActive ? 0 : 1;
-                }
-                break;
-            case HOLDING:
-                state = 1;
-                break;
-            case DIALING:
-                state = 2;
-                break;
-            case ALERTING:
-                state = 3;
-                break;
-            case INCOMING:
-                state = 4;
-                break;
-            case WAITING:
-                state = 5;
-                break;
-            default:
-                return null;  // bad state
-            }
-        }
-
-        int mpty = 0;
-        if (currCdmaCallState == CdmaPhoneCallState.PhoneCallState.CONF_CALL) {
-            if (prevCdmaCallState == CdmaPhoneCallState.PhoneCallState.THRWAY_ACTIVE) {
-                // If the current state is reached after merging two calls
-                // we set the multiparty call true.
-                mpty = 1;
-            } else {
-                // CALL_CONF state is not from merging two calls, but from
-                // accepting the second call. In this case first will be on
-                // hold in most cases but in some cases its already merged.
-                // However, we will follow the common case and the test case
-                // as per Bluetooth SIG PTS
-                mpty = 0;
-            }
-        } else {
-            mpty = 0;
-        }
-
-        int direction = c.isIncoming() ? 1 : 0;
-
-        String number = c.getAddress();
-        int type = -1;
-        if (number != null) {
-            type = PhoneNumberUtils.toaFromString(number);
-        }
-
-        String result = "+CLCC: " + (index + 1) + "," + direction + "," + state + ",0," + mpty;
-        if (number != null) {
-            result += ",\"" + number + "\"," + type;
-        }
-        return result;
-    }
-
-    /*
-     * Register a vendor-specific command.
-     * @param commandName the name of the command.  For example, if the expected
-     * incoming command is <code>AT+FOO=bar,baz</code>, the value of this should be
-     * <code>"+FOO"</code>.
-     * @param companyId the Bluetooth SIG Company Identifier
-     * @param parser the AtParser on which to register the command
-     */
-    private void registerVendorSpecificCommand(String commandName,
-                                               int companyId,
-                                               AtParser parser) {
-        parser.register(commandName,
-                        new VendorSpecificCommandHandler(commandName, companyId));
-    }
-
-    /*
-     * Register all vendor-specific commands here.
-     */
-    private void registerAllVendorSpecificCommands() {
-        AtParser parser = mHeadset.getAtParser();
-
-        // Plantronics-specific headset events go here
-        registerVendorSpecificCommand("+XEVENT",
-                                      BluetoothAssignedNumbers.PLANTRONICS,
-                                      parser);
-    }
-
-    /**
-     * Register AT Command handlers to implement the Headset profile
-     */
-    private void initializeHeadsetAtParser() {
-        if (VDBG) log("Registering Headset AT commands");
-        AtParser parser = mHeadset.getAtParser();
-        // Headsets usually only have one button, which is meant to cause the
-        // HS to send us AT+CKPD=200 or AT+CKPD.
-        parser.register("+CKPD", new AtCommandHandler() {
-            private AtCommandResult headsetButtonPress() {
-                if (mCM.getFirstActiveRingingCall().isRinging()) {
-                    // Answer the call
-                    mBluetoothPhoneState.stopRing();
-                    sendURC("OK");
-                    PhoneUtils.answerCall(mCM.getFirstActiveRingingCall());
-                    // If in-band ring tone is supported, SCO connection will already
-                    // be up and the following call will just return.
-                    audioOn();
-                    return new AtCommandResult(AtCommandResult.UNSOLICITED);
-                } else if (mCM.hasActiveFgCall()) {
-                    if (!isAudioOn()) {
-                        // Transfer audio from AG to HS
-                        audioOn();
-                    } else {
-                        if (mHeadset.getDirection() == HeadsetBase.DIRECTION_INCOMING &&
-                          (System.currentTimeMillis() - mHeadset.getConnectTimestamp()) < 5000) {
-                            // Headset made a recent ACL connection to us - and
-                            // made a mandatory AT+CKPD request to connect
-                            // audio which races with our automatic audio
-                            // setup.  ignore
-                        } else {
-                            // Hang up the call
-                            audioOff();
-                            PhoneUtils.hangup(PhoneApp.getInstance().mCM);
-                        }
-                    }
-                    return new AtCommandResult(AtCommandResult.OK);
-                } else {
-                    // No current call - redial last number
-                    return redial();
-                }
-            }
-            @Override
-            public AtCommandResult handleActionCommand() {
-                return headsetButtonPress();
-            }
-            @Override
-            public AtCommandResult handleSetCommand(Object[] args) {
-                return headsetButtonPress();
-            }
-        });
-    }
-
-    /**
-     * Register AT Command handlers to implement the Handsfree profile
-     */
-    private void initializeHandsfreeAtParser() {
-        if (VDBG) log("Registering Handsfree AT commands");
-        AtParser parser = mHeadset.getAtParser();
-        final Phone phone = mCM.getDefaultPhone();
-
-        // Answer
-        parser.register('A', new AtCommandHandler() {
-            @Override
-            public AtCommandResult handleBasicCommand(String args) {
-                sendURC("OK");
-                mBluetoothPhoneState.stopRing();
-                PhoneUtils.answerCall(mCM.getFirstActiveRingingCall());
-                return new AtCommandResult(AtCommandResult.UNSOLICITED);
-            }
-        });
-        parser.register('D', new AtCommandHandler() {
-            @Override
-            public AtCommandResult handleBasicCommand(String args) {
-                if (args.length() > 0) {
-                    if (args.charAt(0) == '>') {
-                        // Yuck - memory dialling requested.
-                        // Just dial last number for now
-                        if (args.startsWith(">9999")) {   // for PTS test
-                            return new AtCommandResult(AtCommandResult.ERROR);
-                        }
-                        return redial();
-                    } else {
-                        // Send terminateScoUsingVirtualVoiceCall
-                        terminateScoUsingVirtualVoiceCall();
-                        // Remove trailing ';'
-                        if (args.charAt(args.length() - 1) == ';') {
-                            args = args.substring(0, args.length() - 1);
-                        }
-
-                        args = PhoneNumberUtils.convertPreDial(args);
-
-                        Intent intent = new Intent(Intent.ACTION_CALL_PRIVILEGED,
-                                Uri.fromParts(Constants.SCHEME_TEL, args, null));
-                        intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
-                        mContext.startActivity(intent);
-
-                        expectCallStart();
-                        return new AtCommandResult(AtCommandResult.UNSOLICITED);  // send nothing
-                    }
-                }
-                return new AtCommandResult(AtCommandResult.ERROR);
-            }
-        });
-
-        // Hang-up command
-        parser.register("+CHUP", new AtCommandHandler() {
-            @Override
-            public AtCommandResult handleActionCommand() {
-                sendURC("OK");
-                if (isVirtualCallInProgress()) {
-                    terminateScoUsingVirtualVoiceCall();
-                } else {
-                    if (mCM.hasActiveFgCall()) {
-                        PhoneUtils.hangupActiveCall(mCM.getActiveFgCall());
-                    } else if (mCM.hasActiveRingingCall()) {
-                        PhoneUtils.hangupRingingCall(mCM.getFirstActiveRingingCall());
-                    } else if (mCM.hasActiveBgCall()) {
-                        PhoneUtils.hangupHoldingCall(mCM.getFirstActiveBgCall());
-                    }
-                }
-                return new AtCommandResult(AtCommandResult.UNSOLICITED);
-            }
-        });
-
-        // Bluetooth Retrieve Supported Features command
-        parser.register("+BRSF", new AtCommandHandler() {
-            private AtCommandResult sendBRSF() {
-                return new AtCommandResult("+BRSF: " + mLocalBrsf);
-            }
-            @Override
-            public AtCommandResult handleSetCommand(Object[] args) {
-                // AT+BRSF=<handsfree supported features bitmap>
-                // Handsfree is telling us which features it supports. We
-                // send the features we support
-                if (args.length == 1 && (args[0] instanceof Integer)) {
-                    mRemoteBrsf = (Integer) args[0];
-                } else {
-                    Log.w(TAG, "HF didn't sent BRSF assuming 0");
-                }
-                return sendBRSF();
-            }
-            @Override
-            public AtCommandResult handleActionCommand() {
-                // This seems to be out of spec, but lets do the nice thing
-                return sendBRSF();
-            }
-            @Override
-            public AtCommandResult handleReadCommand() {
-                // This seems to be out of spec, but lets do the nice thing
-                return sendBRSF();
-            }
-        });
-
-        // Call waiting notification on/off
-        parser.register("+CCWA", new AtCommandHandler() {
-            @Override
-            public AtCommandResult handleActionCommand() {
-                // Seems to be out of spec, but lets return nicely
-                return new AtCommandResult(AtCommandResult.OK);
-            }
-            @Override
-            public AtCommandResult handleReadCommand() {
-                // Call waiting is always on
-                return new AtCommandResult("+CCWA: 1");
-            }
-            @Override
-            public AtCommandResult handleSetCommand(Object[] args) {
-                // AT+CCWA=<n>
-                // Handsfree is trying to enable/disable call waiting. We
-                // cannot disable in the current implementation.
-                return new AtCommandResult(AtCommandResult.OK);
-            }
-            @Override
-            public AtCommandResult handleTestCommand() {
-                // Request for range of supported CCWA paramters
-                return new AtCommandResult("+CCWA: (\"n\",(1))");
-            }
-        });
-
-        // Mobile Equipment Event Reporting enable/disable command
-        // Of the full 3GPP syntax paramters (mode, keyp, disp, ind, bfr) we
-        // only support paramter ind (disable/enable evert reporting using
-        // +CDEV)
-        parser.register("+CMER", new AtCommandHandler() {
-            @Override
-            public AtCommandResult handleReadCommand() {
-                return new AtCommandResult(
-                        "+CMER: 3,0,0," + (mIndicatorsEnabled ? "1" : "0"));
-            }
-            @Override
-            public AtCommandResult handleSetCommand(Object[] args) {
-                if (args.length < 4) {
-                    // This is a syntax error
-                    return new AtCommandResult(AtCommandResult.ERROR);
-                } else if (args[0].equals(3) && args[1].equals(0) &&
-                           args[2].equals(0)) {
-                    boolean valid = false;
-                    if (args[3].equals(0)) {
-                        mIndicatorsEnabled = false;
-                        valid = true;
-                    } else if (args[3].equals(1)) {
-                        mIndicatorsEnabled = true;
-                        valid = true;
-                    }
-                    if (valid) {
-                        if ((mRemoteBrsf & BRSF_HF_CW_THREE_WAY_CALLING) == 0x0) {
-                            mServiceConnectionEstablished = true;
-                            sendURC("OK");  // send immediately, then initiate audio
-                            if (isIncallAudio()) {
-                                audioOn();
-                            } else if (mCM.getFirstActiveRingingCall().isRinging()) {
-                                // need to update HS with RING cmd when single
-                                // ringing call exist
-                                mBluetoothPhoneState.ring();
-                            }
-                            // only send OK once
-                            return new AtCommandResult(AtCommandResult.UNSOLICITED);
-                        } else {
-                            return new AtCommandResult(AtCommandResult.OK);
-                        }
-                    }
-                }
-                return reportCmeError(BluetoothCmeError.OPERATION_NOT_SUPPORTED);
-            }
-            @Override
-            public AtCommandResult handleTestCommand() {
-                return new AtCommandResult("+CMER: (3),(0),(0),(0-1)");
-            }
-        });
-
-        // Mobile Equipment Error Reporting enable/disable
-        parser.register("+CMEE", new AtCommandHandler() {
-            @Override
-            public AtCommandResult handleActionCommand() {
-                // out of spec, assume they want to enable
-                mCmee = true;
-                return new AtCommandResult(AtCommandResult.OK);
-            }
-            @Override
-            public AtCommandResult handleReadCommand() {
-                return new AtCommandResult("+CMEE: " + (mCmee ? "1" : "0"));
-            }
-            @Override
-            public AtCommandResult handleSetCommand(Object[] args) {
-                // AT+CMEE=<n>
-                if (args.length == 0) {
-                    // <n> ommitted - default to 0
-                    mCmee = false;
-                    return new AtCommandResult(AtCommandResult.OK);
-                } else if (!(args[0] instanceof Integer)) {
-                    // Syntax error
-                    return new AtCommandResult(AtCommandResult.ERROR);
-                } else {
-                    mCmee = ((Integer)args[0] == 1);
-                    return new AtCommandResult(AtCommandResult.OK);
-                }
-            }
-            @Override
-            public AtCommandResult handleTestCommand() {
-                // Probably not required but spec, but no harm done
-                return new AtCommandResult("+CMEE: (0-1)");
-            }
-        });
-
-        // Bluetooth Last Dialled Number
-        parser.register("+BLDN", new AtCommandHandler() {
-            @Override
-            public AtCommandResult handleActionCommand() {
-                return redial();
-            }
-        });
-
-        // Indicator Update command
-        parser.register("+CIND", new AtCommandHandler() {
-            @Override
-            public AtCommandResult handleReadCommand() {
-                return mBluetoothPhoneState.toCindResult();
-            }
-            @Override
-            public AtCommandResult handleTestCommand() {
-                return mBluetoothPhoneState.getCindTestResult();
-            }
-        });
-
-        // Query Signal Quality (legacy)
-        parser.register("+CSQ", new AtCommandHandler() {
-            @Override
-            public AtCommandResult handleActionCommand() {
-                return mBluetoothPhoneState.toCsqResult();
-            }
-        });
-
-        // Query network registration state
-        parser.register("+CREG", new AtCommandHandler() {
-            @Override
-            public AtCommandResult handleReadCommand() {
-                return new AtCommandResult(mBluetoothPhoneState.toCregString());
-            }
-        });
-
-        // Send DTMF. I don't know if we are also expected to play the DTMF tone
-        // locally, right now we don't
-        parser.register("+VTS", new AtCommandHandler() {
-            @Override
-            public AtCommandResult handleSetCommand(Object[] args) {
-                if (args.length >= 1) {
-                    char c;
-                    if (args[0] instanceof Integer) {
-                        c = ((Integer) args[0]).toString().charAt(0);
-                    } else {
-                        c = ((String) args[0]).charAt(0);
-                    }
-                    if (isValidDtmf(c)) {
-                        phone.sendDtmf(c);
-                        return new AtCommandResult(AtCommandResult.OK);
-                    }
-                }
-                return new AtCommandResult(AtCommandResult.ERROR);
-            }
-            private boolean isValidDtmf(char c) {
-                switch (c) {
-                case '#':
-                case '*':
-                    return true;
-                default:
-                    if (Character.digit(c, 14) != -1) {
-                        return true;  // 0-9 and A-D
-                    }
-                    return false;
-                }
-            }
-        });
-
-        // List calls
-        parser.register("+CLCC", new AtCommandHandler() {
-            @Override
-            public AtCommandResult handleActionCommand() {
-                int phoneType = phone.getPhoneType();
-                // Handsfree carkits expect that +CLCC is properly responded to.
-                // Hence we ensure that a proper response is sent for the virtual call too.
-                if (isVirtualCallInProgress()) {
-                    String number = phone.getLine1Number();
-                    AtCommandResult result = new AtCommandResult(AtCommandResult.OK);
-                    String args;
-                    if (number == null) {
-                        args = "+CLCC: 1,0,0,0,0,\"\",0";
-                    }
-                    else
-                    {
-                        args = "+CLCC: 1,0,0,0,0,\"" + number + "\"," +
-                                  PhoneNumberUtils.toaFromString(number);
-                    }
-                    result.addResponse(args);
-                    return result;
-                }
-                if (phoneType == PhoneConstants.PHONE_TYPE_CDMA) {
-                    return cdmaGetClccResult();
-                } else if (phoneType == PhoneConstants.PHONE_TYPE_GSM) {
-                    return gsmGetClccResult();
-                } else {
-                    throw new IllegalStateException("Unexpected phone type: " + phoneType);
-                }
-            }
-        });
-
-        // Call Hold and Multiparty Handling command
-        parser.register("+CHLD", new AtCommandHandler() {
-            @Override
-            public AtCommandResult handleSetCommand(Object[] args) {
-                int phoneType = phone.getPhoneType();
-                Call ringingCall = mCM.getFirstActiveRingingCall();
-                Call backgroundCall = mCM.getFirstActiveBgCall();
-
-                if (args.length >= 1) {
-                    if (args[0].equals(0)) {
-                        boolean result;
-                        if (ringingCall.isRinging()) {
-                            result = PhoneUtils.hangupRingingCall(ringingCall);
-                        } else {
-                            result = PhoneUtils.hangupHoldingCall(backgroundCall);
-                        }
-                        if (result) {
-                            return new AtCommandResult(AtCommandResult.OK);
-                        } else {
-                            return new AtCommandResult(AtCommandResult.ERROR);
-                        }
-                    } else if (args[0].equals(1)) {
-                        if (phoneType == PhoneConstants.PHONE_TYPE_CDMA) {
-                            if (ringingCall.isRinging()) {
-                                // Hangup the active call and then answer call waiting call.
-                                if (VDBG) log("CHLD:1 Callwaiting Answer call");
-                                PhoneUtils.hangupRingingAndActive(phone);
-                            } else {
-                                // If there is no Call waiting then just hangup
-                                // the active call. In CDMA this mean that the complete
-                                // call session would be ended
-                                if (VDBG) log("CHLD:1 Hangup Call");
-                                PhoneUtils.hangup(PhoneApp.getInstance().mCM);
-                            }
-                            return new AtCommandResult(AtCommandResult.OK);
-                        } else if (phoneType == PhoneConstants.PHONE_TYPE_GSM) {
-                            // Hangup active call, answer held call
-                            if (PhoneUtils.answerAndEndActive(
-                                    PhoneApp.getInstance().mCM, ringingCall)) {
-                                return new AtCommandResult(AtCommandResult.OK);
-                            } else {
-                                return new AtCommandResult(AtCommandResult.ERROR);
-                            }
-                        } else {
-                            throw new IllegalStateException("Unexpected phone type: " + phoneType);
-                        }
-                    } else if (args[0].equals(2)) {
-                        sendURC("OK");
-                        if (phoneType == PhoneConstants.PHONE_TYPE_CDMA) {
-                            // For CDMA, the way we switch to a new incoming call is by
-                            // calling PhoneUtils.answerCall(). switchAndHoldActive() won't
-                            // properly update the call state within telephony.
-                            // If the Phone state is already in CONF_CALL then we simply send
-                            // a flash cmd by calling switchHoldingAndActive()
-                            if (ringingCall.isRinging()) {
-                                if (VDBG) log("CHLD:2 Callwaiting Answer call");
-                                PhoneUtils.answerCall(ringingCall);
-                                PhoneUtils.setMute(false);
-                                // Setting the second callers state flag to TRUE (i.e. active)
-                                cdmaSetSecondCallState(true);
-                            } else if (PhoneApp.getInstance().cdmaPhoneCallState
-                                    .getCurrentCallState()
-                                    == CdmaPhoneCallState.PhoneCallState.CONF_CALL) {
-                                if (VDBG) log("CHLD:2 Swap Calls");
-                                PhoneUtils.switchHoldingAndActive(backgroundCall);
-                                // Toggle the second callers active state flag
-                                cdmaSwapSecondCallState();
-                            }
-                        } else if (phoneType == PhoneConstants.PHONE_TYPE_GSM) {
-                            PhoneUtils.switchHoldingAndActive(backgroundCall);
-                        } else {
-                            throw new IllegalStateException("Unexpected phone type: " + phoneType);
-                        }
-                        return new AtCommandResult(AtCommandResult.UNSOLICITED);
-                    } else if (args[0].equals(3)) {
-                        sendURC("OK");
-                        if (phoneType == PhoneConstants.PHONE_TYPE_CDMA) {
-                            CdmaPhoneCallState.PhoneCallState state =
-                                PhoneApp.getInstance().cdmaPhoneCallState.getCurrentCallState();
-                            // For CDMA, we need to check if the call is in THRWAY_ACTIVE state
-                            if (state == CdmaPhoneCallState.PhoneCallState.THRWAY_ACTIVE) {
-                                if (VDBG) log("CHLD:3 Merge Calls");
-                                PhoneUtils.mergeCalls();
-                            } else if (state == CdmaPhoneCallState.PhoneCallState.CONF_CALL) {
-                                // State is CONF_CALL already and we are getting a merge call
-                                // This can happen when CONF_CALL was entered from a Call Waiting
-                                mBluetoothPhoneState.updateCallHeld();
-                            }
-                        } else if (phoneType == PhoneConstants.PHONE_TYPE_GSM) {
-                            if (mCM.hasActiveFgCall() && mCM.hasActiveBgCall()) {
-                                PhoneUtils.mergeCalls();
-                            }
-                        } else {
-                            throw new IllegalStateException("Unexpected phone type: " + phoneType);
-                        }
-                        return new AtCommandResult(AtCommandResult.UNSOLICITED);
-                    }
-                }
-                return new AtCommandResult(AtCommandResult.ERROR);
-            }
-            @Override
-            public AtCommandResult handleTestCommand() {
-                mServiceConnectionEstablished = true;
-                sendURC("+CHLD: (0,1,2,3)");
-                sendURC("OK");  // send reply first, then connect audio
-                if (isIncallAudio()) {
-                    audioOn();
-                } else if (mCM.getFirstActiveRingingCall().isRinging()) {
-                    // need to update HS with RING when single ringing call exist
-                    mBluetoothPhoneState.ring();
-                }
-                // already replied
-                return new AtCommandResult(AtCommandResult.UNSOLICITED);
-            }
-        });
-
-        // Get Network operator name
-        parser.register("+COPS", new AtCommandHandler() {
-            @Override
-            public AtCommandResult handleReadCommand() {
-                String operatorName = phone.getServiceState().getOperatorAlphaLong();
-                if (operatorName != null) {
-                    if (operatorName.length() > 16) {
-                        operatorName = operatorName.substring(0, 16);
-                    }
-                    return new AtCommandResult(
-                            "+COPS: 0,0,\"" + operatorName + "\"");
-                } else {
-                    return new AtCommandResult(
-                            "+COPS: 0");
-                }
-            }
-            @Override
-            public AtCommandResult handleSetCommand(Object[] args) {
-                // Handsfree only supports AT+COPS=3,0
-                if (args.length != 2 || !(args[0] instanceof Integer)
-                    || !(args[1] instanceof Integer)) {
-                    // syntax error
-                    return new AtCommandResult(AtCommandResult.ERROR);
-                } else if ((Integer)args[0] != 3 || (Integer)args[1] != 0) {
-                    return reportCmeError(BluetoothCmeError.OPERATION_NOT_SUPPORTED);
-                } else {
-                    return new AtCommandResult(AtCommandResult.OK);
-                }
-            }
-            @Override
-            public AtCommandResult handleTestCommand() {
-                // Out of spec, but lets be friendly
-                return new AtCommandResult("+COPS: (3),(0)");
-            }
-        });
-
-        // Mobile PIN
-        // AT+CPIN is not in the handsfree spec (although it is in 3GPP)
-        parser.register("+CPIN", new AtCommandHandler() {
-            @Override
-            public AtCommandResult handleReadCommand() {
-                return new AtCommandResult("+CPIN: READY");
-            }
-        });
-
-        // Bluetooth Response and Hold
-        // Only supported on PDC (Japan) and CDMA networks.
-        parser.register("+BTRH", new AtCommandHandler() {
-            @Override
-            public AtCommandResult handleReadCommand() {
-                // Replying with just OK indicates no response and hold
-                // features in use now
-                return new AtCommandResult(AtCommandResult.OK);
-            }
-            @Override
-            public AtCommandResult handleSetCommand(Object[] args) {
-                // Neeed PDC or CDMA
-                return new AtCommandResult(AtCommandResult.ERROR);
-            }
-        });
-
-        // Request International Mobile Subscriber Identity (IMSI)
-        // Not in bluetooth handset spec
-        parser.register("+CIMI", new AtCommandHandler() {
-            @Override
-            public AtCommandResult handleActionCommand() {
-                // AT+CIMI
-                String imsi = phone.getSubscriberId();
-                if (imsi == null || imsi.length() == 0) {
-                    return reportCmeError(BluetoothCmeError.SIM_FAILURE);
-                } else {
-                    return new AtCommandResult(imsi);
-                }
-            }
-        });
-
-        // Calling Line Identification Presentation
-        parser.register("+CLIP", new AtCommandHandler() {
-            @Override
-            public AtCommandResult handleReadCommand() {
-                // Currently assumes the network is provisioned for CLIP
-                return new AtCommandResult("+CLIP: " + (mClip ? "1" : "0") + ",1");
-            }
-            @Override
-            public AtCommandResult handleSetCommand(Object[] args) {
-                // AT+CLIP=<n>
-                if (args.length >= 1 && (args[0].equals(0) || args[0].equals(1))) {
-                    mClip = args[0].equals(1);
-                    return new AtCommandResult(AtCommandResult.OK);
-                } else {
-                    return new AtCommandResult(AtCommandResult.ERROR);
-                }
-            }
-            @Override
-            public AtCommandResult handleTestCommand() {
-                return new AtCommandResult("+CLIP: (0-1)");
-            }
-        });
-
-        // AT+CGSN - Returns the device IMEI number.
-        parser.register("+CGSN", new AtCommandHandler() {
-            @Override
-            public AtCommandResult handleActionCommand() {
-                // Get the IMEI of the device.
-                // phone will not be NULL at this point.
-                return new AtCommandResult("+CGSN: " + phone.getDeviceId());
-            }
-        });
-
-        // AT+CGMM - Query Model Information
-        parser.register("+CGMM", new AtCommandHandler() {
-            @Override
-            public AtCommandResult handleActionCommand() {
-                // Return the Model Information.
-                String model = SystemProperties.get("ro.product.model");
-                if (model != null) {
-                    return new AtCommandResult("+CGMM: " + model);
-                } else {
-                    return new AtCommandResult(AtCommandResult.ERROR);
-                }
-            }
-        });
-
-        // AT+CGMI - Query Manufacturer Information
-        parser.register("+CGMI", new AtCommandHandler() {
-            @Override
-            public AtCommandResult handleActionCommand() {
-                // Return the Model Information.
-                String manuf = SystemProperties.get("ro.product.manufacturer");
-                if (manuf != null) {
-                    return new AtCommandResult("+CGMI: " + manuf);
-                } else {
-                    return new AtCommandResult(AtCommandResult.ERROR);
-                }
-            }
-        });
-
-        // Noise Reduction and Echo Cancellation control
-        parser.register("+NREC", new AtCommandHandler() {
-            @Override
-            public AtCommandResult handleSetCommand(Object[] args) {
-                if (args[0].equals(0)) {
-                    mAudioManager.setParameters(HEADSET_NREC+"=off");
-                    return new AtCommandResult(AtCommandResult.OK);
-                } else if (args[0].equals(1)) {
-                    mAudioManager.setParameters(HEADSET_NREC+"=on");
-                    return new AtCommandResult(AtCommandResult.OK);
-                }
-                return new AtCommandResult(AtCommandResult.ERROR);
-            }
-        });
-
-        // Voice recognition (dialing)
-        parser.register("+BVRA", new AtCommandHandler() {
-            @Override
-            public AtCommandResult handleSetCommand(Object[] args) {
-                if (!BluetoothHeadset.isBluetoothVoiceDialingEnabled(mContext)) {
-                    return new AtCommandResult(AtCommandResult.ERROR);
-                }
-                if (args.length >= 1 && args[0].equals(1)) {
-                    synchronized (BluetoothHandsfree.this) {
-                        if (!isVoiceRecognitionInProgress() &&
-                            !isCellularCallInProgress() &&
-                            !isVirtualCallInProgress()) {
-                            try {
-                                mContext.startActivity(sVoiceCommandIntent);
-                            } catch (ActivityNotFoundException e) {
-                                return new AtCommandResult(AtCommandResult.ERROR);
-                            }
-                            expectVoiceRecognition();
-                        }
-                    }
-                    return new AtCommandResult(AtCommandResult.UNSOLICITED);  // send nothing yet
-                } else if (args.length >= 1 && args[0].equals(0)) {
-                    if (isVoiceRecognitionInProgress()) {
-                        audioOff();
-                    }
-                    return new AtCommandResult(AtCommandResult.OK);
-                }
-                return new AtCommandResult(AtCommandResult.ERROR);
-            }
-            @Override
-            public AtCommandResult handleTestCommand() {
-                return new AtCommandResult("+BVRA: (0-1)");
-            }
-        });
-
-        // Retrieve Subscriber Number
-        parser.register("+CNUM", new AtCommandHandler() {
-            @Override
-            public AtCommandResult handleActionCommand() {
-                String number = phone.getLine1Number();
-                if (number == null) {
-                    return new AtCommandResult(AtCommandResult.OK);
-                }
-                return new AtCommandResult("+CNUM: ,\"" + number + "\"," +
-                        PhoneNumberUtils.toaFromString(number) + ",,4");
-            }
-        });
-
-        // Microphone Gain
-        parser.register("+VGM", new AtCommandHandler() {
-            @Override
-            public AtCommandResult handleSetCommand(Object[] args) {
-                // AT+VGM=<gain>    in range [0,15]
-                // Headset/Handsfree is reporting its current gain setting
-                return new AtCommandResult(AtCommandResult.OK);
-            }
-        });
-
-        // Speaker Gain
-        parser.register("+VGS", new AtCommandHandler() {
-            @Override
-            public AtCommandResult handleSetCommand(Object[] args) {
-                // AT+VGS=<gain>    in range [0,15]
-                if (args.length != 1 || !(args[0] instanceof Integer)) {
-                    return new AtCommandResult(AtCommandResult.ERROR);
-                }
-                mScoGain = (Integer) args[0];
-                int flag =  mAudioManager.isBluetoothScoOn() ? AudioManager.FLAG_SHOW_UI:0;
-
-                mAudioManager.setStreamVolume(AudioManager.STREAM_BLUETOOTH_SCO, mScoGain, flag);
-                return new AtCommandResult(AtCommandResult.OK);
-            }
-        });
-
-        // Phone activity status
-        parser.register("+CPAS", new AtCommandHandler() {
-            @Override
-            public AtCommandResult handleActionCommand() {
-                int status = 0;
-                switch (mCM.getState()) {
-                case IDLE:
-                    status = 0;
-                    break;
-                case RINGING:
-                    status = 3;
-                    break;
-                case OFFHOOK:
-                    status = 4;
-                    break;
-                }
-                return new AtCommandResult("+CPAS: " + status);
-            }
-        });
-
-        mPhonebook.register(parser);
-    }
-
-    public void sendScoGainUpdate(int gain) {
-        if (mScoGain != gain && (mRemoteBrsf & BRSF_HF_REMOTE_VOL_CONTROL) != 0x0) {
-            sendURC("+VGS:" + gain);
-            mScoGain = gain;
-        }
-    }
-
-    public AtCommandResult reportCmeError(int error) {
-        if (mCmee) {
-            AtCommandResult result = new AtCommandResult(AtCommandResult.UNSOLICITED);
-            result.addResponse("+CME ERROR: " + error);
-            return result;
-        } else {
-            return new AtCommandResult(AtCommandResult.ERROR);
-        }
-    }
-
-    private static final int START_CALL_TIMEOUT = 10000;  // ms
-
-    private synchronized void expectCallStart() {
-        mWaitingForCallStart = true;
-        Message msg = Message.obtain(mHandler, CHECK_CALL_STARTED);
-        mHandler.sendMessageDelayed(msg, START_CALL_TIMEOUT);
-        if (!mStartCallWakeLock.isHeld()) {
-            mStartCallWakeLock.acquire(START_CALL_TIMEOUT);
-        }
-    }
-
-    private synchronized void callStarted() {
-        if (mWaitingForCallStart) {
-            mWaitingForCallStart = false;
-            sendURC("OK");
-            if (mStartCallWakeLock.isHeld()) {
-                mStartCallWakeLock.release();
-            }
-        }
-    }
-
-    private static final int START_VOICE_RECOGNITION_TIMEOUT = 5000;  // ms
-
-    private synchronized void expectVoiceRecognition() {
-        mWaitingForVoiceRecognition = true;
-        Message msg = Message.obtain(mHandler, CHECK_VOICE_RECOGNITION_STARTED);
-        mHandler.sendMessageDelayed(msg, START_VOICE_RECOGNITION_TIMEOUT);
-        if (!mStartVoiceRecognitionWakeLock.isHeld()) {
-            mStartVoiceRecognitionWakeLock.acquire(START_VOICE_RECOGNITION_TIMEOUT);
-        }
-    }
-
-    /* package */ synchronized boolean startVoiceRecognition() {
-
-        if  ((isCellularCallInProgress()) ||
-             (isVirtualCallInProgress()) ||
-             mVoiceRecognitionStarted) {
-            Log.e(TAG, "startVoiceRecognition: Call in progress");
-            return false;
-        }
-
-        mVoiceRecognitionStarted = true;
-
-        if (mWaitingForVoiceRecognition) {
-            // HF initiated
-            mWaitingForVoiceRecognition = false;
-            sendURC("OK");
-        } else {
-            // AG initiated
-            sendURC("+BVRA: 1");
-        }
-        boolean ret = audioOn();
-        if (ret == false) {
-            mVoiceRecognitionStarted = false;
-        }
-        if (mStartVoiceRecognitionWakeLock.isHeld()) {
-            mStartVoiceRecognitionWakeLock.release();
-        }
-        return ret;
-    }
-
-    /* package */ synchronized boolean stopVoiceRecognition() {
-
-        if (!isVoiceRecognitionInProgress()) {
-            return false;
-        }
-
-        mVoiceRecognitionStarted = false;
-
-        sendURC("+BVRA: 0");
-        audioOff();
-        return true;
-    }
-
-    // Voice Recognition in Progress
-    private boolean isVoiceRecognitionInProgress() {
-        return (mVoiceRecognitionStarted || mWaitingForVoiceRecognition);
-    }
-
-    /*
-     * This class broadcasts vendor-specific commands + arguments to interested receivers.
-     */
-    private class VendorSpecificCommandHandler extends AtCommandHandler {
-
-        private String mCommandName;
-
-        private int mCompanyId;
-
-        private VendorSpecificCommandHandler(String commandName, int companyId) {
-            mCommandName = commandName;
-            mCompanyId = companyId;
-        }
-
-        @Override
-        public AtCommandResult handleReadCommand() {
-            return new AtCommandResult(AtCommandResult.ERROR);
-        }
-
-        @Override
-        public AtCommandResult handleTestCommand() {
-            return new AtCommandResult(AtCommandResult.ERROR);
-        }
-
-        @Override
-        public AtCommandResult handleActionCommand() {
-            return new AtCommandResult(AtCommandResult.ERROR);
-        }
-
-        @Override
-        public AtCommandResult handleSetCommand(Object[] arguments) {
-            broadcastVendorSpecificEventIntent(mCommandName,
-                                               mCompanyId,
-                                               BluetoothHeadset.AT_CMD_TYPE_SET,
-                                               arguments,
-                                               mHeadset.getRemoteDevice());
-            return new AtCommandResult(AtCommandResult.OK);
-        }
-    }
-
-    private boolean inDebug() {
-        return DBG && SystemProperties.getBoolean(DebugThread.DEBUG_HANDSFREE, false);
-    }
-
-    private boolean allowAudioAnytime() {
-        return inDebug() && SystemProperties.getBoolean(DebugThread.DEBUG_HANDSFREE_AUDIO_ANYTIME,
-                false);
-    }
-
-    private void startDebug() {
-        if (DBG && mDebugThread == null) {
-            mDebugThread = new DebugThread();
-            mDebugThread.start();
-        }
-    }
-
-    private void stopDebug() {
-        if (mDebugThread != null) {
-            mDebugThread.interrupt();
-            mDebugThread = null;
-        }
-    }
-
-    // VirtualCall SCO support
-    //
-
-    // Cellular call in progress
-    private boolean isCellularCallInProgress() {
-        if (mCM.hasActiveFgCall() || mCM.hasActiveRingingCall()) return true;
-        return false;
-    }
-
-    // Virtual Call in Progress
-    private boolean isVirtualCallInProgress() {
-        return mVirtualCallStarted;
-    }
-
-    void setVirtualCallInProgress(boolean state) {
-        mVirtualCallStarted = state;
-    }
-
-    //NOTE: Currently the VirtualCall API does not allow the application to initiate a call
-    // transfer. Call transfer may be initiated from the handsfree device and this is handled by
-    // the VirtualCall API
-    synchronized boolean initiateScoUsingVirtualVoiceCall() {
-        if (DBG) log("initiateScoUsingVirtualVoiceCall: Received");
-        // 1. Check if the SCO state is idle
-        if (isCellularCallInProgress() || isVoiceRecognitionInProgress()) {
-            Log.e(TAG, "initiateScoUsingVirtualVoiceCall: Call in progress");
-            return false;
-        }
-
-        // 2. Perform outgoing call setup procedure
-        if (mBluetoothPhoneState.sendUpdate() && !isVirtualCallInProgress()) {
-            AtCommandResult result = new AtCommandResult(AtCommandResult.UNSOLICITED);
-            // outgoing call
-            result.addResponse("+CIEV: 3,2");
-            result.addResponse("+CIEV: 2,1");
-            result.addResponse("+CIEV: 3,0");
-            sendURC(result.toString());
-            if (DBG) Log.d(TAG, "initiateScoUsingVirtualVoiceCall: Sent Call-setup procedure");
-        }
-
-        mVirtualCallStarted = true;
-
-        // 3. Open the Audio Connection
-        if (audioOn() == false) {
-            log("initiateScoUsingVirtualVoiceCall: audioON failed");
-            terminateScoUsingVirtualVoiceCall();
-            return false;
-        }
-
-        mAudioPossible = true;
-
-        // Done
-        if (DBG) log("initiateScoUsingVirtualVoiceCall: Done");
-        return true;
-    }
-
-    synchronized boolean terminateScoUsingVirtualVoiceCall() {
-        if (DBG) log("terminateScoUsingVirtualVoiceCall: Received");
-
-        if (!isVirtualCallInProgress()) {
-            return false;
-        }
-
-        // 1. Release audio connection
-        audioOff();
-
-        // 2. terminate call-setup
-        if (mBluetoothPhoneState.sendUpdate()) {
-            AtCommandResult result = new AtCommandResult(AtCommandResult.UNSOLICITED);
-            // outgoing call
-            result.addResponse("+CIEV: 2,0");
-            sendURC(result.toString());
-            if (DBG) log("terminateScoUsingVirtualVoiceCall: Sent Call-setup procedure");
-        }
-        mVirtualCallStarted = false;
-        mAudioPossible = false;
-
-        // Done
-        if (DBG) log("terminateScoUsingVirtualVoiceCall: Done");
-        return true;
-    }
-
-
-    /** Debug thread to read debug properties - runs when debug.bt.hfp is true
-     *  at the time a bluetooth handsfree device is connected. Debug properties
-     *  are polled and mock updates sent every 1 second */
-    private class DebugThread extends Thread {
-        /** Turns on/off handsfree profile debugging mode */
-        static final String DEBUG_HANDSFREE = "debug.bt.hfp";
-
-        /** Mock battery level change - use 0 to 5 */
-        static final String DEBUG_HANDSFREE_BATTERY = "debug.bt.hfp.battery";
-
-        /** Mock no cellular service when false */
-        static final String DEBUG_HANDSFREE_SERVICE = "debug.bt.hfp.service";
-
-        /** Mock cellular roaming when true */
-        static final String DEBUG_HANDSFREE_ROAM = "debug.bt.hfp.roam";
-
-        /** false to true transition will force an audio (SCO) connection to
-         *  be established. true to false will force audio to be disconnected
-         */
-        static final String DEBUG_HANDSFREE_AUDIO = "debug.bt.hfp.audio";
-
-        /** true allows incoming SCO connection out of call.
-         */
-        static final String DEBUG_HANDSFREE_AUDIO_ANYTIME = "debug.bt.hfp.audio_anytime";
-
-        /** Mock signal strength change in ASU - use 0 to 31 */
-        static final String DEBUG_HANDSFREE_SIGNAL = "debug.bt.hfp.signal";
-
-        /** Debug AT+CLCC: print +CLCC result */
-        static final String DEBUG_HANDSFREE_CLCC = "debug.bt.hfp.clcc";
-
-        /** Debug AT+BSIR - Send In Band Ringtones Unsolicited AT command.
-         * debug.bt.unsol.inband = 0 => AT+BSIR = 0 sent by the AG
-         * debug.bt.unsol.inband = 1 => AT+BSIR = 0 sent by the AG
-         * Other values are ignored.
-         */
-
-        static final String DEBUG_UNSOL_INBAND_RINGTONE = "debug.bt.unsol.inband";
-
-        @Override
-        public void run() {
-            boolean oldService = true;
-            boolean oldRoam = false;
-            boolean oldAudio = false;
-
-            while (!isInterrupted() && inDebug()) {
-                int batteryLevel = SystemProperties.getInt(DEBUG_HANDSFREE_BATTERY, -1);
-                if (batteryLevel >= 0 && batteryLevel <= 5) {
-                    Intent intent = new Intent();
-                    intent.putExtra("level", batteryLevel);
-                    intent.putExtra("scale", 5);
-                    mBluetoothPhoneState.updateBatteryState(intent);
-                }
-
-                boolean serviceStateChanged = false;
-                if (SystemProperties.getBoolean(DEBUG_HANDSFREE_SERVICE, true) != oldService) {
-                    oldService = !oldService;
-                    serviceStateChanged = true;
-                }
-                if (SystemProperties.getBoolean(DEBUG_HANDSFREE_ROAM, false) != oldRoam) {
-                    oldRoam = !oldRoam;
-                    serviceStateChanged = true;
-                }
-                if (serviceStateChanged) {
-                    Bundle b = new Bundle();
-                    b.putInt("state", oldService ? 0 : 1);
-                    b.putBoolean("roaming", oldRoam);
-                    mBluetoothPhoneState.updateServiceState(true, ServiceState.newFromBundle(b));
-                }
-
-                if (SystemProperties.getBoolean(DEBUG_HANDSFREE_AUDIO, false) != oldAudio) {
-                    oldAudio = !oldAudio;
-                    if (oldAudio) {
-                        audioOn();
-                    } else {
-                        audioOff();
-                    }
-                }
-
-                int signalLevel = SystemProperties.getInt(DEBUG_HANDSFREE_SIGNAL, -1);
-                if (signalLevel >= 0 && signalLevel <= 31) {
-                    SignalStrength signalStrength = new SignalStrength(signalLevel, -1, -1, -1,
-                            -1, -1, -1, true);
-                    Intent intent = new Intent();
-                    Bundle data = new Bundle();
-                    signalStrength.fillInNotifierBundle(data);
-                    intent.putExtras(data);
-                    mBluetoothPhoneState.updateSignalState(intent);
-                }
-
-                if (SystemProperties.getBoolean(DEBUG_HANDSFREE_CLCC, false)) {
-                    log(gsmGetClccResult().toString());
-                }
-                try {
-                    sleep(1000);  // 1 second
-                } catch (InterruptedException e) {
-                    break;
-                }
-
-                int inBandRing =
-                    SystemProperties.getInt(DEBUG_UNSOL_INBAND_RINGTONE, -1);
-                if (inBandRing == 0 || inBandRing == 1) {
-                    AtCommandResult result =
-                        new AtCommandResult(AtCommandResult.UNSOLICITED);
-                    result.addResponse("+BSIR: " + inBandRing);
-                    sendURC(result.toString());
-                }
-            }
-        }
-    }
-
-    public void cdmaSwapSecondCallState() {
-        if (VDBG) log("cdmaSetSecondCallState: Toggling mCdmaIsSecondCallActive");
-        mCdmaIsSecondCallActive = !mCdmaIsSecondCallActive;
-        mCdmaCallsSwapped = true;
-    }
-
-    public void cdmaSetSecondCallState(boolean state) {
-        if (VDBG) log("cdmaSetSecondCallState: Setting mCdmaIsSecondCallActive to " + state);
-        mCdmaIsSecondCallActive = state;
-
-        if (!mCdmaIsSecondCallActive) {
-            mCdmaCallsSwapped = false;
-        }
-    }
-
-    private static void log(String msg) {
-        Log.d(TAG, msg);
-    }
-}
diff --git a/src/com/android/phone/BluetoothHeadsetService.java b/src/com/android/phone/BluetoothHeadsetService.java
deleted file mode 100755
index db64376..0000000
--- a/src/com/android/phone/BluetoothHeadsetService.java
+++ /dev/null
@@ -1,927 +0,0 @@
-/*
- * Copyright (C) 2006 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.app.Service;
-import android.bluetooth.BluetoothAdapter;
-import android.bluetooth.BluetoothAudioGateway;
-import android.bluetooth.BluetoothAudioGateway.IncomingConnectionInfo;
-import android.bluetooth.BluetoothDevice;
-import android.bluetooth.BluetoothHeadset;
-import android.bluetooth.BluetoothProfile;
-import android.bluetooth.BluetoothUuid;
-import android.bluetooth.HeadsetBase;
-import android.bluetooth.IBluetooth;
-import android.bluetooth.IBluetoothHeadset;
-import android.content.BroadcastReceiver;
-import android.content.Context;
-import android.content.Intent;
-import android.content.IntentFilter;
-import android.media.AudioManager;
-import android.os.Handler;
-import android.os.IBinder;
-import android.os.Message;
-import android.os.ParcelUuid;
-import android.os.PowerManager;
-import android.os.RemoteException;
-import android.os.ServiceManager;
-import android.provider.Settings;
-import android.util.Log;
-
-import java.util.ArrayList;
-import java.util.List;
-import java.util.concurrent.ConcurrentHashMap;
-
-/**
- * Provides Bluetooth Headset and Handsfree profile, as a service in
- * the Phone application.
- * @hide
- */
-public class BluetoothHeadsetService extends Service {
-    private static final String TAG = "Bluetooth HSHFP";
-    private static final boolean DBG = true;
-
-    private static final String PREF_NAME = BluetoothHeadsetService.class.getSimpleName();
-    private static final String PREF_LAST_HEADSET = "lastHeadsetAddress";
-
-    private static final int PHONE_STATE_CHANGED = 1;
-
-    private static final String BLUETOOTH_ADMIN_PERM = android.Manifest.permission.BLUETOOTH_ADMIN;
-    private static final String BLUETOOTH_PERM = android.Manifest.permission.BLUETOOTH;
-
-    private static boolean sHasStarted = false;
-
-    private BluetoothDevice mDeviceSdpQuery;
-    private BluetoothAdapter mAdapter;
-    private IBluetooth mBluetoothService;
-    private PowerManager mPowerManager;
-    private BluetoothAudioGateway mAg;
-    private BluetoothHandsfree mBtHandsfree;
-    private ConcurrentHashMap<BluetoothDevice, BluetoothRemoteHeadset> mRemoteHeadsets;
-    private BluetoothDevice mAudioConnectedDevice;
-
-    @Override
-    public void onCreate() {
-        super.onCreate();
-        mAdapter = BluetoothAdapter.getDefaultAdapter();
-        mPowerManager = (PowerManager) getSystemService(Context.POWER_SERVICE);
-        mBtHandsfree = PhoneApp.getInstance().getBluetoothHandsfree();
-        mAg = new BluetoothAudioGateway(mAdapter);
-        IntentFilter filter = new IntentFilter(
-                BluetoothDevice.ACTION_ACL_DISCONNECT_REQUESTED);
-        filter.addAction(BluetoothAdapter.ACTION_STATE_CHANGED);
-        filter.addAction(AudioManager.VOLUME_CHANGED_ACTION);
-        filter.addAction(BluetoothDevice.ACTION_UUID);
-        registerReceiver(mBluetoothReceiver, filter);
-
-        IBinder b = ServiceManager.getService(BluetoothAdapter.BLUETOOTH_SERVICE);
-        if (b == null) {
-            throw new RuntimeException("Bluetooth service not available");
-        }
-        mBluetoothService = IBluetooth.Stub.asInterface(b);
-        mRemoteHeadsets = new ConcurrentHashMap<BluetoothDevice, BluetoothRemoteHeadset>();
-   }
-
-   private class BluetoothRemoteHeadset {
-       private int mState;
-       private int mAudioState;
-       private int mHeadsetType;
-       private HeadsetBase mHeadset;
-       private IncomingConnectionInfo mIncomingInfo;
-
-       BluetoothRemoteHeadset() {
-           mState = BluetoothProfile.STATE_DISCONNECTED;
-           mHeadsetType = BluetoothHandsfree.TYPE_UNKNOWN;
-           mHeadset = null;
-           mIncomingInfo = null;
-           mAudioState = BluetoothHeadset.STATE_AUDIO_DISCONNECTED;
-       }
-
-       BluetoothRemoteHeadset(int headsetType, IncomingConnectionInfo incomingInfo) {
-           mState = BluetoothProfile.STATE_DISCONNECTED;
-           mHeadsetType = headsetType;
-           mHeadset = null;
-           mIncomingInfo = incomingInfo;
-           mAudioState = BluetoothHeadset.STATE_AUDIO_DISCONNECTED;
-       }
-   }
-
-   synchronized private BluetoothDevice getCurrentDevice() {
-       for (BluetoothDevice device : mRemoteHeadsets.keySet()) {
-           int state = mRemoteHeadsets.get(device).mState;
-           if (state == BluetoothProfile.STATE_CONNECTING ||
-               state == BluetoothProfile.STATE_CONNECTED) {
-               return device;
-           }
-       }
-       return null;
-   }
-
-    @Override
-    public void onStart(Intent intent, int startId) {
-         if (mAdapter == null) {
-            Log.w(TAG, "Stopping BluetoothHeadsetService: device does not have BT");
-            stopSelf();
-        } else {
-            if (!sHasStarted) {
-                if (DBG) log("Starting BluetoothHeadsetService");
-                if (mAdapter.isEnabled()) {
-                    mAg.start(mIncomingConnectionHandler);
-                    mBtHandsfree.onBluetoothEnabled();
-                }
-                sHasStarted = true;
-            }
-        }
-    }
-
-    private final Handler mIncomingConnectionHandler = new Handler() {
-        @Override
-        public void handleMessage(Message msg) {
-            synchronized(BluetoothHeadsetService.this) {
-                IncomingConnectionInfo info = (IncomingConnectionInfo)msg.obj;
-                int type = BluetoothHandsfree.TYPE_UNKNOWN;
-                switch(msg.what) {
-                case BluetoothAudioGateway.MSG_INCOMING_HEADSET_CONNECTION:
-                    type = BluetoothHandsfree.TYPE_HEADSET;
-                    break;
-                case BluetoothAudioGateway.MSG_INCOMING_HANDSFREE_CONNECTION:
-                    type = BluetoothHandsfree.TYPE_HANDSFREE;
-                    break;
-                }
-
-                Log.i(TAG, "Incoming rfcomm (" + BluetoothHandsfree.typeToString(type) +
-                      ") connection from " + info.mRemoteDevice + "on channel " +
-                      info.mRfcommChan);
-
-                int priority = BluetoothProfile.PRIORITY_OFF;
-                HeadsetBase headset;
-                priority = getPriority(info.mRemoteDevice);
-                if (priority <= BluetoothProfile.PRIORITY_OFF) {
-                    Log.i(TAG, "Rejecting incoming connection because priority = " + priority);
-
-                    headset = new HeadsetBase(mPowerManager, mAdapter,
-                                              info.mRemoteDevice,
-                                              info.mSocketFd, info.mRfcommChan,
-                                              null);
-                    headset.disconnect();
-                    try {
-                        mBluetoothService.notifyIncomingConnection(info.mRemoteDevice.getAddress(),
-                                                                   true);
-                    } catch (RemoteException e) {
-                        Log.e(TAG, "notifyIncomingConnection", e);
-                    }
-                    return;
-                }
-
-                BluetoothRemoteHeadset remoteHeadset;
-                BluetoothDevice device = getCurrentDevice();
-
-                int state = BluetoothProfile.STATE_DISCONNECTED;
-                if (device != null) {
-                    state = mRemoteHeadsets.get(device).mState;
-                }
-
-                switch (state) {
-                case BluetoothProfile.STATE_DISCONNECTED:
-                    // headset connecting us, lets join
-                    remoteHeadset = new BluetoothRemoteHeadset(type, info);
-                    mRemoteHeadsets.put(info.mRemoteDevice, remoteHeadset);
-
-                    try {
-                        mBluetoothService.notifyIncomingConnection(
-                           info.mRemoteDevice.getAddress(), false);
-                    } catch (RemoteException e) {
-                        Log.e(TAG, "notifyIncomingConnection");
-                    }
-                    break;
-                case BluetoothProfile.STATE_CONNECTING:
-                    if (!info.mRemoteDevice.equals(device)) {
-                        // different headset, ignoring
-                        Log.i(TAG, "Already attempting connect to " + device +
-                              ", disconnecting " + info.mRemoteDevice);
-
-                        headset = new HeadsetBase(mPowerManager, mAdapter,
-                                                  info.mRemoteDevice,
-                                                  info.mSocketFd, info.mRfcommChan,
-                                                  null);
-                        headset.disconnect();
-                        break;
-                    }
-
-                    // Incoming and Outgoing connections to the same headset.
-                    // The state machine manager will cancel outgoing and accept the incoming one.
-                    // Update the state
-                    mRemoteHeadsets.get(info.mRemoteDevice).mHeadsetType = type;
-                    mRemoteHeadsets.get(info.mRemoteDevice).mIncomingInfo = info;
-
-                    try {
-                        mBluetoothService.notifyIncomingConnection(
-                            info.mRemoteDevice.getAddress(), false);
-                    } catch (RemoteException e) {
-                        Log.e(TAG, "notifyIncomingConnection");
-                    }
-                    break;
-                case BluetoothProfile.STATE_CONNECTED:
-                    Log.i(TAG, "Already connected to " + device + ", disconnecting " +
-                            info.mRemoteDevice);
-                    rejectIncomingConnection(info);
-                    break;
-                }
-            }
-        }
-    };
-
-    private void rejectIncomingConnection(IncomingConnectionInfo info) {
-        HeadsetBase headset = new HeadsetBase(mPowerManager, mAdapter,
-            info.mRemoteDevice, info.mSocketFd, info.mRfcommChan, null);
-        headset.disconnect();
-    }
-
-
-    private final BroadcastReceiver mBluetoothReceiver = new BroadcastReceiver() {
-
-        @Override
-        public void onReceive(Context context, Intent intent) {
-            String action = intent.getAction();
-            BluetoothDevice device =
-                    intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
-
-            BluetoothDevice currDevice = getCurrentDevice();
-            int state = BluetoothProfile.STATE_DISCONNECTED;
-            if (currDevice != null) {
-                state = mRemoteHeadsets.get(currDevice).mState;
-            }
-
-            if ((state == BluetoothProfile.STATE_CONNECTED ||
-                    state == BluetoothProfile.STATE_CONNECTING) &&
-                    action.equals(BluetoothDevice.ACTION_ACL_DISCONNECT_REQUESTED) &&
-                    device.equals(currDevice)) {
-                try {
-                    mBinder.disconnect(currDevice);
-                } catch (RemoteException e) {}
-            } else if (action.equals(BluetoothAdapter.ACTION_STATE_CHANGED)) {
-                switch (intent.getIntExtra(BluetoothAdapter.EXTRA_STATE,
-                                           BluetoothAdapter.ERROR)) {
-                case BluetoothAdapter.STATE_ON:
-                    mAg.start(mIncomingConnectionHandler);
-                    mBtHandsfree.onBluetoothEnabled();
-                    break;
-                case BluetoothAdapter.STATE_TURNING_OFF:
-                    mBtHandsfree.onBluetoothDisabled();
-                    mAg.stop();
-                    if (currDevice != null) {
-                        try {
-                            mBinder.disconnect(currDevice);
-                        } catch (RemoteException e) {}
-                    }
-                    break;
-                }
-            } else if (action.equals(AudioManager.VOLUME_CHANGED_ACTION)) {
-                int streamType = intent.getIntExtra(AudioManager.EXTRA_VOLUME_STREAM_TYPE, -1);
-                if (streamType == AudioManager.STREAM_BLUETOOTH_SCO) {
-                    mBtHandsfree.sendScoGainUpdate(intent.getIntExtra(
-                            AudioManager.EXTRA_VOLUME_STREAM_VALUE, 0));
-                }
-
-            } else if (action.equals(BluetoothDevice.ACTION_UUID)) {
-                if (device.equals(mDeviceSdpQuery) && device.equals(currDevice)) {
-                    // We have got SDP records for the device we are interested in.
-                    getSdpRecordsAndConnect(device);
-                }
-            }
-        }
-    };
-
-    private static final int CONNECT_HEADSET_DELAYED = 1;
-    private Handler mHandler = new Handler() {
-        @Override
-        public void handleMessage(Message msg) {
-            switch (msg.what) {
-                case CONNECT_HEADSET_DELAYED:
-                    BluetoothDevice device = (BluetoothDevice) msg.obj;
-                    getSdpRecordsAndConnect(device);
-                    break;
-            }
-        }
-    };
-
-    @Override
-    public IBinder onBind(Intent intent) {
-        return mBinder;
-    }
-
-    // ------------------------------------------------------------------
-    // Bluetooth Headset Connect
-    // ------------------------------------------------------------------
-    private static final int RFCOMM_CONNECTED             = 1;
-    private static final int RFCOMM_ERROR                 = 2;
-
-    private long mTimestamp;
-
-    /**
-     * Thread for RFCOMM connection
-     * Messages are sent to mConnectingStatusHandler as connection progresses.
-     */
-    private RfcommConnectThread mConnectThread;
-    private class RfcommConnectThread extends Thread {
-        private BluetoothDevice device;
-        private int channel;
-        private int type;
-
-        private static final int EINTERRUPT = -1000;
-        private static final int ECONNREFUSED = -111;
-
-        public RfcommConnectThread(BluetoothDevice device, int channel, int type) {
-            super();
-            this.device = device;
-            this.channel = channel;
-            this.type = type;
-        }
-
-        private int waitForConnect(HeadsetBase headset) {
-            // Try to connect for 20 seconds
-            int result = 0;
-            for (int i=0; i < 40 && result == 0; i++) {
-                // waitForAsyncConnect returns 0 on timeout, 1 on success, < 0 on error.
-                result = headset.waitForAsyncConnect(500, mConnectedStatusHandler);
-                if (isInterrupted()) {
-                    headset.disconnect();
-                    return EINTERRUPT;
-                }
-            }
-            return result;
-        }
-
-        @Override
-        public void run() {
-            long timestamp;
-
-            timestamp = System.currentTimeMillis();
-            HeadsetBase headset = new HeadsetBase(mPowerManager, mAdapter,
-                                                  device, channel);
-
-            int result = waitForConnect(headset);
-
-            if (result != EINTERRUPT && result != 1) {
-                if (result == ECONNREFUSED && mDeviceSdpQuery == null) {
-                    // The rfcomm channel number might have changed, do SDP
-                    // query and try to connect again.
-                    mDeviceSdpQuery = getCurrentDevice();
-                    device.fetchUuidsWithSdp();
-                    mConnectThread = null;
-                    return;
-                } else {
-                    Log.i(TAG, "Trying to connect to rfcomm socket again after 1 sec");
-                    try {
-                      sleep(1000);  // 1 second
-                    } catch (InterruptedException e) {
-                      return;
-                    }
-                }
-                result = waitForConnect(headset);
-            }
-            mDeviceSdpQuery = null;
-            if (result == EINTERRUPT) return;
-
-            if (DBG) log("RFCOMM connection attempt took " +
-                  (System.currentTimeMillis() - timestamp) + " ms");
-            if (isInterrupted()) {
-                headset.disconnect();
-                return;
-            }
-            if (result < 0) {
-                Log.w(TAG, "headset.waitForAsyncConnect() error: " + result);
-                mConnectingStatusHandler.obtainMessage(RFCOMM_ERROR).sendToTarget();
-                return;
-            } else if (result == 0) {
-                mConnectingStatusHandler.obtainMessage(RFCOMM_ERROR).sendToTarget();
-                Log.w(TAG, "mHeadset.waitForAsyncConnect() error: " + result + "(timeout)");
-                return;
-            } else {
-                mConnectingStatusHandler.obtainMessage(RFCOMM_CONNECTED, headset).sendToTarget();
-            }
-        }
-    }
-
-    /**
-     * Receives events from mConnectThread back in the main thread.
-     */
-    private final Handler mConnectingStatusHandler = new Handler() {
-        @Override
-        public void handleMessage(Message msg) {
-            BluetoothDevice device = getCurrentDevice();
-            if (device == null ||
-                mRemoteHeadsets.get(device).mState != BluetoothProfile.STATE_CONNECTING) {
-                return;  // stale events
-            }
-
-            switch (msg.what) {
-            case RFCOMM_ERROR:
-                if (DBG) log("Rfcomm error");
-                mConnectThread = null;
-                setState(device, BluetoothProfile.STATE_DISCONNECTED);
-                break;
-            case RFCOMM_CONNECTED:
-                if (DBG) log("Rfcomm connected");
-                mConnectThread = null;
-                HeadsetBase headset = (HeadsetBase)msg.obj;
-                setState(device, BluetoothProfile.STATE_CONNECTED);
-
-                mRemoteHeadsets.get(device).mHeadset = headset;
-                mBtHandsfree.connectHeadset(headset, mRemoteHeadsets.get(device).mHeadsetType);
-                break;
-            }
-        }
-    };
-
-    /**
-     * Receives events from a connected RFCOMM socket back in the main thread.
-     */
-    private final Handler mConnectedStatusHandler = new Handler() {
-        @Override
-        public void handleMessage(Message msg) {
-            switch (msg.what) {
-            case HeadsetBase.RFCOMM_DISCONNECTED:
-                mBtHandsfree.resetAtState();
-                mBtHandsfree.setVirtualCallInProgress(false);
-                BluetoothDevice device = getCurrentDevice();
-                if (device != null) {
-                    setState(device, BluetoothProfile.STATE_DISCONNECTED);
-                }
-                break;
-            }
-        }
-    };
-
-    private synchronized void setState(BluetoothDevice device, int state) {
-        int prevState = mRemoteHeadsets.get(device).mState;
-        if (state != prevState) {
-            if (DBG) log("Device: " + device +
-                " Headset  state" + prevState + " -> " + state);
-            if (prevState == BluetoothProfile.STATE_CONNECTED) {
-                // Headset is disconnecting, stop the parser.
-                mBtHandsfree.disconnectHeadset();
-            }
-            Intent intent = new Intent(BluetoothHeadset.ACTION_CONNECTION_STATE_CHANGED);
-            intent.putExtra(BluetoothProfile.EXTRA_PREVIOUS_STATE, prevState);
-            intent.putExtra(BluetoothProfile.EXTRA_STATE, state);
-            intent.putExtra(BluetoothDevice.EXTRA_DEVICE, device);
-            if (state == BluetoothProfile.STATE_DISCONNECTED) {
-                mRemoteHeadsets.get(device).mHeadset = null;
-                mRemoteHeadsets.get(device).mHeadsetType = BluetoothHandsfree.TYPE_UNKNOWN;
-            }
-
-            mRemoteHeadsets.get(device).mState = state;
-
-            sendBroadcast(intent, BLUETOOTH_PERM);
-            if (state == BluetoothHeadset.STATE_CONNECTED) {
-                // Set the priority to AUTO_CONNECT
-                setPriority(device, BluetoothHeadset.PRIORITY_AUTO_CONNECT);
-                adjustOtherHeadsetPriorities(device);
-            }
-            try {
-                mBluetoothService.sendConnectionStateChange(device, BluetoothProfile.HEADSET,
-                                                            state, prevState);
-            } catch (RemoteException e) {
-                Log.e(TAG, "sendConnectionStateChange: exception");
-            }
-       }
-    }
-
-    private void adjustOtherHeadsetPriorities(BluetoothDevice connectedDevice) {
-       for (BluetoothDevice device : mAdapter.getBondedDevices()) {
-          if (getPriority(device) >= BluetoothHeadset.PRIORITY_AUTO_CONNECT &&
-              !device.equals(connectedDevice)) {
-              setPriority(device, BluetoothHeadset.PRIORITY_ON);
-          }
-       }
-    }
-
-    private void setPriority(BluetoothDevice device, int priority) {
-        try {
-            mBinder.setPriority(device, priority);
-        } catch (RemoteException e) {
-            Log.e(TAG, "Error while setting priority for: " + device);
-        }
-    }
-
-    private int getPriority(BluetoothDevice device) {
-        try {
-            return mBinder.getPriority(device);
-        } catch (RemoteException e) {
-            Log.e(TAG, "Error while getting priority for: " + device);
-        }
-        return BluetoothProfile.PRIORITY_UNDEFINED;
-    }
-
-    private synchronized void getSdpRecordsAndConnect(BluetoothDevice device) {
-        if (!device.equals(getCurrentDevice())) {
-            // stale
-            return;
-        }
-
-        // Check if incoming connection has already connected.
-        if (mRemoteHeadsets.get(device).mState == BluetoothProfile.STATE_CONNECTED) {
-            return;
-        }
-
-        ParcelUuid[] uuids = device.getUuids();
-        ParcelUuid[] localUuids = mAdapter.getUuids();
-        int type = BluetoothHandsfree.TYPE_UNKNOWN;
-        if (uuids != null) {
-            if (BluetoothUuid.isUuidPresent(uuids, BluetoothUuid.Handsfree) &&
-                BluetoothUuid.isUuidPresent(localUuids, BluetoothUuid.Handsfree_AG)) {
-                log("SDP UUID: TYPE_HANDSFREE");
-                type = BluetoothHandsfree.TYPE_HANDSFREE;
-                mRemoteHeadsets.get(device).mHeadsetType = type;
-                int channel = device.getServiceChannel(BluetoothUuid.Handsfree);
-                mConnectThread = new RfcommConnectThread(device, channel, type);
-                if (mAdapter.isDiscovering()) {
-                    mAdapter.cancelDiscovery();
-                }
-                mConnectThread.start();
-                if (getPriority(device) < BluetoothHeadset.PRIORITY_AUTO_CONNECT) {
-                    setPriority(device, BluetoothHeadset.PRIORITY_AUTO_CONNECT);
-                }
-                return;
-            } else if (BluetoothUuid.isUuidPresent(uuids, BluetoothUuid.HSP) &&
-                BluetoothUuid.isUuidPresent(localUuids, BluetoothUuid.HSP_AG)) {
-                log("SDP UUID: TYPE_HEADSET");
-                type = BluetoothHandsfree.TYPE_HEADSET;
-                mRemoteHeadsets.get(device).mHeadsetType = type;
-                int channel = device.getServiceChannel(BluetoothUuid.HSP);
-                mConnectThread = new RfcommConnectThread(device, channel, type);
-                if (mAdapter.isDiscovering()) {
-                    mAdapter.cancelDiscovery();
-                }
-                mConnectThread.start();
-                if (getPriority(device) < BluetoothHeadset.PRIORITY_AUTO_CONNECT) {
-                    setPriority(device, BluetoothHeadset.PRIORITY_AUTO_CONNECT);
-                }
-                return;
-            }
-        }
-        log("SDP UUID: TYPE_UNKNOWN");
-        mRemoteHeadsets.get(device).mHeadsetType = type;
-        setState(device, BluetoothProfile.STATE_DISCONNECTED);
-        return;
-    }
-
-    /**
-     * Handlers for incoming service calls
-     */
-    private final IBluetoothHeadset.Stub mBinder = new IBluetoothHeadset.Stub() {
-        public int getConnectionState(BluetoothDevice device) {
-            enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission");
-            BluetoothRemoteHeadset headset = mRemoteHeadsets.get(device);
-            if (headset == null) {
-                return BluetoothProfile.STATE_DISCONNECTED;
-            }
-            return headset.mState;
-        }
-
-        public List<BluetoothDevice> getConnectedDevices() {
-            enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission");
-            return getDevicesMatchingConnectionStates(
-                new int[] {BluetoothProfile.STATE_CONNECTED});
-        }
-
-        public boolean connect(BluetoothDevice device) {
-            enforceCallingOrSelfPermission(BLUETOOTH_ADMIN_PERM,
-                                           "Need BLUETOOTH_ADMIN permission");
-            synchronized (BluetoothHeadsetService.this) {
-                BluetoothDevice currDevice = getCurrentDevice();
-
-                if (currDevice == device ||
-                    getPriority(device) == BluetoothProfile.PRIORITY_OFF) {
-                    return false;
-                }
-                if (currDevice != null) {
-                    disconnect(currDevice);
-                }
-                try {
-                    return mBluetoothService.connectHeadset(device.getAddress());
-                } catch (RemoteException e) {
-                    Log.e(TAG, "connectHeadset");
-                    return false;
-                }
-            }
-        }
-
-        public boolean disconnect(BluetoothDevice device) {
-            enforceCallingOrSelfPermission(BLUETOOTH_ADMIN_PERM,
-                                           "Need BLUETOOTH_ADMIN permission");
-            synchronized (BluetoothHeadsetService.this) {
-                BluetoothRemoteHeadset headset = mRemoteHeadsets.get(device);
-                if (headset == null ||
-                    headset.mState == BluetoothProfile.STATE_DISCONNECTED ||
-                    headset.mState == BluetoothProfile.STATE_DISCONNECTING) {
-                    return false;
-                }
-                try {
-                    return mBluetoothService.disconnectHeadset(device.getAddress());
-                } catch (RemoteException e) {
-                    Log.e(TAG, "disconnectHeadset");
-                    return false;
-                }
-            }
-        }
-
-        public synchronized boolean isAudioConnected(BluetoothDevice device) {
-            enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission");
-            if (device.equals(mAudioConnectedDevice)) return true;
-            return false;
-        }
-
-        public synchronized List<BluetoothDevice> getDevicesMatchingConnectionStates(int[] states) {
-            enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission");
-            List<BluetoothDevice> headsets = new ArrayList<BluetoothDevice>();
-            for (BluetoothDevice device: mRemoteHeadsets.keySet()) {
-                int headsetState = getConnectionState(device);
-                for (int state : states) {
-                    if (state == headsetState) {
-                        headsets.add(device);
-                        break;
-                    }
-                }
-            }
-            return headsets;
-        }
-
-        public boolean startVoiceRecognition(BluetoothDevice device) {
-            enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission");
-            synchronized (BluetoothHeadsetService.this) {
-                if (device == null ||
-                    mRemoteHeadsets.get(device) == null ||
-                    mRemoteHeadsets.get(device).mState != BluetoothProfile.STATE_CONNECTED) {
-                    return false;
-                }
-                return mBtHandsfree.startVoiceRecognition();
-            }
-        }
-
-        public boolean stopVoiceRecognition(BluetoothDevice device) {
-            enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission");
-            synchronized (BluetoothHeadsetService.this) {
-                if (device == null ||
-                    mRemoteHeadsets.get(device) == null ||
-                    mRemoteHeadsets.get(device).mState != BluetoothProfile.STATE_CONNECTED) {
-                    return false;
-                }
-
-                return mBtHandsfree.stopVoiceRecognition();
-            }
-        }
-
-        public int getBatteryUsageHint(BluetoothDevice device) {
-            enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission");
-
-            return HeadsetBase.getAtInputCount();
-        }
-
-        public int getPriority(BluetoothDevice device) {
-            enforceCallingOrSelfPermission(BLUETOOTH_ADMIN_PERM,
-                "Need BLUETOOTH_ADMIN permission");
-            synchronized (BluetoothHeadsetService.this) {
-                int priority = Settings.Secure.getInt(getContentResolver(),
-                        Settings.Secure.getBluetoothHeadsetPriorityKey(device.getAddress()),
-                        BluetoothProfile.PRIORITY_UNDEFINED);
-                return priority;
-            }
-        }
-
-        public boolean setPriority(BluetoothDevice device, int priority) {
-            enforceCallingOrSelfPermission(BLUETOOTH_ADMIN_PERM,
-                "Need BLUETOOTH_ADMIN permission");
-            synchronized (BluetoothHeadsetService.this) {
-                Settings.Secure.putInt(getContentResolver(),
-                        Settings.Secure.getBluetoothHeadsetPriorityKey(device.getAddress()),
-                        priority);
-                if (DBG) log("Saved priority " + device + " = " + priority);
-                return true;
-            }
-        }
-
-        public boolean createIncomingConnect(BluetoothDevice device) {
-            synchronized (BluetoothHeadsetService.this) {
-                HeadsetBase headset;
-                setState(device, BluetoothProfile.STATE_CONNECTING);
-
-                IncomingConnectionInfo info = mRemoteHeadsets.get(device).mIncomingInfo;
-                headset = new HeadsetBase(mPowerManager, mAdapter,
-                                          device,
-                                          info.mSocketFd, info.mRfcommChan,
-                                          mConnectedStatusHandler);
-
-                mRemoteHeadsets.get(device).mHeadset = headset;
-
-                mConnectingStatusHandler.obtainMessage(RFCOMM_CONNECTED, headset).sendToTarget();
-                return true;
-            }
-        }
-
-        public boolean startScoUsingVirtualVoiceCall(BluetoothDevice device) {
-            enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission");
-            synchronized (BluetoothHeadsetService.this) {
-                if (device == null ||
-                    mRemoteHeadsets.get(device) == null ||
-                    mRemoteHeadsets.get(device).mState != BluetoothProfile.STATE_CONNECTED ||
-                    getAudioState(device) != BluetoothHeadset.STATE_AUDIO_DISCONNECTED) {
-                    return false;
-                }
-                return mBtHandsfree.initiateScoUsingVirtualVoiceCall();
-            }
-        }
-
-        public boolean stopScoUsingVirtualVoiceCall(BluetoothDevice device) {
-            enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission");
-            synchronized (BluetoothHeadsetService.this) {
-                if (device == null ||
-                    mRemoteHeadsets.get(device) == null ||
-                    mRemoteHeadsets.get(device).mState != BluetoothProfile.STATE_CONNECTED ||
-                    getAudioState(device) == BluetoothHeadset.STATE_AUDIO_DISCONNECTED) {
-                    return false;
-                }
-                return mBtHandsfree.terminateScoUsingVirtualVoiceCall();
-            }
-        }
-
-        public boolean rejectIncomingConnect(BluetoothDevice device) {
-            synchronized (BluetoothHeadsetService.this) {
-                BluetoothRemoteHeadset headset = mRemoteHeadsets.get(device);
-                if (headset != null) {
-                    IncomingConnectionInfo info = headset.mIncomingInfo;
-                    rejectIncomingConnection(info);
-                } else {
-                    Log.e(TAG, "Error no record of remote headset");
-                }
-                return true;
-            }
-        }
-
-        public boolean acceptIncomingConnect(BluetoothDevice device) {
-            synchronized (BluetoothHeadsetService.this) {
-                HeadsetBase headset;
-                BluetoothRemoteHeadset cachedHeadset = mRemoteHeadsets.get(device);
-                if (cachedHeadset == null) {
-                    Log.e(TAG, "Cached Headset is Null in acceptIncomingConnect");
-                    return false;
-                }
-                IncomingConnectionInfo info = cachedHeadset.mIncomingInfo;
-                headset = new HeadsetBase(mPowerManager, mAdapter,
-                                          device,
-                                          info.mSocketFd, info.mRfcommChan,
-                                          mConnectedStatusHandler);
-
-                setState(device, BluetoothProfile.STATE_CONNECTED);
-
-                cachedHeadset.mHeadset = headset;
-                mBtHandsfree.connectHeadset(headset, cachedHeadset.mHeadsetType);
-
-                if (DBG) log("Successfully used incoming connection");
-                return true;
-            }
-        }
-
-        public  boolean cancelConnectThread() {
-            synchronized (BluetoothHeadsetService.this) {
-                if (mConnectThread != null) {
-                    // cancel the connection thread
-                    mConnectThread.interrupt();
-                    try {
-                        mConnectThread.join();
-                    } catch (InterruptedException e) {
-                        Log.e(TAG, "Connection cancelled twice?", e);
-                    }
-                    mConnectThread = null;
-                }
-                return true;
-            }
-        }
-
-        public boolean connectHeadsetInternal(BluetoothDevice device) {
-            synchronized (BluetoothHeadsetService.this) {
-                BluetoothDevice currDevice = getCurrentDevice();
-                if (currDevice == null) {
-                    BluetoothRemoteHeadset headset = new BluetoothRemoteHeadset();
-                    mRemoteHeadsets.put(device, headset);
-
-                    setState(device, BluetoothProfile.STATE_CONNECTING);
-                    if (device.getUuids() == null) {
-                        // We might not have got the UUID change notification from
-                        // Bluez yet, if we have just paired. Try after 1.5 secs.
-                        Message msg = new Message();
-                        msg.what = CONNECT_HEADSET_DELAYED;
-                        msg.obj = device;
-                        mHandler.sendMessageDelayed(msg, 1500);
-                    } else {
-                        getSdpRecordsAndConnect(device);
-                    }
-                    return true;
-                } else {
-                      Log.w(TAG, "connectHeadset(" + device + "): failed: already in state " +
-                            mRemoteHeadsets.get(currDevice).mState +
-                            " with headset " + currDevice);
-                }
-                return false;
-            }
-        }
-
-        public boolean disconnectHeadsetInternal(BluetoothDevice device) {
-            synchronized (BluetoothHeadsetService.this) {
-                BluetoothRemoteHeadset remoteHeadset = mRemoteHeadsets.get(device);
-                if (remoteHeadset == null) return false;
-
-                if (remoteHeadset.mState == BluetoothProfile.STATE_CONNECTED) {
-                    // Send a dummy battery level message to force headset
-                    // out of sniff mode so that it will immediately notice
-                    // the disconnection. We are currently sending it for
-                    // handsfree only.
-                    // TODO: Call hci_conn_enter_active_mode() from
-                    // rfcomm_send_disc() in the kernel instead.
-                    // See http://b/1716887
-                    setState(device, BluetoothProfile.STATE_DISCONNECTING);
-
-                    HeadsetBase headset = remoteHeadset.mHeadset;
-                    if (remoteHeadset.mHeadsetType == BluetoothHandsfree.TYPE_HANDSFREE) {
-                        headset.sendURC("+CIEV: 7,3");
-                    }
-
-                    if (headset != null) {
-                        headset.disconnect();
-                        headset = null;
-                    }
-                    setState(device, BluetoothProfile.STATE_DISCONNECTED);
-                    return true;
-                } else if (remoteHeadset.mState == BluetoothProfile.STATE_CONNECTING) {
-                    // The state machine would have canceled the connect thread.
-                    // Just set the state here.
-                    setState(device, BluetoothProfile.STATE_DISCONNECTED);
-                    return true;
-                }
-                return false;
-            }
-        }
-
-        public boolean setAudioState(BluetoothDevice device, int state) {
-            // mRemoteHeadsets handles put/get concurrency by itself
-            int prevState = mRemoteHeadsets.get(device).mAudioState;
-            mRemoteHeadsets.get(device).mAudioState = state;
-            if (state == BluetoothHeadset.STATE_AUDIO_CONNECTED) {
-                mAudioConnectedDevice = device;
-            } else if (state == BluetoothHeadset.STATE_AUDIO_DISCONNECTED) {
-                mAudioConnectedDevice = null;
-            }
-            Intent intent = new Intent(BluetoothHeadset.ACTION_AUDIO_STATE_CHANGED);
-            intent.putExtra(BluetoothHeadset.EXTRA_STATE, state);
-            intent.putExtra(BluetoothHeadset.EXTRA_PREVIOUS_STATE, prevState);
-            intent.putExtra(BluetoothDevice.EXTRA_DEVICE, device);
-            sendBroadcast(intent, android.Manifest.permission.BLUETOOTH);
-            if (DBG) log("AudioStateIntent: " + device + " State: " + state
-                         + " PrevState: " + prevState);
-            return true;
-        }
-
-        public int getAudioState(BluetoothDevice device) {
-            // mRemoteHeadsets handles put/get concurrency by itself
-            BluetoothRemoteHeadset headset = mRemoteHeadsets.get(device);
-            if (headset == null) return BluetoothHeadset.STATE_AUDIO_DISCONNECTED;
-
-            return headset.mAudioState;
-       }
-    };
-
-    @Override
-    public void onDestroy() {
-        super.onDestroy();
-        if (DBG) log("Stopping BluetoothHeadsetService");
-        unregisterReceiver(mBluetoothReceiver);
-        mBtHandsfree.onBluetoothDisabled();
-        mAg.stop();
-        sHasStarted = false;
-        BluetoothDevice device = getCurrentDevice();
-        if (device != null) {
-            setState(device, BluetoothProfile.STATE_DISCONNECTED);
-        }
-    }
-
-
-
-    private static void log(String msg) {
-        Log.d(TAG, msg);
-    }
-}
diff --git a/src/com/android/phone/BluetoothPhoneService.java b/src/com/android/phone/BluetoothPhoneService.java
new file mode 100755
index 0000000..e2f48fd
--- /dev/null
+++ b/src/com/android/phone/BluetoothPhoneService.java
@@ -0,0 +1,931 @@
+/*
+ * Copyright (C) 2012 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.app.Service;
+import android.bluetooth.BluetoothAdapter;
+import android.bluetooth.BluetoothDevice;
+import android.bluetooth.BluetoothHeadset;
+import android.bluetooth.BluetoothProfile;
+import android.bluetooth.IBluetoothHeadsetPhone;
+import android.content.Context;
+import android.content.Intent;
+import android.os.AsyncResult;
+import android.os.Handler;
+import android.os.IBinder;
+import android.os.Message;
+import android.os.PowerManager;
+import android.os.PowerManager.WakeLock;
+import android.os.SystemProperties;
+import android.telephony.PhoneNumberUtils;
+import android.telephony.ServiceState;
+import android.util.Log;
+
+import com.android.internal.telephony.Call;
+import com.android.internal.telephony.Connection;
+import com.android.internal.telephony.Phone;
+import com.android.internal.telephony.PhoneConstants;
+import com.android.internal.telephony.TelephonyIntents;
+import com.android.internal.telephony.CallManager;
+
+import java.io.IOException;
+import java.util.LinkedList;
+import java.util.List;
+
+/**
+ * Bluetooth headset manager for the Phone app.
+ * @hide
+ */
+public class BluetoothPhoneService extends Service {
+    private static final String TAG = "BluetoothPhoneService";
+    private static final boolean DBG = (PhoneGlobals.DBG_LEVEL >= 1)
+            && (SystemProperties.getInt("ro.debuggable", 0) == 1);
+    private static final boolean VDBG = (PhoneGlobals.DBG_LEVEL >= 2);  // even more logging
+
+    private static final String MODIFY_PHONE_STATE = android.Manifest.permission.MODIFY_PHONE_STATE;
+
+    private BluetoothAdapter mAdapter;
+    private CallManager mCM;
+
+    private BluetoothHeadset mBluetoothHeadset;
+
+    private PowerManager mPowerManager;
+
+    private WakeLock mStartCallWakeLock;  // held while waiting for the intent to start call
+
+    private PhoneConstants.State mPhoneState = PhoneConstants.State.IDLE;
+    CdmaPhoneCallState.PhoneCallState mCdmaThreeWayCallState =
+                                            CdmaPhoneCallState.PhoneCallState.IDLE;
+
+    private Call.State mForegroundCallState;
+    private Call.State mRingingCallState;
+    private CallNumber mRingNumber;
+    // number of active calls
+    int mNumActive;
+    // number of background (held) calls
+    int mNumHeld;
+
+    long mBgndEarliestConnectionTime = 0;
+
+    private boolean mRoam = false;
+
+    // CDMA specific flag used in context with BT devices having display capabilities
+    // to show which Caller is active. This state might not be always true as in CDMA
+    // networks if a caller drops off no update is provided to the Phone.
+    // This flag is just used as a toggle to provide a update to the BT device to specify
+    // which caller is active.
+    private boolean mCdmaIsSecondCallActive = false;
+    private boolean mCdmaCallsSwapped = false;
+
+    private long[] mClccTimestamps; // Timestamps associated with each clcc index
+    private boolean[] mClccUsed;     // Is this clcc index in use
+
+    private static final int GSM_MAX_CONNECTIONS = 6;  // Max connections allowed by GSM
+    private static final int CDMA_MAX_CONNECTIONS = 2;  // Max connections allowed by CDMA
+
+    @Override
+    public void onCreate() {
+        super.onCreate();
+        mCM = CallManager.getInstance();
+        mAdapter = BluetoothAdapter.getDefaultAdapter();
+        if (mAdapter == null) {
+            if (VDBG) Log.d(TAG, "mAdapter null");
+            return;
+        }
+
+        mPowerManager = (PowerManager) getSystemService(Context.POWER_SERVICE);
+        mStartCallWakeLock = mPowerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK,
+                                                       TAG + ":StartCall");
+        mStartCallWakeLock.setReferenceCounted(false);
+
+        mAdapter.getProfileProxy(this, mProfileListener, BluetoothProfile.HEADSET);
+
+        mForegroundCallState = Call.State.IDLE;
+        mRingingCallState = Call.State.IDLE;
+        mNumActive = 0;
+        mNumHeld = 0;
+        mRingNumber = new CallNumber("", 0);;
+        mRoam = false;
+
+        updateServiceState(mCM.getDefaultPhone().getServiceState());
+        handlePreciseCallStateChange(null);
+
+        if(VDBG) Log.d(TAG, "registerForServiceStateChanged");
+        // register for updates
+        // Use the service state of default phone as BT service state to
+        // avoid situation such as no cell or wifi connection but still
+        // reporting in service (since SipPhone always reports in service).
+        mCM.getDefaultPhone().registerForServiceStateChanged(mHandler,
+                                                             SERVICE_STATE_CHANGED, null);
+        mCM.registerForPreciseCallStateChanged(mHandler,
+                                               PRECISE_CALL_STATE_CHANGED, null);
+        mCM.registerForCallWaiting(mHandler,
+                                   PHONE_CDMA_CALL_WAITING, null);
+        // TODO(BT) registerForIncomingRing?
+        // TODO(BT) registerdisconnection?
+        mClccTimestamps = new long[GSM_MAX_CONNECTIONS];
+        mClccUsed = new boolean[GSM_MAX_CONNECTIONS];
+        for (int i = 0; i < GSM_MAX_CONNECTIONS; i++) {
+            mClccUsed[i] = false;
+        }
+    }
+
+    @Override
+    public void onStart(Intent intent, int startId) {
+        if (mAdapter == null) {
+            Log.w(TAG, "Stopping Bluetooth BluetoothPhoneService Service: device does not have BT");
+            stopSelf();
+        }
+        if (VDBG) Log.d(TAG, "BluetoothPhoneService started");
+    }
+
+    @Override
+    public void onDestroy() {
+        super.onDestroy();
+        if (DBG) log("Stopping Bluetooth BluetoothPhoneService Service");
+    }
+
+    @Override
+    public IBinder onBind(Intent intent) {
+        return mBinder;
+    }
+
+    private static final int SERVICE_STATE_CHANGED = 1;
+    private static final int PRECISE_CALL_STATE_CHANGED = 2;
+    private static final int PHONE_CDMA_CALL_WAITING = 3;
+    private static final int LIST_CURRENT_CALLS = 4;
+    private static final int QUERY_PHONE_STATE = 5;
+    private static final int CDMA_SWAP_SECOND_CALL_STATE = 6;
+    private static final int CDMA_SET_SECOND_CALL_STATE = 7;
+
+    private Handler mHandler = new Handler() {
+        @Override
+        public void handleMessage(Message msg) {
+            if (VDBG) Log.d(TAG, "handleMessage: " + msg.what);
+            switch(msg.what) {
+                case SERVICE_STATE_CHANGED:
+                    ServiceState state = (ServiceState) ((AsyncResult) msg.obj).result;
+                    updateServiceState(state);
+                    break;
+                case PRECISE_CALL_STATE_CHANGED:
+                case PHONE_CDMA_CALL_WAITING:
+                    Connection connection = null;
+                    if (((AsyncResult) msg.obj).result instanceof Connection) {
+                        connection = (Connection) ((AsyncResult) msg.obj).result;
+                    }
+                    handlePreciseCallStateChange(connection);
+                    break;
+                case LIST_CURRENT_CALLS:
+                    handleListCurrentCalls();
+                    break;
+                case QUERY_PHONE_STATE:
+                    handleQueryPhoneState();
+                    break;
+                case CDMA_SWAP_SECOND_CALL_STATE:
+                    handleCdmaSwapSecondCallState();
+                    break;
+                case CDMA_SET_SECOND_CALL_STATE:
+                    handleCdmaSetSecondCallState((Boolean) msg.obj);
+                    break;
+            }
+        }
+    };
+
+    private void updateBtPhoneStateAfterRadioTechnologyChange() {
+        if(VDBG) Log.d(TAG, "updateBtPhoneStateAfterRadioTechnologyChange...");
+
+        //Unregister all events from the old obsolete phone
+        mCM.getDefaultPhone().unregisterForServiceStateChanged(mHandler);
+        mCM.unregisterForPreciseCallStateChanged(mHandler);
+        mCM.unregisterForCallWaiting(mHandler);
+
+        //Register all events new to the new active phone
+        mCM.getDefaultPhone().registerForServiceStateChanged(mHandler,
+                                                             SERVICE_STATE_CHANGED, null);
+        mCM.registerForPreciseCallStateChanged(mHandler,
+                                               PRECISE_CALL_STATE_CHANGED, null);
+        mCM.registerForCallWaiting(mHandler,
+                                   PHONE_CDMA_CALL_WAITING, null);
+    }
+
+    private void updateServiceState(ServiceState state) {
+        boolean roam = state.getRoaming();
+
+        if (roam != mRoam) {
+            mRoam = roam;
+            if (mBluetoothHeadset != null) {
+                mBluetoothHeadset.roamChanged(roam);
+            }
+        }
+    }
+
+    private void handlePreciseCallStateChange(Connection connection) {
+        // get foreground call state
+        int oldNumActive = mNumActive;
+        int oldNumHeld = mNumHeld;
+        Call.State oldRingingCallState = mRingingCallState;
+        Call.State oldForegroundCallState = mForegroundCallState;
+        CallNumber oldRingNumber = mRingNumber;
+
+        Call foregroundCall = mCM.getActiveFgCall();
+
+        if (VDBG)
+            Log.d(TAG, " handlePreciseCallStateChange: foreground: " + foregroundCall +
+                " background: " + mCM.getFirstActiveBgCall() + " ringing: " +
+                mCM.getFirstActiveRingingCall());
+
+        mForegroundCallState = foregroundCall.getState();
+        /* if in transition, do not update */
+        if (mForegroundCallState == Call.State.DISCONNECTING)
+        {
+            Log.d(TAG, "handlePreciseCallStateChange. Call disconnecting, wait before update");
+            return;
+        }
+        else
+            mNumActive = (mForegroundCallState == Call.State.ACTIVE) ? 1 : 0;
+
+        Call ringingCall = mCM.getFirstActiveRingingCall();
+        mRingingCallState = ringingCall.getState();
+        mRingNumber = getCallNumber(connection, ringingCall);
+
+        if (mCM.getDefaultPhone().getPhoneType() == PhoneConstants.PHONE_TYPE_CDMA) {
+            mNumHeld = getNumHeldCdma();
+            PhoneGlobals app = PhoneGlobals.getInstance();
+            if (app.cdmaPhoneCallState != null) {
+                CdmaPhoneCallState.PhoneCallState currCdmaThreeWayCallState =
+                        app.cdmaPhoneCallState.getCurrentCallState();
+                CdmaPhoneCallState.PhoneCallState prevCdmaThreeWayCallState =
+                    app.cdmaPhoneCallState.getPreviousCallState();
+
+                log("CDMA call state: " + currCdmaThreeWayCallState + " prev state:" +
+                    prevCdmaThreeWayCallState);
+
+                if ((mBluetoothHeadset != null) &&
+                    (mCdmaThreeWayCallState != currCdmaThreeWayCallState)) {
+                    // In CDMA, the network does not provide any feedback
+                    // to the phone when the 2nd MO call goes through the
+                    // stages of DIALING > ALERTING -> ACTIVE we fake the
+                    // sequence
+                    log("CDMA 3way call state change. mNumActive: " + mNumActive +
+                        " mNumHeld: " + mNumHeld + " IsThreeWayCallOrigStateDialing: " +
+                        app.cdmaPhoneCallState.IsThreeWayCallOrigStateDialing());
+                    if ((currCdmaThreeWayCallState ==
+                            CdmaPhoneCallState.PhoneCallState.THRWAY_ACTIVE)
+                                && app.cdmaPhoneCallState.IsThreeWayCallOrigStateDialing()) {
+                        // Mimic dialing, put the call on hold, alerting
+                        mBluetoothHeadset.phoneStateChanged(0, mNumHeld,
+                            convertCallState(Call.State.IDLE, Call.State.DIALING),
+                            mRingNumber.mNumber, mRingNumber.mType);
+
+                        mBluetoothHeadset.phoneStateChanged(0, mNumHeld,
+                            convertCallState(Call.State.IDLE, Call.State.ALERTING),
+                            mRingNumber.mNumber, mRingNumber.mType);
+
+                    }
+
+                    // In CDMA, the network does not provide any feedback to
+                    // the phone when a user merges a 3way call or swaps
+                    // between two calls we need to send a CIEV response
+                    // indicating that a call state got changed which should
+                    // trigger a CLCC update request from the BT client.
+                    if (currCdmaThreeWayCallState ==
+                            CdmaPhoneCallState.PhoneCallState.CONF_CALL &&
+                            prevCdmaThreeWayCallState ==
+                              CdmaPhoneCallState.PhoneCallState.THRWAY_ACTIVE) {
+                        log("CDMA 3way conf call. mNumActive: " + mNumActive +
+                            " mNumHeld: " + mNumHeld);
+                        mBluetoothHeadset.phoneStateChanged(mNumActive, mNumHeld,
+                            convertCallState(Call.State.IDLE, mForegroundCallState),
+                            mRingNumber.mNumber, mRingNumber.mType);
+                    }
+                }
+                mCdmaThreeWayCallState = currCdmaThreeWayCallState;
+            }
+        } else {
+            mNumHeld = getNumHeldUmts();
+        }
+
+        boolean callsSwitched = false;
+        if (mCM.getDefaultPhone().getPhoneType() == PhoneConstants.PHONE_TYPE_CDMA &&
+            mCdmaThreeWayCallState == CdmaPhoneCallState.PhoneCallState.CONF_CALL) {
+            callsSwitched = mCdmaCallsSwapped;
+        } else {
+            Call backgroundCall = mCM.getFirstActiveBgCall();
+            callsSwitched =
+                (mNumHeld == 1 && ! (backgroundCall.getEarliestConnectTime() ==
+                    mBgndEarliestConnectionTime));
+            mBgndEarliestConnectionTime = backgroundCall.getEarliestConnectTime();
+        }
+
+        if (mNumActive != oldNumActive || mNumHeld != oldNumHeld ||
+            mRingingCallState != oldRingingCallState ||
+            mForegroundCallState != oldForegroundCallState ||
+            !mRingNumber.equalTo(oldRingNumber) ||
+            callsSwitched) {
+            if (mBluetoothHeadset != null) {
+                mBluetoothHeadset.phoneStateChanged(mNumActive, mNumHeld,
+                    convertCallState(mRingingCallState, mForegroundCallState),
+                    mRingNumber.mNumber, mRingNumber.mType);
+            }
+        }
+    }
+
+    private void handleListCurrentCalls() {
+        Phone phone = mCM.getDefaultPhone();
+        int phoneType = phone.getPhoneType();
+
+        // TODO(BT) handle virtual call
+
+        if (phoneType == PhoneConstants.PHONE_TYPE_CDMA) {
+            listCurrentCallsCdma();
+        } else if (phoneType == PhoneConstants.PHONE_TYPE_GSM) {
+            listCurrentCallsGsm();
+        } else {
+            Log.e(TAG, "Unexpected phone type: " + phoneType);
+        }
+        // end the result
+        // when index is 0, other parameter does not matter
+        mBluetoothHeadset.clccResponse(0, 0, 0, 0, false, "", 0);
+    }
+
+    private void handleQueryPhoneState() {
+        if (mBluetoothHeadset != null) {
+            mBluetoothHeadset.phoneStateChanged(mNumActive, mNumHeld,
+                convertCallState(mRingingCallState, mForegroundCallState),
+                mRingNumber.mNumber, mRingNumber.mType);
+        }
+    }
+
+    private int getNumHeldUmts() {
+        int countHeld = 0;
+        List<Call> heldCalls = mCM.getBackgroundCalls();
+
+        for (Call call : heldCalls) {
+            if (call.getState() == Call.State.HOLDING) {
+                countHeld++;
+            }
+        }
+        return countHeld;
+    }
+
+    private int getNumHeldCdma() {
+        int numHeld = 0;
+        PhoneGlobals app = PhoneGlobals.getInstance();
+        if (app.cdmaPhoneCallState != null) {
+            CdmaPhoneCallState.PhoneCallState curr3WayCallState =
+                app.cdmaPhoneCallState.getCurrentCallState();
+            CdmaPhoneCallState.PhoneCallState prev3WayCallState =
+                app.cdmaPhoneCallState.getPreviousCallState();
+
+            log("CDMA call state: " + curr3WayCallState + " prev state:" +
+                prev3WayCallState);
+            if (curr3WayCallState == CdmaPhoneCallState.PhoneCallState.CONF_CALL) {
+                if (prev3WayCallState == CdmaPhoneCallState.PhoneCallState.THRWAY_ACTIVE) {
+                    numHeld = 0; //0: no calls held, as now *both* the caller are active
+                } else {
+                    numHeld = 1; //1: held call and active call, as on answering a
+                    // Call Waiting, one of the caller *is* put on hold
+                }
+            } else if (curr3WayCallState == CdmaPhoneCallState.PhoneCallState.THRWAY_ACTIVE) {
+                numHeld = 1; //1: held call and active call, as on make a 3 Way Call
+                // the first caller *is* put on hold
+            } else {
+                numHeld = 0; //0: no calls held as this is a SINGLE_ACTIVE call
+            }
+        }
+        return numHeld;
+    }
+
+    private CallNumber getCallNumber(Connection connection, Call call) {
+        String number = null;
+        int type = 128;
+        // find phone number and type
+        if (connection == null) {
+            connection = call.getEarliestConnection();
+            if (connection == null) {
+                Log.e(TAG, "Could not get a handle on Connection object for the call");
+            }
+        }
+        if (connection != null) {
+            number = connection.getAddress();
+            if (number != null) {
+                type = PhoneNumberUtils.toaFromString(number);
+            }
+        }
+        if (number == null) {
+            number = "";
+        }
+        return new CallNumber(number, type);
+    }
+
+    private class CallNumber
+    {
+        private String mNumber = null;
+        private int mType = 0;
+
+        private CallNumber(String number, int type) {
+            mNumber = number;
+            mType = type;
+        }
+
+        private boolean equalTo(CallNumber callNumber) 
+        {
+            if (mType != callNumber.mType) return false;
+            
+            if (mNumber != null && mNumber.compareTo(callNumber.mNumber) == 0) {
+                return true;
+            }
+            return false;
+        }
+    }
+
+    private BluetoothProfile.ServiceListener mProfileListener =
+            new BluetoothProfile.ServiceListener() {
+        public void onServiceConnected(int profile, BluetoothProfile proxy) {
+            mBluetoothHeadset = (BluetoothHeadset) proxy;
+        }
+        public void onServiceDisconnected(int profile) {
+            mBluetoothHeadset = null;
+        }
+    };
+
+    private void listCurrentCallsGsm() {
+        // Collect all known connections
+        // clccConnections isindexed by CLCC index
+        Connection[] clccConnections = new Connection[GSM_MAX_CONNECTIONS];
+        LinkedList<Connection> newConnections = new LinkedList<Connection>();
+        LinkedList<Connection> connections = new LinkedList<Connection>();
+
+        Call foregroundCall = mCM.getActiveFgCall();
+        Call backgroundCall = mCM.getFirstActiveBgCall();
+        Call ringingCall = mCM.getFirstActiveRingingCall();
+
+        if (ringingCall.getState().isAlive()) {
+            connections.addAll(ringingCall.getConnections());
+        }
+        if (foregroundCall.getState().isAlive()) {
+            connections.addAll(foregroundCall.getConnections());
+        }
+        if (backgroundCall.getState().isAlive()) {
+            connections.addAll(backgroundCall.getConnections());
+        }
+
+        // Mark connections that we already known about
+        boolean clccUsed[] = new boolean[GSM_MAX_CONNECTIONS];
+        for (int i = 0; i < GSM_MAX_CONNECTIONS; i++) {
+            clccUsed[i] = mClccUsed[i];
+            mClccUsed[i] = false;
+        }
+        for (Connection c : connections) {
+            boolean found = false;
+            long timestamp = c.getCreateTime();
+            for (int i = 0; i < GSM_MAX_CONNECTIONS; i++) {
+                if (clccUsed[i] && timestamp == mClccTimestamps[i]) {
+                    mClccUsed[i] = true;
+                    found = true;
+                    clccConnections[i] = c;
+                    break;
+                }
+            }
+            if (!found) {
+                newConnections.add(c);
+            }
+        }
+
+        // Find a CLCC index for new connections
+        while (!newConnections.isEmpty()) {
+            // Find lowest empty index
+            int i = 0;
+            while (mClccUsed[i]) i++;
+            // Find earliest connection
+            long earliestTimestamp = newConnections.get(0).getCreateTime();
+            Connection earliestConnection = newConnections.get(0);
+            for (int j = 0; j < newConnections.size(); j++) {
+                long timestamp = newConnections.get(j).getCreateTime();
+                if (timestamp < earliestTimestamp) {
+                    earliestTimestamp = timestamp;
+                    earliestConnection = newConnections.get(j);
+                }
+            }
+
+            // update
+            mClccUsed[i] = true;
+            mClccTimestamps[i] = earliestTimestamp;
+            clccConnections[i] = earliestConnection;
+            newConnections.remove(earliestConnection);
+        }
+
+        // Send CLCC response to Bluetooth headset service
+        for (int i = 0; i < clccConnections.length; i++) {
+            if (mClccUsed[i]) {
+                sendClccResponseGsm(i, clccConnections[i]);
+            }
+        }
+    }
+
+    /** Convert a Connection object into a single +CLCC result */
+    private void sendClccResponseGsm(int index, Connection connection) {
+        int state = convertCallState(connection.getState());
+        boolean mpty = false;
+        Call call = connection.getCall();
+        if (call != null) {
+            mpty = call.isMultiparty();
+        }
+
+        int direction = connection.isIncoming() ? 1 : 0;
+
+        String number = connection.getAddress();
+        int type = -1;
+        if (number != null) {
+            type = PhoneNumberUtils.toaFromString(number);
+        }
+
+        mBluetoothHeadset.clccResponse(index + 1, direction, state, 0, mpty, number, type);
+    }
+
+    /** Build the +CLCC result for CDMA
+     *  The complexity arises from the fact that we need to maintain the same
+     *  CLCC index even as a call moves between states. */
+    private synchronized void listCurrentCallsCdma() {
+        // In CDMA at one time a user can have only two live/active connections
+        Connection[] clccConnections = new Connection[CDMA_MAX_CONNECTIONS];// indexed by CLCC index
+        Call foregroundCall = mCM.getActiveFgCall();
+        Call ringingCall = mCM.getFirstActiveRingingCall();
+
+        Call.State ringingCallState = ringingCall.getState();
+        // If the Ringing Call state is INCOMING, that means this is the very first call
+        // hence there should not be any Foreground Call
+        if (ringingCallState == Call.State.INCOMING) {
+            if (VDBG) log("Filling clccConnections[0] for INCOMING state");
+            clccConnections[0] = ringingCall.getLatestConnection();
+        } else if (foregroundCall.getState().isAlive()) {
+            // Getting Foreground Call connection based on Call state
+            if (ringingCall.isRinging()) {
+                if (VDBG) log("Filling clccConnections[0] & [1] for CALL WAITING state");
+                clccConnections[0] = foregroundCall.getEarliestConnection();
+                clccConnections[1] = ringingCall.getLatestConnection();
+            } else {
+                if (foregroundCall.getConnections().size() <= 1) {
+                    // Single call scenario
+                    if (VDBG) {
+                        log("Filling clccConnections[0] with ForgroundCall latest connection");
+                    }
+                    clccConnections[0] = foregroundCall.getLatestConnection();
+                } else {
+                    // Multiple Call scenario. This would be true for both
+                    // CONF_CALL and THRWAY_ACTIVE state
+                    if (VDBG) {
+                        log("Filling clccConnections[0] & [1] with ForgroundCall connections");
+                    }
+                    clccConnections[0] = foregroundCall.getEarliestConnection();
+                    clccConnections[1] = foregroundCall.getLatestConnection();
+                }
+            }
+        }
+
+        // Update the mCdmaIsSecondCallActive flag based on the Phone call state
+        if (PhoneGlobals.getInstance().cdmaPhoneCallState.getCurrentCallState()
+                == CdmaPhoneCallState.PhoneCallState.SINGLE_ACTIVE) {
+            Message msg = mHandler.obtainMessage(CDMA_SET_SECOND_CALL_STATE, false);
+            mHandler.sendMessage(msg);
+        } else if (PhoneGlobals.getInstance().cdmaPhoneCallState.getCurrentCallState()
+                == CdmaPhoneCallState.PhoneCallState.THRWAY_ACTIVE) {
+            Message msg = mHandler.obtainMessage(CDMA_SET_SECOND_CALL_STATE, true);
+            mHandler.sendMessage(msg);
+        }
+
+        // send CLCC result
+        for (int i = 0; (i < clccConnections.length) && (clccConnections[i] != null); i++) {
+            sendClccResponseCdma(i, clccConnections[i]);
+        }
+    }
+
+    /** Send ClCC results for a Connection object for CDMA phone */
+    private void sendClccResponseCdma(int index, Connection connection) {
+        int state;
+        PhoneGlobals app = PhoneGlobals.getInstance();
+        CdmaPhoneCallState.PhoneCallState currCdmaCallState =
+                app.cdmaPhoneCallState.getCurrentCallState();
+        CdmaPhoneCallState.PhoneCallState prevCdmaCallState =
+                app.cdmaPhoneCallState.getPreviousCallState();
+
+        if ((prevCdmaCallState == CdmaPhoneCallState.PhoneCallState.THRWAY_ACTIVE)
+                && (currCdmaCallState == CdmaPhoneCallState.PhoneCallState.CONF_CALL)) {
+            // If the current state is reached after merging two calls
+            // we set the state of all the connections as ACTIVE
+            state = CALL_STATE_ACTIVE;
+        } else {
+            Call.State callState = connection.getState();
+            switch (callState) {
+            case ACTIVE:
+                // For CDMA since both the connections are set as active by FW after accepting
+                // a Call waiting or making a 3 way call, we need to set the state specifically
+                // to ACTIVE/HOLDING based on the mCdmaIsSecondCallActive flag. This way the
+                // CLCC result will allow BT devices to enable the swap or merge options
+                if (index == 0) { // For the 1st active connection
+                    state = mCdmaIsSecondCallActive ? CALL_STATE_HELD : CALL_STATE_ACTIVE;
+                } else { // for the 2nd active connection
+                    state = mCdmaIsSecondCallActive ? CALL_STATE_ACTIVE : CALL_STATE_HELD;
+                }
+                break;
+            case HOLDING:
+                state = CALL_STATE_HELD;
+                break;
+            case DIALING:
+                state = CALL_STATE_DIALING;
+                break;
+            case ALERTING:
+                state = CALL_STATE_ALERTING;
+                break;
+            case INCOMING:
+                state = CALL_STATE_INCOMING;
+                break;
+            case WAITING:
+                state = CALL_STATE_WAITING;
+                break;
+            default:
+                Log.e(TAG, "bad call state: " + callState);
+                return;
+            }
+        }
+
+        boolean mpty = false;
+        if (currCdmaCallState == CdmaPhoneCallState.PhoneCallState.CONF_CALL) {
+            if (prevCdmaCallState == CdmaPhoneCallState.PhoneCallState.THRWAY_ACTIVE) {
+                // If the current state is reached after merging two calls
+                // we set the multiparty call true.
+                mpty = true;
+            } // else
+                // CALL_CONF state is not from merging two calls, but from
+                // accepting the second call. In this case first will be on
+                // hold in most cases but in some cases its already merged.
+                // However, we will follow the common case and the test case
+                // as per Bluetooth SIG PTS
+        }
+
+        int direction = connection.isIncoming() ? 1 : 0;
+
+        String number = connection.getAddress();
+        int type = -1;
+        if (number != null) {
+            type = PhoneNumberUtils.toaFromString(number);
+        } else {
+            number = "";
+        }
+
+        mBluetoothHeadset.clccResponse(index + 1, direction, state, 0, mpty, number, type);
+    }
+
+    private void handleCdmaSwapSecondCallState() {
+        if (VDBG) log("cdmaSwapSecondCallState: Toggling mCdmaIsSecondCallActive");
+        mCdmaIsSecondCallActive = !mCdmaIsSecondCallActive;
+        mCdmaCallsSwapped = true;
+    }
+
+    private void handleCdmaSetSecondCallState(boolean state) {
+        if (VDBG) log("cdmaSetSecondCallState: Setting mCdmaIsSecondCallActive to " + state);
+        mCdmaIsSecondCallActive = state;
+
+        if (!mCdmaIsSecondCallActive) {
+            mCdmaCallsSwapped = false;
+        }
+    }
+
+    private final IBluetoothHeadsetPhone.Stub mBinder = new IBluetoothHeadsetPhone.Stub() {
+        public boolean answerCall() {
+            enforceCallingOrSelfPermission(MODIFY_PHONE_STATE, null);
+            return PhoneUtils.answerCall(mCM.getFirstActiveRingingCall());
+        }
+
+        public boolean hangupCall() {
+            enforceCallingOrSelfPermission(MODIFY_PHONE_STATE, null);
+            if (mCM.hasActiveFgCall()) {
+                return PhoneUtils.hangupActiveCall(mCM.getActiveFgCall());
+            } else if (mCM.hasActiveRingingCall()) {
+                return PhoneUtils.hangupRingingCall(mCM.getFirstActiveRingingCall());
+            } else if (mCM.hasActiveBgCall()) {
+                return PhoneUtils.hangupHoldingCall(mCM.getFirstActiveBgCall());
+            }
+            // TODO(BT) handle virtual voice call
+            return false;
+        }
+
+        public boolean sendDtmf(int dtmf) {
+            enforceCallingOrSelfPermission(MODIFY_PHONE_STATE, null);
+            return mCM.sendDtmf((char) dtmf);
+        }
+
+        public boolean processChld(int chld) {
+            enforceCallingOrSelfPermission(MODIFY_PHONE_STATE, null);
+            Phone phone = mCM.getDefaultPhone();
+            int phoneType = phone.getPhoneType();
+            Call ringingCall = mCM.getFirstActiveRingingCall();
+            Call backgroundCall = mCM.getFirstActiveBgCall();
+
+            if (chld == CHLD_TYPE_RELEASEHELD) {
+                if (ringingCall.isRinging()) {
+                    return PhoneUtils.hangupRingingCall(ringingCall);
+                } else {
+                    return PhoneUtils.hangupHoldingCall(backgroundCall);
+                }
+            } else if (chld == CHLD_TYPE_RELEASEACTIVE_ACCEPTHELD) {
+                if (phoneType == PhoneConstants.PHONE_TYPE_CDMA) {
+                    if (ringingCall.isRinging()) {
+                        // Hangup the active call and then answer call waiting call.
+                        if (VDBG) log("CHLD:1 Callwaiting Answer call");
+                        PhoneUtils.hangupRingingAndActive(phone);
+                    } else {
+                        // If there is no Call waiting then just hangup
+                        // the active call. In CDMA this mean that the complete
+                        // call session would be ended
+                        if (VDBG) log("CHLD:1 Hangup Call");
+                        PhoneUtils.hangup(PhoneGlobals.getInstance().mCM);
+                    }
+                    return true;
+                } else if (phoneType == PhoneConstants.PHONE_TYPE_GSM) {
+                    // Hangup active call, answer held call
+                    return PhoneUtils.answerAndEndActive(PhoneGlobals.getInstance().mCM, ringingCall);
+                } else {
+                    Log.e(TAG, "bad phone type: " + phoneType);
+                    return false;
+                }
+            } else if (chld == CHLD_TYPE_HOLDACTIVE_ACCEPTHELD) {
+                if (phoneType == PhoneConstants.PHONE_TYPE_CDMA) {
+                    // For CDMA, the way we switch to a new incoming call is by
+                    // calling PhoneUtils.answerCall(). switchAndHoldActive() won't
+                    // properly update the call state within telephony.
+                    // If the Phone state is already in CONF_CALL then we simply send
+                    // a flash cmd by calling switchHoldingAndActive()
+                    if (ringingCall.isRinging()) {
+                        if (VDBG) log("CHLD:2 Callwaiting Answer call");
+                        PhoneUtils.answerCall(ringingCall);
+                        PhoneUtils.setMute(false);
+                        // Setting the second callers state flag to TRUE (i.e. active)
+                        cdmaSetSecondCallState(true);
+                        return true;
+                    } else if (PhoneGlobals.getInstance().cdmaPhoneCallState
+                               .getCurrentCallState()
+                               == CdmaPhoneCallState.PhoneCallState.CONF_CALL) {
+                        if (VDBG) log("CHLD:2 Swap Calls");
+                        PhoneUtils.switchHoldingAndActive(backgroundCall);
+                        // Toggle the second callers active state flag
+                        cdmaSwapSecondCallState();
+                        return true;
+                    }
+                    Log.e(TAG, "CDMA fail to do hold active and accept held");
+                    return false;
+                } else if (phoneType == PhoneConstants.PHONE_TYPE_GSM) {
+                    PhoneUtils.switchHoldingAndActive(backgroundCall);
+                    return true;
+                } else {
+                    Log.e(TAG, "Unexpected phone type: " + phoneType);
+                    return false;
+                }
+            } else if (chld == CHLD_TYPE_ADDHELDTOCONF) {
+                if (phoneType == PhoneConstants.PHONE_TYPE_CDMA) {
+                    CdmaPhoneCallState.PhoneCallState state =
+                        PhoneGlobals.getInstance().cdmaPhoneCallState.getCurrentCallState();
+                    // For CDMA, we need to check if the call is in THRWAY_ACTIVE state
+                    if (state == CdmaPhoneCallState.PhoneCallState.THRWAY_ACTIVE) {
+                        if (VDBG) log("CHLD:3 Merge Calls");
+                        PhoneUtils.mergeCalls();
+                        return true;
+                    }   else if (state == CdmaPhoneCallState.PhoneCallState.CONF_CALL) {
+                        // State is CONF_CALL already and we are getting a merge call
+                        // This can happen when CONF_CALL was entered from a Call Waiting
+                        // TODO(BT)
+                        return false;
+                    }
+                    Log.e(TAG, "GSG no call to add conference");
+                    return false;
+                } else if (phoneType == PhoneConstants.PHONE_TYPE_GSM) {
+                    if (mCM.hasActiveFgCall() && mCM.hasActiveBgCall()) {
+                        PhoneUtils.mergeCalls();
+                        return true;
+                    } else {
+                        Log.e(TAG, "GSG no call to merge");
+                        return false;
+                    }
+                } else {
+                    Log.e(TAG, "Unexpected phone type: " + phoneType);
+                    return false;
+                }                
+            } else {
+                Log.e(TAG, "bad CHLD value: " + chld);
+                return false;
+            }
+        }
+
+        public String getNetworkOperator() {
+            enforceCallingOrSelfPermission(MODIFY_PHONE_STATE, null);
+            return mCM.getDefaultPhone().getServiceState().getOperatorAlphaLong();
+        }
+
+        public String getSubscriberNumber() {
+            enforceCallingOrSelfPermission(MODIFY_PHONE_STATE, null);
+            return mCM.getDefaultPhone().getLine1Number();
+        }
+
+        public boolean listCurrentCalls() {
+            enforceCallingOrSelfPermission(MODIFY_PHONE_STATE, null);
+            Message msg = Message.obtain(mHandler, LIST_CURRENT_CALLS);
+            mHandler.sendMessage(msg);
+            return true;
+        }
+
+        public boolean queryPhoneState() {
+            enforceCallingOrSelfPermission(MODIFY_PHONE_STATE, null);
+            Message msg = Message.obtain(mHandler, QUERY_PHONE_STATE);
+            mHandler.sendMessage(msg);
+            return true;
+        }
+
+        public void updateBtHandsfreeAfterRadioTechnologyChange() {
+            enforceCallingOrSelfPermission(MODIFY_PHONE_STATE, null);
+            if (VDBG) Log.d(TAG, "updateBtHandsfreeAfterRadioTechnologyChange...");
+            updateBtPhoneStateAfterRadioTechnologyChange();
+        }
+
+        public void cdmaSwapSecondCallState() {
+            enforceCallingOrSelfPermission(MODIFY_PHONE_STATE, null);
+            Message msg = Message.obtain(mHandler, CDMA_SWAP_SECOND_CALL_STATE);
+            mHandler.sendMessage(msg);
+        }
+
+        public void cdmaSetSecondCallState(boolean state) {
+            enforceCallingOrSelfPermission(MODIFY_PHONE_STATE, null);
+            Message msg = mHandler.obtainMessage(CDMA_SET_SECOND_CALL_STATE, state);
+            mHandler.sendMessage(msg);
+        }
+    };
+
+    // match up with bthf_call_state_t of bt_hf.h
+    final static int CALL_STATE_ACTIVE = 0;
+    final static int CALL_STATE_HELD = 1;
+    final static int CALL_STATE_DIALING = 2;
+    final static int CALL_STATE_ALERTING = 3;
+    final static int CALL_STATE_INCOMING = 4;
+    final static int CALL_STATE_WAITING = 5;
+    final static int CALL_STATE_IDLE = 6;
+
+    // match up with bthf_chld_type_t of bt_hf.h
+    final static int CHLD_TYPE_RELEASEHELD = 0;
+    final static int CHLD_TYPE_RELEASEACTIVE_ACCEPTHELD = 1;
+    final static int CHLD_TYPE_HOLDACTIVE_ACCEPTHELD = 2;
+    final static int CHLD_TYPE_ADDHELDTOCONF = 3;
+
+     /* Convert telephony phone call state into hf hal call state */
+    static int convertCallState(Call.State ringingState, Call.State foregroundState) {
+        if ((ringingState == Call.State.INCOMING) ||
+            (ringingState == Call.State.WAITING) )
+            return CALL_STATE_INCOMING;
+        else if (foregroundState == Call.State.DIALING)
+            return CALL_STATE_DIALING;
+        else if (foregroundState == Call.State.ALERTING)
+            return CALL_STATE_ALERTING;
+        else
+            return CALL_STATE_IDLE;
+    }
+
+    static int convertCallState(Call.State callState) {
+        switch (callState) {
+        case IDLE:
+        case DISCONNECTED:
+        case DISCONNECTING:
+            return CALL_STATE_IDLE;
+        case ACTIVE:
+            return CALL_STATE_ACTIVE;
+        case HOLDING:
+            return CALL_STATE_HELD;
+        case DIALING:
+            return CALL_STATE_DIALING;
+        case ALERTING:
+            return CALL_STATE_ALERTING;
+        case INCOMING:
+            return CALL_STATE_INCOMING;
+        case WAITING:
+            return CALL_STATE_WAITING;
+        default:
+            Log.e(TAG, "bad call state: " + callState);
+            return CALL_STATE_IDLE;
+        }
+    }
+
+    private static void log(String msg) {
+        Log.d(TAG, msg);
+    }
+}
diff --git a/src/com/android/phone/CLIRListPreference.java b/src/com/android/phone/CLIRListPreference.java
index b23277a..198bdb0 100644
--- a/src/com/android/phone/CLIRListPreference.java
+++ b/src/com/android/phone/CLIRListPreference.java
@@ -20,7 +20,7 @@
  */
 public class CLIRListPreference extends ListPreference {
     private static final String LOG_TAG = "CLIRListPreference";
-    private final boolean DBG = (PhoneApp.DBG_LEVEL >= 2);
+    private final boolean DBG = (PhoneGlobals.DBG_LEVEL >= 2);
 
     private final MyHandler mHandler = new MyHandler();
     private final Phone mPhone;
@@ -31,7 +31,7 @@
     public CLIRListPreference(Context context, AttributeSet attrs) {
         super(context, attrs);
 
-        mPhone = PhoneApp.getPhone();
+        mPhone = PhoneGlobals.getPhone();
     }
 
     public CLIRListPreference(Context context) {
diff --git a/src/com/android/phone/CallCard.java b/src/com/android/phone/CallCard.java
index 77702d1..4c6822c 100644
--- a/src/com/android/phone/CallCard.java
+++ b/src/com/android/phone/CallCard.java
@@ -33,6 +33,7 @@
 import android.text.format.DateUtils;
 import android.util.AttributeSet;
 import android.util.Log;
+import android.view.Gravity;
 import android.view.View;
 import android.view.ViewGroup;
 import android.view.ViewStub;
@@ -61,7 +62,7 @@
         implements CallTime.OnTickListener, CallerInfoAsyncQuery.OnQueryCompleteListener,
                    ContactsAsyncHelper.OnImageLoadCompleteListener {
     private static final String LOG_TAG = "CallCard";
-    private static final boolean DBG = (PhoneApp.DBG_LEVEL >= 2);
+    private static final boolean DBG = (PhoneGlobals.DBG_LEVEL >= 2);
 
     private static final int TOKEN_UPDATE_PHOTO_FOR_CALL_STATE = 0;
     private static final int TOKEN_DO_NOTHING = 1;
@@ -89,7 +90,7 @@
     private InCallScreen mInCallScreen;
 
     // Phone app instance
-    private PhoneApp mApplication;
+    private PhoneGlobals mApplication;
 
     // Top-level subviews of the CallCard
     /** Container for info about the current call(s) */
@@ -181,7 +182,7 @@
         if (DBG) log("- this = " + this);
         if (DBG) log("- context " + context + ", attrs " + attrs);
 
-        mApplication = PhoneApp.getInstance();
+        mApplication = PhoneGlobals.getInstance();
 
         mCallTime = new CallTime(this);
 
@@ -255,8 +256,12 @@
         Call fgCall = cm.getActiveFgCall();
         Call bgCall = cm.getFirstActiveBgCall();
 
-        // Update the overall layout of the onscreen elements.
-        updateCallInfoLayout(state);
+        // Update the overall layout of the onscreen elements, if in PORTRAIT.
+        // Portrait uses a programatically altered layout, whereas landscape uses layout xml's.
+        // Landscape view has the views side by side, so no shifting of the picture is needed
+        if (!PhoneUtils.isLandscape(this.getContext())) {
+            updateCallInfoLayout(state);
+        }
 
         // If the FG call is dialing/alerting, we should display for that call
         // and ignore the ringing call. This case happens when the telephony
@@ -810,7 +815,7 @@
                 // Display "Dialing" while dialing a 3Way call, even
                 // though the foreground call state is actually ACTIVE.
                 callStateLabel = context.getString(R.string.card_title_dialing);
-            } else if (PhoneApp.getInstance().notifier.getIsCdmaRedialCall()) {
+            } else if (PhoneGlobals.getInstance().notifier.getIsCdmaRedialCall()) {
                 callStateLabel = context.getString(R.string.card_title_redialing);
             }
         }
@@ -866,6 +871,14 @@
             }
         } else {
             mCallStateLabel.setVisibility(View.GONE);
+            // Gravity is aligned left when receiving an incoming call in landscape.
+            // In that rare case, the gravity needs to be reset to the right.
+            // Also, setText("") is used since there is a delay in making the view GONE,
+            // so the user will otherwise see the text jump to the right side before disappearing.
+            if(mCallStateLabel.getGravity() != Gravity.RIGHT) {
+                mCallStateLabel.setText("");
+                mCallStateLabel.setGravity(Gravity.RIGHT);
+            }
         }
         if (skipAnimation) {
             // Restore LayoutTransition object to recover animation.
@@ -942,7 +955,7 @@
     private void displaySecondaryCallStatus(CallManager cm, Call call) {
         if (DBG) log("displayOnHoldCallStatus(call =" + call + ")...");
 
-        if ((call == null) || (PhoneApp.getInstance().isOtaCallInActiveState())) {
+        if ((call == null) || (PhoneGlobals.getInstance().isOtaCallInActiveState())) {
             mSecondaryCallInfo.setVisibility(View.GONE);
             return;
         }
@@ -999,7 +1012,7 @@
                     List<Connection> connections = call.getConnections();
                     if (connections.size() > 2) {
                         // This means that current Mobile Originated call is the not the first 3-Way
-                        // call the user is making, which in turn tells the PhoneApp that we no
+                        // call the user is making, which in turn tells the PhoneGlobals that we no
                         // longer know which previous caller/party had dropped out before the user
                         // made this call.
                         mSecondaryCallName.setText(
diff --git a/src/com/android/phone/CallController.java b/src/com/android/phone/CallController.java
index d9ec62d..e33e442 100644
--- a/src/com/android/phone/CallController.java
+++ b/src/com/android/phone/CallController.java
@@ -61,14 +61,14 @@
 public class CallController extends Handler {
     private static final String TAG = "CallController";
     private static final boolean DBG =
-            (PhoneApp.DBG_LEVEL >= 1) && (SystemProperties.getInt("ro.debuggable", 0) == 1);
+            (PhoneGlobals.DBG_LEVEL >= 1) && (SystemProperties.getInt("ro.debuggable", 0) == 1);
     // Do not check in with VDBG = true, since that may write PII to the system log.
     private static final boolean VDBG = false;
 
     /** The singleton CallController instance. */
     private static CallController sInstance;
 
-    private PhoneApp mApp;
+    private PhoneGlobals mApp;
     private CallManager mCM;
 
     /** Helper object for emergency calls in some rare use cases.  Created lazily. */
@@ -100,7 +100,7 @@
      * PhoneApp's public "callController" field, which is why there's no
      * getInstance() method here.
      */
-    /* package */ static CallController init(PhoneApp app) {
+    /* package */ static CallController init(PhoneGlobals app) {
         synchronized (CallController.class) {
             if (sInstance == null) {
                 sInstance = new CallController(app);
@@ -115,7 +115,7 @@
      * Private constructor (this is a singleton).
      * @see init()
      */
-    private CallController(PhoneApp app) {
+    private CallController(PhoneGlobals app) {
         if (DBG) log("CallController constructor: app = " + app);
         mApp = app;
         mCM = app.mCM;
diff --git a/src/com/android/phone/CallFeaturesSetting.java b/src/com/android/phone/CallFeaturesSetting.java
index 53ee8f4..ee1233d 100644
--- a/src/com/android/phone/CallFeaturesSetting.java
+++ b/src/com/android/phone/CallFeaturesSetting.java
@@ -39,6 +39,7 @@
 import android.os.Bundle;
 import android.os.Handler;
 import android.os.Message;
+import android.os.UserHandle;
 import android.os.Vibrator;
 import android.preference.CheckBoxPreference;
 import android.preference.ListPreference;
@@ -95,7 +96,7 @@
         EditPhoneNumberPreference.OnDialogClosedListener,
         EditPhoneNumberPreference.GetDefaultNumberListener{
     private static final String LOG_TAG = "CallFeaturesSetting";
-    private static final boolean DBG = (PhoneApp.DBG_LEVEL >= 2);
+    private static final boolean DBG = (PhoneGlobals.DBG_LEVEL >= 2);
 
     /**
      * Intent action to bring up Voicemail Provider settings.
@@ -474,8 +475,8 @@
         } else if (preference == mButtonTTY) {
             return true;
         } else if (preference == mButtonAutoRetry) {
-            android.provider.Settings.System.putInt(mPhone.getContext().getContentResolver(),
-                    android.provider.Settings.System.CALL_AUTO_RETRY,
+            android.provider.Settings.Global.putInt(mPhone.getContext().getContentResolver(),
+                    android.provider.Settings.Global.CALL_AUTO_RETRY,
                     mButtonAutoRetry.isChecked() ? 1 : 0);
             return true;
         } else if (preference == mButtonHAC) {
@@ -1482,7 +1483,7 @@
     protected void onCreate(Bundle icicle) {
         super.onCreate(icicle);
         if (DBG) log("onCreate(). Intent: " + getIntent());
-        mPhone = PhoneApp.getPhone();
+        mPhone = PhoneGlobals.getPhone();
 
         addPreferencesFromResource(R.xml.call_feature_setting);
 
@@ -1725,8 +1726,8 @@
         }
 
         if (mButtonAutoRetry != null) {
-            int autoretry = Settings.System.getInt(getContentResolver(),
-                    Settings.System.CALL_AUTO_RETRY, 0);
+            int autoretry = Settings.Global.getInt(getContentResolver(),
+                    Settings.Global.CALL_AUTO_RETRY, 0);
             mButtonAutoRetry.setChecked(autoretry != 0);
         }
 
@@ -1799,7 +1800,7 @@
             updatePreferredTtyModeSummary(buttonTtyMode);
             Intent ttyModeChanged = new Intent(TtyIntent.TTY_PREFERRED_MODE_CHANGE_ACTION);
             ttyModeChanged.putExtra(TtyIntent.TTY_PREFFERED_MODE, buttonTtyMode);
-            sendBroadcast(ttyModeChanged);
+            sendBroadcastAsUser(ttyModeChanged, UserHandle.ALL);
         }
     }
 
diff --git a/src/com/android/phone/CallForwardEditPreference.java b/src/com/android/phone/CallForwardEditPreference.java
index 544d4c2..f925022 100644
--- a/src/com/android/phone/CallForwardEditPreference.java
+++ b/src/com/android/phone/CallForwardEditPreference.java
@@ -21,7 +21,7 @@
 
 public class CallForwardEditPreference extends EditPhoneNumberPreference {
     private static final String LOG_TAG = "CallForwardEditPreference";
-    private static final boolean DBG = (PhoneApp.DBG_LEVEL >= 2);
+    private static final boolean DBG = (PhoneGlobals.DBG_LEVEL >= 2);
 
     private static final String SRC_TAGS[]       = {"{0}"};
     private CharSequence mSummaryOnTemplate;
@@ -43,7 +43,7 @@
     public CallForwardEditPreference(Context context, AttributeSet attrs) {
         super(context, attrs);
 
-        phone = PhoneApp.getPhone();
+        phone = PhoneGlobals.getPhone();
         mSummaryOnTemplate = this.getSummaryOn();
 
         TypedArray a = context.obtainStyledAttributes(attrs,
diff --git a/src/com/android/phone/CallNotifier.java b/src/com/android/phone/CallNotifier.java
index dee75de..99636df 100755
--- a/src/com/android/phone/CallNotifier.java
+++ b/src/com/android/phone/CallNotifier.java
@@ -31,6 +31,9 @@
 import com.android.internal.telephony.cdma.SignalToneUtil;
 
 import android.app.ActivityManagerNative;
+import android.bluetooth.BluetoothAdapter;
+import android.bluetooth.BluetoothHeadset;
+import android.bluetooth.BluetoothProfile;
 import android.content.Context;
 import android.media.AudioManager;
 import android.media.ToneGenerator;
@@ -61,8 +64,8 @@
         implements CallerInfoAsyncQuery.OnQueryCompleteListener {
     private static final String LOG_TAG = "CallNotifier";
     private static final boolean DBG =
-            (PhoneApp.DBG_LEVEL >= 1) && (SystemProperties.getInt("ro.debuggable", 0) == 1);
-    private static final boolean VDBG = (PhoneApp.DBG_LEVEL >= 2);
+            (PhoneGlobals.DBG_LEVEL >= 1) && (SystemProperties.getInt("ro.debuggable", 0) == 1);
+    private static final boolean VDBG = (PhoneGlobals.DBG_LEVEL >= 2);
 
     // Maximum time we allow the CallerInfo query to run,
     // before giving up and falling back to the default ringtone.
@@ -148,10 +151,10 @@
     private static final int EMERGENCY_TONE_ALERT = 1;
     private static final int EMERGENCY_TONE_VIBRATE = 2;
 
-    private PhoneApp mApplication;
+    private PhoneGlobals mApplication;
     private CallManager mCM;
     private Ringer mRinger;
-    private BluetoothHandsfree mBluetoothHandsfree;
+    private BluetoothHeadset mBluetoothHeadset;
     private CallLogAsync mCallLog;
     private boolean mSilentRingerRequested;
 
@@ -183,11 +186,11 @@
      * Initialize the singleton CallNotifier instance.
      * This is only done once, at startup, from PhoneApp.onCreate().
      */
-    /* package */ static CallNotifier init(PhoneApp app, Phone phone, Ringer ringer,
-                                           BluetoothHandsfree btMgr, CallLogAsync callLog) {
+    /* package */ static CallNotifier init(PhoneGlobals app, Phone phone, Ringer ringer,
+                                           CallLogAsync callLog) {
         synchronized (CallNotifier.class) {
             if (sInstance == null) {
-                sInstance = new CallNotifier(app, phone, ringer, btMgr, callLog);
+                sInstance = new CallNotifier(app, phone, ringer, callLog);
             } else {
                 Log.wtf(LOG_TAG, "init() called multiple times!  sInstance = " + sInstance);
             }
@@ -196,8 +199,7 @@
     }
 
     /** Private constructor; @see init() */
-    private CallNotifier(PhoneApp app, Phone phone, Ringer ringer,
-                         BluetoothHandsfree btMgr, CallLogAsync callLog) {
+    private CallNotifier(PhoneGlobals app, Phone phone, Ringer ringer, CallLogAsync callLog) {
         mApplication = app;
         mCM = app.mCM;
         mCallLog = callLog;
@@ -220,7 +222,12 @@
         }
 
         mRinger = ringer;
-        mBluetoothHandsfree = btMgr;
+        BluetoothAdapter adapter = BluetoothAdapter.getDefaultAdapter();
+        if (adapter != null) {
+            adapter.getProfileProxy(mApplication.getApplicationContext(),
+                                    mBluetoothProfileServiceListener,
+                                    BluetoothProfile.HEADSET);
+        }
 
         TelephonyManager telephonyManager = (TelephonyManager)app.getSystemService(
                 Context.TELEPHONY_SERVICE);
@@ -435,7 +442,7 @@
         // (This will be upgraded soon to a full wake lock; see
         // showIncomingCall().)
         if (VDBG) log("Holding wake lock on new incoming connection.");
-        mApplication.requestWakeState(PhoneApp.WakeState.PARTIAL);
+        mApplication.requestWakeState(PhoneGlobals.WakeState.PARTIAL);
 
         // - don't ring for call waiting connections
         // - do this before showing the incoming call panel
@@ -484,7 +491,7 @@
      */
     private boolean ignoreAllIncomingCalls(Phone phone) {
         // Incoming calls are totally ignored on non-voice-capable devices.
-        if (!PhoneApp.sVoiceCapable) {
+        if (!PhoneGlobals.sVoiceCapable) {
             // ...but still log a warning, since we shouldn't have gotten this
             // event in the first place!  (Incoming calls *should* be blocked at
             // the telephony layer on non-voice-capable capable devices.)
@@ -501,8 +508,8 @@
         }
 
         // Incoming calls are totally ignored if the device isn't provisioned yet.
-        boolean provisioned = Settings.Secure.getInt(mApplication.getContentResolver(),
-            Settings.Secure.DEVICE_PROVISIONED, 0) != 0;
+        boolean provisioned = Settings.Global.getInt(mApplication.getContentResolver(),
+            Settings.Global.DEVICE_PROVISIONED, 0) != 0;
         if (!provisioned) {
             Log.i(LOG_TAG, "Ignoring incoming call: not provisioned");
             return true;
@@ -701,34 +708,7 @@
         // Go directly to the in-call screen.
         // (No need to do anything special if we're already on the in-call
         // screen; it'll notice the phone state change and update itself.)
-
-        // But first, grab a full wake lock.  We do this here, before we
-        // even fire off the InCallScreen intent, to make sure the
-        // ActivityManager doesn't try to pause the InCallScreen as soon
-        // as it comes up.  (See bug 1648751.)
-        //
-        // And since the InCallScreen isn't visible yet (we haven't even
-        // fired off the intent yet), we DON'T want the screen to actually
-        // come on right now.  So *before* acquiring the wake lock we need
-        // to call preventScreenOn(), which tells the PowerManager that
-        // the screen should stay off even if someone's holding a full
-        // wake lock.  (This prevents any flicker during the "incoming
-        // call" sequence.  The corresponding preventScreenOn(false) call
-        // will come from the InCallScreen when it's finally ready to be
-        // displayed.)
-        //
-        // TODO: this is all a temporary workaround.  The real fix is to add
-        // an Activity attribute saying "this Activity wants to wake up the
-        // phone when it's displayed"; that way the ActivityManager could
-        // manage the wake locks *and* arrange for the screen to come on at
-        // the exact moment that the InCallScreen is ready to be displayed.
-        // (See bug 1648751.)
-        //
-        // TODO: also, we should probably *not* do any of this if the
-        // screen is already on(!)
-
-        mApplication.preventScreenOn(true);
-        mApplication.requestWakeState(PhoneApp.WakeState.FULL);
+        mApplication.requestWakeState(PhoneGlobals.WakeState.FULL);
 
         // Post the "incoming call" notification *and* include the
         // fullScreenIntent that'll launch the incoming-call UI.
@@ -797,8 +777,7 @@
             // if the call screen is showing, let it handle the event,
             // otherwise handle it here.
             if (!mApplication.isShowingCallScreen()) {
-                mApplication.setScreenTimeout(PhoneApp.ScreenTimeoutDuration.DEFAULT);
-                mApplication.requestWakeState(PhoneApp.WakeState.SLEEP);
+                mApplication.requestWakeState(PhoneGlobals.WakeState.SLEEP);
             }
 
             // Since we're now in-call, the Ringer should definitely *not*
@@ -842,9 +821,9 @@
                 }
 
                 if (callState == Call.State.DIALING || callState == Call.State.ALERTING) {
-                    mIsEmergencyToneOn = Settings.System.getInt(
+                    mIsEmergencyToneOn = Settings.Global.getInt(
                             mApplication.getContentResolver(),
-                            Settings.System.EMERGENCY_TONE, EMERGENCY_TONE_OFF);
+                            Settings.Global.EMERGENCY_TONE, EMERGENCY_TONE_OFF);
                     if (mIsEmergencyToneOn != EMERGENCY_TONE_OFF &&
                         mCurrentEmergencyToneState == EMERGENCY_TONE_OFF) {
                         if (mEmergencyTonePlayerVibrator != null) {
@@ -1033,8 +1012,8 @@
 
         int autoretrySetting = 0;
         if ((c != null) && (c.getCall().getPhone().getPhoneType() == PhoneConstants.PHONE_TYPE_CDMA)) {
-            autoretrySetting = android.provider.Settings.System.getInt(mApplication.
-                    getContentResolver(),android.provider.Settings.System.CALL_AUTO_RETRY, 0);
+            autoretrySetting = android.provider.Settings.Global.getInt(mApplication.
+                    getContentResolver(),android.provider.Settings.Global.CALL_AUTO_RETRY, 0);
         }
 
         // Stop any signalInfo tone being played when a call gets ended
@@ -1160,14 +1139,6 @@
             }
 
             mApplication.notificationMgr.cancelCallInProgressNotifications();
-
-            // If the screen is turned off when all the phone calls are hung up,
-            // InCallScreen#onDisconnect() will wake up the screen (only once) and let users
-            // check the disconnected status.
-            if (mApplication.isShowingCallScreen()) {
-                if (VDBG) log("onDisconnect: In call screen. Set short timeout.");
-                mApplication.clearUserActivityTimeout();
-            }
         }
 
         if (c != null) {
@@ -1292,8 +1263,8 @@
     private void resetAudioStateAfterDisconnect() {
         if (VDBG) log("resetAudioStateAfterDisconnect()...");
 
-        if (mBluetoothHandsfree != null) {
-            mBluetoothHandsfree.audioOff();
+        if (mBluetoothHeadset != null) {
+            mBluetoothHeadset.disconnectAudio();
         }
 
         // call turnOnSpeaker() with state=false and store=true even if speaker
@@ -1308,7 +1279,7 @@
 
         // "Voicemail" is meaningless on non-voice-capable devices,
         // so ignore MWI events.
-        if (!PhoneApp.sVoiceCapable) {
+        if (!PhoneGlobals.sVoiceCapable) {
             // ...but still log a warning, since we shouldn't have gotten this
             // event in the first place!
             // (PhoneStateListener.LISTEN_MESSAGE_WAITING_INDICATOR events
@@ -1528,8 +1499,8 @@
             ToneGenerator toneGenerator;
             try {
                 int stream;
-                if (mBluetoothHandsfree != null) {
-                    stream = mBluetoothHandsfree.isAudioOn() ? AudioManager.STREAM_BLUETOOTH_SCO:
+                if (mBluetoothHeadset != null) {
+                    stream = mBluetoothHeadset.isAudioOn() ? AudioManager.STREAM_BLUETOOTH_SCO:
                         AudioManager.STREAM_VOICE_CALL;
                 } else {
                     stream = AudioManager.STREAM_VOICE_CALL;
@@ -1694,7 +1665,7 @@
      */
     private void onSignalInfo(AsyncResult r) {
         // Signal Info are totally ignored on non-voice-capable devices.
-        if (!PhoneApp.sVoiceCapable) {
+        if (!PhoneGlobals.sVoiceCapable) {
             Log.w(LOG_TAG, "Got onSignalInfo() on non-voice-capable device! Ignoring...");
             return;
         }
@@ -1995,6 +1966,18 @@
         }
     }
 
+     private BluetoothProfile.ServiceListener mBluetoothProfileServiceListener =
+        new BluetoothProfile.ServiceListener() {
+        public void onServiceConnected(int profile, BluetoothProfile proxy) {
+            mBluetoothHeadset = (BluetoothHeadset) proxy;
+            if (VDBG) log("- Got BluetoothHeadset: " + mBluetoothHeadset);
+        }
+
+        public void onServiceDisconnected(int profile) {
+            mBluetoothHeadset = null;
+        }
+    };
+
     private void onRingbackTone(AsyncResult r) {
         boolean playTone = (Boolean)(r.result);
 
diff --git a/src/com/android/phone/CallTime.java b/src/com/android/phone/CallTime.java
index 39a69af..92c7972 100644
--- a/src/com/android/phone/CallTime.java
+++ b/src/com/android/phone/CallTime.java
@@ -195,7 +195,7 @@
             // For now, we move away from temp directory in favor of
             // the application's data directory to store the trace
             // information (/data/data/com.android.phone).
-            File file = PhoneApp.getInstance().getDir ("phoneTrace", Context.MODE_PRIVATE);
+            File file = PhoneGlobals.getInstance().getDir ("phoneTrace", Context.MODE_PRIVATE);
             if (file.exists() == false) {
                 file.mkdirs();
             }
diff --git a/src/com/android/phone/CallWaitingCheckBoxPreference.java b/src/com/android/phone/CallWaitingCheckBoxPreference.java
index 6394ff1..a2f5c70 100644
--- a/src/com/android/phone/CallWaitingCheckBoxPreference.java
+++ b/src/com/android/phone/CallWaitingCheckBoxPreference.java
@@ -17,7 +17,7 @@
 
 public class CallWaitingCheckBoxPreference extends CheckBoxPreference {
     private static final String LOG_TAG = "CallWaitingCheckBoxPreference";
-    private final boolean DBG = (PhoneApp.DBG_LEVEL >= 2);
+    private final boolean DBG = (PhoneGlobals.DBG_LEVEL >= 2);
 
     private final MyHandler mHandler = new MyHandler();
     private final Phone mPhone;
@@ -26,7 +26,7 @@
     public CallWaitingCheckBoxPreference(Context context, AttributeSet attrs, int defStyle) {
         super(context, attrs, defStyle);
 
-        mPhone = PhoneApp.getPhone();
+        mPhone = PhoneGlobals.getPhone();
     }
 
     public CallWaitingCheckBoxPreference(Context context, AttributeSet attrs) {
diff --git a/src/com/android/phone/CallerInfoCache.java b/src/com/android/phone/CallerInfoCache.java
index dc6ffae..76f79af 100644
--- a/src/com/android/phone/CallerInfoCache.java
+++ b/src/com/android/phone/CallerInfoCache.java
@@ -45,7 +45,7 @@
 public class CallerInfoCache {
     private static final String LOG_TAG = CallerInfoCache.class.getSimpleName();
     private static final boolean DBG =
-            (PhoneApp.DBG_LEVEL >= 1) && (SystemProperties.getInt("ro.debuggable", 0) == 1);
+            (PhoneGlobals.DBG_LEVEL >= 1) && (SystemProperties.getInt("ro.debuggable", 0) == 1);
 
     /** This must not be set to true when submitting changes. */
     private static final boolean VDBG = false;
diff --git a/src/com/android/phone/CallerInfoCacheUpdateReceiver.java b/src/com/android/phone/CallerInfoCacheUpdateReceiver.java
index 5d60947..c0a2d83 100644
--- a/src/com/android/phone/CallerInfoCacheUpdateReceiver.java
+++ b/src/com/android/phone/CallerInfoCacheUpdateReceiver.java
@@ -31,7 +31,7 @@
 public class CallerInfoCacheUpdateReceiver extends BroadcastReceiver {
     private static final String LOG_TAG = CallerInfoCacheUpdateReceiver.class.getSimpleName();
     private static final boolean DBG =
-            (PhoneApp.DBG_LEVEL >= 1) && (SystemProperties.getInt("ro.debuggable", 0) == 1);
+            (PhoneGlobals.DBG_LEVEL >= 1) && (SystemProperties.getInt("ro.debuggable", 0) == 1);
 
     public static final String ACTION_UPDATE_CALLER_INFO_CACHE =
             "com.android.phone.UPDATE_CALLER_INFO_CACHE";
@@ -39,7 +39,7 @@
     @Override
     public void onReceive(Context context, Intent intent) {
         if (DBG) log("CallerInfoCacheUpdateReceiver#onReceive(). Intent: " + intent);
-        PhoneApp.getInstance().callerInfoCache.startAsyncCache();
+        PhoneGlobals.getInstance().callerInfoCache.startAsyncCache();
     }
 
     private static void log(String msg) {
diff --git a/src/com/android/phone/CdmaCallOptions.java b/src/com/android/phone/CdmaCallOptions.java
index 656863b..8eecd27 100644
--- a/src/com/android/phone/CdmaCallOptions.java
+++ b/src/com/android/phone/CdmaCallOptions.java
@@ -32,7 +32,7 @@
 
 public class CdmaCallOptions extends PreferenceActivity {
     private static final String LOG_TAG = "CdmaCallOptions";
-    private final boolean DBG = (PhoneApp.DBG_LEVEL >= 2);
+    private final boolean DBG = (PhoneGlobals.DBG_LEVEL >= 2);
 
     private static final String BUTTON_VP_KEY = "button_voice_privacy_key";
     private CheckBoxPreference mButtonVoicePrivacy;
@@ -44,7 +44,7 @@
         addPreferencesFromResource(R.xml.cdma_call_privacy);
 
         mButtonVoicePrivacy = (CheckBoxPreference) findPreference(BUTTON_VP_KEY);
-        if (PhoneApp.getPhone().getPhoneType() != PhoneConstants.PHONE_TYPE_CDMA
+        if (PhoneGlobals.getPhone().getPhoneType() != PhoneConstants.PHONE_TYPE_CDMA
                 || getResources().getBoolean(R.bool.config_voice_privacy_disable)) {
             //disable the entire screen
             getPreferenceScreen().setEnabled(false);
diff --git a/src/com/android/phone/CdmaDisplayInfo.java b/src/com/android/phone/CdmaDisplayInfo.java
index 1e7dee8..1a88333 100755
--- a/src/com/android/phone/CdmaDisplayInfo.java
+++ b/src/com/android/phone/CdmaDisplayInfo.java
@@ -63,7 +63,7 @@
                 WindowManager.LayoutParams.FLAG_DIM_BEHIND);
 
         sDisplayInfoDialog.show();
-        PhoneApp.getInstance().wakeUpScreen();
+        PhoneGlobals.getInstance().wakeUpScreen();
 
     }
 
diff --git a/src/com/android/phone/CdmaSubscriptionListPreference.java b/src/com/android/phone/CdmaSubscriptionListPreference.java
index 43d3c0b..9b96850 100644
--- a/src/com/android/phone/CdmaSubscriptionListPreference.java
+++ b/src/com/android/phone/CdmaSubscriptionListPreference.java
@@ -22,6 +22,7 @@
 import android.os.Handler;
 import android.os.Message;
 import android.preference.ListPreference;
+import android.provider.Settings;
 import android.provider.Settings.Secure;
 import android.util.AttributeSet;
 import android.util.Log;
@@ -53,8 +54,8 @@
     }
 
     private void setCurrentCdmaSubscriptionModeValue() {
-        int cdmaSubscriptionMode = Secure.getInt(mPhone.getContext().getContentResolver(),
-                android.provider.Settings.Secure.CDMA_SUBSCRIPTION_MODE, preferredSubscriptionMode);
+        int cdmaSubscriptionMode = Settings.Global.getInt(mPhone.getContext().getContentResolver(),
+                Settings.Global.CDMA_SUBSCRIPTION_MODE, preferredSubscriptionMode);
         setValue(Integer.toString(cdmaSubscriptionMode));
     }
 
@@ -120,8 +121,8 @@
             if (ar.exception == null) {
                 // Get the original string entered by the user
                 int cdmaSubscriptionMode = Integer.valueOf((String) ar.userObj).intValue();
-                Secure.putInt(mPhone.getContext().getContentResolver(),
-                        Secure.CDMA_SUBSCRIPTION_MODE,
+                Settings.Global.putInt(mPhone.getContext().getContentResolver(),
+                        Settings.Global.CDMA_SUBSCRIPTION_MODE,
                         cdmaSubscriptionMode );
             } else {
                 Log.e(LOG_TAG, "Setting Cdma subscription source failed");
diff --git a/src/com/android/phone/CdmaSystemSelectListPreference.java b/src/com/android/phone/CdmaSystemSelectListPreference.java
index 7bbe008..d291fd7 100644
--- a/src/com/android/phone/CdmaSystemSelectListPreference.java
+++ b/src/com/android/phone/CdmaSystemSelectListPreference.java
@@ -23,6 +23,7 @@
 import android.os.Handler;
 import android.os.Message;
 import android.preference.ListPreference;
+import android.provider.Settings;
 import android.provider.Settings.Secure;
 import android.util.AttributeSet;
 import android.util.Log;
@@ -41,7 +42,7 @@
     public CdmaSystemSelectListPreference(Context context, AttributeSet attrs) {
         super(context, attrs);
 
-        mPhone = PhoneApp.getPhone();
+        mPhone = PhoneGlobals.getPhone();
         mHandler = new MyHandler();
         mPhone.queryCdmaRoamingPreference(
                 mHandler.obtainMessage(MyHandler.MESSAGE_GET_ROAMING_PREFERENCE));
@@ -68,8 +69,8 @@
         if (positiveResult && (getValue() != null)) {
             int buttonCdmaRoamingMode = Integer.valueOf(getValue()).intValue();
             int settingsCdmaRoamingMode =
-                    Secure.getInt(mPhone.getContext().getContentResolver(),
-                    Secure.CDMA_ROAMING_MODE, Phone.CDMA_RM_HOME);
+                    Settings.Global.getInt(mPhone.getContext().getContentResolver(),
+                    Settings.Global.CDMA_ROAMING_MODE, Phone.CDMA_RM_HOME);
             if (buttonCdmaRoamingMode != settingsCdmaRoamingMode) {
                 int statusCdmaRoamingMode;
                 switch(buttonCdmaRoamingMode) {
@@ -81,8 +82,8 @@
                         statusCdmaRoamingMode = Phone.CDMA_RM_HOME;
                 }
                 //Set the Settings.Secure network mode
-                Secure.putInt(mPhone.getContext().getContentResolver(),
-                        Secure.CDMA_ROAMING_MODE,
+                Settings.Global.putInt(mPhone.getContext().getContentResolver(),
+                        Settings.Global.CDMA_ROAMING_MODE,
                         buttonCdmaRoamingMode );
                 //Set the roaming preference mode
                 mPhone.setCdmaRoamingPreference(statusCdmaRoamingMode, mHandler
@@ -117,9 +118,9 @@
 
             if (ar.exception == null) {
                 int statusCdmaRoamingMode = ((int[])ar.result)[0];
-                int settingsRoamingMode = Secure.getInt(
+                int settingsRoamingMode = Settings.Global.getInt(
                         mPhone.getContext().getContentResolver(),
-                        Secure.CDMA_ROAMING_MODE, Phone.CDMA_RM_HOME);
+                        Settings.Global.CDMA_ROAMING_MODE, Phone.CDMA_RM_HOME);
                 //check that statusCdmaRoamingMode is from an accepted value
                 if (statusCdmaRoamingMode == Phone.CDMA_RM_HOME ||
                         statusCdmaRoamingMode == Phone.CDMA_RM_ANY ) {
@@ -127,9 +128,9 @@
                     if (statusCdmaRoamingMode != settingsRoamingMode) {
                         settingsRoamingMode = statusCdmaRoamingMode;
                         //changes the Settings.Secure accordingly to statusCdmaRoamingMode
-                        Secure.putInt(
+                        Settings.Global.putInt(
                                 mPhone.getContext().getContentResolver(),
-                                Secure.CDMA_ROAMING_MODE,
+                                Settings.Global.CDMA_ROAMING_MODE,
                                 settingsRoamingMode );
                     }
                     //changes the mButtonPreferredNetworkMode accordingly to modemNetworkMode
@@ -147,8 +148,8 @@
 
             if ((ar.exception == null) && (getValue() != null)) {
                 int cdmaRoamingMode = Integer.valueOf(getValue()).intValue();
-                Secure.putInt(mPhone.getContext().getContentResolver(),
-                        Secure.CDMA_ROAMING_MODE,
+                Settings.Global.putInt(mPhone.getContext().getContentResolver(),
+                        Settings.Global.CDMA_ROAMING_MODE,
                         cdmaRoamingMode );
             } else {
                 mPhone.queryCdmaRoamingPreference(obtainMessage(MESSAGE_GET_ROAMING_PREFERENCE));
@@ -159,8 +160,8 @@
             //set the mButtonCdmaRoam
             setValue(Integer.toString(Phone.CDMA_RM_HOME));
             //set the Settings.System
-            Secure.putInt(mPhone.getContext().getContentResolver(),
-                        Secure.CDMA_ROAMING_MODE,
+            Settings.Global.putInt(mPhone.getContext().getContentResolver(),
+                        Settings.Global.CDMA_ROAMING_MODE,
                         Phone.CDMA_RM_HOME );
             //Set the Status
             mPhone.setCdmaRoamingPreference(Phone.CDMA_RM_HOME,
diff --git a/src/com/android/phone/CdmaVoicePrivacyCheckBoxPreference.java b/src/com/android/phone/CdmaVoicePrivacyCheckBoxPreference.java
index 6439c67..a5ff37e 100644
--- a/src/com/android/phone/CdmaVoicePrivacyCheckBoxPreference.java
+++ b/src/com/android/phone/CdmaVoicePrivacyCheckBoxPreference.java
@@ -28,7 +28,7 @@
 
 public class CdmaVoicePrivacyCheckBoxPreference extends CheckBoxPreference {
     private static final String LOG_TAG = "CdmaVoicePrivacyCheckBoxPreference";
-    private final boolean DBG = (PhoneApp.DBG_LEVEL >= 2);
+    private final boolean DBG = (PhoneGlobals.DBG_LEVEL >= 2);
 
     Phone phone;
     private MyHandler mHandler = new MyHandler();
@@ -36,7 +36,7 @@
     public CdmaVoicePrivacyCheckBoxPreference(Context context, AttributeSet attrs, int defStyle) {
         super(context, attrs, defStyle);
 
-        phone = PhoneApp.getPhone();
+        phone = PhoneGlobals.getPhone();
         phone.getEnhancedVoicePrivacy(mHandler.obtainMessage(MyHandler.MESSAGE_GET_VP));
     }
 
diff --git a/src/com/android/phone/CellBroadcastSms.java b/src/com/android/phone/CellBroadcastSms.java
index 296fb69..7428321 100644
--- a/src/com/android/phone/CellBroadcastSms.java
+++ b/src/com/android/phone/CellBroadcastSms.java
@@ -183,15 +183,15 @@
             if(mButtonBcSms.isChecked()) {
                 mPhone.activateCellBroadcastSms(RILConstants.CDMA_CELL_BROADCAST_SMS_ENABLED,
                         Message.obtain(mHandler, MESSAGE_ACTIVATE_CB_SMS));
-                android.provider.Settings.Secure.putInt(mPhone.getContext().getContentResolver(),
-                        android.provider.Settings.Secure.CDMA_CELL_BROADCAST_SMS,
+                android.provider.Settings.Global.putInt(mPhone.getContext().getContentResolver(),
+                        android.provider.Settings.Global.CDMA_CELL_BROADCAST_SMS,
                         RILConstants.CDMA_CELL_BROADCAST_SMS_ENABLED);
                 enableDisableAllCbConfigButtons(true);
             } else {
                 mPhone.activateCellBroadcastSms(RILConstants.CDMA_CELL_BROADCAST_SMS_DISABLED,
                         Message.obtain(mHandler, MESSAGE_ACTIVATE_CB_SMS));
-                android.provider.Settings.Secure.putInt(mPhone.getContext().getContentResolver(),
-                        android.provider.Settings.Secure.CDMA_CELL_BROADCAST_SMS,
+                android.provider.Settings.Global.putInt(mPhone.getContext().getContentResolver(),
+                        android.provider.Settings.Global.CDMA_CELL_BROADCAST_SMS,
                         RILConstants.CDMA_CELL_BROADCAST_SMS_DISABLED);
                 enableDisableAllCbConfigButtons(false);
             }
@@ -337,7 +337,7 @@
 
         addPreferencesFromResource(R.xml.cell_broadcast_sms);
 
-        mPhone = PhoneApp.getPhone();
+        mPhone = PhoneGlobals.getPhone();
         mHandler = new MyHandler();
 
         PreferenceScreen prefSet = getPreferenceScreen();
@@ -422,9 +422,9 @@
 
         getPreferenceScreen().setEnabled(true);
 
-        int settingCbSms = android.provider.Settings.Secure.getInt(
+        int settingCbSms = android.provider.Settings.Global.getInt(
                 mPhone.getContext().getContentResolver(),
-                android.provider.Settings.Secure.CDMA_CELL_BROADCAST_SMS,
+                android.provider.Settings.Global.CDMA_CELL_BROADCAST_SMS,
                 RILConstants.CDMA_CELL_BROADCAST_SMS_DISABLED);
         mButtonBcSms.setChecked(settingCbSms == RILConstants.CDMA_CELL_BROADCAST_SMS_ENABLED);
 
@@ -547,8 +547,8 @@
                     mButtonBcSms.setChecked(false);
                     mPhone.activateCellBroadcastSms(RILConstants.CDMA_CELL_BROADCAST_SMS_DISABLED,
                             Message.obtain(mHandler, MESSAGE_ACTIVATE_CB_SMS));
-                    android.provider.Settings.Secure.putInt(mPhone.getContext().getContentResolver(),
-                            android.provider.Settings.Secure.CDMA_CELL_BROADCAST_SMS,
+                    android.provider.Settings.Global.putInt(mPhone.getContext().getContentResolver(),
+                            android.provider.Settings.Global.CDMA_CELL_BROADCAST_SMS,
                             RILConstants.CDMA_CELL_BROADCAST_SMS_DISABLED);
                     enableDisableAllCbConfigButtons(false);
                 }
diff --git a/src/com/android/phone/ChangeIccPinScreen.java b/src/com/android/phone/ChangeIccPinScreen.java
index 7a77294..70bf431 100644
--- a/src/com/android/phone/ChangeIccPinScreen.java
+++ b/src/com/android/phone/ChangeIccPinScreen.java
@@ -42,7 +42,7 @@
  * "Change ICC PIN" UI for the Phone app.
  */
 public class ChangeIccPinScreen extends Activity {
-    private static final String LOG_TAG = PhoneApp.LOG_TAG;
+    private static final String LOG_TAG = PhoneGlobals.LOG_TAG;
     private static final boolean DBG = false;
 
     private static final int EVENT_PIN_CHANGED = 100;
@@ -91,7 +91,7 @@
     public void onCreate(Bundle icicle) {
         super.onCreate(icicle);
 
-        mPhone = PhoneApp.getPhone();
+        mPhone = PhoneGlobals.getPhone();
 
         resolveIntent();
 
diff --git a/src/com/android/phone/ClearMissedCallsService.java b/src/com/android/phone/ClearMissedCallsService.java
index c9608b8..b882472 100644
--- a/src/com/android/phone/ClearMissedCallsService.java
+++ b/src/com/android/phone/ClearMissedCallsService.java
@@ -29,7 +29,7 @@
     public static final String ACTION_CLEAR_MISSED_CALLS =
             "com.android.phone.intent.CLEAR_MISSED_CALLS";
 
-    private PhoneApp mApp;
+    private PhoneGlobals mApp;
 
     public ClearMissedCallsService() {
         super(ClearMissedCallsService.class.getSimpleName());
@@ -38,7 +38,7 @@
     @Override
     public void onCreate() {
         super.onCreate();
-        mApp = PhoneApp.getInstance();
+        mApp = PhoneGlobals.getInstance();
     }
 
     @Override
diff --git a/src/com/android/phone/DTMFTwelveKeyDialer.java b/src/com/android/phone/DTMFTwelveKeyDialer.java
index c47b366..0f198f2 100644
--- a/src/com/android/phone/DTMFTwelveKeyDialer.java
+++ b/src/com/android/phone/DTMFTwelveKeyDialer.java
@@ -16,6 +16,7 @@
 
 package com.android.phone;
 
+import android.content.Context;
 import android.media.AudioManager;
 import android.media.ToneGenerator;
 import android.os.Handler;
@@ -30,6 +31,9 @@
 import android.view.KeyEvent;
 import android.view.MotionEvent;
 import android.view.View;
+import android.view.ViewConfiguration;
+import android.view.View.OnHoverListener;
+import android.view.accessibility.AccessibilityManager;
 import android.view.ViewStub;
 import android.widget.EditText;
 
@@ -46,14 +50,18 @@
  * Dialer class that encapsulates the DTMF twelve key behaviour.
  * This model backs up the UI behaviour in DTMFTwelveKeyDialerView.java.
  */
-public class DTMFTwelveKeyDialer implements View.OnTouchListener, View.OnKeyListener {
+public class DTMFTwelveKeyDialer implements View.OnTouchListener, View.OnKeyListener,
+        View.OnHoverListener, View.OnClickListener {
     private static final String LOG_TAG = "DTMFTwelveKeyDialer";
-    private static final boolean DBG = (PhoneApp.DBG_LEVEL >= 2);
+    private static final boolean DBG = (PhoneGlobals.DBG_LEVEL >= 2);
 
     // events
     private static final int PHONE_DISCONNECT = 100;
     private static final int DTMF_SEND_CNF = 101;
 
+    /** Accessibility manager instance used to check touch exploration state. */
+    private final AccessibilityManager mAccessibilityManager;
+
     private CallManager mCM;
     private ToneGenerator mToneGenerator;
     private final Object mToneGeneratorLock = new Object();
@@ -366,10 +374,7 @@
      */
     public DTMFTwelveKeyDialer(InCallScreen parent,
                                 DTMFTwelveKeyDialerView dialerView) {
-        if (DBG) log("DTMFTwelveKeyDialer constructor... this = " + this);
-
-        mInCallScreen = parent;
-        mCM = PhoneApp.getInstance().mCM;
+        this(parent);
 
         // The passed-in DTMFTwelveKeyDialerView *should* always be
         // non-null, now that the in-call UI uses only portrait mode.
@@ -398,10 +403,7 @@
      * {@link ViewStub#inflate()}.
      */
     public DTMFTwelveKeyDialer(InCallScreen parent, ViewStub dialerStub) {
-        if (DBG) log("DTMFTwelveKeyDialer constructor... this = " + this);
-
-        mInCallScreen = parent;
-        mCM = PhoneApp.getInstance().mCM;
+        this(parent);
 
         mDialerStub = dialerStub;
         if (DBG) log("- Got passed-in mDialerStub: " + mDialerStub);
@@ -410,6 +412,21 @@
     }
 
     /**
+     * Private constructor used for initialization calls common to all public
+     * constructors.
+     *
+     * @param parent the InCallScreen instance that owns us.
+     */
+    private DTMFTwelveKeyDialer(InCallScreen parent) {
+        if (DBG) log("DTMFTwelveKeyDialer constructor... this = " + this);
+
+        mInCallScreen = parent;
+        mCM = PhoneGlobals.getInstance().mCM;
+        mAccessibilityManager = (AccessibilityManager) parent.getSystemService(
+                Context.ACCESSIBILITY_SERVICE);
+    }
+
+    /**
      * Prepare the dialer view and relevant variables.
      */
     private void setupDialerView() {
@@ -467,7 +484,7 @@
 
         // On some devices the screen timeout is set to a special value
         // while the dialpad is up.
-        PhoneApp.getInstance().updateWakeState();
+        PhoneGlobals.getInstance().updateWakeState();
 
         // Give the InCallScreen a chance to do any necessary UI updates.
         if (mInCallScreen != null) {
@@ -493,7 +510,7 @@
         if (DBG) log("startDialerSession()... this = " + this);
 
         // see if we need to play local tones.
-        if (PhoneApp.getInstance().getResources().getBoolean(R.bool.allow_local_dtmf_tones)) {
+        if (PhoneGlobals.getInstance().getResources().getBoolean(R.bool.allow_local_dtmf_tones)) {
             mLocalToneEnabled = Settings.System.getInt(mInCallScreen.getContentResolver(),
                     Settings.System.DTMF_TONE_WHEN_DIALING, 1) == 1;
         } else {
@@ -526,7 +543,7 @@
         if (DBG) log("onDialerClose()...");
 
         // reset back to a short delay for the poke lock.
-        PhoneApp app = PhoneApp.getInstance();
+        PhoneGlobals app = PhoneGlobals.getInstance();
         app.updateWakeState();
 
         mCM.unregisterForDisconnect(mHandler);
@@ -593,6 +610,8 @@
             button.setOnTouchListener(this);
             button.setClickable(true);
             button.setOnKeyListener(this);
+            button.setOnHoverListener(this);
+            button.setOnClickListener(this);
         }
     }
 
@@ -621,6 +640,53 @@
     }
 
     /**
+     * Implemented for {@link android.view.View.OnHoverListener}. Handles touch
+     * events for accessibility when touch exploration is enabled.
+     */
+    @Override
+    public boolean onHover(View v, MotionEvent event) {
+        // When touch exploration is turned on, lifting a finger while inside
+        // the button's hover target bounds should perform a click action.
+        if (mAccessibilityManager.isEnabled()
+                && mAccessibilityManager.isTouchExplorationEnabled()) {
+            final int left = v.getPaddingLeft();
+            final int right = (v.getWidth() - v.getPaddingRight());
+            final int top = v.getPaddingTop();
+            final int bottom = (v.getHeight() - v.getPaddingBottom());
+
+            switch (event.getActionMasked()) {
+                case MotionEvent.ACTION_HOVER_ENTER:
+                    // Lift-to-type temporarily disables double-tap activation.
+                    v.setClickable(false);
+                    break;
+                case MotionEvent.ACTION_HOVER_EXIT:
+                    final int x = (int) event.getX();
+                    final int y = (int) event.getY();
+                    if ((x > left) && (x < right) && (y > top) && (y < bottom)) {
+                        v.performClick();
+                    }
+                    v.setClickable(true);
+                    break;
+            }
+        }
+
+        return false;
+    }
+
+    @Override
+    public void onClick(View v) {
+        // When accessibility is on, simulate press and release to preserve the
+        // semantic meaning of performClick(). Required for Braille support.
+        if (mAccessibilityManager.isEnabled()) {
+            final int id = v.getId();
+            // Checking the press state prevents double activation.
+            if (!v.isPressed() && mDisplayMap.containsKey(id)) {
+                processDtmf(mDisplayMap.get(id), true /* forceShortTone */);
+            }
+        }
+    }
+
+    /**
      * Implemented for the TouchListener, process the touch events.
      */
     @Override
@@ -764,8 +830,19 @@
      * Processes the specified digit as a DTMF key, by playing the
      * appropriate DTMF tone, and appending the digit to the EditText
      * field that displays the DTMF digits sent so far.
+     *
+     * @see #processDtmf(char, boolean)
      */
     private final void processDtmf(char c) {
+        processDtmf(c, false);
+    }
+
+    /**
+     * Processes the specified digit as a DTMF key, by playing the appropriate
+     * DTMF tone (or short tone if requested), and appending the digit to the
+     * EditText field that displays the DTMF digits sent so far.
+     */
+    private final void processDtmf(char c, boolean forceShortTone) {
         // if it is a valid key, then update the display and send the dtmf tone.
         if (PhoneNumberUtils.is12Key(c)) {
             if (DBG) log("updating display and sending dtmf tone for '" + c + "'");
@@ -787,14 +864,14 @@
             // Play the tone if it exists.
             if (mToneMap.containsKey(c)) {
                 // begin tone playback.
-                startTone(c);
+                startTone(c, forceShortTone);
             }
         } else if (DBG) {
             log("ignoring dtmf request for '" + c + "'");
         }
 
         // Any DTMF keypress counts as explicit "user activity".
-        PhoneApp.getInstance().pokeUserActivity();
+        PhoneGlobals.getInstance().pokeUserActivity();
     }
 
     /**
@@ -858,7 +935,7 @@
     /**
      * Plays the local tone based the phone type.
      */
-    public void startTone(char c) {
+    public void startTone(char c, boolean forceShortTone) {
         // Only play the tone if it exists.
         if (!mToneMap.containsKey(c)) {
             return;
@@ -875,20 +952,28 @@
         if (DBG) log("startDtmfTone()...");
 
         // For Short DTMF we need to play the local tone for fixed duration
-        if (mShortTone) {
+        if (forceShortTone || mShortTone) {
             sendShortDtmfToNetwork(c);
         } else {
             // Pass as a char to be sent to network
-            Log.i(LOG_TAG, "send long dtmf for " + c);
+            if (DBG) log("send long dtmf for " + c);
             mCM.startDtmf(c);
         }
-        startLocalToneIfNeeded(c);
+        startLocalToneIfNeeded(c, forceShortTone);
     }
 
     /**
      * Plays the local tone based the phone type.
      */
     public void startLocalToneIfNeeded(char c) {
+        startLocalToneIfNeeded(c, false);
+    }
+
+    /**
+     * Plays the local tone based the phone type, optionally forcing a short
+     * tone.
+     */
+    private void startLocalToneIfNeeded(char c, boolean forceShortTone) {
         // if local tone playback is enabled, start it.
         // Only play the tone if it exists.
         if (!mToneMap.containsKey(c)) {
@@ -901,7 +986,7 @@
                 } else {
                     if (DBG) log("starting local tone " + c);
                     int toneDuration = -1;
-                    if (mShortTone) {
+                    if (forceShortTone || mShortTone) {
                         toneDuration = DTMF_DURATION_MS;
                     }
                     mToneGenerator.startTone(mToneMap.get(c), toneDuration);
diff --git a/src/com/android/phone/DeleteFdnContactScreen.java b/src/com/android/phone/DeleteFdnContactScreen.java
index 19b10c6..074078c 100644
--- a/src/com/android/phone/DeleteFdnContactScreen.java
+++ b/src/com/android/phone/DeleteFdnContactScreen.java
@@ -36,7 +36,7 @@
  * Activity to let the user delete an FDN contact.
  */
 public class DeleteFdnContactScreen extends Activity {
-    private static final String LOG_TAG = PhoneApp.LOG_TAG;
+    private static final String LOG_TAG = PhoneGlobals.LOG_TAG;
     private static final boolean DBG = false;
 
     private static final String INTENT_EXTRA_NAME = "name";
diff --git a/src/com/android/phone/EditFdnContactScreen.java b/src/com/android/phone/EditFdnContactScreen.java
index 36a6b79..cca9a9f 100644
--- a/src/com/android/phone/EditFdnContactScreen.java
+++ b/src/com/android/phone/EditFdnContactScreen.java
@@ -51,7 +51,7 @@
  * Activity to let the user add or edit an FDN contact.
  */
 public class EditFdnContactScreen extends Activity {
-    private static final String LOG_TAG = PhoneApp.LOG_TAG;
+    private static final String LOG_TAG = PhoneGlobals.LOG_TAG;
     private static final boolean DBG = false;
 
     // Menu item codes
diff --git a/src/com/android/phone/EditPhoneNumberPreference.java b/src/com/android/phone/EditPhoneNumberPreference.java
index d5ef3a4..86671a8 100644
--- a/src/com/android/phone/EditPhoneNumberPreference.java
+++ b/src/com/android/phone/EditPhoneNumberPreference.java
@@ -260,7 +260,7 @@
             }
         }
         // set the call icon on the title.
-        builder.setIcon(R.drawable.ic_launcher_phone);
+        builder.setIcon(R.mipmap.ic_launcher_phone);
     }
 
 
diff --git a/src/com/android/phone/EmergencyCallHelper.java b/src/com/android/phone/EmergencyCallHelper.java
index 3508b94..7f5b0d2 100644
--- a/src/com/android/phone/EmergencyCallHelper.java
+++ b/src/com/android/phone/EmergencyCallHelper.java
@@ -29,6 +29,7 @@
 import android.os.Handler;
 import android.os.Message;
 import android.os.PowerManager;
+import android.os.UserHandle;
 import android.provider.Settings;
 import android.telephony.ServiceState;
 import android.util.Log;
@@ -65,7 +66,7 @@
     private static final int RETRY_TIMEOUT = 4;
 
     private CallController mCallController;
-    private PhoneApp mApp;
+    private PhoneGlobals mApp;
     private CallManager mCM;
     private Phone mPhone;
     private String mNumber;  // The emergency number we're trying to dial
@@ -77,7 +78,7 @@
     public EmergencyCallHelper(CallController callController) {
         if (DBG) log("EmergencyCallHelper constructor...");
         mCallController = callController;
-        mApp = PhoneApp.getInstance();
+        mApp = PhoneGlobals.getInstance();
         mCM =  mApp.mCM;
     }
 
@@ -346,18 +347,18 @@
 
         // If airplane mode is on, we turn it off the same way that the
         // Settings activity turns it off.
-        if (Settings.System.getInt(mApp.getContentResolver(),
-                                   Settings.System.AIRPLANE_MODE_ON, 0) > 0) {
+        if (Settings.Global.getInt(mApp.getContentResolver(),
+                                   Settings.Global.AIRPLANE_MODE_ON, 0) > 0) {
             if (DBG) log("==> Turning off airplane mode...");
 
             // Change the system setting
-            Settings.System.putInt(mApp.getContentResolver(),
-                                   Settings.System.AIRPLANE_MODE_ON, 0);
+            Settings.Global.putInt(mApp.getContentResolver(),
+                                   Settings.Global.AIRPLANE_MODE_ON, 0);
 
             // Post the intent
             Intent intent = new Intent(Intent.ACTION_AIRPLANE_MODE_CHANGED);
             intent.putExtra("state", false);
-            mApp.sendBroadcast(intent);
+            mApp.sendBroadcastAsUser(intent, UserHandle.ALL);
         } else {
             // Otherwise, for some strange reason the radio is off
             // (even though the Settings database doesn't think we're
diff --git a/src/com/android/phone/EmergencyCallbackModeExitDialog.java b/src/com/android/phone/EmergencyCallbackModeExitDialog.java
index 2257aba..7758b23 100644
--- a/src/com/android/phone/EmergencyCallbackModeExitDialog.java
+++ b/src/com/android/phone/EmergencyCallbackModeExitDialog.java
@@ -91,7 +91,7 @@
         waitForConnectionCompleteThread.start();
 
         // Register ECM timer reset notfication
-        mPhone = PhoneApp.getPhone();
+        mPhone = PhoneGlobals.getPhone();
         mPhone.registerForEcmTimerReset(mTimerResetHandler, ECM_TIMER_RESET, null);
 
         // Register receiver for intent closing the dialog
diff --git a/src/com/android/phone/EmergencyDialer.java b/src/com/android/phone/EmergencyDialer.java
index a3c8d89..f3d9a14 100644
--- a/src/com/android/phone/EmergencyDialer.java
+++ b/src/com/android/phone/EmergencyDialer.java
@@ -37,8 +37,10 @@
 import android.text.method.DialerKeyListener;
 import android.util.Log;
 import android.view.KeyEvent;
+import android.view.MotionEvent;
 import android.view.View;
 import android.view.WindowManager;
+import android.view.accessibility.AccessibilityManager;
 import android.widget.EditText;
 
 
@@ -59,21 +61,28 @@
  * Or could we figure out some way to move *this* class into apps/Contacts
  * also?
  */
-public class EmergencyDialer extends Activity
-        implements View.OnClickListener, View.OnLongClickListener,
-        View.OnKeyListener, TextWatcher {
+public class EmergencyDialer extends Activity implements View.OnClickListener,
+        View.OnLongClickListener, View.OnHoverListener, View.OnKeyListener, TextWatcher {
     // Keys used with onSaveInstanceState().
     private static final String LAST_NUMBER = "lastNumber";
 
     // Intent action for this activity.
     public static final String ACTION_DIAL = "com.android.phone.EmergencyDialer.DIAL";
 
+    // List of dialer button IDs.
+    private static final int[] DIALER_KEYS = new int[] {
+            R.id.one, R.id.two, R.id.three,
+            R.id.four, R.id.five, R.id.six,
+            R.id.seven, R.id.eight, R.id.nine,
+            R.id.star, R.id.zero, R.id.pound };
+
     // Debug constants.
     private static final boolean DBG = false;
     private static final String LOG_TAG = "EmergencyDialer";
 
-    private PhoneApp mApp;
+    private PhoneGlobals mApp;
     private StatusBarManager mStatusBarManager;
+    private AccessibilityManager mAccessibilityManager;
 
     /** The length of DTMF tones in milliseconds */
     private static final int TONE_LENGTH_MS = 150;
@@ -86,6 +95,8 @@
 
     private static final int BAD_EMERGENCY_NUMBER_DIALOG = 0;
 
+    private static final int USER_ACTIVITY_TIMEOUT_WHEN_NO_PROX_SENSOR = 15000; // millis
+
     EditText mDigits;
     private View mDialButton;
     private View mDelete;
@@ -144,11 +155,18 @@
     protected void onCreate(Bundle icicle) {
         super.onCreate(icicle);
 
-        mApp = PhoneApp.getInstance();
+        mApp = PhoneGlobals.getInstance();
         mStatusBarManager = (StatusBarManager) getSystemService(Context.STATUS_BAR_SERVICE);
+        mAccessibilityManager = (AccessibilityManager) getSystemService(ACCESSIBILITY_SERVICE);
 
         // Allow this activity to be displayed in front of the keyguard / lockscreen.
-        getWindow().addFlags(WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED);
+        WindowManager.LayoutParams lp = getWindow().getAttributes();
+        lp.flags |= WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED;
+        if (!mApp.proximitySensorModeEnabled()) {
+            // When no proximity sensor is available, use a shorter timeout.
+            lp.userActivityTimeout = USER_ACTIVITY_TIMEOUT_WHEN_NO_PROX_SENSOR;
+        }
+        getWindow().setAttributes(lp);
 
         setContentView(R.layout.emergency_dialer);
 
@@ -157,6 +175,10 @@
         mDigits.setOnClickListener(this);
         mDigits.setOnKeyListener(this);
         mDigits.setLongClickable(false);
+        if (mAccessibilityManager.isEnabled()) {
+            // The text view must be selected to send accessibility events.
+            mDigits.setSelected(true);
+        }
         maybeAddNumberFormatting();
 
         // Check for the presence of the keypad
@@ -260,22 +282,14 @@
 
     private void setupKeypad() {
         // Setup the listeners for the buttons
-        findViewById(R.id.one).setOnClickListener(this);
-        findViewById(R.id.two).setOnClickListener(this);
-        findViewById(R.id.three).setOnClickListener(this);
-        findViewById(R.id.four).setOnClickListener(this);
-        findViewById(R.id.five).setOnClickListener(this);
-        findViewById(R.id.six).setOnClickListener(this);
-        findViewById(R.id.seven).setOnClickListener(this);
-        findViewById(R.id.eight).setOnClickListener(this);
-        findViewById(R.id.nine).setOnClickListener(this);
-        findViewById(R.id.star).setOnClickListener(this);
+        for (int id : DIALER_KEYS) {
+            final View key = findViewById(id);
+            key.setOnClickListener(this);
+            key.setOnHoverListener(this);
+        }
 
         View view = findViewById(R.id.zero);
-        view.setOnClickListener(this);
         view.setOnLongClickListener(this);
-
-        findViewById(R.id.pound).setOnClickListener(this);
     }
 
     /**
@@ -405,6 +419,40 @@
     }
 
     /**
+     * Implemented for {@link android.view.View.OnHoverListener}. Handles touch
+     * events for accessibility when touch exploration is enabled.
+     */
+    @Override
+    public boolean onHover(View v, MotionEvent event) {
+        // When touch exploration is turned on, lifting a finger while inside
+        // the button's hover target bounds should perform a click action.
+        if (mAccessibilityManager.isEnabled()
+                && mAccessibilityManager.isTouchExplorationEnabled()) {
+
+            switch (event.getActionMasked()) {
+                case MotionEvent.ACTION_HOVER_ENTER:
+                    // Lift-to-type temporarily disables double-tap activation.
+                    v.setClickable(false);
+                    break;
+                case MotionEvent.ACTION_HOVER_EXIT:
+                    final int left = v.getPaddingLeft();
+                    final int right = (v.getWidth() - v.getPaddingRight());
+                    final int top = v.getPaddingTop();
+                    final int bottom = (v.getHeight() - v.getPaddingBottom());
+                    final int x = (int) event.getX();
+                    final int y = (int) event.getY();
+                    if ((x > left) && (x < right) && (y > top) && (y < bottom)) {
+                        v.performClick();
+                    }
+                    v.setClickable(true);
+                    break;
+            }
+        }
+
+        return false;
+    }
+
+    /**
      * called for long touch events
      */
     @Override
@@ -456,7 +504,6 @@
         // There is no need to do anything with the wake lock.
         if (DBG) Log.d(LOG_TAG, "disabling status bar, set to long timeout");
         mStatusBarManager.disable(StatusBarManager.DISABLE_EXPAND);
-        mApp.setScreenTimeout(PhoneApp.ScreenTimeoutDuration.MEDIUM);
 
         updateDialAndDeleteButtonStateEnabledAttr();
     }
@@ -467,7 +514,6 @@
         // There is no need to do anything with the wake lock.
         if (DBG) Log.d(LOG_TAG, "reenabling status bar and closing the dialer");
         mStatusBarManager.disable(StatusBarManager.DISABLE_NONE);
-        mApp.setScreenTimeout(PhoneApp.ScreenTimeoutDuration.DEFAULT);
 
         super.onPause();
 
diff --git a/src/com/android/phone/EnableFdnScreen.java b/src/com/android/phone/EnableFdnScreen.java
index 305407f..0db47c3 100644
--- a/src/com/android/phone/EnableFdnScreen.java
+++ b/src/com/android/phone/EnableFdnScreen.java
@@ -36,7 +36,7 @@
  * UI to enable/disable FDN.
  */
 public class EnableFdnScreen extends Activity {
-    private static final String LOG_TAG = PhoneApp.LOG_TAG;
+    private static final String LOG_TAG = PhoneGlobals.LOG_TAG;
     private static final boolean DBG = false;
 
     private static final int ENABLE_FDN_COMPLETE = 100;
@@ -67,7 +67,7 @@
         setContentView(R.layout.enable_fdn_screen);
         setupView();
 
-        mPhone = PhoneApp.getPhone();
+        mPhone = PhoneGlobals.getPhone();
         mEnable = !mPhone.getIccCard().getIccFdnEnabled();
 
         int id = mEnable ? R.string.enable_fdn : R.string.disable_fdn;
@@ -77,7 +77,7 @@
     @Override
     protected void onResume() {
         super.onResume();
-        mPhone = PhoneApp.getPhone();
+        mPhone = PhoneGlobals.getPhone();
     }
 
     private void setupView() {
diff --git a/src/com/android/phone/EnableIccPinScreen.java b/src/com/android/phone/EnableIccPinScreen.java
index a623d46..160978f 100644
--- a/src/com/android/phone/EnableIccPinScreen.java
+++ b/src/com/android/phone/EnableIccPinScreen.java
@@ -36,7 +36,7 @@
  * UI to enable/disable the ICC PIN.
  */
 public class EnableIccPinScreen extends Activity {
-    private static final String LOG_TAG = PhoneApp.LOG_TAG;
+    private static final String LOG_TAG = PhoneGlobals.LOG_TAG;
 
     private static final int ENABLE_ICC_PIN_COMPLETE = 100;
     private static final boolean DBG = false;
@@ -67,7 +67,7 @@
         setContentView(R.layout.enable_sim_pin_screen);
         setupView();
 
-        mPhone = PhoneApp.getPhone();
+        mPhone = PhoneGlobals.getPhone();
         mEnable = !mPhone.getIccCard().getIccLockEnabled();
 
         int id = mEnable ? R.string.enable_sim_pin : R.string.disable_sim_pin;
diff --git a/src/com/android/phone/FakePhoneActivity.java b/src/com/android/phone/FakePhoneActivity.java
index 07fce9c..686a766 100644
--- a/src/com/android/phone/FakePhoneActivity.java
+++ b/src/com/android/phone/FakePhoneActivity.java
@@ -54,10 +54,10 @@
                     }
                 });
 
-        mRadioControl = PhoneApp.getPhone().getSimulatedRadioControl();
+        mRadioControl = PhoneGlobals.getPhone().getSimulatedRadioControl();
 
-        Log.i(TAG, "- PhoneApp.getInstance(): " + PhoneApp.getInstance());
-        Log.i(TAG, "- PhoneApp.getPhone(): " + PhoneApp.getPhone());
+        Log.i(TAG, "- PhoneApp.getInstance(): " + PhoneGlobals.getInstance());
+        Log.i(TAG, "- PhoneApp.getPhone(): " + PhoneGlobals.getPhone());
         Log.i(TAG, "- mRadioControl: " + mRadioControl);
     }
 
diff --git a/src/com/android/phone/FdnSetting.java b/src/com/android/phone/FdnSetting.java
index 4f21e2f..283d612 100644
--- a/src/com/android/phone/FdnSetting.java
+++ b/src/com/android/phone/FdnSetting.java
@@ -40,7 +40,7 @@
 public class FdnSetting extends PreferenceActivity
         implements EditPinPreference.OnPinEnteredListener, DialogInterface.OnCancelListener {
 
-    private static final String LOG_TAG = PhoneApp.LOG_TAG;
+    private static final String LOG_TAG = PhoneGlobals.LOG_TAG;
     private static final boolean DBG = false;
 
     private Phone mPhone;
@@ -423,7 +423,7 @@
 
         addPreferencesFromResource(R.xml.fdn_setting);
 
-        mPhone = PhoneApp.getPhone();
+        mPhone = PhoneGlobals.getPhone();
 
         //get UI object references
         PreferenceScreen prefSet = getPreferenceScreen();
@@ -458,7 +458,7 @@
     @Override
     protected void onResume() {
         super.onResume();
-        mPhone = PhoneApp.getPhone();
+        mPhone = PhoneGlobals.getPhone();
         updateEnableFDN();
     }
 
diff --git a/src/com/android/phone/GetPin2Screen.java b/src/com/android/phone/GetPin2Screen.java
index c3fda66..a06b0cf 100644
--- a/src/com/android/phone/GetPin2Screen.java
+++ b/src/com/android/phone/GetPin2Screen.java
@@ -34,7 +34,7 @@
  * Pin2 entry screen.
  */
 public class GetPin2Screen extends Activity implements TextView.OnEditorActionListener {
-    private static final String LOG_TAG = PhoneApp.LOG_TAG;
+    private static final String LOG_TAG = PhoneGlobals.LOG_TAG;
 
     private EditText mPin2Field;
     private Button mOkButton;
diff --git a/src/com/android/phone/GsmUmtsAdditionalCallOptions.java b/src/com/android/phone/GsmUmtsAdditionalCallOptions.java
index 131ffe5..cd400f9 100644
--- a/src/com/android/phone/GsmUmtsAdditionalCallOptions.java
+++ b/src/com/android/phone/GsmUmtsAdditionalCallOptions.java
@@ -13,7 +13,7 @@
 public class GsmUmtsAdditionalCallOptions extends
         TimeConsumingPreferenceActivity {
     private static final String LOG_TAG = "GsmUmtsAdditionalCallOptions";
-    private final boolean DBG = (PhoneApp.DBG_LEVEL >= 2);
+    private final boolean DBG = (PhoneGlobals.DBG_LEVEL >= 2);
 
     private static final String BUTTON_CLIR_KEY  = "button_clir_key";
     private static final String BUTTON_CW_KEY    = "button_cw_key";
diff --git a/src/com/android/phone/GsmUmtsCallForwardOptions.java b/src/com/android/phone/GsmUmtsCallForwardOptions.java
index 09459eb..5f68135 100644
--- a/src/com/android/phone/GsmUmtsCallForwardOptions.java
+++ b/src/com/android/phone/GsmUmtsCallForwardOptions.java
@@ -18,7 +18,7 @@
 
 public class GsmUmtsCallForwardOptions extends TimeConsumingPreferenceActivity {
     private static final String LOG_TAG = "GsmUmtsCallForwardOptions";
-    private final boolean DBG = (PhoneApp.DBG_LEVEL >= 2);
+    private final boolean DBG = (PhoneGlobals.DBG_LEVEL >= 2);
 
     private static final String NUM_PROJECTION[] = {Phone.NUMBER};
 
diff --git a/src/com/android/phone/GsmUmtsCallOptions.java b/src/com/android/phone/GsmUmtsCallOptions.java
index ed28be9..a9a1940 100644
--- a/src/com/android/phone/GsmUmtsCallOptions.java
+++ b/src/com/android/phone/GsmUmtsCallOptions.java
@@ -27,7 +27,7 @@
 
 public class GsmUmtsCallOptions extends PreferenceActivity {
     private static final String LOG_TAG = "GsmUmtsCallOptions";
-    private final boolean DBG = (PhoneApp.DBG_LEVEL >= 2);
+    private final boolean DBG = (PhoneGlobals.DBG_LEVEL >= 2);
 
     @Override
     protected void onCreate(Bundle icicle) {
@@ -35,7 +35,7 @@
 
         addPreferencesFromResource(R.xml.gsm_umts_call_options);
 
-        if (PhoneApp.getPhone().getPhoneType() != PhoneConstants.PHONE_TYPE_GSM) {
+        if (PhoneGlobals.getPhone().getPhoneType() != PhoneConstants.PHONE_TYPE_GSM) {
             //disable the entire screen
             getPreferenceScreen().setEnabled(false);
         }
diff --git a/src/com/android/phone/IccNetworkDepersonalizationPanel.java b/src/com/android/phone/IccNetworkDepersonalizationPanel.java
index 3688be2..aa582a1 100644
--- a/src/com/android/phone/IccNetworkDepersonalizationPanel.java
+++ b/src/com/android/phone/IccNetworkDepersonalizationPanel.java
@@ -39,7 +39,7 @@
 /**
  * "SIM network unlock" PIN entry screen.
  *
- * @see PhoneApp.EVENT_SIM_NETWORK_LOCKED
+ * @see PhoneGlobals.EVENT_SIM_NETWORK_LOCKED
  *
  * TODO: This UI should be part of the lock screen, not the
  * phone app (see bug 1804111).
@@ -148,7 +148,7 @@
         mStatusPanel = (LinearLayout) findViewById(R.id.status_panel);
         mStatusText = (TextView) findViewById(R.id.status_text);
 
-        mPhone = PhoneApp.getPhone();
+        mPhone = PhoneGlobals.getPhone();
     }
 
     @Override
diff --git a/src/com/android/phone/IccPanel.java b/src/com/android/phone/IccPanel.java
index c80b5dc..e603a06 100644
--- a/src/com/android/phone/IccPanel.java
+++ b/src/com/android/phone/IccPanel.java
@@ -29,7 +29,7 @@
  * Base class for ICC-related panels in the Phone UI.
  */
 public class IccPanel extends Dialog {
-    protected static final String TAG = PhoneApp.LOG_TAG;
+    protected static final String TAG = PhoneGlobals.LOG_TAG;
 
     private StatusBarManager mStatusBarManager;
 
@@ -65,7 +65,7 @@
         // TODO: we shouldn't need the mStatusBarManager calls here either,
         // once this dialog gets moved into the framework and becomes a truly
         // full-screen UI.
-        PhoneApp app = PhoneApp.getInstance();
+        PhoneGlobals app = PhoneGlobals.getInstance();
         mStatusBarManager = (StatusBarManager) app.getSystemService(Context.STATUS_BAR_SERVICE);
 
         requestWindowFeature(Window.FEATURE_NO_TITLE);
diff --git a/src/com/android/phone/InCallControlState.java b/src/com/android/phone/InCallControlState.java
index e901cf1..e5c7f20 100644
--- a/src/com/android/phone/InCallControlState.java
+++ b/src/com/android/phone/InCallControlState.java
@@ -42,7 +42,7 @@
  */
 public class InCallControlState {
     private static final String LOG_TAG = "InCallControlState";
-    private static final boolean DBG = (PhoneApp.DBG_LEVEL >= 2);
+    private static final boolean DBG = (PhoneGlobals.DBG_LEVEL >= 2);
 
     private InCallScreen mInCallScreen;
     private CallManager mCM;
diff --git a/src/com/android/phone/InCallScreen.java b/src/com/android/phone/InCallScreen.java
index 05675e6..f8ba9c7 100755
--- a/src/com/android/phone/InCallScreen.java
+++ b/src/com/android/phone/InCallScreen.java
@@ -25,6 +25,7 @@
 import android.bluetooth.BluetoothDevice;
 import android.bluetooth.BluetoothHeadset;
 import android.bluetooth.BluetoothProfile;
+import android.bluetooth.IBluetoothHeadsetPhone;
 import android.content.ActivityNotFoundException;
 import android.content.BroadcastReceiver;
 import android.content.Context;
@@ -41,6 +42,7 @@
 import android.os.Handler;
 import android.os.Message;
 import android.os.PowerManager;
+import android.os.RemoteException;
 import android.os.SystemClock;
 import android.os.SystemProperties;
 import android.telephony.ServiceState;
@@ -83,8 +85,8 @@
     private static final String LOG_TAG = "InCallScreen";
 
     private static final boolean DBG =
-            (PhoneApp.DBG_LEVEL >= 1) && (SystemProperties.getInt("ro.debuggable", 0) == 1);
-    private static final boolean VDBG = (PhoneApp.DBG_LEVEL >= 2);
+            (PhoneGlobals.DBG_LEVEL >= 1) && (SystemProperties.getInt("ro.debuggable", 0) == 1);
+    private static final boolean VDBG = (PhoneGlobals.DBG_LEVEL >= 2);
 
     /**
      * Intent extra used to specify whether the DTMF dialpad should be
@@ -151,7 +153,6 @@
     private static final int DONT_ADD_VOICEMAIL_NUMBER = 107;
     private static final int DELAYED_CLEANUP_AFTER_DISCONNECT = 108;
     private static final int SUPP_SERVICE_FAILED = 110;
-    private static final int ALLOW_SCREEN_ON = 112;
     private static final int REQUEST_UPDATE_BLUETOOTH_INDICATION = 114;
     private static final int PHONE_CDMA_CALL_WAITING = 115;
     private static final int REQUEST_CLOSE_SPC_ERROR_NOTICE = 118;
@@ -187,7 +188,7 @@
 
     private boolean mRegisteredForPhoneStates;
 
-    private PhoneApp mApp;
+    private PhoneGlobals mApp;
     private CallManager mCM;
 
     // TODO: need to clean up all remaining uses of mPhone.
@@ -197,9 +198,8 @@
     // based on the current foreground Call.)
     private Phone mPhone;
 
-    private BluetoothHandsfree mBluetoothHandsfree;
     private BluetoothHeadset mBluetoothHeadset;
-    private BluetoothAdapter mAdapter;
+    private BluetoothAdapter mBluetoothAdapter;
     private boolean mBluetoothConnectionPending;
     private long mBluetoothConnectionRequestTime;
 
@@ -316,7 +316,7 @@
                 // onMMIInitiate((AsyncResult) msg.obj);
                 //    break;
 
-                case PhoneApp.MMI_CANCEL:
+                case PhoneGlobals.MMI_CANCEL:
                     onMMICancel();
                     break;
 
@@ -324,7 +324,7 @@
                 // since the message display class has been replaced with
                 // a system dialog in PhoneUtils.displayMMIComplete(), we
                 // should finish the activity here to close the window.
-                case PhoneApp.MMI_COMPLETE:
+                case PhoneGlobals.MMI_COMPLETE:
                     onMMIComplete((MmiCode) ((AsyncResult) msg.obj).result);
                     break;
 
@@ -344,15 +344,6 @@
                     delayedCleanupAfterDisconnect();
                     break;
 
-                case ALLOW_SCREEN_ON:
-                    if (VDBG) log("ALLOW_SCREEN_ON message...");
-                    // Undo our previous call to preventScreenOn(true).
-                    // (Note this will cause the screen to turn on
-                    // immediately, if it's currently off because of a
-                    // prior preventScreenOn(true) call.)
-                    mApp.preventScreenOn(false);
-                    break;
-
                 case REQUEST_UPDATE_BLUETOOTH_INDICATION:
                     if (VDBG) log("REQUEST_UPDATE_BLUETOOTH_INDICATION...");
                     // The bluetooth headset state changed, so some UI
@@ -448,7 +439,7 @@
         super.onCreate(icicle);
 
         // Make sure this is a voice-capable device.
-        if (!PhoneApp.sVoiceCapable) {
+        if (!PhoneGlobals.sVoiceCapable) {
             // There should be no way to ever reach the InCallScreen on a
             // non-voice-capable device, since this activity is not exported by
             // our manifest, and we explicitly disable any other external APIs
@@ -459,11 +450,12 @@
             return;
         }
 
-        mApp = PhoneApp.getInstance();
+        mApp = PhoneGlobals.getInstance();
         mApp.setInCallScreenInstance(this);
 
         // set this flag so this activity will stay in front of the keyguard
-        int flags = WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED;
+        int flags = WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED
+                | WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON;
         if (mApp.getPhoneState() == PhoneConstants.State.OFFHOOK) {
             // While we are in call, the in-call screen should dismiss the keyguard.
             // This allows the user to press Home to go directly home without going through
@@ -472,24 +464,26 @@
             // bypass the keyguard if the call is not answered or declined.
             flags |= WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD;
         }
-        getWindow().addFlags(flags);
+
+        WindowManager.LayoutParams lp = getWindow().getAttributes();
+        lp.flags |= flags;
+        if (!mApp.proximitySensorModeEnabled()) {
+            // If we don't have a proximity sensor, then the in-call screen explicitly
+            // controls user activity.  This is to prevent spurious touches from waking
+            // the display.
+            lp.inputFeatures |= WindowManager.LayoutParams.INPUT_FEATURE_DISABLE_USER_ACTIVITY;
+        }
+        getWindow().setAttributes(lp);
 
         setPhone(mApp.phone);  // Sets mPhone
 
         mCM =  mApp.mCM;
         log("- onCreate: phone state = " + mCM.getState());
 
-        mBluetoothHandsfree = mApp.getBluetoothHandsfree();
-        if (VDBG) log("- mBluetoothHandsfree: " + mBluetoothHandsfree);
-
-        if (mBluetoothHandsfree != null) {
-            // The PhoneApp only creates a BluetoothHandsfree instance in the
-            // first place if BluetoothAdapter.getDefaultAdapter()
-            // succeeds.  So at this point we know the device is BT-capable.
-            mAdapter = BluetoothAdapter.getDefaultAdapter();
-            mAdapter.getProfileProxy(getApplicationContext(), mBluetoothProfileServiceListener,
+        mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
+        if (mBluetoothAdapter != null) {
+            mBluetoothAdapter.getProfileProxy(getApplicationContext(), mBluetoothProfileServiceListener,
                                     BluetoothProfile.HEADSET);
-
         }
 
         requestWindowFeature(Window.FEATURE_NO_TITLE);
@@ -497,6 +491,13 @@
         // Inflate everything in incall_screen.xml and add it to the screen.
         setContentView(R.layout.incall_screen);
 
+        // If in landscape, then one of the ViewStubs (instead of <include>) is used for the
+        // incall_touch_ui, because CDMA and GSM button layouts are noticeably different.
+        final ViewStub touchUiStub = (ViewStub) findViewById(
+                mPhone.getPhoneType() == PhoneConstants.PHONE_TYPE_CDMA
+                ? R.id.inCallTouchUiCdmaStub : R.id.inCallTouchUiStub);
+        if (touchUiStub != null) touchUiStub.inflate();
+
         initInCallScreen();
 
         registerForPhoneStates();
@@ -560,11 +561,6 @@
         final InCallUiState inCallUiState = mApp.inCallUiState;
         if (VDBG) inCallUiState.dumpState();
 
-        // Touch events are never considered "user activity" while the
-        // InCallScreen is active, so that unintentional touches won't
-        // prevent the device from going to sleep.
-        mApp.setIgnoreTouchUserActivity(true);
-
         updateExpandedViewState();
 
         // ...and update the in-call notification too, since the status bar
@@ -711,40 +707,6 @@
         // InCallScreen is now active.
         EventLog.writeEvent(EventLogTags.PHONE_UI_ENTER);
 
-        // Coming to the foreground while in an incoming call is ringing.
-        // We need to do something special.
-        if (mCM.getState() == PhoneConstants.State.RINGING) {
-            // If the phone is ringing, we *should* already be holding a
-            // full wake lock (which we would have acquired before
-            // firing off the intent that brought us here; see
-            // CallNotifier.showIncomingCall().)
-            //
-            // We also called preventScreenOn(true) at that point, to
-            // avoid cosmetic glitches while we were being launched.
-            // So now we need to post an ALLOW_SCREEN_ON message to
-            // (eventually) undo the prior preventScreenOn(true) call.
-            //
-            // (In principle we shouldn't do this until after our first
-            // layout/draw pass.  But in practice, the delay caused by
-            // simply waiting for the end of the message queue is long
-            // enough to avoid any flickering of the lock screen before
-            // the InCallScreen comes up.)
-            if (VDBG) log("- posting ALLOW_SCREEN_ON message...");
-            mHandler.removeMessages(ALLOW_SCREEN_ON);
-            mHandler.sendEmptyMessage(ALLOW_SCREEN_ON);
-
-            // TODO: There ought to be a more elegant way of doing this,
-            // probably by having the PowerManager and ActivityManager
-            // work together to let apps request that the screen on/off
-            // state be synchronized with the Activity lifecycle.
-            // (See bug 1648751.)
-        } else {
-            // The phone isn't ringing; this is either an outgoing call, or
-            // we're returning to a call in progress.  There *shouldn't* be
-            // any prior preventScreenOn(true) call that we need to undo,
-            // but let's do this just to be safe:
-            mApp.preventScreenOn(false);
-        }
         // Update the poke lock and wake lock when we move to the foreground.
         // This will be no-op when prox sensor is effective.
         mApp.updateWakeState();
@@ -779,7 +741,7 @@
         if (!mPhone.getPendingMmiCodes().isEmpty()) {
             if (mMmiStartedDialog == null) {
                 MmiCode mmiCode = mPhone.getPendingMmiCodes().get(0);
-                Message message = Message.obtain(mHandler, PhoneApp.MMI_CANCEL);
+                Message message = Message.obtain(mHandler, PhoneGlobals.MMI_CANCEL);
                 mMmiStartedDialog = PhoneUtils.displayMMIInitiate(this, mmiCode,
                         message, mMmiStartedDialog);
                 // mInCallScreen needs to receive MMI_COMPLETE/MMI_CANCEL event from telephony,
@@ -894,17 +856,6 @@
         // foreground.)
         unregisterReceiver(mReceiver);
 
-        // Re-enable "user activity" for touch events.
-        // We actually do this slightly *after* onPause(), to work around a
-        // race condition where a touch can come in after we've paused
-        // but before the device actually goes to sleep.
-        // TODO: The PowerManager itself should prevent this from happening.
-        mHandler.postDelayed(new Runnable() {
-                public void run() {
-                    mApp.setIgnoreTouchUserActivity(false);
-                }
-            }, 500);
-
         // Make sure we revert the poke lock and wake lock when we move to
         // the background.
         mApp.updateWakeState();
@@ -989,7 +940,7 @@
         // are moving out of the foreground.
 
         if (mBluetoothHeadset != null) {
-            mAdapter.closeProfileProxy(BluetoothProfile.HEADSET, mBluetoothHeadset);
+            mBluetoothAdapter.closeProfileProxy(BluetoothProfile.HEADSET, mBluetoothHeadset);
             mBluetoothHeadset = null;
         }
 
@@ -1099,7 +1050,7 @@
             // message display class in PhoneUtils.displayMMIComplete().
             // We'll listen for that message too, so that we can finish
             // the activity at the same time.
-            mCM.registerForMmiComplete(mHandler, PhoneApp.MMI_COMPLETE, null);
+            mCM.registerForMmiComplete(mHandler, PhoneGlobals.MMI_COMPLETE, null);
             mCM.registerForCallWaiting(mHandler, PHONE_CDMA_CALL_WAITING, null);
             mCM.registerForPostDialCharacter(mHandler, POST_ON_DIAL_CHARS, null);
             mCM.registerForSuppServiceFailed(mHandler, SUPP_SERVICE_FAILED, null);
@@ -1721,8 +1672,8 @@
             // Get the Auto-retry setting only if Phone State is IDLE,
             // else let it stay as AUTO_RETRY_OFF
             if (currentlyIdle) {
-                autoretrySetting = android.provider.Settings.System.getInt(mPhone.getContext().
-                        getContentResolver(), android.provider.Settings.System.CALL_AUTO_RETRY, 0);
+                autoretrySetting = android.provider.Settings.Global.getInt(mPhone.getContext().
+                        getContentResolver(), android.provider.Settings.Global.CALL_AUTO_RETRY, 0);
             }
         }
 
@@ -2685,7 +2636,7 @@
                 if ((mLastDisconnectCause != Connection.DisconnectCause.INCOMING_MISSED)
                         && (mLastDisconnectCause != Connection.DisconnectCause.INCOMING_REJECTED)
                         && !isPhoneStateRestricted()
-                        && PhoneApp.sVoiceCapable) {
+                        && PhoneGlobals.sVoiceCapable) {
                     final Intent intent = mApp.createPhoneEndIntentUsingCallOrigin();
                     ActivityOptions opts = ActivityOptions.makeCustomAnimation(this,
                             R.anim.activity_close_enter, R.anim.activity_close_exit);
@@ -2711,8 +2662,8 @@
                     // stay in the activity history.
                 }
 
-                endInCallScreenSession();
             }
+            endInCallScreenSession();
 
             // Reset the call origin when the session ends and this in-call UI is being finished.
             mApp.setLatestActiveCallOrigin(null);
@@ -3700,13 +3651,17 @@
         // multiple background calls, for now, always act on the first background calll.
         PhoneUtils.switchHoldingAndActive(mCM.getFirstActiveBgCall());
 
-        // If we have a valid BluetoothHandsfree then since CDMA network or
+        // If we have a valid BluetoothPhoneService then since CDMA network or
         // Telephony FW does not send us information on which caller got swapped
-        // we need to update the second call active state in BluetoothHandsfree internally
+        // we need to update the second call active state in BluetoothPhoneService internally
         if (mCM.getBgPhone().getPhoneType() == PhoneConstants.PHONE_TYPE_CDMA) {
-            BluetoothHandsfree bthf = mApp.getBluetoothHandsfree();
-            if (bthf != null) {
-                bthf.cdmaSwapSecondCallState();
+            IBluetoothHeadsetPhone btPhone = mApp.getBluetoothPhoneService();
+            if (btPhone != null) {
+                try {
+                    btPhone.cdmaSwapSecondCallState();
+                } catch (RemoteException e) {
+                    Log.e(LOG_TAG, Log.getStackTraceString(new Throwable()));
+                }
             }
         }
 
@@ -4117,13 +4072,6 @@
     //   headset (which we don't do from the Phone UI!) but also lets you
     //   get the address of the currently active headset and see whether
     //   it's currently connected.
-    //
-    // - BluetoothHandsfree is the API to control the audio connection to
-    //   a bluetooth headset. We use this API to switch the headset on and
-    //   off when the user presses the "Bluetooth" button.
-    //   Our BluetoothHandsfree instance (mBluetoothHandsfree) is created
-    //   by the PhoneApp and will be null if the device is not BT capable.
-    //
 
     /**
      * @return true if the Bluetooth on/off switch in the UI should be
@@ -4132,11 +4080,6 @@
      */
     /* package */ boolean isBluetoothAvailable() {
         if (VDBG) log("isBluetoothAvailable()...");
-        if (mBluetoothHandsfree == null) {
-            // Device is not BT capable.
-            if (VDBG) log("  ==> FALSE (not BT capable)");
-            return false;
-        }
 
         // There's no need to ask the Bluetooth system service if BT is enabled:
         //
@@ -4173,14 +4116,20 @@
     }
 
     /**
-     * @return true if a BT device is available, and its audio is currently connected.
+     * @return true if a BT Headset is available, and its audio is currently connected.
      */
     /* package */ boolean isBluetoothAudioConnected() {
-        if (mBluetoothHandsfree == null) {
-            if (VDBG) log("isBluetoothAudioConnected: ==> FALSE (null mBluetoothHandsfree)");
+        if (mBluetoothHeadset == null) {
+            if (VDBG) log("isBluetoothAudioConnected: ==> FALSE (null mBluetoothHeadset)");
             return false;
         }
-        boolean isAudioOn = mBluetoothHandsfree.isAudioOn();
+        List<BluetoothDevice> deviceList = mBluetoothHeadset.getConnectedDevices();
+
+        if (deviceList.isEmpty()) {
+            return false;
+        }
+        BluetoothDevice device = deviceList.get(0);
+        boolean isAudioOn = mBluetoothHeadset.isAudioConnected(device);
         if (VDBG) log("isBluetoothAudioConnected: ==> isAudioOn = " + isAudioOn);
         return isAudioOn;
     }
@@ -4190,7 +4139,7 @@
      * see InCallControlState.bluetoothIndicatorOn.
      *
      * @return true if a BT device is available and its audio is currently connected,
-     *              <b>or</b> if we issued a BluetoothHandsfree.userWantsAudioOn()
+     *              <b>or</b> if we issued a BluetoothHeadset.connectAudio()
      *              call within the last 5 seconds (which presumably means
      *              that the BT audio connection is currently being set
      *              up, and will be connected soon.)
@@ -4201,7 +4150,7 @@
             return true;
         }
 
-        // If we issued a userWantsAudioOn() call "recently enough", even
+        // If we issued a connectAudio() call "recently enough", even
         // if BT isn't actually connected yet, let's still pretend BT is
         // on.  This makes the onscreen indication more responsive.
         if (mBluetoothConnectionPending) {
@@ -4244,8 +4193,7 @@
         log("= PhoneApp.showBluetoothIndication: "
             + mApp.showBluetoothIndication());
         log("=");
-        if (mBluetoothHandsfree != null) {
-            log("= BluetoothHandsfree.isAudioOn: " + mBluetoothHandsfree.isAudioOn());
+        if (mBluetoothAdapter != null) {
             if (mBluetoothHeadset != null) {
                 List<BluetoothDevice> deviceList = mBluetoothHeadset.getConnectedDevices();
 
@@ -4254,23 +4202,26 @@
                     log("= BluetoothHeadset.getCurrentDevice: " + device);
                     log("= BluetoothHeadset.State: "
                         + mBluetoothHeadset.getConnectionState(device));
+                    log("= BluetoothHeadset audio connected: " +
+                        mBluetoothHeadset.isAudioConnected(device));
                 }
             } else {
                 log("= mBluetoothHeadset is null");
             }
         } else {
-            log("= mBluetoothHandsfree is null; device is not BT capable");
+            log("= mBluetoothAdapter is null; device is not BT capable");
         }
     }
 
     /* package */ void connectBluetoothAudio() {
         if (VDBG) log("connectBluetoothAudio()...");
-        if (mBluetoothHandsfree != null) {
-            mBluetoothHandsfree.userWantsAudioOn();
+        if (mBluetoothHeadset != null) {
+            // TODO(BT) check return
+            mBluetoothHeadset.connectAudio();
         }
 
         // Watch out: The bluetooth connection doesn't happen instantly;
-        // the userWantsAudioOn() call returns instantly but does its real
+        // the connectAudio() call returns instantly but does its real
         // work in another thread.  The mBluetoothConnectionPending flag
         // is just a little trickery to ensure that the onscreen UI updates
         // instantly. (See isBluetoothAudioConnectedOrPending() above.)
@@ -4280,8 +4231,8 @@
 
     /* package */ void disconnectBluetoothAudio() {
         if (VDBG) log("disconnectBluetoothAudio()...");
-        if (mBluetoothHandsfree != null) {
-            mBluetoothHandsfree.userWantsAudioOff();
+        if (mBluetoothHeadset != null) {
+            mBluetoothHeadset.disconnectAudio();
         }
         mBluetoothConnectionPending = false;
     }
@@ -4535,11 +4486,12 @@
     /**
      * Manually handle configuration changes.
      *
-     * We specify android:configChanges="orientation|keyboardHidden|uiMode" in
-     * our manifest to make sure the system doesn't destroy and re-create us
-     * due to the above config changes.  Instead, this method will be called,
-     * and should manually rebuild the onscreen UI to keep it in sync with the
-     * current configuration.
+     * Originally android:configChanges was set to "orientation|keyboardHidden|uiMode"
+     * in order "to make sure the system doesn't destroy and re-create us due to the
+     * above config changes". However it is currently set to "keyboardHidden" since
+     * the system needs to handle rotation when inserted into a compatible cardock.
+     * Even without explicitly handling orientation and uiMode, the app still runs
+     * and does not drop the call when rotated.
      *
      */
     public void onConfigurationChanged(Configuration newConfig) {
@@ -4652,4 +4604,11 @@
             log("Requested to remove provider info after " + PROVIDER_INFO_TIMEOUT + " msec.");
         }
     }
+
+    /**
+     * Indicates whether or not the QuickResponseDialog is currently showing in the call screen
+     */
+    public boolean isQuickResponseDialogShowing() {
+        return mRespondViaSmsManager != null && mRespondViaSmsManager.isShowingPopup();
+    }
 }
diff --git a/src/com/android/phone/InCallScreenShowActivation.java b/src/com/android/phone/InCallScreenShowActivation.java
index ad13186..221b915 100644
--- a/src/com/android/phone/InCallScreenShowActivation.java
+++ b/src/com/android/phone/InCallScreenShowActivation.java
@@ -42,7 +42,7 @@
 public class InCallScreenShowActivation extends Activity {
     private static final String LOG_TAG = "InCallScreenShowActivation";
     private static final boolean DBG =
-            (PhoneApp.DBG_LEVEL >= 1) && (SystemProperties.getInt("ro.debuggable", 0) == 1);
+            (PhoneGlobals.DBG_LEVEL >= 1) && (SystemProperties.getInt("ro.debuggable", 0) == 1);
 
     @Override
     protected void onCreate(Bundle icicle) {
@@ -56,7 +56,7 @@
             Log.d(LOG_TAG, "      - extras = " + extras);
         }
 
-        PhoneApp app = PhoneApp.getInstance();
+        PhoneGlobals app = PhoneGlobals.getInstance();
         Phone phone = app.getPhone();
         if (!TelephonyCapabilities.supportsOtasp(phone)) {
             Log.w(LOG_TAG, "CDMA Provisioning not supported on this device");
@@ -69,7 +69,7 @@
 
             // On voice-capable devices, we perform CDMA provisioning in
             // "interactive" mode by directly launching the InCallScreen.
-            boolean interactiveMode = PhoneApp.sVoiceCapable;
+            boolean interactiveMode = PhoneGlobals.sVoiceCapable;
             Log.d(LOG_TAG, "ACTION_PERFORM_CDMA_PROVISIONING (interactiveMode = "
                   + interactiveMode + ")...");
 
diff --git a/src/com/android/phone/InCallTouchUi.java b/src/com/android/phone/InCallTouchUi.java
index 84176d1..986765e 100644
--- a/src/com/android/phone/InCallTouchUi.java
+++ b/src/com/android/phone/InCallTouchUi.java
@@ -41,6 +41,7 @@
 import android.widget.FrameLayout;
 import android.widget.ImageButton;
 import android.widget.PopupMenu;
+import android.widget.TextView;
 import android.widget.Toast;
 
 import com.android.internal.telephony.Call;
@@ -61,7 +62,7 @@
         implements View.OnClickListener, View.OnLongClickListener, OnTriggerListener,
         PopupMenu.OnMenuItemClickListener, PopupMenu.OnDismissListener {
     private static final String LOG_TAG = "InCallTouchUi";
-    private static final boolean DBG = (PhoneApp.DBG_LEVEL >= 2);
+    private static final boolean DBG = (PhoneGlobals.DBG_LEVEL >= 2);
 
     // Incoming call widget targets
     private static final int ANSWER_CALL_ID = 0;  // drag right
@@ -76,7 +77,7 @@
     private InCallScreen mInCallScreen;
 
     // Phone app instance
-    private PhoneApp mApp;
+    private PhoneGlobals mApp;
 
     // UI containers / elements
     private GlowPadView mIncomingCallWidget;  // UI used for an incoming call
@@ -142,7 +143,7 @@
         if (DBG) log("InCallTouchUi constructor...");
         if (DBG) log("- this = " + this);
         if (DBG) log("- context " + context + ", attrs " + attrs);
-        mApp = PhoneApp.getInstance();
+        mApp = PhoneGlobals.getInstance();
     }
 
     void setInCallScreenInstance(InCallScreen inCallScreen) {
@@ -207,14 +208,20 @@
         // Buttons shown on the "extra button row", only visible in certain (rare) states.
         mExtraButtonRow = (ViewStub) mInCallControls.findViewById(R.id.extraButtonRow);
 
-        // Add a custom OnTouchListener to manually shrink the "hit target".
-        View.OnTouchListener smallerHitTargetTouchListener = new SmallerHitTargetTouchListener();
-        mEndButton.setOnTouchListener(smallerHitTargetTouchListener);
+        // If in PORTRAIT, add a custom OnTouchListener to shrink the "hit target".
+        if (!PhoneUtils.isLandscape(this.getContext())) {
+            mEndButton.setOnTouchListener(new SmallerHitTargetTouchListener());
+        }
+
     }
 
     /**
      * Updates the visibility and/or state of our UI elements, based on
      * the current state of the phone.
+     *
+     * TODO: This function should be relying on a state defined by InCallScreen,
+     * and not generic call states. The incoming call screen handles more states
+     * than Call.State or PhoneConstant.State know about.
      */
     /* package */ void updateState(CallManager cm) {
         if (mInCallScreen == null) {
@@ -263,6 +270,24 @@
                 log("updateState: Too soon after last action; not drawing!");
                 showIncomingCallControls = false;
             }
+
+            // b/6765896
+            // If the glowview triggers two hits of the respond-via-sms gadget in
+            // quick succession, it can cause the incoming call widget to show and hide
+            // twice in a row.  However, the second hide doesn't get triggered because
+            // we are already attemping to hide.  This causes an additional glowview to
+            // stay up above all other screens.
+            // In reality, we shouldn't even be showing incoming-call UI while we are
+            // showing the respond-via-sms popup, so we check for that here.
+            //
+            // TODO: In the future, this entire state machine
+            // should be reworked.  Respond-via-sms was stapled onto the current
+            // design (and so were other states) and should be made a first-class
+            // citizen in a new state machine.
+            if (mInCallScreen.isQuickResponseDialogShowing()) {
+                log("updateState: quickResponse visible. Cancel showing incoming call controls.");
+                showIncomingCallControls = false;
+            }
         } else {
             // Ok, show the regular in-call touch UI (with some exceptions):
             if (okToShowInCallControls()) {
@@ -420,6 +445,7 @@
         }
         return false;
     }
+
     /**
      * Updates the enabledness and "checked" state of the buttons on the
      * "inCallControls" panel, based on the current telephony state.
@@ -523,10 +549,12 @@
             mHoldButton.setEnabled(true);
             mHoldButton.setChecked(inCallControlState.onHold);
             mSwapButton.setVisibility(View.GONE);
+            mHoldSwapSpacer.setVisibility(View.VISIBLE);
         } else if (inCallControlState.canSwap) {
             mSwapButton.setVisibility(View.VISIBLE);
             mSwapButton.setEnabled(true);
             mHoldButton.setVisibility(View.GONE);
+            mHoldSwapSpacer.setVisibility(View.VISIBLE);
         } else {
             // Neither "Hold" nor "Swap" is available.  This can happen for two
             // reasons:
@@ -1057,6 +1085,9 @@
         //
         // If requested above (i.e. if mShowInCallControlsDuringHidingAnimation is set to true),
         // in-call controls will start being shown too.
+        //
+        // TODO: The decision to hide this should be made by the controller
+        // (InCallScreen), and not this view.
         hideIncomingCallWidget();
 
         // Regardless of what action the user did, be sure to clear out
@@ -1072,16 +1103,14 @@
      * Apply an animation to hide the incoming call widget.
      */
     private void hideIncomingCallWidget() {
-        // if (DBG) log("hideIncomingCallWidget()...");
+        if (DBG) log("hideIncomingCallWidget()...");
         if (mIncomingCallWidget.getVisibility() != View.VISIBLE
                 || mIncomingCallWidgetIsFadingOut) {
+            if (DBG) log("Skipping hideIncomingCallWidget action");
             // Widget is already hidden or in the process of being hidden
             return;
         }
 
-        // TODO: remove this once we fixed issue 6603655
-        log("hideIncomingCallWidget()");
-
         // Hide the incoming call screen with a transition
         mIncomingCallWidgetIsFadingOut = true;
         ViewPropertyAnimator animator = mIncomingCallWidget.animate();
@@ -1096,6 +1125,7 @@
                     mInCallControls.setVisibility(View.VISIBLE);
                 }
             }
+
             @Override
             public void onAnimationEnd(Animator animation) {
                 if (DBG) log("IncomingCallWidget's hiding animation ended");
@@ -1106,6 +1136,7 @@
                 mIncomingCallWidgetIsFadingOut = false;
                 mIncomingCallWidgetShouldBeReset = true;
             }
+
             @Override
             public void onAnimationCancel(Animator animation) {
                 mIncomingCallWidget.animate().setListener(null);
@@ -1124,12 +1155,11 @@
      * Shows the incoming call widget and cancels any animation that may be fading it out.
      */
     private void showIncomingCallWidget(Call ringingCall) {
-        // if (DBG) log("showIncomingCallWidget()...");
+        if (DBG) log("showIncomingCallWidget()...");
 
-        // TODO: remove this once we fixed issue 6603655
         // TODO: wouldn't be ok to suppress this whole request if the widget is already VISIBLE
         //       and we don't need to reset it?
-        log("showIncomingCallWidget(). widget visibility: " + mIncomingCallWidget.getVisibility());
+        // log("showIncomingCallWidget(). widget visibility: " + mIncomingCallWidget.getVisibility());
 
         ViewPropertyAnimator animator = mIncomingCallWidget.animate();
         if (animator != null) {
@@ -1179,6 +1209,16 @@
             mIncomingCallWidgetShouldBeReset = false;
         }
 
+        // On an incoming call, if the layout is landscape, then align the "incoming call" text
+        // to the left, because the incomingCallWidget (black background with glowing ring)
+        // is aligned to the right and would cover the "incoming call" text.
+        // Note that callStateLabel is within CallCard, outside of the context of InCallTouchUi
+        if (PhoneUtils.isLandscape(this.getContext())) {
+            TextView callStateLabel = (TextView) mIncomingCallWidget
+                    .getRootView().findViewById(R.id.callStateLabel);
+            if (callStateLabel != null) callStateLabel.setGravity(Gravity.LEFT);
+        }
+
         mIncomingCallWidget.setVisibility(View.VISIBLE);
 
         // Finally, manually trigger a "ping" animation.
diff --git a/src/com/android/phone/InCallUiState.java b/src/com/android/phone/InCallUiState.java
index cfaed99..3b700d7 100644
--- a/src/com/android/phone/InCallUiState.java
+++ b/src/com/android/phone/InCallUiState.java
@@ -393,8 +393,8 @@
      * call. See also {@link InCallScreen} for more detail. There is *no* specific specification
      * about how this variable will be used.
      *
-     * @see PhoneApp#setLatestActiveCallOrigin(String)
-     * @see PhoneApp#createPhoneEndIntentUsingCallOrigin()
+     * @see PhoneGlobals#setLatestActiveCallOrigin(String)
+     * @see PhoneGlobals#createPhoneEndIntentUsingCallOrigin()
      *
      * TODO: we should determine some public behavior for this variable.
      */
diff --git a/src/com/android/phone/ManageConferenceUtils.java b/src/com/android/phone/ManageConferenceUtils.java
index e884798..5821754 100644
--- a/src/com/android/phone/ManageConferenceUtils.java
+++ b/src/com/android/phone/ManageConferenceUtils.java
@@ -41,7 +41,7 @@
 public class ManageConferenceUtils {
     private static final String LOG_TAG = "ManageConferenceUtils";
     private static final boolean DBG =
-            (PhoneApp.DBG_LEVEL >= 1) && (SystemProperties.getInt("ro.debuggable", 0) == 1);
+            (PhoneGlobals.DBG_LEVEL >= 1) && (SystemProperties.getInt("ro.debuggable", 0) == 1);
 
     /**
      * CallerInfoAsyncQuery.OnQueryCompleteListener implementation.
@@ -232,7 +232,7 @@
                     @Override
                     public void onClick(View v) {
                         endConferenceConnection(i, connection);
-                        PhoneApp.getInstance().pokeUserActivity();
+                        PhoneGlobals.getInstance().pokeUserActivity();
                     }
                 };
             endButton.setOnClickListener(endThisConnection);
@@ -242,7 +242,7 @@
                         @Override
                         public void onClick(View v) {
                             separateConferenceConnection(i, connection);
-                            PhoneApp.getInstance().pokeUserActivity();
+                            PhoneGlobals.getInstance().pokeUserActivity();
                         }
                     };
                 separateButton.setOnClickListener(separateThisConnection);
diff --git a/src/com/android/phone/MobileNetworkSettings.java b/src/com/android/phone/MobileNetworkSettings.java
index 2948216..a81d7c2 100644
--- a/src/com/android/phone/MobileNetworkSettings.java
+++ b/src/com/android/phone/MobileNetworkSettings.java
@@ -144,8 +144,8 @@
             return true;
         } else if (preference == mButtonPreferredNetworkMode) {
             //displays the value taken from the Settings.System
-            int settingsNetworkMode = android.provider.Settings.Secure.getInt(mPhone.getContext().
-                    getContentResolver(), android.provider.Settings.Secure.PREFERRED_NETWORK_MODE,
+            int settingsNetworkMode = android.provider.Settings.Global.getInt(mPhone.getContext().
+                    getContentResolver(), android.provider.Settings.Global.PREFERRED_NETWORK_MODE,
                     preferredNetworkMode);
             mButtonPreferredNetworkMode.setValue(Integer.toString(settingsNetworkMode));
             return true;
@@ -176,8 +176,8 @@
             cm.setMobileDataEnabled(mButtonDataEnabled.isChecked());
             return true;
         } else if (preference == mLteDataServicePref) {
-            String tmpl = android.provider.Settings.Secure.getString(getContentResolver(),
-                        android.provider.Settings.Secure.SETUP_PREPAID_DATA_SERVICE_URL);
+            String tmpl = android.provider.Settings.Global.getString(getContentResolver(),
+                        android.provider.Settings.Global.SETUP_PREPAID_DATA_SERVICE_URL);
             if (!TextUtils.isEmpty(tmpl)) {
                 TelephonyManager tm = (TelephonyManager) getSystemService(
                         Context.TELEPHONY_SERVICE);
@@ -209,7 +209,7 @@
 
         addPreferencesFromResource(R.xml.network_setting);
 
-        mPhone = PhoneApp.getPhone();
+        mPhone = PhoneGlobals.getPhone();
         mHandler = new MyHandler();
 
         //get UI object references
@@ -229,8 +229,8 @@
             mButtonPreferredNetworkMode.setOnPreferenceChangeListener(this);
 
             //Get the networkMode from Settings.System and displays it
-            int settingsNetworkMode = android.provider.Settings.Secure.getInt(mPhone.getContext().
-                    getContentResolver(),android.provider.Settings.Secure.PREFERRED_NETWORK_MODE,
+            int settingsNetworkMode = android.provider.Settings.Global.getInt(mPhone.getContext().
+                    getContentResolver(),android.provider.Settings.Global.PREFERRED_NETWORK_MODE,
                     preferredNetworkMode);
             mButtonPreferredNetworkMode.setValue(Integer.toString(settingsNetworkMode));
             mCdmaOptions = new CdmaOptions(this, prefSet, mPhone);
@@ -248,9 +248,9 @@
                             R.array.preferred_network_mode_choices_lte);
                     mButtonPreferredNetworkMode.setEntryValues(
                             R.array.preferred_network_mode_values_lte);
-                    int settingsNetworkMode = android.provider.Settings.Secure.getInt(
+                    int settingsNetworkMode = android.provider.Settings.Global.getInt(
                             mPhone.getContext().getContentResolver(),
-                            android.provider.Settings.Secure.PREFERRED_NETWORK_MODE,
+                            android.provider.Settings.Global.PREFERRED_NETWORK_MODE,
                             preferredNetworkMode);
                     mButtonPreferredNetworkMode.setValue(
                             Integer.toString(settingsNetworkMode));
@@ -264,8 +264,8 @@
         }
 
         final boolean missingDataServiceUrl = TextUtils.isEmpty(
-                android.provider.Settings.Secure.getString(getContentResolver(),
-                        android.provider.Settings.Secure.SETUP_PREPAID_DATA_SERVICE_URL));
+                android.provider.Settings.Global.getString(getContentResolver(),
+                        android.provider.Settings.Global.SETUP_PREPAID_DATA_SERVICE_URL));
         if (!isLteOnCdma || missingDataServiceUrl) {
             prefSet.removePreference(mLteDataServicePref);
         } else {
@@ -327,9 +327,9 @@
             mButtonPreferredNetworkMode.setValue((String) objValue);
             int buttonNetworkMode;
             buttonNetworkMode = Integer.valueOf((String) objValue).intValue();
-            int settingsNetworkMode = android.provider.Settings.Secure.getInt(
+            int settingsNetworkMode = android.provider.Settings.Global.getInt(
                     mPhone.getContext().getContentResolver(),
-                    android.provider.Settings.Secure.PREFERRED_NETWORK_MODE, preferredNetworkMode);
+                    android.provider.Settings.Global.PREFERRED_NETWORK_MODE, preferredNetworkMode);
             if (buttonNetworkMode != settingsNetworkMode) {
                 int modemNetworkMode;
                 switch(buttonNetworkMode) {
@@ -371,8 +371,8 @@
 
                 UpdatePreferredNetworkModeSummary(buttonNetworkMode);
 
-                android.provider.Settings.Secure.putInt(mPhone.getContext().getContentResolver(),
-                        android.provider.Settings.Secure.PREFERRED_NETWORK_MODE,
+                android.provider.Settings.Global.putInt(mPhone.getContext().getContentResolver(),
+                        android.provider.Settings.Global.PREFERRED_NETWORK_MODE,
                         buttonNetworkMode );
                 //Set the modem network mode
                 mPhone.setPreferredNetworkType(modemNetworkMode, mHandler
@@ -413,9 +413,9 @@
                             modemNetworkMode);
                 }
 
-                int settingsNetworkMode = android.provider.Settings.Secure.getInt(
+                int settingsNetworkMode = android.provider.Settings.Global.getInt(
                         mPhone.getContext().getContentResolver(),
-                        android.provider.Settings.Secure.PREFERRED_NETWORK_MODE,
+                        android.provider.Settings.Global.PREFERRED_NETWORK_MODE,
                         preferredNetworkMode);
 
                 if (DBG) {
@@ -451,9 +451,9 @@
                         }
 
                         //changes the Settings.System accordingly to modemNetworkMode
-                        android.provider.Settings.Secure.putInt(
+                        android.provider.Settings.Global.putInt(
                                 mPhone.getContext().getContentResolver(),
-                                android.provider.Settings.Secure.PREFERRED_NETWORK_MODE,
+                                android.provider.Settings.Global.PREFERRED_NETWORK_MODE,
                                 settingsNetworkMode );
                     }
 
@@ -476,8 +476,8 @@
             if (ar.exception == null) {
                 int networkMode = Integer.valueOf(
                         mButtonPreferredNetworkMode.getValue()).intValue();
-                android.provider.Settings.Secure.putInt(mPhone.getContext().getContentResolver(),
-                        android.provider.Settings.Secure.PREFERRED_NETWORK_MODE,
+                android.provider.Settings.Global.putInt(mPhone.getContext().getContentResolver(),
+                        android.provider.Settings.Global.PREFERRED_NETWORK_MODE,
                         networkMode );
             } else {
                 mPhone.getPreferredNetworkType(obtainMessage(MESSAGE_GET_PREFERRED_NETWORK_TYPE));
@@ -488,8 +488,8 @@
             //set the mButtonPreferredNetworkMode
             mButtonPreferredNetworkMode.setValue(Integer.toString(preferredNetworkMode));
             //set the Settings.System
-            android.provider.Settings.Secure.putInt(mPhone.getContext().getContentResolver(),
-                        android.provider.Settings.Secure.PREFERRED_NETWORK_MODE,
+            android.provider.Settings.Global.putInt(mPhone.getContext().getContentResolver(),
+                        android.provider.Settings.Global.PREFERRED_NETWORK_MODE,
                         preferredNetworkMode );
             //Set the Modem
             mPhone.setPreferredNetworkType(preferredNetworkMode,
diff --git a/src/com/android/phone/NetworkSetting.java b/src/com/android/phone/NetworkSetting.java
index 87bd05a..a11ebab 100644
--- a/src/com/android/phone/NetworkSetting.java
+++ b/src/com/android/phone/NetworkSetting.java
@@ -219,7 +219,7 @@
 
         addPreferencesFromResource(R.xml.carrier_select);
 
-        mPhone = PhoneApp.getPhone();
+        mPhone = PhoneGlobals.getPhone();
 
         mNetworkList = (PreferenceGroup) getPreferenceScreen().findPreference(LIST_NETWORKS_KEY);
         mNetworkMap = new HashMap<Preference, OperatorInfo>();
@@ -322,7 +322,7 @@
     private void displayNetworkQueryFailed(int error) {
         String status = getResources().getString(R.string.network_query_error);
 
-        final PhoneApp app = PhoneApp.getInstance();
+        final PhoneGlobals app = PhoneGlobals.getInstance();
         app.notificationMgr.postTransientNotification(
                 NotificationMgr.NETWORK_SELECTION_NOTIFICATION, status);
     }
@@ -339,7 +339,7 @@
             status = getResources().getString(R.string.connect_later);
         }
 
-        final PhoneApp app = PhoneApp.getInstance();
+        final PhoneGlobals app = PhoneGlobals.getInstance();
         app.notificationMgr.postTransientNotification(
                 NotificationMgr.NETWORK_SELECTION_NOTIFICATION, status);
     }
@@ -347,7 +347,7 @@
     private void displayNetworkSelectionSucceeded() {
         String status = getResources().getString(R.string.registration_done);
 
-        final PhoneApp app = PhoneApp.getInstance();
+        final PhoneGlobals app = PhoneGlobals.getInstance();
         app.notificationMgr.postTransientNotification(
                 NotificationMgr.NETWORK_SELECTION_NOTIFICATION, status);
 
diff --git a/src/com/android/phone/NotificationMgr.java b/src/com/android/phone/NotificationMgr.java
index 530389c..044418c 100644
--- a/src/com/android/phone/NotificationMgr.java
+++ b/src/com/android/phone/NotificationMgr.java
@@ -65,12 +65,12 @@
  * framework's NotificationManager, and is used to display status bar
  * icons and control other status bar-related behavior.
  *
- * @see PhoneApp.notificationMgr
+ * @see PhoneGlobals.notificationMgr
  */
 public class NotificationMgr implements CallerInfoAsyncQuery.OnQueryCompleteListener{
     private static final String LOG_TAG = "NotificationMgr";
     private static final boolean DBG =
-            (PhoneApp.DBG_LEVEL >= 1) && (SystemProperties.getInt("ro.debuggable", 0) == 1);
+            (PhoneGlobals.DBG_LEVEL >= 1) && (SystemProperties.getInt("ro.debuggable", 0) == 1);
     // Do not check in with VDBG = true, since that may write PII to the system log.
     private static final boolean VDBG = false;
 
@@ -95,7 +95,7 @@
     /** The singleton NotificationMgr instance. */
     private static NotificationMgr sInstance;
 
-    private PhoneApp mApp;
+    private PhoneGlobals mApp;
     private Phone mPhone;
     private CallManager mCM;
 
@@ -133,7 +133,7 @@
      * Private constructor (this is a singleton).
      * @see init()
      */
-    private NotificationMgr(PhoneApp app) {
+    private NotificationMgr(PhoneGlobals app) {
         mApp = app;
         mContext = app;
         mNotificationManager =
@@ -155,7 +155,7 @@
      * PhoneApp's public "notificationMgr" field, which is why there's no
      * getInstance() method here.
      */
-    /* package */ static NotificationMgr init(PhoneApp app) {
+    /* package */ static NotificationMgr init(PhoneGlobals app) {
         synchronized (NotificationMgr.class) {
             if (sInstance == null) {
                 sInstance = new NotificationMgr(app);
@@ -484,12 +484,12 @@
             String name, String number, String type, Drawable photo, Bitmap photoIcon, long date) {
 
         // When the user clicks this notification, we go to the call log.
-        final Intent callLogIntent = PhoneApp.createCallLogIntent();
+        final Intent callLogIntent = PhoneGlobals.createCallLogIntent();
 
         // Never display the missed call notification on non-voice-capable
         // devices, even if the device does somehow manage to get an
         // incoming call.
-        if (!PhoneApp.sVoiceCapable) {
+        if (!PhoneGlobals.sVoiceCapable) {
             if (DBG) log("notifyMissedCall: non-voice-capable device, not posting notification");
             return;
         }
@@ -553,11 +553,11 @@
 
             builder.addAction(R.drawable.stat_sys_phone_call,
                     mContext.getString(R.string.notification_missedCall_call_back),
-                    PhoneApp.getCallBackPendingIntent(mContext, number));
+                    PhoneGlobals.getCallBackPendingIntent(mContext, number));
 
             builder.addAction(R.drawable.ic_text_holo_dark,
                     mContext.getString(R.string.notification_missedCall_message),
-                    PhoneApp.getSendSmsFromNotificationPendingIntent(mContext, number));
+                    PhoneGlobals.getSendSmsFromNotificationPendingIntent(mContext, number));
 
             if (photoIcon != null) {
                 builder.setLargeIcon(photoIcon);
@@ -777,7 +777,7 @@
         // Never display the "ongoing call" notification on
         // non-voice-capable devices, even if the phone is actually
         // offhook (like during a non-interactive OTASP call.)
-        if (!PhoneApp.sVoiceCapable) {
+        if (!PhoneGlobals.sVoiceCapable) {
             if (DBG) log("- non-voice-capable device; suppressing notification.");
             return;
         }
@@ -892,7 +892,7 @@
         // call (see the "fullScreenIntent" field below).
         PendingIntent inCallPendingIntent =
                 PendingIntent.getActivity(mContext, 0,
-                                          PhoneApp.createInCallIntent(), 0);
+                                          PhoneGlobals.createInCallIntent(), 0);
         builder.setContentIntent(inCallPendingIntent);
 
         // Update icon on the left of the notification.
@@ -989,7 +989,16 @@
                 // and translate that into the elapsedRealtime() timebase.
                 long callDurationMsec = currentConn.getDurationMillis();
                 builder.setWhen(System.currentTimeMillis() - callDurationMsec);
-                builder.setContentText(mContext.getString(R.string.notification_ongoing_call));
+
+                int contextTextId = R.string.notification_ongoing_call;
+
+                Call call = mCM.getActiveFgCall();
+                if (TelephonyCapabilities.canDistinguishDialingAndConnected(
+                        call.getPhone().getPhoneType()) && call.isDialingOrAlerting()) {
+                  contextTextId = R.string.notification_dialing;
+                }
+
+                builder.setContentText(mContext.getString(contextTextId));
             }
         } else if (DBG) {
             Log.w(LOG_TAG, "updateInCallNotification: null connection, can't set exp view line 1.");
@@ -1093,7 +1102,7 @@
             // TODO: use better asset.
             builder.addAction(R.drawable.stat_sys_phone_call_end,
                     mContext.getText(R.string.notification_action_end_call),
-                    PhoneApp.createHangUpOngoingCallPendingIntent(mContext));
+                    PhoneGlobals.createHangUpOngoingCallPendingIntent(mContext));
         }
 
         Notification notification = builder.getNotification();
diff --git a/src/com/android/phone/OtaStartupReceiver.java b/src/com/android/phone/OtaStartupReceiver.java
index 180041f..594b63a 100644
--- a/src/com/android/phone/OtaStartupReceiver.java
+++ b/src/com/android/phone/OtaStartupReceiver.java
@@ -86,7 +86,7 @@
                     // it's finally OK to start OTA provisioning
                     if (state.getState() == ServiceState.STATE_IN_SERVICE) {
                         if (DBG) Log.d(TAG, "call OtaUtils.maybeDoOtaCall after network is available");
-                        Phone phone = PhoneApp.getPhone();
+                        Phone phone = PhoneGlobals.getPhone();
                         phone.unregisterForServiceStateChanged(this);
                         OtaUtils.maybeDoOtaCall(mContext, mHandler, MIN_READY);
                     }
@@ -105,7 +105,13 @@
                     "  mOtaspMode=" + mOtaspMode);
         }
 
-        if (!TelephonyCapabilities.supportsOtasp(PhoneApp.getPhone())) {
+        PhoneGlobals globals = PhoneGlobals.getInstanceIfPrimary();
+        if (globals == null) {
+            if (DBG) Log.d(TAG, "Not primary user, nothing to do.");
+            return;
+        }
+
+        if (!TelephonyCapabilities.supportsOtasp(PhoneGlobals.getPhone())) {
             if (DBG) Log.d(TAG, "OTASP not supported, nothing to do.");
             return;
         }
@@ -126,8 +132,8 @@
         }
 
         // Delay OTA provisioning if network is not available yet
-        PhoneApp app = PhoneApp.getInstance();
-        Phone phone = PhoneApp.getPhone();
+        PhoneGlobals app = PhoneGlobals.getInstance();
+        Phone phone = PhoneGlobals.getPhone();
         if (app.mCM.getServiceState() != ServiceState.STATE_IN_SERVICE) {
             if (DBG) Log.w(TAG, "Network is not ready. Registering to receive notification.");
             phone.registerForServiceStateChanged(mHandler, SERVICE_STATE_CHANGED, null);
@@ -158,8 +164,8 @@
         Intent intent = new Intent("android.intent.action.DEVICE_INITIALIZATION_WIZARD");
         ResolveInfo resolveInfo = context.getPackageManager().resolveActivity(intent,
                 PackageManager.MATCH_DEFAULT_ONLY);
-        boolean provisioned = Settings.Secure.getInt(context.getContentResolver(),
-                Settings.Secure.DEVICE_PROVISIONED, 0) != 0;
+        boolean provisioned = Settings.Global.getInt(context.getContentResolver(),
+                Settings.Global.DEVICE_PROVISIONED, 0) != 0;
         String mode = SystemProperties.get("ro.setupwizard.mode", "REQUIRED");
         boolean runningSetupWizard = "REQUIRED".equals(mode) || "OPTIONAL".equals(mode);
         if (DBG) {
diff --git a/src/com/android/phone/OtaUtils.java b/src/com/android/phone/OtaUtils.java
index 572c6ac..495df27 100644
--- a/src/com/android/phone/OtaUtils.java
+++ b/src/com/android/phone/OtaUtils.java
@@ -27,6 +27,7 @@
 import android.app.AlertDialog;
 import android.app.PendingIntent;
 import android.app.PendingIntent.CanceledException;
+import android.content.ActivityNotFoundException;
 import android.content.Context;
 import android.content.DialogInterface;
 import android.content.Intent;
@@ -35,6 +36,7 @@
 import android.os.Handler;
 import android.os.SystemClock;
 import android.os.SystemProperties;
+import android.os.UserHandle;
 import android.telephony.TelephonyManager;
 import android.util.Log;
 import android.view.KeyEvent;
@@ -141,7 +143,7 @@
 
     private InCallScreen mInCallScreen;
     private Context mContext;
-    private PhoneApp mApplication;
+    private PhoneGlobals mApplication;
     private OtaWidgetData mOtaWidgetData;
     private ViewGroup mInCallTouchUi;  // UI controls for regular calls
     private CallCard mCallCard;
@@ -214,7 +216,7 @@
      */
     public OtaUtils(Context context, boolean interactive) {
         if (DBG) log("OtaUtils constructor...");
-        mApplication = PhoneApp.getInstance();
+        mApplication = PhoneGlobals.getInstance();
         mContext = context;
         mInteractive = interactive;
     }
@@ -282,7 +284,7 @@
      * @return true if we were able to launch Ota activity or it's not required; false otherwise
      */
     public static boolean maybeDoOtaCall(Context context, Handler handler, int request) {
-        PhoneApp app = PhoneApp.getInstance();
+        PhoneGlobals app = PhoneGlobals.getInstance();
         Phone phone = app.phone;
 
         if (ActivityManager.isRunningInTestHarness()) {
@@ -324,7 +326,7 @@
 
         // Run the OTASP call in "interactive" mode only if
         // this is a non-LTE "voice capable" device.
-        if (PhoneApp.sVoiceCapable && getLteOnCdmaMode(context) == PhoneConstants.LTE_ON_CDMA_FALSE) {
+        if (PhoneGlobals.sVoiceCapable && getLteOnCdmaMode(context) == PhoneConstants.LTE_ON_CDMA_FALSE) {
             if (phoneNeedsActivation
                     && (otaShowActivationScreen == OTA_SHOW_ACTIVATION_SCREEN_ON)) {
                 app.cdmaOtaProvisionData.isOtaCallIntentProcessed = false;
@@ -343,7 +345,12 @@
                 Intent newIntent = new Intent(ACTION_PERFORM_VOICELESS_CDMA_PROVISIONING);
                 newIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
                 newIntent.putExtra(EXTRA_VOICELESS_PROVISIONING_OFFER_DONTSHOW, true);
-                context.startActivity(newIntent);
+                try {
+                    context.startActivity(newIntent);
+                } catch (ActivityNotFoundException e) {
+                    loge("No activity Handling PERFORM_VOICELESS_CDMA_PROVISIONING!");
+                    return false;
+                }
                 if (DBG) log("maybeDoOtaCall: non-interactive; activation intent sent.");
             } else {
                 if (DBG) log("maybeDoOtaCall: non-interactive, no need for OTASP.");
@@ -361,7 +368,7 @@
      */
     public static void startInteractiveOtasp(Context context) {
         if (DBG) log("startInteractiveOtasp()...");
-        PhoneApp app = PhoneApp.getInstance();
+        PhoneGlobals app = PhoneGlobals.getInstance();
 
         // There are two ways to start OTASP on voice-capable devices:
         //
@@ -426,7 +433,7 @@
      */
     public static int startNonInteractiveOtasp(Context context) {
         if (DBG) log("startNonInteractiveOtasp()...");
-        PhoneApp app = PhoneApp.getInstance();
+        PhoneGlobals app = PhoneGlobals.getInstance();
 
         if (app.otaUtils != null) {
             // An OtaUtils instance already exists, presumably from a previous OTASP call.
@@ -442,7 +449,7 @@
         // TODO(InCallScreen redesign): This should probably go through
         // the CallController, rather than directly calling
         // PhoneUtils.placeCall().
-        Phone phone = PhoneApp.getPhone();
+        Phone phone = PhoneGlobals.getPhone();
         String number = OTASP_NUMBER_NON_INTERACTIVE;
         Log.i(LOG_TAG, "startNonInteractiveOtasp: placing call to '" + number + "'...");
         int callStatus = PhoneUtils.placeCall(context,
@@ -485,7 +492,7 @@
      */
     public static boolean isOtaspCallIntent(Intent intent) {
         if (DBG) log("isOtaspCallIntent(" + intent + ")...");
-        PhoneApp app = PhoneApp.getInstance();
+        PhoneGlobals app = PhoneGlobals.getInstance();
         Phone phone = app.mCM.getDefaultPhone();
 
         if (intent == null) {
@@ -541,7 +548,7 @@
      */
     public static void setupOtaspCall(Intent intent) {
         if (DBG) log("setupOtaspCall(): preparing for OTASP call to " + intent);
-        PhoneApp app = PhoneApp.getInstance();
+        PhoneGlobals app = PhoneGlobals.getInstance();
 
         if (app.otaUtils != null) {
             // An OtaUtils instance already exists, presumably from a prior OTASP call.
@@ -707,7 +714,7 @@
         Intent intent = new Intent(Intent.ACTION_MAIN);
         intent.addCategory (Intent.CATEGORY_HOME);
         intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
-        mContext.startActivity(intent);
+        mContext.startActivityAsUser(intent, UserHandle.CURRENT);
         return;
     }
 
@@ -1631,4 +1638,8 @@
     private static void log(String msg) {
         Log.d(LOG_TAG, msg);
     }
+
+    private static void loge(String msg) {
+        Log.e(LOG_TAG, msg);
+    }
 }
diff --git a/src/com/android/phone/OutgoingCallBroadcaster.java b/src/com/android/phone/OutgoingCallBroadcaster.java
index df14ece..dabffa2 100644
--- a/src/com/android/phone/OutgoingCallBroadcaster.java
+++ b/src/com/android/phone/OutgoingCallBroadcaster.java
@@ -29,6 +29,7 @@
 import android.os.Handler;
 import android.os.Message;
 import android.os.SystemProperties;
+import android.os.UserHandle;
 import android.telephony.PhoneNumberUtils;
 import android.text.TextUtils;
 import android.util.Log;
@@ -60,7 +61,7 @@
     private static final String PERMISSION = android.Manifest.permission.PROCESS_OUTGOING_CALLS;
     private static final String TAG = "OutgoingCallBroadcaster";
     private static final boolean DBG =
-            (PhoneApp.DBG_LEVEL >= 1) && (SystemProperties.getInt("ro.debuggable", 0) == 1);
+            (PhoneGlobals.DBG_LEVEL >= 1) && (SystemProperties.getInt("ro.debuggable", 0) == 1);
     // Do not check in with VDBG = true, since that may write PII to the system log.
     private static final boolean VDBG = false;
 
@@ -145,7 +146,7 @@
             number = getResultData();
             if (VDBG) Log.v(TAG, "- got number from resultData: '" + number + "'");
 
-            final PhoneApp app = PhoneApp.getInstance();
+            final PhoneGlobals app = PhoneGlobals.getInstance();
 
             // OTASP-specific checks.
             // TODO: This should probably all happen in
@@ -390,7 +391,7 @@
         final Configuration configuration = getResources().getConfiguration();
 
         // Outgoing phone calls are only allowed on "voice-capable" devices.
-        if (!PhoneApp.sVoiceCapable) {
+        if (!PhoneGlobals.sVoiceCapable) {
             Log.i(TAG, "This device is detected as non-voice-capable device.");
             handleNonVoiceCapable(intent);
             return;
@@ -521,7 +522,7 @@
         // Also, this ensures the device stays awake while doing the following
         // broadcast; technically we should be holding a wake lock here
         // as well.
-        PhoneApp.getInstance().wakeUpScreen();
+        PhoneGlobals.getInstance().wakeUpScreen();
 
         // If number is null, we're probably trying to call a non-existent voicemail number,
         // send an empty flash or something else is fishy.  Whatever the problem, there's no
@@ -529,7 +530,7 @@
         if (TextUtils.isEmpty(number)) {
             if (intent.getBooleanExtra(EXTRA_SEND_EMPTY_FLASH, false)) {
                 Log.i(TAG, "onCreate: SEND_EMPTY_FLASH...");
-                PhoneUtils.sendEmptyFlash(PhoneApp.getPhone());
+                PhoneUtils.sendEmptyFlash(PhoneGlobals.getPhone());
                 finish();
                 return;
             } else {
@@ -547,7 +548,7 @@
 
             // Initiate the outgoing call, and simultaneously launch the
             // InCallScreen to display the in-call UI:
-            PhoneApp.getInstance().callController.placeCall(intent);
+            PhoneGlobals.getInstance().callController.placeCall(intent);
 
             // Note we do *not* "return" here, but instead continue and
             // send the ACTION_NEW_OUTGOING_CALL broadcast like for any
@@ -559,13 +560,13 @@
 
         // Remember the call origin so that users will be able to see an appropriate screen
         // after the phone call. This should affect both phone calls and SIP calls.
-        final String callOrigin = intent.getStringExtra(PhoneApp.EXTRA_CALL_ORIGIN);
+        final String callOrigin = intent.getStringExtra(PhoneGlobals.EXTRA_CALL_ORIGIN);
         if (callOrigin != null) {
             if (DBG) Log.v(TAG, " - Call origin is passed (" + callOrigin + ")");
-            PhoneApp.getInstance().setLatestActiveCallOrigin(callOrigin);
+            PhoneGlobals.getInstance().setLatestActiveCallOrigin(callOrigin);
         } else {
             if (DBG) Log.v(TAG, " - Call origin is not passed. Reset current one.");
-            PhoneApp.getInstance().resetLatestActiveCallOrigin();
+            PhoneGlobals.getInstance().resetLatestActiveCallOrigin();
         }
 
         // For now, SIP calls will be processed directly without a
@@ -609,7 +610,8 @@
         // timeout.
         mHandler.sendEmptyMessageDelayed(EVENT_OUTGOING_CALL_TIMEOUT,
                 OUTGOING_CALL_TIMEOUT_THRESHOLD);
-        sendOrderedBroadcast(broadcastIntent, PERMISSION, new OutgoingCallReceiver(),
+        sendOrderedBroadcastAsUser(broadcastIntent, UserHandle.OWNER,
+                PERMISSION, new OutgoingCallReceiver(),
                 null,  // scheduler
                 Activity.RESULT_OK,  // initialCode
                 number,  // initialData: initial value for the result data
diff --git a/src/com/android/phone/PhoneApp.java b/src/com/android/phone/PhoneApp.java
index 10099f8..e3d3fa9 100644
--- a/src/com/android/phone/PhoneApp.java
+++ b/src/com/android/phone/PhoneApp.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2006 The Android Open Source Project
+ * Copyright (C) 2012 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.
@@ -16,1993 +16,34 @@
 
 package com.android.phone;
 
-import android.app.Activity;
 import android.app.Application;
-import android.app.KeyguardManager;
-import android.app.PendingIntent;
-import android.app.ProgressDialog;
-import android.bluetooth.BluetoothAdapter;
-import android.bluetooth.BluetoothHeadset;
-import android.bluetooth.BluetoothProfile;
-import android.content.ActivityNotFoundException;
-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.res.Configuration;
-import android.media.AudioManager;
-import android.net.Uri;
-import android.os.AsyncResult;
-import android.os.Binder;
-import android.os.Handler;
-import android.os.IBinder;
-import android.os.IPowerManager;
-import android.os.LocalPowerManager;
-import android.os.Message;
-import android.os.PowerManager;
-import android.os.RemoteException;
-import android.os.ServiceManager;
-import android.os.SystemClock;
-import android.os.SystemProperties;
-import android.os.UpdateLock;
-import android.preference.PreferenceManager;
-import android.provider.Settings.System;
-import android.telephony.ServiceState;
-import android.text.TextUtils;
-import android.util.Log;
-import android.view.KeyEvent;
-
-import com.android.internal.telephony.Call;
-import com.android.internal.telephony.CallManager;
-import com.android.internal.telephony.IccCard;
-import com.android.internal.telephony.IccCardConstants;
-import com.android.internal.telephony.MmiCode;
-import com.android.internal.telephony.Phone;
-import com.android.internal.telephony.PhoneConstants;
-import com.android.internal.telephony.PhoneFactory;
-import com.android.internal.telephony.TelephonyCapabilities;
-import com.android.internal.telephony.TelephonyIntents;
-import com.android.internal.telephony.cdma.TtyIntent;
-import com.android.phone.OtaUtils.CdmaOtaScreenState;
-import com.android.server.sip.SipService;
+import android.os.UserHandle;
 
 /**
  * Top-level Application class for the Phone app.
  */
-public class PhoneApp extends Application implements AccelerometerListener.OrientationListener {
-    /* package */ static final String LOG_TAG = "PhoneApp";
-
-    /**
-     * Phone app-wide debug level:
-     *   0 - no debug logging
-     *   1 - normal debug logging if ro.debuggable is set (which is true in
-     *       "eng" and "userdebug" builds but not "user" builds)
-     *   2 - ultra-verbose debug logging
-     *
-     * Most individual classes in the phone app have a local DBG constant,
-     * typically set to
-     *   (PhoneApp.DBG_LEVEL >= 1) && (SystemProperties.getInt("ro.debuggable", 0) == 1)
-     * or else
-     *   (PhoneApp.DBG_LEVEL >= 2)
-     * depending on the desired verbosity.
-     *
-     * ***** DO NOT SUBMIT WITH DBG_LEVEL > 0 *************
-     */
-    /* package */ static final int DBG_LEVEL = 0;
-
-    private static final boolean DBG =
-            (PhoneApp.DBG_LEVEL >= 1) && (SystemProperties.getInt("ro.debuggable", 0) == 1);
-    private static final boolean VDBG = (PhoneApp.DBG_LEVEL >= 2);
-
-    // Message codes; see mHandler below.
-    private static final int EVENT_SIM_NETWORK_LOCKED = 3;
-    private static final int EVENT_WIRED_HEADSET_PLUG = 7;
-    private static final int EVENT_SIM_STATE_CHANGED = 8;
-    private static final int EVENT_UPDATE_INCALL_NOTIFICATION = 9;
-    private static final int EVENT_DATA_ROAMING_DISCONNECTED = 10;
-    private static final int EVENT_DATA_ROAMING_OK = 11;
-    private static final int EVENT_UNSOL_CDMA_INFO_RECORD = 12;
-    private static final int EVENT_DOCK_STATE_CHANGED = 13;
-    private static final int EVENT_TTY_PREFERRED_MODE_CHANGED = 14;
-    private static final int EVENT_TTY_MODE_GET = 15;
-    private static final int EVENT_TTY_MODE_SET = 16;
-    private static final int EVENT_START_SIP_SERVICE = 17;
-
-    // The MMI codes are also used by the InCallScreen.
-    public static final int MMI_INITIATE = 51;
-    public static final int MMI_COMPLETE = 52;
-    public static final int MMI_CANCEL = 53;
-    // Don't use message codes larger than 99 here; those are reserved for
-    // the individual Activities of the Phone UI.
-
-    /**
-     * Allowable values for the poke lock code (timeout between a user activity and the
-     * going to sleep), please refer to {@link com.android.server.PowerManagerService}
-     * for additional reference.
-     *   SHORT uses the short delay for the timeout (SHORT_KEYLIGHT_DELAY, 6 sec)
-     *   MEDIUM uses the medium delay for the timeout (MEDIUM_KEYLIGHT_DELAY, 15 sec)
-     *   DEFAULT is the system-wide default delay for the timeout (1 min)
-     */
-    public enum ScreenTimeoutDuration {
-        SHORT,
-        MEDIUM,
-        DEFAULT
-    }
-
-    /**
-     * Allowable values for the wake lock code.
-     *   SLEEP means the device can be put to sleep.
-     *   PARTIAL means wake the processor, but we display can be kept off.
-     *   FULL means wake both the processor and the display.
-     */
-    public enum WakeState {
-        SLEEP,
-        PARTIAL,
-        FULL
-    }
-
-    /**
-     * Intent Action used for hanging up the current call from Notification bar. This will
-     * choose first ringing call, first active call, or first background call (typically in
-     * HOLDING state).
-     */
-    public static final String ACTION_HANG_UP_ONGOING_CALL =
-            "com.android.phone.ACTION_HANG_UP_ONGOING_CALL";
-
-    /**
-     * Intent Action used for making a phone call from Notification bar.
-     * This is for missed call notifications.
-     */
-    public static final String ACTION_CALL_BACK_FROM_NOTIFICATION =
-            "com.android.phone.ACTION_CALL_BACK_FROM_NOTIFICATION";
-
-    /**
-     * Intent Action used for sending a SMS from notification bar.
-     * This is for missed call notifications.
-     */
-    public static final String ACTION_SEND_SMS_FROM_NOTIFICATION =
-            "com.android.phone.ACTION_SEND_SMS_FROM_NOTIFICATION";
-
-    private static PhoneApp sMe;
-
-    // A few important fields we expose to the rest of the package
-    // directly (rather than thru set/get methods) for efficiency.
-    Phone phone;
-    CallController callController;
-    InCallUiState inCallUiState;
-    CallerInfoCache callerInfoCache;
-    CallNotifier notifier;
-    NotificationMgr notificationMgr;
-    Ringer ringer;
-    BluetoothHandsfree mBtHandsfree;
-    PhoneInterfaceManager phoneMgr;
-    CallManager mCM;
-    int mBluetoothHeadsetState = BluetoothProfile.STATE_DISCONNECTED;
-    int mBluetoothHeadsetAudioState = BluetoothHeadset.STATE_AUDIO_DISCONNECTED;
-    boolean mShowBluetoothIndication = false;
-    static int mDockState = Intent.EXTRA_DOCK_STATE_UNDOCKED;
-    static boolean sVoiceCapable = true;
-
-    // Internal PhoneApp Call state tracker
-    CdmaPhoneCallState cdmaPhoneCallState;
-
-    // The InCallScreen instance (or null if the InCallScreen hasn't been
-    // created yet.)
-    private InCallScreen mInCallScreen;
-
-    // The currently-active PUK entry activity and progress dialog.
-    // Normally, these are the Emergency Dialer and the subsequent
-    // progress dialog.  null if there is are no such objects in
-    // the foreground.
-    private Activity mPUKEntryActivity;
-    private ProgressDialog mPUKEntryProgressDialog;
-
-    private boolean mIsSimPinEnabled;
-    private String mCachedSimPin;
-
-    // True if a wired headset is currently plugged in, based on the state
-    // from the latest Intent.ACTION_HEADSET_PLUG broadcast we received in
-    // mReceiver.onReceive().
-    private boolean mIsHeadsetPlugged;
-
-    // True if the keyboard is currently *not* hidden
-    // Gets updated whenever there is a Configuration change
-    private boolean mIsHardKeyboardOpen;
-
-    // True if we are beginning a call, but the phone state has not changed yet
-    private boolean mBeginningCall;
-
-    // Last phone state seen by updatePhoneState()
-    private PhoneConstants.State mLastPhoneState = PhoneConstants.State.IDLE;
-
-    private WakeState mWakeState = WakeState.SLEEP;
-
-    /**
-     * Timeout setting used by PokeLock.
-     *
-     * This variable won't be effective when proximity sensor is available in the device.
-     *
-     * @see ScreenTimeoutDuration
-     */
-    private ScreenTimeoutDuration mScreenTimeoutDuration = ScreenTimeoutDuration.DEFAULT;
-    /**
-     * Used to set/unset {@link LocalPowerManager#POKE_LOCK_IGNORE_TOUCH_EVENTS} toward PokeLock.
-     *
-     * This variable won't be effective when proximity sensor is available in the device.
-     */
-    private boolean mIgnoreTouchUserActivity = false;
-    private final IBinder mPokeLockToken = new Binder();
-
-    private IPowerManager mPowerManagerService;
-    private PowerManager.WakeLock mWakeLock;
-    private PowerManager.WakeLock mPartialWakeLock;
-    private PowerManager.WakeLock mProximityWakeLock;
-    private KeyguardManager mKeyguardManager;
-    private AccelerometerListener mAccelerometerListener;
-    private int mOrientation = AccelerometerListener.ORIENTATION_UNKNOWN;
-
-    private UpdateLock mUpdateLock;
-
-    // Broadcast receiver for various intent broadcasts (see onCreate())
-    private final BroadcastReceiver mReceiver = new PhoneAppBroadcastReceiver();
-
-    // Broadcast receiver purely for ACTION_MEDIA_BUTTON broadcasts
-    private final BroadcastReceiver mMediaButtonReceiver = new MediaButtonBroadcastReceiver();
-
-    /** boolean indicating restoring mute state on InCallScreen.onResume() */
-    private boolean mShouldRestoreMuteOnInCallResume;
-
-    /**
-     * The singleton OtaUtils instance used for OTASP calls.
-     *
-     * The OtaUtils instance is created lazily the first time we need to
-     * make an OTASP call, regardless of whether it's an interactive or
-     * non-interactive OTASP call.
-     */
-    public OtaUtils otaUtils;
-
-    // Following are the CDMA OTA information Objects used during OTA Call.
-    // cdmaOtaProvisionData object store static OTA information that needs
-    // to be maintained even during Slider open/close scenarios.
-    // cdmaOtaConfigData object stores configuration info to control visiblity
-    // of each OTA Screens.
-    // cdmaOtaScreenState object store OTA Screen State information.
-    public OtaUtils.CdmaOtaProvisionData cdmaOtaProvisionData;
-    public OtaUtils.CdmaOtaConfigData cdmaOtaConfigData;
-    public OtaUtils.CdmaOtaScreenState cdmaOtaScreenState;
-    public OtaUtils.CdmaOtaInCallScreenUiState cdmaOtaInCallScreenUiState;
-
-    // TTY feature enabled on this platform
-    private boolean mTtyEnabled;
-    // Current TTY operating mode selected by user
-    private int mPreferredTtyMode = Phone.TTY_MODE_OFF;
-
-    /**
-     * Set the restore mute state flag. Used when we are setting the mute state
-     * OUTSIDE of user interaction {@link PhoneUtils#startNewCall(Phone)}
-     */
-    /*package*/void setRestoreMuteOnInCallResume (boolean mode) {
-        mShouldRestoreMuteOnInCallResume = mode;
-    }
-
-    /**
-     * Get the restore mute state flag.
-     * This is used by the InCallScreen {@link InCallScreen#onResume()} to figure
-     * out if we need to restore the mute state for the current active call.
-     */
-    /*package*/boolean getRestoreMuteOnInCallResume () {
-        return mShouldRestoreMuteOnInCallResume;
-    }
-
-    Handler mHandler = new Handler() {
-        @Override
-        public void handleMessage(Message msg) {
-            PhoneConstants.State phoneState;
-            switch (msg.what) {
-                // Starts the SIP service. It's a no-op if SIP API is not supported
-                // on the deivce.
-                // TODO: Having the phone process host the SIP service is only
-                // temporary. Will move it to a persistent communication process
-                // later.
-                case EVENT_START_SIP_SERVICE:
-                    SipService.start(getApplicationContext());
-                    break;
-
-                // TODO: This event should be handled by the lock screen, just
-                // like the "SIM missing" and "Sim locked" cases (bug 1804111).
-                case EVENT_SIM_NETWORK_LOCKED:
-                    if (getResources().getBoolean(R.bool.ignore_sim_network_locked_events)) {
-                        // Some products don't have the concept of a "SIM network lock"
-                        Log.i(LOG_TAG, "Ignoring EVENT_SIM_NETWORK_LOCKED event; "
-                              + "not showing 'SIM network unlock' PIN entry screen");
-                    } else {
-                        // Normal case: show the "SIM network unlock" PIN entry screen.
-                        // The user won't be able to do anything else until
-                        // they enter a valid SIM network PIN.
-                        Log.i(LOG_TAG, "show sim depersonal panel");
-                        IccNetworkDepersonalizationPanel ndpPanel =
-                                new IccNetworkDepersonalizationPanel(PhoneApp.getInstance());
-                        ndpPanel.show();
-                    }
-                    break;
-
-                case EVENT_UPDATE_INCALL_NOTIFICATION:
-                    // Tell the NotificationMgr to update the "ongoing
-                    // call" icon in the status bar, if necessary.
-                    // Currently, this is triggered by a bluetooth headset
-                    // state change (since the status bar icon needs to
-                    // turn blue when bluetooth is active.)
-                    if (DBG) Log.d (LOG_TAG, "- updating in-call notification from handler...");
-                    notificationMgr.updateInCallNotification();
-                    break;
-
-                case EVENT_DATA_ROAMING_DISCONNECTED:
-                    notificationMgr.showDataDisconnectedRoaming();
-                    break;
-
-                case EVENT_DATA_ROAMING_OK:
-                    notificationMgr.hideDataDisconnectedRoaming();
-                    break;
-
-                case MMI_COMPLETE:
-                    onMMIComplete((AsyncResult) msg.obj);
-                    break;
-
-                case MMI_CANCEL:
-                    PhoneUtils.cancelMmiCode(phone);
-                    break;
-
-                case EVENT_WIRED_HEADSET_PLUG:
-                    // Since the presence of a wired headset or bluetooth affects the
-                    // speakerphone, update the "speaker" state.  We ONLY want to do
-                    // this on the wired headset connect / disconnect events for now
-                    // though, so we're only triggering on EVENT_WIRED_HEADSET_PLUG.
-
-                    phoneState = mCM.getState();
-                    // Do not change speaker state if phone is not off hook
-                    if (phoneState == PhoneConstants.State.OFFHOOK) {
-                        if (mBtHandsfree == null || !mBtHandsfree.isAudioOn()) {
-                            if (!isHeadsetPlugged()) {
-                                // if the state is "not connected", restore the speaker state.
-                                PhoneUtils.restoreSpeakerMode(getApplicationContext());
-                            } else {
-                                // if the state is "connected", force the speaker off without
-                                // storing the state.
-                                PhoneUtils.turnOnSpeaker(getApplicationContext(), false, false);
-                            }
-                        }
-                    }
-                    // Update the Proximity sensor based on headset state
-                    updateProximitySensorMode(phoneState);
-
-                    // Force TTY state update according to new headset state
-                    if (mTtyEnabled) {
-                        sendMessage(obtainMessage(EVENT_TTY_PREFERRED_MODE_CHANGED, 0));
-                    }
-                    break;
-
-                case EVENT_SIM_STATE_CHANGED:
-                    // Marks the event where the SIM goes into ready state.
-                    // Right now, this is only used for the PUK-unlocking
-                    // process.
-                    if (msg.obj.equals(IccCardConstants.INTENT_VALUE_ICC_READY)) {
-                        // when the right event is triggered and there
-                        // are UI objects in the foreground, we close
-                        // them to display the lock panel.
-                        if (mPUKEntryActivity != null) {
-                            mPUKEntryActivity.finish();
-                            mPUKEntryActivity = null;
-                        }
-                        if (mPUKEntryProgressDialog != null) {
-                            mPUKEntryProgressDialog.dismiss();
-                            mPUKEntryProgressDialog = null;
-                        }
-                    }
-                    break;
-
-                case EVENT_UNSOL_CDMA_INFO_RECORD:
-                    //TODO: handle message here;
-                    break;
-
-                case EVENT_DOCK_STATE_CHANGED:
-                    // If the phone is docked/undocked during a call, and no wired or BT headset
-                    // is connected: turn on/off the speaker accordingly.
-                    boolean inDockMode = false;
-                    if (mDockState != Intent.EXTRA_DOCK_STATE_UNDOCKED) {
-                        inDockMode = true;
-                    }
-                    if (VDBG) Log.d(LOG_TAG, "received EVENT_DOCK_STATE_CHANGED. Phone inDock = "
-                            + inDockMode);
-
-                    phoneState = mCM.getState();
-                    if (phoneState == PhoneConstants.State.OFFHOOK &&
-                            !isHeadsetPlugged() &&
-                            !(mBtHandsfree != null && mBtHandsfree.isAudioOn())) {
-                        PhoneUtils.turnOnSpeaker(getApplicationContext(), inDockMode, true);
-                        updateInCallScreen();  // Has no effect if the InCallScreen isn't visible
-                    }
-                    break;
-
-                case EVENT_TTY_PREFERRED_MODE_CHANGED:
-                    // TTY mode is only applied if a headset is connected
-                    int ttyMode;
-                    if (isHeadsetPlugged()) {
-                        ttyMode = mPreferredTtyMode;
-                    } else {
-                        ttyMode = Phone.TTY_MODE_OFF;
-                    }
-                    phone.setTTYMode(ttyMode, mHandler.obtainMessage(EVENT_TTY_MODE_SET));
-                    break;
-
-                case EVENT_TTY_MODE_GET:
-                    handleQueryTTYModeResponse(msg);
-                    break;
-
-                case EVENT_TTY_MODE_SET:
-                    handleSetTTYModeResponse(msg);
-                    break;
-            }
-        }
-    };
+public class PhoneApp extends Application {
+    PhoneGlobals mPhoneGlobals;
 
     public PhoneApp() {
-        sMe = this;
     }
 
     @Override
     public void onCreate() {
-        if (VDBG) Log.v(LOG_TAG, "onCreate()...");
-
-        ContentResolver resolver = getContentResolver();
-
-        // Cache the "voice capable" flag.
-        // This flag currently comes from a resource (which is
-        // overrideable on a per-product basis):
-        sVoiceCapable =
-                getResources().getBoolean(com.android.internal.R.bool.config_voice_capable);
-        // ...but this might eventually become a PackageManager "system
-        // feature" instead, in which case we'd do something like:
-        // sVoiceCapable =
-        //   getPackageManager().hasSystemFeature(PackageManager.FEATURE_TELEPHONY_VOICE_CALLS);
-
-        if (phone == null) {
-            // Initialize the telephony framework
-            PhoneFactory.makeDefaultPhones(this);
-
-            // Get the default phone
-            phone = PhoneFactory.getDefaultPhone();
-
-            // Start TelephonyDebugService After the default phone is created.
-            Intent intent = new Intent(this, TelephonyDebugService.class);
-            startService(intent);
-
-            mCM = CallManager.getInstance();
-            mCM.registerPhone(phone);
-
-            // Create the NotificationMgr singleton, which is used to display
-            // status bar icons and control other status bar behavior.
-            notificationMgr = NotificationMgr.init(this);
-
-            phoneMgr = PhoneInterfaceManager.init(this, phone);
-
-            mHandler.sendEmptyMessage(EVENT_START_SIP_SERVICE);
-
-            int phoneType = phone.getPhoneType();
-
-            if (phoneType == PhoneConstants.PHONE_TYPE_CDMA) {
-                // Create an instance of CdmaPhoneCallState and initialize it to IDLE
-                cdmaPhoneCallState = new CdmaPhoneCallState();
-                cdmaPhoneCallState.CdmaPhoneCallStateInit();
-            }
-
-            if (BluetoothAdapter.getDefaultAdapter() != null) {
-                // Start BluetoothHandsree even if device is not voice capable.
-                // The device can still support VOIP.
-                mBtHandsfree = BluetoothHandsfree.init(this, mCM);
-                startService(new Intent(this, BluetoothHeadsetService.class));
-            } else {
-                // Device is not bluetooth capable
-                mBtHandsfree = null;
-            }
-
-            ringer = Ringer.init(this);
-
-            // before registering for phone state changes
-            PowerManager pm = (PowerManager) getSystemService(Context.POWER_SERVICE);
-            mWakeLock = pm.newWakeLock(PowerManager.FULL_WAKE_LOCK
-                    | PowerManager.ACQUIRE_CAUSES_WAKEUP,
-                    LOG_TAG);
-            // lock used to keep the processor awake, when we don't care for the display.
-            mPartialWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK
-                    | PowerManager.ON_AFTER_RELEASE, LOG_TAG);
-            // Wake lock used to control proximity sensor behavior.
-            if ((pm.getSupportedWakeLockFlags()
-                 & PowerManager.PROXIMITY_SCREEN_OFF_WAKE_LOCK) != 0x0) {
-                mProximityWakeLock =
-                        pm.newWakeLock(PowerManager.PROXIMITY_SCREEN_OFF_WAKE_LOCK, LOG_TAG);
-            }
-            if (DBG) Log.d(LOG_TAG, "onCreate: mProximityWakeLock: " + mProximityWakeLock);
-
-            // create mAccelerometerListener only if we are using the proximity sensor
-            if (proximitySensorModeEnabled()) {
-                mAccelerometerListener = new AccelerometerListener(this, this);
-            }
-
-            mKeyguardManager = (KeyguardManager) getSystemService(Context.KEYGUARD_SERVICE);
-
-            // get a handle to the service so that we can use it later when we
-            // want to set the poke lock.
-            mPowerManagerService = IPowerManager.Stub.asInterface(
-                    ServiceManager.getService("power"));
-
-            // Get UpdateLock to suppress system-update related events (e.g. dialog show-up)
-            // during phone calls.
-            mUpdateLock = new UpdateLock("phone");
-
-            if (DBG) Log.d(LOG_TAG, "onCreate: mUpdateLock: " + mUpdateLock);
-
-            // Create the CallController singleton, which is the interface
-            // to the telephony layer for user-initiated telephony functionality
-            // (like making outgoing calls.)
-            callController = CallController.init(this);
-            // ...and also the InCallUiState instance, used by the CallController to
-            // keep track of some "persistent state" of the in-call UI.
-            inCallUiState = InCallUiState.init(this);
-
-            // Create the CallerInfoCache singleton, which remembers custom ring tone and
-            // send-to-voicemail settings.
-            //
-            // The asynchronous caching will start just after this call.
-            callerInfoCache = CallerInfoCache.init(this);
-
-            // Create the CallNotifer singleton, which handles
-            // asynchronous events from the telephony layer (like
-            // launching the incoming-call UI when an incoming call comes
-            // in.)
-            notifier = CallNotifier.init(this, phone, ringer, mBtHandsfree, new CallLogAsync());
-
-            // register for ICC status
-            IccCard sim = phone.getIccCard();
-            if (sim != null) {
-                if (VDBG) Log.v(LOG_TAG, "register for ICC status");
-                sim.registerForNetworkLocked(mHandler, EVENT_SIM_NETWORK_LOCKED, null);
-            }
-
-            // register for MMI/USSD
-            mCM.registerForMmiComplete(mHandler, MMI_COMPLETE, null);
-
-            // register connection tracking to PhoneUtils
-            PhoneUtils.initializeConnectionHandler(mCM);
-
-            // Read platform settings for TTY feature
-            mTtyEnabled = getResources().getBoolean(R.bool.tty_enabled);
-
-            // Register for misc other intent broadcasts.
-            IntentFilter intentFilter =
-                    new IntentFilter(Intent.ACTION_AIRPLANE_MODE_CHANGED);
-            intentFilter.addAction(BluetoothHeadset.ACTION_CONNECTION_STATE_CHANGED);
-            intentFilter.addAction(BluetoothHeadset.ACTION_AUDIO_STATE_CHANGED);
-            intentFilter.addAction(TelephonyIntents.ACTION_ANY_DATA_CONNECTION_STATE_CHANGED);
-            intentFilter.addAction(Intent.ACTION_HEADSET_PLUG);
-            intentFilter.addAction(Intent.ACTION_DOCK_EVENT);
-            intentFilter.addAction(TelephonyIntents.ACTION_SIM_STATE_CHANGED);
-            intentFilter.addAction(TelephonyIntents.ACTION_RADIO_TECHNOLOGY_CHANGED);
-            intentFilter.addAction(TelephonyIntents.ACTION_SERVICE_STATE_CHANGED);
-            intentFilter.addAction(TelephonyIntents.ACTION_EMERGENCY_CALLBACK_MODE_CHANGED);
-            if (mTtyEnabled) {
-                intentFilter.addAction(TtyIntent.TTY_PREFERRED_MODE_CHANGE_ACTION);
-            }
-            intentFilter.addAction(AudioManager.RINGER_MODE_CHANGED_ACTION);
-            registerReceiver(mReceiver, intentFilter);
-
-            // Use a separate receiver for ACTION_MEDIA_BUTTON broadcasts,
-            // since we need to manually adjust its priority (to make sure
-            // we get these intents *before* the media player.)
-            IntentFilter mediaButtonIntentFilter =
-                    new IntentFilter(Intent.ACTION_MEDIA_BUTTON);
-            // TODO verify the independent priority doesn't need to be handled thanks to the
-            //  private intent handler registration
-            // Make sure we're higher priority than the media player's
-            // MediaButtonIntentReceiver (which currently has the default
-            // priority of zero; see apps/Music/AndroidManifest.xml.)
-            mediaButtonIntentFilter.setPriority(1);
-            //
-            registerReceiver(mMediaButtonReceiver, mediaButtonIntentFilter);
-            // register the component so it gets priority for calls
-            AudioManager am = (AudioManager) getSystemService(Context.AUDIO_SERVICE);
-            am.registerMediaButtonEventReceiverForCalls(new ComponentName(this.getPackageName(),
-                    MediaButtonBroadcastReceiver.class.getName()));
-
-            //set the default values for the preferences in the phone.
-            PreferenceManager.setDefaultValues(this, R.xml.network_setting, 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);
+        if (UserHandle.myUserId() == 0) {
+            // We are running as the primary user, so should bring up the
+            // global phone state.
+            mPhoneGlobals = new PhoneGlobals(this);
+            mPhoneGlobals.onCreate();
         }
-
-        if (TelephonyCapabilities.supportsOtasp(phone)) {
-            cdmaOtaProvisionData = new OtaUtils.CdmaOtaProvisionData();
-            cdmaOtaConfigData = new OtaUtils.CdmaOtaConfigData();
-            cdmaOtaScreenState = new OtaUtils.CdmaOtaScreenState();
-            cdmaOtaInCallScreenUiState = new OtaUtils.CdmaOtaInCallScreenUiState();
-        }
-
-        // XXX pre-load the SimProvider so that it's ready
-        resolver.getType(Uri.parse("content://icc/adn"));
-
-        // start with the default value to set the mute state.
-        mShouldRestoreMuteOnInCallResume = false;
-
-        // TODO: Register for Cdma Information Records
-        // phone.registerCdmaInformationRecord(mHandler, EVENT_UNSOL_CDMA_INFO_RECORD, null);
-
-        // Read TTY settings and store it into BP NV.
-        // AP owns (i.e. stores) the TTY setting in AP settings database and pushes the setting
-        // to BP at power up (BP does not need to make the TTY setting persistent storage).
-        // This way, there is a single owner (i.e AP) for the TTY setting in the phone.
-        if (mTtyEnabled) {
-            mPreferredTtyMode = android.provider.Settings.Secure.getInt(
-                    phone.getContext().getContentResolver(),
-                    android.provider.Settings.Secure.PREFERRED_TTY_MODE,
-                    Phone.TTY_MODE_OFF);
-            mHandler.sendMessage(mHandler.obtainMessage(EVENT_TTY_PREFERRED_MODE_CHANGED, 0));
-        }
-        // Read HAC settings and configure audio hardware
-        if (getResources().getBoolean(R.bool.hac_enabled)) {
-            int hac = android.provider.Settings.System.getInt(phone.getContext().getContentResolver(),
-                                                              android.provider.Settings.System.HEARING_AID,
-                                                              0);
-            AudioManager audioManager = (AudioManager) getSystemService(Context.AUDIO_SERVICE);
-            audioManager.setParameter(CallFeaturesSetting.HAC_KEY, hac != 0 ?
-                                      CallFeaturesSetting.HAC_VAL_ON :
-                                      CallFeaturesSetting.HAC_VAL_OFF);
-        }
-   }
+    }
 
     @Override
     public void onConfigurationChanged(Configuration newConfig) {
-        if (newConfig.hardKeyboardHidden == Configuration.HARDKEYBOARDHIDDEN_NO) {
-            mIsHardKeyboardOpen = true;
-        } else {
-            mIsHardKeyboardOpen = false;
+        if (mPhoneGlobals != null) {
+            mPhoneGlobals.onConfigurationChanged(newConfig);
         }
-
-        // Update the Proximity sensor based on keyboard state
-        updateProximitySensorMode(mCM.getState());
         super.onConfigurationChanged(newConfig);
     }
-
-    /**
-     * Returns the singleton instance of the PhoneApp.
-     */
-    static PhoneApp getInstance() {
-        return sMe;
-    }
-
-    /**
-     * Returns the Phone associated with this instance
-     */
-    static Phone getPhone() {
-        return getInstance().phone;
-    }
-
-    Ringer getRinger() {
-        return ringer;
-    }
-
-    BluetoothHandsfree getBluetoothHandsfree() {
-        return mBtHandsfree;
-    }
-
-    /**
-     * Returns an Intent that can be used to go to the "Call log"
-     * UI (aka CallLogActivity) in the Contacts app.
-     *
-     * Watch out: there's no guarantee that the system has any activity to
-     * handle this intent.  (In particular there may be no "Call log" at
-     * all on on non-voice-capable devices.)
-     */
-    /* package */ static Intent createCallLogIntent() {
-        Intent intent = new Intent(Intent.ACTION_VIEW, null);
-        intent.setType("vnd.android.cursor.dir/calls");
-        return intent;
-    }
-
-    /**
-     * Return an Intent that can be used to bring up the in-call screen.
-     *
-     * This intent can only be used from within the Phone app, since the
-     * InCallScreen is not exported from our AndroidManifest.
-     */
-    /* package */ static Intent createInCallIntent() {
-        Intent intent = new Intent(Intent.ACTION_MAIN, null);
-        intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK
-                | Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS
-                | Intent.FLAG_ACTIVITY_NO_USER_ACTION);
-        intent.setClassName("com.android.phone", getCallScreenClassName());
-        return intent;
-    }
-
-    /**
-     * Variation of createInCallIntent() that also specifies whether the
-     * DTMF dialpad should be initially visible when the InCallScreen
-     * comes up.
-     */
-    /* package */ static Intent createInCallIntent(boolean showDialpad) {
-        Intent intent = createInCallIntent();
-        intent.putExtra(InCallScreen.SHOW_DIALPAD_EXTRA, showDialpad);
-        return intent;
-    }
-
-    /**
-     * Returns PendingIntent for hanging up ongoing phone call. This will typically be used from
-     * Notification context.
-     */
-    /* package */ static PendingIntent createHangUpOngoingCallPendingIntent(Context context) {
-        Intent intent = new Intent(PhoneApp.ACTION_HANG_UP_ONGOING_CALL, null,
-                context, NotificationBroadcastReceiver.class);
-        return PendingIntent.getBroadcast(context, 0, intent, 0);
-    }
-
-    /* package */ static PendingIntent getCallBackPendingIntent(Context context, String number) {
-        Intent intent = new Intent(ACTION_CALL_BACK_FROM_NOTIFICATION,
-                Uri.fromParts(Constants.SCHEME_TEL, number, null),
-                context, NotificationBroadcastReceiver.class);
-        return PendingIntent.getBroadcast(context, 0, intent, 0);
-    }
-
-    /* package */ static PendingIntent getSendSmsFromNotificationPendingIntent(
-            Context context, String number) {
-        Intent intent = new Intent(ACTION_SEND_SMS_FROM_NOTIFICATION,
-                Uri.fromParts(Constants.SCHEME_SMSTO, number, null),
-                context, NotificationBroadcastReceiver.class);
-        return PendingIntent.getBroadcast(context, 0, intent, 0);
-    }
-
-    private static String getCallScreenClassName() {
-        return InCallScreen.class.getName();
-    }
-
-    /**
-     * Starts the InCallScreen Activity.
-     */
-    /* package */ void displayCallScreen() {
-        if (VDBG) Log.d(LOG_TAG, "displayCallScreen()...");
-
-        // On non-voice-capable devices we shouldn't ever be trying to
-        // bring up the InCallScreen in the first place.
-        if (!sVoiceCapable) {
-            Log.w(LOG_TAG, "displayCallScreen() not allowed: non-voice-capable device",
-                  new Throwable("stack dump"));  // Include a stack trace since this warning
-                                                 // indicates a bug in our caller
-            return;
-        }
-
-        try {
-            startActivity(createInCallIntent());
-        } catch (ActivityNotFoundException e) {
-            // It's possible that the in-call UI might not exist (like on
-            // non-voice-capable devices), so don't crash if someone
-            // accidentally tries to bring it up...
-            Log.w(LOG_TAG, "displayCallScreen: transition to InCallScreen failed: " + e);
-        }
-        Profiler.callScreenRequested();
-    }
-
-    boolean isSimPinEnabled() {
-        return mIsSimPinEnabled;
-    }
-
-    boolean authenticateAgainstCachedSimPin(String pin) {
-        return (mCachedSimPin != null && mCachedSimPin.equals(pin));
-    }
-
-    void setCachedSimPin(String pin) {
-        mCachedSimPin = pin;
-    }
-
-    void setInCallScreenInstance(InCallScreen inCallScreen) {
-        mInCallScreen = inCallScreen;
-    }
-
-    /**
-     * @return true if the in-call UI is running as the foreground
-     * activity.  (In other words, from the perspective of the
-     * InCallScreen activity, return true between onResume() and
-     * onPause().)
-     *
-     * Note this method will return false if the screen is currently off,
-     * even if the InCallScreen *was* in the foreground just before the
-     * screen turned off.  (This is because the foreground activity is
-     * always "paused" while the screen is off.)
-     */
-    boolean isShowingCallScreen() {
-        if (mInCallScreen == null) return false;
-        return mInCallScreen.isForegroundActivity();
-    }
-
-    /**
-     * @return true if the in-call UI is running as the foreground activity, or,
-     * it went to background due to screen being turned off. This might be useful
-     * to determine if the in-call screen went to background because of other
-     * activities, or its proximity sensor state or manual power-button press.
-     *
-     * Here are some examples.
-     *
-     * - If you want to know if the activity is in foreground or screen is turned off
-     *   from the in-call UI (i.e. though it is not "foreground" anymore it will become
-     *   so after screen being turned on), check
-     *   {@link #isShowingCallScreenForProximity()} is true or not.
-     *   {@link #updateProximitySensorMode(com.android.internal.telephony.PhoneConstants.State)} is
-     *   doing this.
-     *
-     * - If you want to know if the activity is not in foreground just because screen
-     *   is turned off (not due to other activity's interference), check
-     *   {@link #isShowingCallScreen()} is false *and* {@link #isShowingCallScreenForProximity()}
-     *   is true. InCallScreen#onDisconnect() is doing this check.
-     *
-     * @see #isShowingCallScreen()
-     *
-     * TODO: come up with better naming..
-     */
-    boolean isShowingCallScreenForProximity() {
-        if (mInCallScreen == null) return false;
-        return mInCallScreen.isForegroundActivityForProximity();
-    }
-
-    /**
-     * Dismisses the in-call UI.
-     *
-     * This also ensures that you won't be able to get back to the in-call
-     * UI via the BACK button (since this call removes the InCallScreen
-     * from the activity history.)
-     * For OTA Call, it call InCallScreen api to handle OTA Call End scenario
-     * to display OTA Call End screen.
-     */
-    /* package */ void dismissCallScreen() {
-        if (mInCallScreen != null) {
-            if ((TelephonyCapabilities.supportsOtasp(phone)) &&
-                    (mInCallScreen.isOtaCallInActiveState()
-                    || mInCallScreen.isOtaCallInEndState()
-                    || ((cdmaOtaScreenState != null)
-                    && (cdmaOtaScreenState.otaScreenState
-                            != CdmaOtaScreenState.OtaScreenState.OTA_STATUS_UNDEFINED)))) {
-                // TODO: During OTA Call, display should not become dark to
-                // allow user to see OTA UI update. Phone app needs to hold
-                // a SCREEN_DIM_WAKE_LOCK wake lock during the entire OTA call.
-                wakeUpScreen();
-                // If InCallScreen is not in foreground we resume it to show the OTA call end screen
-                // Fire off the InCallScreen intent
-                displayCallScreen();
-
-                mInCallScreen.handleOtaCallEnd();
-                return;
-            } else {
-                mInCallScreen.finish();
-            }
-        }
-    }
-
-    /**
-     * Handles OTASP-related events from the telephony layer.
-     *
-     * While an OTASP call is active, the CallNotifier forwards
-     * OTASP-related telephony events to this method.
-     */
-    void handleOtaspEvent(Message msg) {
-        if (DBG) Log.d(LOG_TAG, "handleOtaspEvent(message " + msg + ")...");
-
-        if (otaUtils == null) {
-            // We shouldn't be getting OTASP events without ever
-            // having started the OTASP call in the first place!
-            Log.w(LOG_TAG, "handleOtaEvents: got an event but otaUtils is null! "
-                  + "message = " + msg);
-            return;
-        }
-
-        otaUtils.onOtaProvisionStatusChanged((AsyncResult) msg.obj);
-    }
-
-    /**
-     * Similarly, handle the disconnect event of an OTASP call
-     * by forwarding it to the OtaUtils instance.
-     */
-    /* package */ void handleOtaspDisconnect() {
-        if (DBG) Log.d(LOG_TAG, "handleOtaspDisconnect()...");
-
-        if (otaUtils == null) {
-            // We shouldn't be getting OTASP events without ever
-            // having started the OTASP call in the first place!
-            Log.w(LOG_TAG, "handleOtaspDisconnect: otaUtils is null!");
-            return;
-        }
-
-        otaUtils.onOtaspDisconnect();
-    }
-
-    /**
-     * Sets the activity responsible for un-PUK-blocking the device
-     * so that we may close it when we receive a positive result.
-     * mPUKEntryActivity is also used to indicate to the device that
-     * we are trying to un-PUK-lock the phone. In other words, iff
-     * it is NOT null, then we are trying to unlock and waiting for
-     * the SIM to move to READY state.
-     *
-     * @param activity is the activity to close when PUK has
-     * finished unlocking. Can be set to null to indicate the unlock
-     * or SIM READYing process is over.
-     */
-    void setPukEntryActivity(Activity activity) {
-        mPUKEntryActivity = activity;
-    }
-
-    Activity getPUKEntryActivity() {
-        return mPUKEntryActivity;
-    }
-
-    /**
-     * Sets the dialog responsible for notifying the user of un-PUK-
-     * blocking - SIM READYing progress, so that we may dismiss it
-     * when we receive a positive result.
-     *
-     * @param dialog indicates the progress dialog informing the user
-     * of the state of the device.  Dismissed upon completion of
-     * READYing process
-     */
-    void setPukEntryProgressDialog(ProgressDialog dialog) {
-        mPUKEntryProgressDialog = dialog;
-    }
-
-    ProgressDialog getPUKEntryProgressDialog() {
-        return mPUKEntryProgressDialog;
-    }
-
-    /**
-     * Controls how quickly the screen times out.
-     *
-     * This is no-op when the device supports proximity sensor.
-     *
-     * The poke lock controls how long it takes before the screen powers
-     * down, and therefore has no immediate effect when the current
-     * WakeState (see {@link PhoneApp#requestWakeState}) is FULL.
-     * If we're in a state where the screen *is* allowed to turn off,
-     * though, the poke lock will determine the timeout interval (long or
-     * short).
-     */
-    /* package */ void setScreenTimeout(ScreenTimeoutDuration duration) {
-        if (VDBG) Log.d(LOG_TAG, "setScreenTimeout(" + duration + ")...");
-
-        // stick with default timeout if we are using the proximity sensor
-        if (proximitySensorModeEnabled()) {
-            return;
-        }
-
-        // make sure we don't set the poke lock repeatedly so that we
-        // avoid triggering the userActivity calls in
-        // PowerManagerService.setPokeLock().
-        if (duration == mScreenTimeoutDuration) {
-            return;
-        }
-        mScreenTimeoutDuration = duration;
-        updatePokeLock();
-    }
-
-    /**
-     * Update the state of the poke lock held by the phone app,
-     * based on the current desired screen timeout and the
-     * current "ignore user activity on touch" flag.
-     */
-    private void updatePokeLock() {
-        // Caller must take care of the check. This block is purely for safety.
-        if (proximitySensorModeEnabled()) {
-            Log.wtf(LOG_TAG, "PokeLock should not be used when proximity sensor is available on"
-                    + " the device.");
-            return;
-        }
-
-        // This is kind of convoluted, but the basic thing to remember is
-        // that the poke lock just sends a message to the screen to tell
-        // it to stay on for a while.
-        // The default is 0, for a long timeout and should be set that way
-        // when we are heading back into a the keyguard / screen off
-        // state, and also when we're trying to keep the screen alive
-        // while ringing.  We'll also want to ignore the cheek events
-        // regardless of the timeout duration.
-        // The short timeout is really used whenever we want to give up
-        // the screen lock, such as when we're in call.
-        int pokeLockSetting = 0;
-        switch (mScreenTimeoutDuration) {
-            case SHORT:
-                // Set the poke lock to timeout the display after a short
-                // timeout (5s). This ensures that the screen goes to sleep
-                // as soon as acceptably possible after we the wake lock
-                // has been released.
-                pokeLockSetting |= LocalPowerManager.POKE_LOCK_SHORT_TIMEOUT;
-                break;
-
-            case MEDIUM:
-                // Set the poke lock to timeout the display after a medium
-                // timeout (15s). This ensures that the screen goes to sleep
-                // as soon as acceptably possible after we the wake lock
-                // has been released.
-                pokeLockSetting |= LocalPowerManager.POKE_LOCK_MEDIUM_TIMEOUT;
-                break;
-
-            case DEFAULT:
-            default:
-                // set the poke lock to timeout the display after a long
-                // delay by default.
-                // TODO: it may be nice to be able to disable cheek presses
-                // for long poke locks (emergency dialer, for instance).
-                break;
-        }
-
-        if (mIgnoreTouchUserActivity) {
-            pokeLockSetting |= LocalPowerManager.POKE_LOCK_IGNORE_TOUCH_EVENTS;
-        }
-
-        // Send the request
-        try {
-            mPowerManagerService.setPokeLock(pokeLockSetting, mPokeLockToken, LOG_TAG);
-        } catch (RemoteException e) {
-            Log.w(LOG_TAG, "mPowerManagerService.setPokeLock() failed: " + e);
-        }
-    }
-
-    /**
-     * 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 PhoneApp#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.
-     */
-    /* package */ void wakeUpScreen() {
-        synchronized (this) {
-            if (mWakeState == WakeState.SLEEP) {
-                if (DBG) Log.d(LOG_TAG, "pulse screen lock");
-                try {
-                    mPowerManagerService.userActivityWithForce(SystemClock.uptimeMillis(), false, true);
-                } catch (RemoteException ex) {
-                    // Ignore -- the system process is dead.
-                }
-            }
-        }
-    }
-
-    /**
-     * 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 PhoneApp#requestWakeState} and {@link PhoneApp#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 in-call UI is the foreground activity.
-        // (Note this will be false if the screen is currently off,
-        // since in that case *no* activity is in the foreground.)
-        boolean isShowingCallScreen = isShowingCallScreen();
-
-        // True if the InCallScreen's DTMF dialer is currently opened.
-        // (Note this does NOT imply whether or not the InCallScreen
-        // itself is visible.)
-        boolean isDialerOpened = (mInCallScreen != null) && mInCallScreen.isDialerOpened();
-
-        // 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.)
-
-        if (DBG) Log.d(LOG_TAG, "updateWakeState: callscreen " + isShowingCallScreen
-                       + ", dialer " + isDialerOpened
-                       + ", speaker " + isSpeakerInUse + "...");
-
-        //
-        // (1) Set the screen timeout.
-        //
-        // Note that the "screen timeout" value we determine here is
-        // meaningless if the screen is forced on (see (2) below.)
-        //
-
-        // Historical note: In froyo and earlier, we checked here for a special
-        // case: the in-call UI being active, the speaker off, and the DTMF dialpad
-        // not visible.  In that case, with no touchable UI onscreen at all (for
-        // non-prox-sensor devices at least), we could assume the user was probably
-        // holding the phone up to their face and *not* actually looking at the
-        // screen.  So we'd switch to a special screen timeout value
-        // (ScreenTimeoutDuration.MEDIUM), purely to save battery life.
-        //
-        // On current devices, we can rely on the proximity sensor to turn the
-        // screen off in this case, so we use the system-wide default timeout
-        // unconditionally.
-        setScreenTimeout(ScreenTimeoutDuration.DEFAULT);
-
-        //
-        // (2) 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.
-        //
-        boolean isRinging = (state == PhoneConstants.State.RINGING);
-        boolean isDialing = (phone.getForegroundCall().getState() == Call.State.DIALING);
-        boolean showingDisconnectedConnection =
-                PhoneUtils.hasDisconnectedConnections(phone) && isShowingCallScreen;
-        boolean keepScreenOn = isRinging || isDialing || showingDisconnectedConnection;
-        if (DBG) Log.d(LOG_TAG, "updateWakeState: keepScreenOn = " + keepScreenOn
-                       + " (isRinging " + isRinging
-                       + ", isDialing " + isDialing
-                       + ", showingDisc " + showingDisconnectedConnection + ")");
-        // keepScreenOn == true means we'll hold a full wake lock:
-        requestWakeState(keepScreenOn ? WakeState.FULL : WakeState.SLEEP);
-    }
-
-    /**
-     * Wrapper around the PowerManagerService.preventScreenOn() API.
-     * This allows the in-call UI to prevent the screen from turning on
-     * even if a subsequent call to updateWakeState() causes us to acquire
-     * a full wake lock.
-     */
-    /* package */ void preventScreenOn(boolean prevent) {
-        if (VDBG) Log.d(LOG_TAG, "- preventScreenOn(" + prevent + ")...");
-        try {
-            mPowerManagerService.preventScreenOn(prevent);
-        } catch (RemoteException e) {
-            Log.w(LOG_TAG, "mPowerManagerService.preventScreenOn() failed: " + e);
-        }
-    }
-
-    /**
-     * Sets or clears the flag that tells the PowerManager that touch
-     * (and cheek) events should NOT be considered "user activity".
-     *
-     * This method is no-op when proximity sensor is available on the device.
-     *
-     * Since the in-call UI is totally insensitive to touch in most
-     * states, we set this flag whenever the InCallScreen is in the
-     * foreground.  (Otherwise, repeated unintentional touches could
-     * prevent the device from going to sleep.)
-     *
-     * There *are* some some touch events that really do count as user
-     * activity, though.  For those, we need to manually poke the
-     * PowerManager's userActivity method; see pokeUserActivity().
-     */
-    /* package */ void setIgnoreTouchUserActivity(boolean ignore) {
-        if (VDBG) Log.d(LOG_TAG, "setIgnoreTouchUserActivity(" + ignore + ")...");
-        // stick with default timeout if we are using the proximity sensor
-        if (proximitySensorModeEnabled()) {
-            return;
-        }
-
-        mIgnoreTouchUserActivity = ignore;
-        updatePokeLock();
-    }
-
-    /**
-     * Manually pokes the PowerManager's userActivity method.  Since we
-     * hold the POKE_LOCK_IGNORE_TOUCH_EVENTS poke lock while
-     * the InCallScreen is active, we need to do this for touch events
-     * that really do count as user activity (like pressing any
-     * onscreen UI elements.)
-     */
-    /* package */ void pokeUserActivity() {
-        if (VDBG) Log.d(LOG_TAG, "pokeUserActivity()...");
-        try {
-            mPowerManagerService.userActivity(SystemClock.uptimeMillis(), false);
-        } catch (RemoteException e) {
-            Log.w(LOG_TAG, "mPowerManagerService.userActivity() failed: " + e);
-        }
-    }
-
-    /**
-     * Set when a new outgoing call is beginning, so we can update
-     * the proximity sensor state.
-     * Cleared when the InCallScreen is no longer in the foreground,
-     * in case the call fails without changing the telephony state.
-     */
-    /* package */ void setBeginningCall(boolean beginning) {
-        // Note that we are beginning a new call, for proximity sensor support
-        mBeginningCall = beginning;
-        // Update the Proximity sensor based on mBeginningCall state
-        updateProximitySensorMode(mCM.getState());
-    }
-
-    /**
-     * Updates the wake lock used to control proximity sensor behavior,
-     * based on the current state of the phone.  This method is called
-     * from the CallNotifier on any phone state change.
-     *
-     * On devices that have a proximity sensor, to avoid false touches
-     * during a call, we hold a PROXIMITY_SCREEN_OFF_WAKE_LOCK wake lock
-     * whenever the phone is off hook.  (When held, that wake lock causes
-     * the screen to turn off automatically when the sensor detects an
-     * object close to the screen.)
-     *
-     * This method is a no-op for devices that don't have a proximity
-     * sensor.
-     *
-     * Note this method doesn't care if the InCallScreen is the foreground
-     * activity or not.  That's because we want the proximity sensor to be
-     * enabled any time the phone is in use, to avoid false cheek events
-     * for whatever app you happen to be running.
-     *
-     * Proximity wake lock will *not* be held if any one of the
-     * conditions is true while on a call:
-     * 1) If the audio is routed via Bluetooth
-     * 2) If a wired headset is connected
-     * 3) if the speaker is ON
-     * 4) If the slider is open(i.e. the hardkeyboard is *not* hidden)
-     *
-     * @param state current state of the phone (see {@link Phone#State})
-     */
-    /* package */ void updateProximitySensorMode(PhoneConstants.State state) {
-        if (VDBG) Log.d(LOG_TAG, "updateProximitySensorMode: state = " + state);
-
-        if (proximitySensorModeEnabled()) {
-            synchronized (mProximityWakeLock) {
-                // turn proximity sensor off and turn screen on immediately if
-                // we are using a headset, the keyboard is open, or the device
-                // is being held in a horizontal position.
-                boolean screenOnImmediately = (isHeadsetPlugged()
-                            || PhoneUtils.isSpeakerOn(this)
-                            || ((mBtHandsfree != null) && mBtHandsfree.isAudioOn())
-                            || mIsHardKeyboardOpen);
-
-                // We do not keep the screen off when the user is outside in-call screen and we are
-                // horizontal, but we do not force it on when we become horizontal until the
-                // proximity sensor goes negative.
-                boolean horizontal =
-                        (mOrientation == AccelerometerListener.ORIENTATION_HORIZONTAL);
-                screenOnImmediately |= !isShowingCallScreenForProximity() && horizontal;
-
-                // We do not keep the screen off when dialpad is visible, we are horizontal, and
-                // the in-call screen is being shown.
-                // At that moment we're pretty sure users want to use it, instead of letting the
-                // proximity sensor turn off the screen by their hands.
-                boolean dialpadVisible = false;
-                if (mInCallScreen != null) {
-                    dialpadVisible =
-                            mInCallScreen.getUpdatedInCallControlState().dialpadEnabled
-                            && mInCallScreen.getUpdatedInCallControlState().dialpadVisible
-                            && isShowingCallScreen();
-                }
-                screenOnImmediately |= dialpadVisible && horizontal;
-
-                if (((state == PhoneConstants.State.OFFHOOK) || mBeginningCall) && !screenOnImmediately) {
-                    // Phone is in use!  Arrange for the screen to turn off
-                    // automatically when the sensor detects a close object.
-                    if (!mProximityWakeLock.isHeld()) {
-                        if (DBG) Log.d(LOG_TAG, "updateProximitySensorMode: acquiring...");
-                        mProximityWakeLock.acquire();
-                    } else {
-                        if (VDBG) Log.d(LOG_TAG, "updateProximitySensorMode: lock already held.");
-                    }
-                } else {
-                    // Phone is either idle, or ringing.  We don't want any
-                    // special proximity sensor behavior in either case.
-                    if (mProximityWakeLock.isHeld()) {
-                        if (DBG) Log.d(LOG_TAG, "updateProximitySensorMode: releasing...");
-                        // Wait until user has moved the phone away from his head if we are
-                        // releasing due to the phone call ending.
-                        // Qtherwise, turn screen on immediately
-                        int flags =
-                            (screenOnImmediately ? 0 : PowerManager.WAIT_FOR_PROXIMITY_NEGATIVE);
-                        mProximityWakeLock.release(flags);
-                    } else {
-                        if (VDBG) {
-                            Log.d(LOG_TAG, "updateProximitySensorMode: lock already released.");
-                        }
-                    }
-                }
-            }
-        }
-    }
-
-    @Override
-    public void orientationChanged(int orientation) {
-        mOrientation = orientation;
-        updateProximitySensorMode(mCM.getState());
-    }
-
-    /**
-     * Notifies the phone app when the phone state changes.
-     *
-     * This method will updates various states inside Phone app (e.g. proximity sensor mode,
-     * accelerometer listener state, update-lock state, etc.)
-     */
-    /* package */ void updatePhoneState(PhoneConstants.State state) {
-        if (state != mLastPhoneState) {
-            mLastPhoneState = state;
-            updateProximitySensorMode(state);
-
-            // Try to acquire or release UpdateLock.
-            //
-            // Watch out: we don't release the lock here when the screen is still in foreground.
-            // At that time InCallScreen will release it on onPause().
-            if (state != PhoneConstants.State.IDLE) {
-                // UpdateLock is a recursive lock, while we may get "acquire" request twice and
-                // "release" request once for a single call (RINGING + OFFHOOK and IDLE).
-                // We need to manually ensure the lock is just acquired once for each (and this
-                // will prevent other possible buggy situations too).
-                if (!mUpdateLock.isHeld()) {
-                    mUpdateLock.acquire();
-                }
-            } else {
-                if (!isShowingCallScreen()) {
-                    if (!mUpdateLock.isHeld()) {
-                        mUpdateLock.release();
-                    }
-                } else {
-                    // For this case InCallScreen will take care of the release() call.
-                }
-            }
-
-            if (mAccelerometerListener != null) {
-                // use accelerometer to augment proximity sensor when in call
-                mOrientation = AccelerometerListener.ORIENTATION_UNKNOWN;
-                mAccelerometerListener.enable(state == PhoneConstants.State.OFFHOOK);
-            }
-            // clear our beginning call flag
-            mBeginningCall = false;
-            // While we are in call, the in-call screen should dismiss the keyguard.
-            // This allows the user to press Home to go directly home without going through
-            // an insecure lock screen.
-            // But we do not want to do this if there is no active call so we do not
-            // bypass the keyguard if the call is not answered or declined.
-            if (mInCallScreen != null) {
-                mInCallScreen.updateKeyguardPolicy(state == PhoneConstants.State.OFFHOOK);
-            }
-        }
-    }
-
-    /* package */ PhoneConstants.State getPhoneState() {
-        return mLastPhoneState;
-    }
-
-    /**
-     * Returns UpdateLock object.
-     */
-    /* package */ UpdateLock getUpdateLock() {
-        return mUpdateLock;
-    }
-
-    /**
-     * @return true if this device supports the "proximity sensor
-     * auto-lock" feature while in-call (see updateProximitySensorMode()).
-     */
-    /* package */ boolean proximitySensorModeEnabled() {
-        return (mProximityWakeLock != null);
-    }
-
-    KeyguardManager getKeyguardManager() {
-        return mKeyguardManager;
-    }
-
-    private void onMMIComplete(AsyncResult r) {
-        if (VDBG) Log.d(LOG_TAG, "onMMIComplete()...");
-        MmiCode mmiCode = (MmiCode) r.result;
-        PhoneUtils.displayMMIComplete(phone, getInstance(), mmiCode, null, null);
-    }
-
-    private void initForNewRadioTechnology() {
-        if (DBG) Log.d(LOG_TAG, "initForNewRadioTechnology...");
-
-         if (phone.getPhoneType() == PhoneConstants.PHONE_TYPE_CDMA) {
-            // Create an instance of CdmaPhoneCallState and initialize it to IDLE
-            cdmaPhoneCallState = new CdmaPhoneCallState();
-            cdmaPhoneCallState.CdmaPhoneCallStateInit();
-        }
-        if (TelephonyCapabilities.supportsOtasp(phone)) {
-            //create instances of CDMA OTA data classes
-            if (cdmaOtaProvisionData == null) {
-                cdmaOtaProvisionData = new OtaUtils.CdmaOtaProvisionData();
-            }
-            if (cdmaOtaConfigData == null) {
-                cdmaOtaConfigData = new OtaUtils.CdmaOtaConfigData();
-            }
-            if (cdmaOtaScreenState == null) {
-                cdmaOtaScreenState = new OtaUtils.CdmaOtaScreenState();
-            }
-            if (cdmaOtaInCallScreenUiState == null) {
-                cdmaOtaInCallScreenUiState = new OtaUtils.CdmaOtaInCallScreenUiState();
-            }
-        } else {
-            //Clean up OTA data in GSM/UMTS. It is valid only for CDMA
-            clearOtaState();
-        }
-
-        ringer.updateRingerContextAfterRadioTechnologyChange(this.phone);
-        notifier.updateCallNotifierRegistrationsAfterRadioTechnologyChange();
-        if (mBtHandsfree != null) {
-            mBtHandsfree.updateBtHandsfreeAfterRadioTechnologyChange();
-        }
-        if (mInCallScreen != null) {
-            mInCallScreen.updateAfterRadioTechnologyChange();
-        }
-
-        // Update registration for ICC status after radio technology change
-        IccCard sim = phone.getIccCard();
-        if (sim != null) {
-            if (DBG) Log.d(LOG_TAG, "Update registration for ICC status...");
-
-            //Register all events new to the new active phone
-            sim.registerForNetworkLocked(mHandler, EVENT_SIM_NETWORK_LOCKED, null);
-        }
-    }
-
-
-    /**
-     * @return true if a wired headset is currently plugged in.
-     *
-     * @see Intent.ACTION_HEADSET_PLUG (which we listen for in mReceiver.onReceive())
-     */
-    boolean isHeadsetPlugged() {
-        return mIsHeadsetPlugged;
-    }
-
-    /**
-     * @return true if the onscreen UI should currently be showing the
-     * special "bluetooth is active" indication in a couple of places (in
-     * which UI elements turn blue and/or show the bluetooth logo.)
-     *
-     * This depends on the BluetoothHeadset state *and* the current
-     * telephony state; see shouldShowBluetoothIndication().
-     *
-     * @see CallCard
-     * @see NotificationMgr.updateInCallNotification
-     */
-    /* package */ boolean showBluetoothIndication() {
-        return mShowBluetoothIndication;
-    }
-
-    /**
-     * Recomputes the mShowBluetoothIndication flag based on the current
-     * bluetooth state and current telephony state.
-     *
-     * This needs to be called any time the bluetooth headset state or the
-     * telephony state changes.
-     *
-     * @param forceUiUpdate if true, force the UI elements that care
-     *                      about this flag to update themselves.
-     */
-    /* package */ void updateBluetoothIndication(boolean forceUiUpdate) {
-        mShowBluetoothIndication = shouldShowBluetoothIndication(mBluetoothHeadsetState,
-                                                                 mBluetoothHeadsetAudioState,
-                                                                 mCM);
-        if (forceUiUpdate) {
-            // Post Handler messages to the various components that might
-            // need to be refreshed based on the new state.
-            if (isShowingCallScreen()) mInCallScreen.requestUpdateBluetoothIndication();
-            if (DBG) Log.d (LOG_TAG, "- updating in-call notification for BT state change...");
-            mHandler.sendEmptyMessage(EVENT_UPDATE_INCALL_NOTIFICATION);
-        }
-
-        // Update the Proximity sensor based on Bluetooth audio state
-        updateProximitySensorMode(mCM.getState());
-    }
-
-    /**
-     * UI policy helper function for the couple of places in the UI that
-     * have some way of indicating that "bluetooth is in use."
-     *
-     * @return true if the onscreen UI should indicate that "bluetooth is in use",
-     *         based on the specified bluetooth headset state, and the
-     *         current state of the phone.
-     * @see showBluetoothIndication()
-     */
-    private static boolean shouldShowBluetoothIndication(int bluetoothState,
-                                                         int bluetoothAudioState,
-                                                         CallManager cm) {
-        // We want the UI to indicate that "bluetooth is in use" in two
-        // slightly different cases:
-        //
-        // (a) The obvious case: if a bluetooth headset is currently in
-        //     use for an ongoing call.
-        //
-        // (b) The not-so-obvious case: if an incoming call is ringing,
-        //     and we expect that audio *will* be routed to a bluetooth
-        //     headset once the call is answered.
-
-        switch (cm.getState()) {
-            case OFFHOOK:
-                // This covers normal active calls, and also the case if
-                // the foreground call is DIALING or ALERTING.  In this
-                // case, bluetooth is considered "active" if a headset
-                // is connected *and* audio is being routed to it.
-                return ((bluetoothState == BluetoothHeadset.STATE_CONNECTED)
-                        && (bluetoothAudioState == BluetoothHeadset.STATE_AUDIO_CONNECTED));
-
-            case RINGING:
-                // If an incoming call is ringing, we're *not* yet routing
-                // audio to the headset (since there's no in-call audio
-                // yet!)  In this case, if a bluetooth headset is
-                // connected at all, we assume that it'll become active
-                // once the user answers the phone.
-                return (bluetoothState == BluetoothHeadset.STATE_CONNECTED);
-
-            default:  // Presumably IDLE
-                return false;
-        }
-    }
-
-
-    /**
-     * Receiver for misc intent broadcasts the Phone app cares about.
-     */
-    private class PhoneAppBroadcastReceiver extends BroadcastReceiver {
-        @Override
-        public void onReceive(Context context, Intent intent) {
-            String action = intent.getAction();
-            if (action.equals(Intent.ACTION_AIRPLANE_MODE_CHANGED)) {
-                boolean enabled = System.getInt(getContentResolver(),
-                        System.AIRPLANE_MODE_ON, 0) == 0;
-                phone.setRadioPower(enabled);
-            } else if (action.equals(BluetoothHeadset.ACTION_CONNECTION_STATE_CHANGED)) {
-                mBluetoothHeadsetState = intent.getIntExtra(BluetoothHeadset.EXTRA_STATE,
-                                                          BluetoothHeadset.STATE_DISCONNECTED);
-                if (VDBG) Log.d(LOG_TAG, "mReceiver: HEADSET_STATE_CHANGED_ACTION");
-                if (VDBG) Log.d(LOG_TAG, "==> new state: " + mBluetoothHeadsetState);
-                updateBluetoothIndication(true);  // Also update any visible UI if necessary
-            } else if (action.equals(BluetoothHeadset.ACTION_AUDIO_STATE_CHANGED)) {
-                mBluetoothHeadsetAudioState =
-                        intent.getIntExtra(BluetoothHeadset.EXTRA_STATE,
-                                           BluetoothHeadset.STATE_AUDIO_DISCONNECTED);
-                if (VDBG) Log.d(LOG_TAG, "mReceiver: HEADSET_AUDIO_STATE_CHANGED_ACTION");
-                if (VDBG) Log.d(LOG_TAG, "==> new state: " + mBluetoothHeadsetAudioState);
-                updateBluetoothIndication(true);  // Also update any visible UI if necessary
-            } else if (action.equals(TelephonyIntents.ACTION_ANY_DATA_CONNECTION_STATE_CHANGED)) {
-                if (VDBG) Log.d(LOG_TAG, "mReceiver: ACTION_ANY_DATA_CONNECTION_STATE_CHANGED");
-                if (VDBG) Log.d(LOG_TAG, "- state: " + intent.getStringExtra(PhoneConstants.STATE_KEY));
-                if (VDBG) Log.d(LOG_TAG, "- reason: "
-                                + intent.getStringExtra(PhoneConstants.STATE_CHANGE_REASON_KEY));
-
-                // The "data disconnected due to roaming" notification is shown
-                // if (a) you have the "data roaming" feature turned off, and
-                // (b) you just lost data connectivity because you're roaming.
-                boolean disconnectedDueToRoaming =
-                        !phone.getDataRoamingEnabled()
-                        && "DISCONNECTED".equals(intent.getStringExtra(PhoneConstants.STATE_KEY))
-                        && Phone.REASON_ROAMING_ON.equals(
-                            intent.getStringExtra(PhoneConstants.STATE_CHANGE_REASON_KEY));
-                mHandler.sendEmptyMessage(disconnectedDueToRoaming
-                                          ? EVENT_DATA_ROAMING_DISCONNECTED
-                                          : EVENT_DATA_ROAMING_OK);
-            } else if (action.equals(Intent.ACTION_HEADSET_PLUG)) {
-                if (VDBG) Log.d(LOG_TAG, "mReceiver: ACTION_HEADSET_PLUG");
-                if (VDBG) Log.d(LOG_TAG, "    state: " + intent.getIntExtra("state", 0));
-                if (VDBG) Log.d(LOG_TAG, "    name: " + intent.getStringExtra("name"));
-                mIsHeadsetPlugged = (intent.getIntExtra("state", 0) == 1);
-                mHandler.sendMessage(mHandler.obtainMessage(EVENT_WIRED_HEADSET_PLUG, 0));
-            } else if ((action.equals(TelephonyIntents.ACTION_SIM_STATE_CHANGED)) &&
-                    (mPUKEntryActivity != null)) {
-                // if an attempt to un-PUK-lock the device was made, while we're
-                // receiving this state change notification, notify the handler.
-                // NOTE: This is ONLY triggered if an attempt to un-PUK-lock has
-                // been attempted.
-                mHandler.sendMessage(mHandler.obtainMessage(EVENT_SIM_STATE_CHANGED,
-                        intent.getStringExtra(IccCardConstants.INTENT_KEY_ICC_STATE)));
-            } else if (action.equals(TelephonyIntents.ACTION_RADIO_TECHNOLOGY_CHANGED)) {
-                String newPhone = intent.getStringExtra(PhoneConstants.PHONE_NAME_KEY);
-                Log.d(LOG_TAG, "Radio technology switched. Now " + newPhone + " is active.");
-                initForNewRadioTechnology();
-            } else if (action.equals(TelephonyIntents.ACTION_SERVICE_STATE_CHANGED)) {
-                handleServiceStateChanged(intent);
-            } else if (action.equals(TelephonyIntents.ACTION_EMERGENCY_CALLBACK_MODE_CHANGED)) {
-                if (TelephonyCapabilities.supportsEcm(phone)) {
-                    Log.d(LOG_TAG, "Emergency Callback Mode arrived in PhoneApp.");
-                    // Start Emergency Callback Mode service
-                    if (intent.getBooleanExtra("phoneinECMState", false)) {
-                        context.startService(new Intent(context,
-                                EmergencyCallbackModeService.class));
-                    }
-                } else {
-                    // It doesn't make sense to get ACTION_EMERGENCY_CALLBACK_MODE_CHANGED
-                    // on a device that doesn't support ECM in the first place.
-                    Log.e(LOG_TAG, "Got ACTION_EMERGENCY_CALLBACK_MODE_CHANGED, "
-                          + "but ECM isn't supported for phone: " + phone.getPhoneName());
-                }
-            } else if (action.equals(Intent.ACTION_DOCK_EVENT)) {
-                mDockState = intent.getIntExtra(Intent.EXTRA_DOCK_STATE,
-                        Intent.EXTRA_DOCK_STATE_UNDOCKED);
-                if (VDBG) Log.d(LOG_TAG, "ACTION_DOCK_EVENT -> mDockState = " + mDockState);
-                mHandler.sendMessage(mHandler.obtainMessage(EVENT_DOCK_STATE_CHANGED, 0));
-            } else if (action.equals(TtyIntent.TTY_PREFERRED_MODE_CHANGE_ACTION)) {
-                mPreferredTtyMode = intent.getIntExtra(TtyIntent.TTY_PREFFERED_MODE,
-                                                       Phone.TTY_MODE_OFF);
-                if (VDBG) Log.d(LOG_TAG, "mReceiver: TTY_PREFERRED_MODE_CHANGE_ACTION");
-                if (VDBG) Log.d(LOG_TAG, "    mode: " + mPreferredTtyMode);
-                mHandler.sendMessage(mHandler.obtainMessage(EVENT_TTY_PREFERRED_MODE_CHANGED, 0));
-            } else if (action.equals(AudioManager.RINGER_MODE_CHANGED_ACTION)) {
-                int ringerMode = intent.getIntExtra(AudioManager.EXTRA_RINGER_MODE,
-                        AudioManager.RINGER_MODE_NORMAL);
-                if (ringerMode == AudioManager.RINGER_MODE_SILENT) {
-                    notifier.silenceRinger();
-                }
-            }
-        }
-    }
-
-    /**
-     * Broadcast receiver for the ACTION_MEDIA_BUTTON broadcast intent.
-     *
-     * This functionality isn't lumped in with the other intents in
-     * PhoneAppBroadcastReceiver because we instantiate this as a totally
-     * separate BroadcastReceiver instance, since we need to manually
-     * adjust its IntentFilter's priority (to make sure we get these
-     * intents *before* the media player.)
-     */
-    private class MediaButtonBroadcastReceiver extends BroadcastReceiver {
-        @Override
-        public void onReceive(Context context, Intent intent) {
-            KeyEvent event = (KeyEvent) intent.getParcelableExtra(Intent.EXTRA_KEY_EVENT);
-            if (VDBG) Log.d(LOG_TAG,
-                           "MediaButtonBroadcastReceiver.onReceive()...  event = " + event);
-            if ((event != null)
-                && (event.getKeyCode() == KeyEvent.KEYCODE_HEADSETHOOK)) {
-                if (VDBG) Log.d(LOG_TAG, "MediaButtonBroadcastReceiver: HEADSETHOOK");
-                boolean consumed = PhoneUtils.handleHeadsetHook(phone, event);
-                if (VDBG) Log.d(LOG_TAG, "==> handleHeadsetHook(): consumed = " + consumed);
-                if (consumed) {
-                    // If a headset is attached and the press is consumed, also update
-                    // any UI items (such as an InCallScreen mute button) that may need to
-                    // be updated if their state changed.
-                    updateInCallScreen();  // Has no effect if the InCallScreen isn't visible
-                    abortBroadcast();
-                }
-            } else {
-                if (mCM.getState() != PhoneConstants.State.IDLE) {
-                    // If the phone is anything other than completely idle,
-                    // then we consume and ignore any media key events,
-                    // Otherwise it is too easy to accidentally start
-                    // playing music while a phone call is in progress.
-                    if (VDBG) Log.d(LOG_TAG, "MediaButtonBroadcastReceiver: consumed");
-                    abortBroadcast();
-                }
-            }
-        }
-    }
-
-    /**
-     * Accepts broadcast Intents which will be prepared by {@link NotificationMgr} and thus
-     * sent from framework's notification mechanism (which is outside Phone context).
-     * This should be visible from outside, but shouldn't be in "exported" state.
-     *
-     * TODO: If possible merge this into PhoneAppBroadcastReceiver.
-     */
-    public static class NotificationBroadcastReceiver extends BroadcastReceiver {
-        @Override
-        public void onReceive(Context context, Intent intent) {
-            String action = intent.getAction();
-            // TODO: use "if (VDBG)" here.
-            Log.d(LOG_TAG, "Broadcast from Notification: " + action);
-
-            if (action.equals(ACTION_HANG_UP_ONGOING_CALL)) {
-                PhoneUtils.hangup(PhoneApp.getInstance().mCM);
-            } else if (action.equals(ACTION_CALL_BACK_FROM_NOTIFICATION)) {
-                // Collapse the expanded notification and the notification item itself.
-                closeSystemDialogs(context);
-                clearMissedCallNotification(context);
-
-                Intent callIntent = new Intent(Intent.ACTION_CALL_PRIVILEGED, intent.getData());
-                callIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK
-                        | Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
-                context.startActivity(callIntent);
-            } else if (action.equals(ACTION_SEND_SMS_FROM_NOTIFICATION)) {
-                // Collapse the expanded notification and the notification item itself.
-                closeSystemDialogs(context);
-                clearMissedCallNotification(context);
-
-                Intent smsIntent = new Intent(Intent.ACTION_SENDTO, intent.getData());
-                smsIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
-                context.startActivity(smsIntent);
-            } else {
-                Log.w(LOG_TAG, "Received hang-up request from notification,"
-                        + " but there's no call the system can hang up.");
-            }
-        }
-
-        private void closeSystemDialogs(Context context) {
-            Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
-            context.sendBroadcast(intent);
-        }
-
-        private void clearMissedCallNotification(Context context) {
-            Intent clearIntent = new Intent(context, ClearMissedCallsService.class);
-            clearIntent.setAction(ClearMissedCallsService.ACTION_CLEAR_MISSED_CALLS);
-            context.startService(clearIntent);
-        }
-    }
-
-    private void handleServiceStateChanged(Intent intent) {
-        /**
-         * This used to handle updating EriTextWidgetProvider this routine
-         * and and listening for ACTION_SERVICE_STATE_CHANGED intents could
-         * be removed. But leaving just in case it might be needed in the near
-         * future.
-         */
-
-        // If service just returned, start sending out the queued messages
-        ServiceState ss = ServiceState.newFromBundle(intent.getExtras());
-
-        if (ss != null) {
-            int state = ss.getState();
-            notificationMgr.updateNetworkSelection(state);
-        }
-    }
-
-    public boolean isOtaCallInActiveState() {
-        boolean otaCallActive = false;
-        if (mInCallScreen != null) {
-            otaCallActive = mInCallScreen.isOtaCallInActiveState();
-        }
-        if (VDBG) Log.d(LOG_TAG, "- isOtaCallInActiveState " + otaCallActive);
-        return otaCallActive;
-    }
-
-    public boolean isOtaCallInEndState() {
-        boolean otaCallEnded = false;
-        if (mInCallScreen != null) {
-            otaCallEnded = mInCallScreen.isOtaCallInEndState();
-        }
-        if (VDBG) Log.d(LOG_TAG, "- isOtaCallInEndState " + otaCallEnded);
-        return otaCallEnded;
-    }
-
-    // it is safe to call clearOtaState() even if the InCallScreen isn't active
-    public void clearOtaState() {
-        if (DBG) Log.d(LOG_TAG, "- clearOtaState ...");
-        if ((mInCallScreen != null)
-                && (otaUtils != null)) {
-            otaUtils.cleanOtaScreen(true);
-            if (DBG) Log.d(LOG_TAG, "  - clearOtaState clears OTA screen");
-        }
-    }
-
-    // it is safe to call dismissOtaDialogs() even if the InCallScreen isn't active
-    public void dismissOtaDialogs() {
-        if (DBG) Log.d(LOG_TAG, "- dismissOtaDialogs ...");
-        if ((mInCallScreen != null)
-                && (otaUtils != null)) {
-            otaUtils.dismissAllOtaDialogs();
-            if (DBG) Log.d(LOG_TAG, "  - dismissOtaDialogs clears OTA dialogs");
-        }
-    }
-
-    // it is safe to call clearInCallScreenMode() even if the InCallScreen isn't active
-    public void clearInCallScreenMode() {
-        if (DBG) Log.d(LOG_TAG, "- clearInCallScreenMode ...");
-        if (mInCallScreen != null) {
-            mInCallScreen.resetInCallScreenMode();
-        }
-    }
-
-    /**
-     * Force the in-call UI to refresh itself, if it's currently visible.
-     *
-     * This method can be used any time there's a state change anywhere in
-     * the phone app that needs to be reflected in the onscreen UI.
-     *
-     * Note that it's *not* necessary to manually refresh the in-call UI
-     * (via this method) for regular telephony state changes like
-     * DIALING -> ALERTING -> ACTIVE, since the InCallScreen already
-     * listens for those state changes itself.
-     *
-     * This method does *not* force the in-call UI to come up if it's not
-     * already visible.  To do that, use displayCallScreen().
-     */
-    /* package */ void updateInCallScreen() {
-        if (DBG) Log.d(LOG_TAG, "- updateInCallScreen()...");
-        if (mInCallScreen != null) {
-            // Post an updateScreen() request.  Note that the
-            // updateScreen() call will end up being a no-op if the
-            // InCallScreen isn't the foreground activity.
-            mInCallScreen.requestUpdateScreen();
-        }
-    }
-
-    private void handleQueryTTYModeResponse(Message msg) {
-        AsyncResult ar = (AsyncResult) msg.obj;
-        if (ar.exception != null) {
-            if (DBG) Log.d(LOG_TAG, "handleQueryTTYModeResponse: Error getting TTY state.");
-        } else {
-            if (DBG) Log.d(LOG_TAG,
-                           "handleQueryTTYModeResponse: TTY enable state successfully queried.");
-
-            int ttymode = ((int[]) ar.result)[0];
-            if (DBG) Log.d(LOG_TAG, "handleQueryTTYModeResponse:ttymode=" + ttymode);
-
-            Intent ttyModeChanged = new Intent(TtyIntent.TTY_ENABLED_CHANGE_ACTION);
-            ttyModeChanged.putExtra("ttyEnabled", ttymode != Phone.TTY_MODE_OFF);
-            sendBroadcast(ttyModeChanged);
-
-            String audioTtyMode;
-            switch (ttymode) {
-            case Phone.TTY_MODE_FULL:
-                audioTtyMode = "tty_full";
-                break;
-            case Phone.TTY_MODE_VCO:
-                audioTtyMode = "tty_vco";
-                break;
-            case Phone.TTY_MODE_HCO:
-                audioTtyMode = "tty_hco";
-                break;
-            case Phone.TTY_MODE_OFF:
-            default:
-                audioTtyMode = "tty_off";
-                break;
-            }
-            AudioManager audioManager = (AudioManager) getSystemService(Context.AUDIO_SERVICE);
-            audioManager.setParameters("tty_mode="+audioTtyMode);
-        }
-    }
-
-    private void handleSetTTYModeResponse(Message msg) {
-        AsyncResult ar = (AsyncResult) msg.obj;
-
-        if (ar.exception != null) {
-            if (DBG) Log.d (LOG_TAG,
-                    "handleSetTTYModeResponse: Error setting TTY mode, ar.exception"
-                    + ar.exception);
-        }
-        phone.queryTTYMode(mHandler.obtainMessage(EVENT_TTY_MODE_GET));
-    }
-
-    /* package */ void clearUserActivityTimeout() {
-        try {
-            mPowerManagerService.clearUserActivityTimeout(SystemClock.uptimeMillis(),
-                    10*1000 /* 10 sec */);
-        } catch (RemoteException ex) {
-            // System process is dead.
-        }
-    }
-
-    /**
-     * "Call origin" may be used by Contacts app to specify where the phone call comes from.
-     * Currently, the only permitted value for this extra is {@link #ALLOWED_EXTRA_CALL_ORIGIN}.
-     * Any other value will be ignored, to make sure that malicious apps can't trick the in-call
-     * UI into launching some random other app after a call ends.
-     *
-     * TODO: make this more generic. Note that we should let the "origin" specify its package
-     * while we are now assuming it is "com.android.contacts"
-     */
-    public static final String EXTRA_CALL_ORIGIN = "com.android.phone.CALL_ORIGIN";
-    private static final String DEFAULT_CALL_ORIGIN_PACKAGE = "com.android.contacts";
-    private static final String ALLOWED_EXTRA_CALL_ORIGIN =
-            "com.android.contacts.activities.DialtactsActivity";
-    /**
-     * Used to determine if the preserved call origin is fresh enough.
-     */
-    private static final long CALL_ORIGIN_EXPIRATION_MILLIS = 30 * 1000;
-
-    public void setLatestActiveCallOrigin(String callOrigin) {
-        inCallUiState.latestActiveCallOrigin = callOrigin;
-        if (callOrigin != null) {
-            inCallUiState.latestActiveCallOriginTimeStamp = SystemClock.elapsedRealtime();
-        } else {
-            inCallUiState.latestActiveCallOriginTimeStamp = 0;
-        }
-    }
-
-    /**
-     * Reset call origin depending on its timestamp.
-     *
-     * See if the current call origin preserved by the app is fresh enough or not. If it is,
-     * previous call origin will be used as is. If not, call origin will be reset.
-     *
-     * This will be effective especially for 3rd party apps which want to bypass phone calls with
-     * their own telephone lines. In that case Phone app may finish the phone call once and make
-     * another for the external apps, which will drop call origin information in Intent.
-     * Even in that case we are sure the second phone call should be initiated just after the first
-     * phone call, so here we restore it from the previous information iff the second call is done
-     * fairly soon.
-     */
-    public void resetLatestActiveCallOrigin() {
-        final long callOriginTimestamp = inCallUiState.latestActiveCallOriginTimeStamp;
-        final long currentTimestamp = SystemClock.elapsedRealtime();
-        if (VDBG) {
-            Log.d(LOG_TAG, "currentTimeMillis: " + currentTimestamp
-                    + ", saved timestamp for call origin: " + callOriginTimestamp);
-        }
-        if (inCallUiState.latestActiveCallOriginTimeStamp > 0
-                && (currentTimestamp - callOriginTimestamp < CALL_ORIGIN_EXPIRATION_MILLIS)) {
-            if (VDBG) {
-                Log.d(LOG_TAG, "Resume previous call origin (" +
-                        inCallUiState.latestActiveCallOrigin + ")");
-            }
-            // Do nothing toward call origin itself but update the timestamp just in case.
-            inCallUiState.latestActiveCallOriginTimeStamp = currentTimestamp;
-        } else {
-            if (VDBG) Log.d(LOG_TAG, "Drop previous call origin and set the current one to null");
-            setLatestActiveCallOrigin(null);
-        }
-    }
-
-    /**
-     * @return Intent which will be used when in-call UI is shown and the phone call is hang up.
-     * By default CallLog screen will be introduced, but the destination may change depending on
-     * its latest call origin state.
-     */
-    public Intent createPhoneEndIntentUsingCallOrigin() {
-        if (TextUtils.equals(inCallUiState.latestActiveCallOrigin, ALLOWED_EXTRA_CALL_ORIGIN)) {
-            if (VDBG) Log.d(LOG_TAG, "Valid latestActiveCallOrigin("
-                    + inCallUiState.latestActiveCallOrigin + ") was found. "
-                    + "Go back to the previous screen.");
-            // Right now we just launch the Activity which launched in-call UI. Note that we're
-            // assuming the origin is from "com.android.contacts", which may be incorrect in the
-            // future.
-            final Intent intent = new Intent();
-            intent.setClassName(DEFAULT_CALL_ORIGIN_PACKAGE, inCallUiState.latestActiveCallOrigin);
-            return intent;
-        } else {
-            if (VDBG) Log.d(LOG_TAG, "Current latestActiveCallOrigin ("
-                    + inCallUiState.latestActiveCallOrigin + ") is not valid. "
-                    + "Just use CallLog as a default destination.");
-            return PhoneApp.createCallLogIntent();
-        }
-    }
 }
diff --git a/src/com/android/phone/PhoneGlobals.java b/src/com/android/phone/PhoneGlobals.java
new file mode 100644
index 0000000..acfdd7e
--- /dev/null
+++ b/src/com/android/phone/PhoneGlobals.java
@@ -0,0 +1,1850 @@
+/*
+ * Copyright (C) 2006 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.app.Activity;
+import android.app.KeyguardManager;
+import android.app.PendingIntent;
+import android.app.ProgressDialog;
+import android.bluetooth.BluetoothAdapter;
+import android.bluetooth.BluetoothHeadset;
+import android.bluetooth.BluetoothProfile;
+import android.bluetooth.IBluetoothHeadsetPhone;
+import android.content.ActivityNotFoundException;
+import android.content.BroadcastReceiver;
+import android.content.ComponentName;
+import android.content.ContentResolver;
+import android.content.Context;
+import android.content.ContextWrapper;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.content.ServiceConnection;
+import android.content.res.Configuration;
+import android.media.AudioManager;
+import android.net.Uri;
+import android.os.AsyncResult;
+import android.os.Binder;
+import android.os.Handler;
+import android.os.IBinder;
+import android.os.IPowerManager;
+import android.os.Message;
+import android.os.PowerManager;
+import android.os.RemoteException;
+import android.os.ServiceManager;
+import android.os.SystemClock;
+import android.os.SystemProperties;
+import android.os.UpdateLock;
+import android.os.UserHandle;
+import android.preference.PreferenceManager;
+import android.provider.Settings.System;
+import android.telephony.ServiceState;
+import android.text.TextUtils;
+import android.util.Log;
+import android.util.Slog;
+import android.view.KeyEvent;
+
+import com.android.internal.telephony.Call;
+import com.android.internal.telephony.CallManager;
+import com.android.internal.telephony.IccCard;
+import com.android.internal.telephony.IccCardConstants;
+import com.android.internal.telephony.MmiCode;
+import com.android.internal.telephony.Phone;
+import com.android.internal.telephony.PhoneConstants;
+import com.android.internal.telephony.PhoneFactory;
+import com.android.internal.telephony.TelephonyCapabilities;
+import com.android.internal.telephony.TelephonyIntents;
+import com.android.internal.telephony.cdma.TtyIntent;
+import com.android.phone.OtaUtils.CdmaOtaScreenState;
+import com.android.server.sip.SipService;
+
+/**
+ * Global state for the telephony subsystem when running in the primary
+ * phone process.
+ */
+public class PhoneGlobals extends ContextWrapper
+        implements AccelerometerListener.OrientationListener {
+    /* package */ static final String LOG_TAG = "PhoneApp";
+
+    /**
+     * Phone app-wide debug level:
+     *   0 - no debug logging
+     *   1 - normal debug logging if ro.debuggable is set (which is true in
+     *       "eng" and "userdebug" builds but not "user" builds)
+     *   2 - ultra-verbose debug logging
+     *
+     * Most individual classes in the phone app have a local DBG constant,
+     * typically set to
+     *   (PhoneApp.DBG_LEVEL >= 1) && (SystemProperties.getInt("ro.debuggable", 0) == 1)
+     * or else
+     *   (PhoneApp.DBG_LEVEL >= 2)
+     * depending on the desired verbosity.
+     *
+     * ***** DO NOT SUBMIT WITH DBG_LEVEL > 0 *************
+     */
+    /* package */ static final int DBG_LEVEL = 0;
+
+    private static final boolean DBG =
+            (PhoneGlobals.DBG_LEVEL >= 1) && (SystemProperties.getInt("ro.debuggable", 0) == 1);
+    private static final boolean VDBG = (PhoneGlobals.DBG_LEVEL >= 2);
+
+    // Message codes; see mHandler below.
+    private static final int EVENT_SIM_NETWORK_LOCKED = 3;
+    private static final int EVENT_WIRED_HEADSET_PLUG = 7;
+    private static final int EVENT_SIM_STATE_CHANGED = 8;
+    private static final int EVENT_UPDATE_INCALL_NOTIFICATION = 9;
+    private static final int EVENT_DATA_ROAMING_DISCONNECTED = 10;
+    private static final int EVENT_DATA_ROAMING_OK = 11;
+    private static final int EVENT_UNSOL_CDMA_INFO_RECORD = 12;
+    private static final int EVENT_DOCK_STATE_CHANGED = 13;
+    private static final int EVENT_TTY_PREFERRED_MODE_CHANGED = 14;
+    private static final int EVENT_TTY_MODE_GET = 15;
+    private static final int EVENT_TTY_MODE_SET = 16;
+    private static final int EVENT_START_SIP_SERVICE = 17;
+
+    // The MMI codes are also used by the InCallScreen.
+    public static final int MMI_INITIATE = 51;
+    public static final int MMI_COMPLETE = 52;
+    public static final int MMI_CANCEL = 53;
+    // Don't use message codes larger than 99 here; those are reserved for
+    // the individual Activities of the Phone UI.
+
+    /**
+     * Allowable values for the wake lock code.
+     *   SLEEP means the device can be put to sleep.
+     *   PARTIAL means wake the processor, but we display can be kept off.
+     *   FULL means wake both the processor and the display.
+     */
+    public enum WakeState {
+        SLEEP,
+        PARTIAL,
+        FULL
+    }
+
+    /**
+     * Intent Action used for hanging up the current call from Notification bar. This will
+     * choose first ringing call, first active call, or first background call (typically in
+     * HOLDING state).
+     */
+    public static final String ACTION_HANG_UP_ONGOING_CALL =
+            "com.android.phone.ACTION_HANG_UP_ONGOING_CALL";
+
+    /**
+     * Intent Action used for making a phone call from Notification bar.
+     * This is for missed call notifications.
+     */
+    public static final String ACTION_CALL_BACK_FROM_NOTIFICATION =
+            "com.android.phone.ACTION_CALL_BACK_FROM_NOTIFICATION";
+
+    /**
+     * Intent Action used for sending a SMS from notification bar.
+     * This is for missed call notifications.
+     */
+    public static final String ACTION_SEND_SMS_FROM_NOTIFICATION =
+            "com.android.phone.ACTION_SEND_SMS_FROM_NOTIFICATION";
+
+    private static PhoneGlobals sMe;
+
+    // A few important fields we expose to the rest of the package
+    // directly (rather than thru set/get methods) for efficiency.
+    Phone phone;
+    CallController callController;
+    InCallUiState inCallUiState;
+    CallerInfoCache callerInfoCache;
+    CallNotifier notifier;
+    NotificationMgr notificationMgr;
+    Ringer ringer;
+    IBluetoothHeadsetPhone mBluetoothPhone;
+    PhoneInterfaceManager phoneMgr;
+    CallManager mCM;
+    int mBluetoothHeadsetState = BluetoothProfile.STATE_DISCONNECTED;
+    int mBluetoothHeadsetAudioState = BluetoothHeadset.STATE_AUDIO_DISCONNECTED;
+    boolean mShowBluetoothIndication = false;
+    static int mDockState = Intent.EXTRA_DOCK_STATE_UNDOCKED;
+    static boolean sVoiceCapable = true;
+
+    // Internal PhoneApp Call state tracker
+    CdmaPhoneCallState cdmaPhoneCallState;
+
+    // The InCallScreen instance (or null if the InCallScreen hasn't been
+    // created yet.)
+    private InCallScreen mInCallScreen;
+
+    // The currently-active PUK entry activity and progress dialog.
+    // Normally, these are the Emergency Dialer and the subsequent
+    // progress dialog.  null if there is are no such objects in
+    // the foreground.
+    private Activity mPUKEntryActivity;
+    private ProgressDialog mPUKEntryProgressDialog;
+
+    private boolean mIsSimPinEnabled;
+    private String mCachedSimPin;
+
+    // True if a wired headset is currently plugged in, based on the state
+    // from the latest Intent.ACTION_HEADSET_PLUG broadcast we received in
+    // mReceiver.onReceive().
+    private boolean mIsHeadsetPlugged;
+
+    // True if the keyboard is currently *not* hidden
+    // Gets updated whenever there is a Configuration change
+    private boolean mIsHardKeyboardOpen;
+
+    // True if we are beginning a call, but the phone state has not changed yet
+    private boolean mBeginningCall;
+
+    // Last phone state seen by updatePhoneState()
+    private PhoneConstants.State mLastPhoneState = PhoneConstants.State.IDLE;
+
+    private WakeState mWakeState = WakeState.SLEEP;
+
+    private PowerManager mPowerManager;
+    private IPowerManager mPowerManagerService;
+    private PowerManager.WakeLock mWakeLock;
+    private PowerManager.WakeLock mPartialWakeLock;
+    private PowerManager.WakeLock mProximityWakeLock;
+    private KeyguardManager mKeyguardManager;
+    private AccelerometerListener mAccelerometerListener;
+    private int mOrientation = AccelerometerListener.ORIENTATION_UNKNOWN;
+
+    private UpdateLock mUpdateLock;
+
+    // Broadcast receiver for various intent broadcasts (see onCreate())
+    private final BroadcastReceiver mReceiver = new PhoneAppBroadcastReceiver();
+
+    // Broadcast receiver purely for ACTION_MEDIA_BUTTON broadcasts
+    private final BroadcastReceiver mMediaButtonReceiver = new MediaButtonBroadcastReceiver();
+
+    /** boolean indicating restoring mute state on InCallScreen.onResume() */
+    private boolean mShouldRestoreMuteOnInCallResume;
+
+    /**
+     * The singleton OtaUtils instance used for OTASP calls.
+     *
+     * The OtaUtils instance is created lazily the first time we need to
+     * make an OTASP call, regardless of whether it's an interactive or
+     * non-interactive OTASP call.
+     */
+    public OtaUtils otaUtils;
+
+    // Following are the CDMA OTA information Objects used during OTA Call.
+    // cdmaOtaProvisionData object store static OTA information that needs
+    // to be maintained even during Slider open/close scenarios.
+    // cdmaOtaConfigData object stores configuration info to control visiblity
+    // of each OTA Screens.
+    // cdmaOtaScreenState object store OTA Screen State information.
+    public OtaUtils.CdmaOtaProvisionData cdmaOtaProvisionData;
+    public OtaUtils.CdmaOtaConfigData cdmaOtaConfigData;
+    public OtaUtils.CdmaOtaScreenState cdmaOtaScreenState;
+    public OtaUtils.CdmaOtaInCallScreenUiState cdmaOtaInCallScreenUiState;
+
+    // TTY feature enabled on this platform
+    private boolean mTtyEnabled;
+    // Current TTY operating mode selected by user
+    private int mPreferredTtyMode = Phone.TTY_MODE_OFF;
+
+    /**
+     * Set the restore mute state flag. Used when we are setting the mute state
+     * OUTSIDE of user interaction {@link PhoneUtils#startNewCall(Phone)}
+     */
+    /*package*/void setRestoreMuteOnInCallResume (boolean mode) {
+        mShouldRestoreMuteOnInCallResume = mode;
+    }
+
+    /**
+     * Get the restore mute state flag.
+     * This is used by the InCallScreen {@link InCallScreen#onResume()} to figure
+     * out if we need to restore the mute state for the current active call.
+     */
+    /*package*/boolean getRestoreMuteOnInCallResume () {
+        return mShouldRestoreMuteOnInCallResume;
+    }
+
+    Handler mHandler = new Handler() {
+        @Override
+        public void handleMessage(Message msg) {
+            PhoneConstants.State phoneState;
+            switch (msg.what) {
+                // Starts the SIP service. It's a no-op if SIP API is not supported
+                // on the deivce.
+                // TODO: Having the phone process host the SIP service is only
+                // temporary. Will move it to a persistent communication process
+                // later.
+                case EVENT_START_SIP_SERVICE:
+                    SipService.start(getApplicationContext());
+                    break;
+
+                // TODO: This event should be handled by the lock screen, just
+                // like the "SIM missing" and "Sim locked" cases (bug 1804111).
+                case EVENT_SIM_NETWORK_LOCKED:
+                    if (getResources().getBoolean(R.bool.ignore_sim_network_locked_events)) {
+                        // Some products don't have the concept of a "SIM network lock"
+                        Log.i(LOG_TAG, "Ignoring EVENT_SIM_NETWORK_LOCKED event; "
+                              + "not showing 'SIM network unlock' PIN entry screen");
+                    } else {
+                        // Normal case: show the "SIM network unlock" PIN entry screen.
+                        // The user won't be able to do anything else until
+                        // they enter a valid SIM network PIN.
+                        Log.i(LOG_TAG, "show sim depersonal panel");
+                        IccNetworkDepersonalizationPanel ndpPanel =
+                                new IccNetworkDepersonalizationPanel(PhoneGlobals.getInstance());
+                        ndpPanel.show();
+                    }
+                    break;
+
+                case EVENT_UPDATE_INCALL_NOTIFICATION:
+                    // Tell the NotificationMgr to update the "ongoing
+                    // call" icon in the status bar, if necessary.
+                    // Currently, this is triggered by a bluetooth headset
+                    // state change (since the status bar icon needs to
+                    // turn blue when bluetooth is active.)
+                    if (DBG) Log.d (LOG_TAG, "- updating in-call notification from handler...");
+                    notificationMgr.updateInCallNotification();
+                    break;
+
+                case EVENT_DATA_ROAMING_DISCONNECTED:
+                    notificationMgr.showDataDisconnectedRoaming();
+                    break;
+
+                case EVENT_DATA_ROAMING_OK:
+                    notificationMgr.hideDataDisconnectedRoaming();
+                    break;
+
+                case MMI_COMPLETE:
+                    onMMIComplete((AsyncResult) msg.obj);
+                    break;
+
+                case MMI_CANCEL:
+                    PhoneUtils.cancelMmiCode(phone);
+                    break;
+
+                case EVENT_WIRED_HEADSET_PLUG:
+                    // Since the presence of a wired headset or bluetooth affects the
+                    // speakerphone, update the "speaker" state.  We ONLY want to do
+                    // this on the wired headset connect / disconnect events for now
+                    // though, so we're only triggering on EVENT_WIRED_HEADSET_PLUG.
+
+                    phoneState = mCM.getState();
+                    // Do not change speaker state if phone is not off hook
+                    if (phoneState == PhoneConstants.State.OFFHOOK && !isBluetoothHeadsetAudioOn()) {
+                        if (!isHeadsetPlugged()) {
+                            // if the state is "not connected", restore the speaker state.
+                            PhoneUtils.restoreSpeakerMode(getApplicationContext());
+                        } else {
+                            // if the state is "connected", force the speaker off without
+                            // storing the state.
+                            PhoneUtils.turnOnSpeaker(getApplicationContext(), false, false);
+                        }
+                    }
+                    // Update the Proximity sensor based on headset state
+                    updateProximitySensorMode(phoneState);
+
+                    // Force TTY state update according to new headset state
+                    if (mTtyEnabled) {
+                        sendMessage(obtainMessage(EVENT_TTY_PREFERRED_MODE_CHANGED, 0));
+                    }
+                    break;
+
+                case EVENT_SIM_STATE_CHANGED:
+                    // Marks the event where the SIM goes into ready state.
+                    // Right now, this is only used for the PUK-unlocking
+                    // process.
+                    if (msg.obj.equals(IccCardConstants.INTENT_VALUE_ICC_READY)) {
+                        // when the right event is triggered and there
+                        // are UI objects in the foreground, we close
+                        // them to display the lock panel.
+                        if (mPUKEntryActivity != null) {
+                            mPUKEntryActivity.finish();
+                            mPUKEntryActivity = null;
+                        }
+                        if (mPUKEntryProgressDialog != null) {
+                            mPUKEntryProgressDialog.dismiss();
+                            mPUKEntryProgressDialog = null;
+                        }
+                    }
+                    break;
+
+                case EVENT_UNSOL_CDMA_INFO_RECORD:
+                    //TODO: handle message here;
+                    break;
+
+                case EVENT_DOCK_STATE_CHANGED:
+                    // If the phone is docked/undocked during a call, and no wired or BT headset
+                    // is connected: turn on/off the speaker accordingly.
+                    boolean inDockMode = false;
+                    if (mDockState != Intent.EXTRA_DOCK_STATE_UNDOCKED) {
+                        inDockMode = true;
+                    }
+                    if (VDBG) Log.d(LOG_TAG, "received EVENT_DOCK_STATE_CHANGED. Phone inDock = "
+                            + inDockMode);
+
+                    phoneState = mCM.getState();
+                    if (phoneState == PhoneConstants.State.OFFHOOK &&
+                        !isHeadsetPlugged() && !isBluetoothHeadsetAudioOn()) {
+                        PhoneUtils.turnOnSpeaker(getApplicationContext(), inDockMode, true);
+                        updateInCallScreen();  // Has no effect if the InCallScreen isn't visible
+                    }
+                    break;
+
+                case EVENT_TTY_PREFERRED_MODE_CHANGED:
+                    // TTY mode is only applied if a headset is connected
+                    int ttyMode;
+                    if (isHeadsetPlugged()) {
+                        ttyMode = mPreferredTtyMode;
+                    } else {
+                        ttyMode = Phone.TTY_MODE_OFF;
+                    }
+                    phone.setTTYMode(ttyMode, mHandler.obtainMessage(EVENT_TTY_MODE_SET));
+                    break;
+
+                case EVENT_TTY_MODE_GET:
+                    handleQueryTTYModeResponse(msg);
+                    break;
+
+                case EVENT_TTY_MODE_SET:
+                    handleSetTTYModeResponse(msg);
+                    break;
+            }
+        }
+    };
+
+    public PhoneGlobals(Context context) {
+        super(context);
+        sMe = this;
+    }
+
+    public void onCreate() {
+        if (VDBG) Log.v(LOG_TAG, "onCreate()...");
+
+        ContentResolver resolver = getContentResolver();
+
+        // Cache the "voice capable" flag.
+        // This flag currently comes from a resource (which is
+        // overrideable on a per-product basis):
+        sVoiceCapable =
+                getResources().getBoolean(com.android.internal.R.bool.config_voice_capable);
+        // ...but this might eventually become a PackageManager "system
+        // feature" instead, in which case we'd do something like:
+        // sVoiceCapable =
+        //   getPackageManager().hasSystemFeature(PackageManager.FEATURE_TELEPHONY_VOICE_CALLS);
+
+        if (phone == null) {
+            // Initialize the telephony framework
+            PhoneFactory.makeDefaultPhones(this);
+
+            // Get the default phone
+            phone = PhoneFactory.getDefaultPhone();
+
+            // Start TelephonyDebugService After the default phone is created.
+            Intent intent = new Intent(this, TelephonyDebugService.class);
+            startService(intent);
+
+            mCM = CallManager.getInstance();
+            mCM.registerPhone(phone);
+
+            // Create the NotificationMgr singleton, which is used to display
+            // status bar icons and control other status bar behavior.
+            notificationMgr = NotificationMgr.init(this);
+
+            phoneMgr = PhoneInterfaceManager.init(this, phone);
+
+            mHandler.sendEmptyMessage(EVENT_START_SIP_SERVICE);
+
+            int phoneType = phone.getPhoneType();
+
+            if (phoneType == PhoneConstants.PHONE_TYPE_CDMA) {
+                // Create an instance of CdmaPhoneCallState and initialize it to IDLE
+                cdmaPhoneCallState = new CdmaPhoneCallState();
+                cdmaPhoneCallState.CdmaPhoneCallStateInit();
+            }
+
+            if (BluetoothAdapter.getDefaultAdapter() != null) {
+                // Start BluetoothPhoneService even if device is not voice capable.
+                // The device can still support VOIP.
+                startService(new Intent(this, BluetoothPhoneService.class));
+                bindService(new Intent(this, BluetoothPhoneService.class),
+                            mBluetoothPhoneConnection, 0);
+            } else {
+                // Device is not bluetooth capable
+                mBluetoothPhone = null;
+            }
+
+            ringer = Ringer.init(this);
+
+            // before registering for phone state changes
+            mPowerManager = (PowerManager) getSystemService(Context.POWER_SERVICE);
+            mWakeLock = mPowerManager.newWakeLock(PowerManager.FULL_WAKE_LOCK, LOG_TAG);
+            // lock used to keep the processor awake, when we don't care for the display.
+            mPartialWakeLock = mPowerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK
+                    | PowerManager.ON_AFTER_RELEASE, LOG_TAG);
+            // Wake lock used to control proximity sensor behavior.
+            if (mPowerManager.isWakeLockLevelSupported(
+                    PowerManager.PROXIMITY_SCREEN_OFF_WAKE_LOCK)) {
+                mProximityWakeLock = mPowerManager.newWakeLock(
+                        PowerManager.PROXIMITY_SCREEN_OFF_WAKE_LOCK, LOG_TAG);
+            }
+            if (DBG) Log.d(LOG_TAG, "onCreate: mProximityWakeLock: " + mProximityWakeLock);
+
+            // create mAccelerometerListener only if we are using the proximity sensor
+            if (proximitySensorModeEnabled()) {
+                mAccelerometerListener = new AccelerometerListener(this, this);
+            }
+
+            mKeyguardManager = (KeyguardManager) getSystemService(Context.KEYGUARD_SERVICE);
+
+            // get a handle to the service so that we can use it later when we
+            // want to set the poke lock.
+            mPowerManagerService = IPowerManager.Stub.asInterface(
+                    ServiceManager.getService("power"));
+
+            // Get UpdateLock to suppress system-update related events (e.g. dialog show-up)
+            // during phone calls.
+            mUpdateLock = new UpdateLock("phone");
+
+            if (DBG) Log.d(LOG_TAG, "onCreate: mUpdateLock: " + mUpdateLock);
+
+            // Create the CallController singleton, which is the interface
+            // to the telephony layer for user-initiated telephony functionality
+            // (like making outgoing calls.)
+            callController = CallController.init(this);
+            // ...and also the InCallUiState instance, used by the CallController to
+            // keep track of some "persistent state" of the in-call UI.
+            inCallUiState = InCallUiState.init(this);
+
+            // Create the CallerInfoCache singleton, which remembers custom ring tone and
+            // send-to-voicemail settings.
+            //
+            // The asynchronous caching will start just after this call.
+            callerInfoCache = CallerInfoCache.init(this);
+
+            // Create the CallNotifer singleton, which handles
+            // asynchronous events from the telephony layer (like
+            // launching the incoming-call UI when an incoming call comes
+            // in.)
+            notifier = CallNotifier.init(this, phone, ringer, new CallLogAsync());
+
+            // register for ICC status
+            IccCard sim = phone.getIccCard();
+            if (sim != null) {
+                if (VDBG) Log.v(LOG_TAG, "register for ICC status");
+                sim.registerForNetworkLocked(mHandler, EVENT_SIM_NETWORK_LOCKED, null);
+            }
+
+            // register for MMI/USSD
+            mCM.registerForMmiComplete(mHandler, MMI_COMPLETE, null);
+
+            // register connection tracking to PhoneUtils
+            PhoneUtils.initializeConnectionHandler(mCM);
+
+            // Read platform settings for TTY feature
+            mTtyEnabled = getResources().getBoolean(R.bool.tty_enabled);
+
+            // Register for misc other intent broadcasts.
+            IntentFilter intentFilter =
+                    new IntentFilter(Intent.ACTION_AIRPLANE_MODE_CHANGED);
+            intentFilter.addAction(BluetoothHeadset.ACTION_CONNECTION_STATE_CHANGED);
+            intentFilter.addAction(BluetoothHeadset.ACTION_AUDIO_STATE_CHANGED);
+            intentFilter.addAction(TelephonyIntents.ACTION_ANY_DATA_CONNECTION_STATE_CHANGED);
+            intentFilter.addAction(Intent.ACTION_HEADSET_PLUG);
+            intentFilter.addAction(Intent.ACTION_DOCK_EVENT);
+            intentFilter.addAction(TelephonyIntents.ACTION_SIM_STATE_CHANGED);
+            intentFilter.addAction(TelephonyIntents.ACTION_RADIO_TECHNOLOGY_CHANGED);
+            intentFilter.addAction(TelephonyIntents.ACTION_SERVICE_STATE_CHANGED);
+            intentFilter.addAction(TelephonyIntents.ACTION_EMERGENCY_CALLBACK_MODE_CHANGED);
+            if (mTtyEnabled) {
+                intentFilter.addAction(TtyIntent.TTY_PREFERRED_MODE_CHANGE_ACTION);
+            }
+            intentFilter.addAction(AudioManager.RINGER_MODE_CHANGED_ACTION);
+            registerReceiver(mReceiver, intentFilter);
+
+            // Use a separate receiver for ACTION_MEDIA_BUTTON broadcasts,
+            // since we need to manually adjust its priority (to make sure
+            // we get these intents *before* the media player.)
+            IntentFilter mediaButtonIntentFilter =
+                    new IntentFilter(Intent.ACTION_MEDIA_BUTTON);
+            // TODO verify the independent priority doesn't need to be handled thanks to the
+            //  private intent handler registration
+            // Make sure we're higher priority than the media player's
+            // MediaButtonIntentReceiver (which currently has the default
+            // priority of zero; see apps/Music/AndroidManifest.xml.)
+            mediaButtonIntentFilter.setPriority(1);
+            //
+            registerReceiver(mMediaButtonReceiver, mediaButtonIntentFilter);
+            // register the component so it gets priority for calls
+            AudioManager am = (AudioManager) getSystemService(Context.AUDIO_SERVICE);
+            am.registerMediaButtonEventReceiverForCalls(new ComponentName(this.getPackageName(),
+                    MediaButtonBroadcastReceiver.class.getName()));
+
+            //set the default values for the preferences in the phone.
+            PreferenceManager.setDefaultValues(this, R.xml.network_setting, 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);
+        }
+
+        if (TelephonyCapabilities.supportsOtasp(phone)) {
+            cdmaOtaProvisionData = new OtaUtils.CdmaOtaProvisionData();
+            cdmaOtaConfigData = new OtaUtils.CdmaOtaConfigData();
+            cdmaOtaScreenState = new OtaUtils.CdmaOtaScreenState();
+            cdmaOtaInCallScreenUiState = new OtaUtils.CdmaOtaInCallScreenUiState();
+        }
+
+        // XXX pre-load the SimProvider so that it's ready
+        resolver.getType(Uri.parse("content://icc/adn"));
+
+        // start with the default value to set the mute state.
+        mShouldRestoreMuteOnInCallResume = false;
+
+        // TODO: Register for Cdma Information Records
+        // phone.registerCdmaInformationRecord(mHandler, EVENT_UNSOL_CDMA_INFO_RECORD, null);
+
+        // Read TTY settings and store it into BP NV.
+        // AP owns (i.e. stores) the TTY setting in AP settings database and pushes the setting
+        // to BP at power up (BP does not need to make the TTY setting persistent storage).
+        // This way, there is a single owner (i.e AP) for the TTY setting in the phone.
+        if (mTtyEnabled) {
+            mPreferredTtyMode = android.provider.Settings.Secure.getInt(
+                    phone.getContext().getContentResolver(),
+                    android.provider.Settings.Secure.PREFERRED_TTY_MODE,
+                    Phone.TTY_MODE_OFF);
+            mHandler.sendMessage(mHandler.obtainMessage(EVENT_TTY_PREFERRED_MODE_CHANGED, 0));
+        }
+        // Read HAC settings and configure audio hardware
+        if (getResources().getBoolean(R.bool.hac_enabled)) {
+            int hac = android.provider.Settings.System.getInt(phone.getContext().getContentResolver(),
+                                                              android.provider.Settings.System.HEARING_AID,
+                                                              0);
+            AudioManager audioManager = (AudioManager) getSystemService(Context.AUDIO_SERVICE);
+            audioManager.setParameter(CallFeaturesSetting.HAC_KEY, hac != 0 ?
+                                      CallFeaturesSetting.HAC_VAL_ON :
+                                      CallFeaturesSetting.HAC_VAL_OFF);
+        }
+   }
+
+    public void onConfigurationChanged(Configuration newConfig) {
+        if (newConfig.hardKeyboardHidden == Configuration.HARDKEYBOARDHIDDEN_NO) {
+            mIsHardKeyboardOpen = true;
+        } else {
+            mIsHardKeyboardOpen = false;
+        }
+
+        // Update the Proximity sensor based on keyboard state
+        updateProximitySensorMode(mCM.getState());
+    }
+
+    /**
+     * Returns the singleton instance of the PhoneApp.
+     */
+    static PhoneGlobals getInstance() {
+        if (sMe == null) {
+            throw new IllegalStateException("No PhoneGlobals here!");
+        }
+        return sMe;
+    }
+
+    /**
+     * Returns the singleton instance of the PhoneApp if running as the
+     * primary user, otherwise null.
+     */
+    static PhoneGlobals getInstanceIfPrimary() {
+        return sMe;
+    }
+
+    /**
+     * Returns the Phone associated with this instance
+     */
+    static Phone getPhone() {
+        return getInstance().phone;
+    }
+
+    Ringer getRinger() {
+        return ringer;
+    }
+
+    IBluetoothHeadsetPhone getBluetoothPhoneService() {
+        return mBluetoothPhone;
+    }
+
+    boolean isBluetoothHeadsetAudioOn() {
+        return (mBluetoothHeadsetAudioState != BluetoothHeadset.STATE_AUDIO_DISCONNECTED);
+    }
+
+    /**
+     * Returns an Intent that can be used to go to the "Call log"
+     * UI (aka CallLogActivity) in the Contacts app.
+     *
+     * Watch out: there's no guarantee that the system has any activity to
+     * handle this intent.  (In particular there may be no "Call log" at
+     * all on on non-voice-capable devices.)
+     */
+    /* package */ static Intent createCallLogIntent() {
+        Intent intent = new Intent(Intent.ACTION_VIEW, null);
+        intent.setType("vnd.android.cursor.dir/calls");
+        return intent;
+    }
+
+    /**
+     * Return an Intent that can be used to bring up the in-call screen.
+     *
+     * This intent can only be used from within the Phone app, since the
+     * InCallScreen is not exported from our AndroidManifest.
+     */
+    /* package */ static Intent createInCallIntent() {
+        Intent intent = new Intent(Intent.ACTION_MAIN, null);
+        intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK
+                | Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS
+                | Intent.FLAG_ACTIVITY_NO_USER_ACTION);
+        intent.setClassName("com.android.phone", getCallScreenClassName());
+        return intent;
+    }
+
+    /**
+     * Variation of createInCallIntent() that also specifies whether the
+     * DTMF dialpad should be initially visible when the InCallScreen
+     * comes up.
+     */
+    /* package */ static Intent createInCallIntent(boolean showDialpad) {
+        Intent intent = createInCallIntent();
+        intent.putExtra(InCallScreen.SHOW_DIALPAD_EXTRA, showDialpad);
+        return intent;
+    }
+
+    /**
+     * Returns PendingIntent for hanging up ongoing phone call. This will typically be used from
+     * Notification context.
+     */
+    /* package */ static PendingIntent createHangUpOngoingCallPendingIntent(Context context) {
+        Intent intent = new Intent(PhoneGlobals.ACTION_HANG_UP_ONGOING_CALL, null,
+                context, NotificationBroadcastReceiver.class);
+        return PendingIntent.getBroadcast(context, 0, intent, 0);
+    }
+
+    /* package */ static PendingIntent getCallBackPendingIntent(Context context, String number) {
+        Intent intent = new Intent(ACTION_CALL_BACK_FROM_NOTIFICATION,
+                Uri.fromParts(Constants.SCHEME_TEL, number, null),
+                context, NotificationBroadcastReceiver.class);
+        return PendingIntent.getBroadcast(context, 0, intent, 0);
+    }
+
+    /* package */ static PendingIntent getSendSmsFromNotificationPendingIntent(
+            Context context, String number) {
+        Intent intent = new Intent(ACTION_SEND_SMS_FROM_NOTIFICATION,
+                Uri.fromParts(Constants.SCHEME_SMSTO, number, null),
+                context, NotificationBroadcastReceiver.class);
+        return PendingIntent.getBroadcast(context, 0, intent, 0);
+    }
+
+    private static String getCallScreenClassName() {
+        return InCallScreen.class.getName();
+    }
+
+    /**
+     * Starts the InCallScreen Activity.
+     */
+    /* package */ void displayCallScreen() {
+        if (VDBG) Log.d(LOG_TAG, "displayCallScreen()...");
+
+        // On non-voice-capable devices we shouldn't ever be trying to
+        // bring up the InCallScreen in the first place.
+        if (!sVoiceCapable) {
+            Log.w(LOG_TAG, "displayCallScreen() not allowed: non-voice-capable device",
+                  new Throwable("stack dump"));  // Include a stack trace since this warning
+                                                 // indicates a bug in our caller
+            return;
+        }
+
+        try {
+            startActivity(createInCallIntent());
+        } catch (ActivityNotFoundException e) {
+            // It's possible that the in-call UI might not exist (like on
+            // non-voice-capable devices), so don't crash if someone
+            // accidentally tries to bring it up...
+            Log.w(LOG_TAG, "displayCallScreen: transition to InCallScreen failed: " + e);
+        }
+        Profiler.callScreenRequested();
+    }
+
+    boolean isSimPinEnabled() {
+        return mIsSimPinEnabled;
+    }
+
+    boolean authenticateAgainstCachedSimPin(String pin) {
+        return (mCachedSimPin != null && mCachedSimPin.equals(pin));
+    }
+
+    void setCachedSimPin(String pin) {
+        mCachedSimPin = pin;
+    }
+
+    void setInCallScreenInstance(InCallScreen inCallScreen) {
+        mInCallScreen = inCallScreen;
+    }
+
+    /**
+     * @return true if the in-call UI is running as the foreground
+     * activity.  (In other words, from the perspective of the
+     * InCallScreen activity, return true between onResume() and
+     * onPause().)
+     *
+     * Note this method will return false if the screen is currently off,
+     * even if the InCallScreen *was* in the foreground just before the
+     * screen turned off.  (This is because the foreground activity is
+     * always "paused" while the screen is off.)
+     */
+    boolean isShowingCallScreen() {
+        if (mInCallScreen == null) return false;
+        return mInCallScreen.isForegroundActivity();
+    }
+
+    /**
+     * @return true if the in-call UI is running as the foreground activity, or,
+     * it went to background due to screen being turned off. This might be useful
+     * to determine if the in-call screen went to background because of other
+     * activities, or its proximity sensor state or manual power-button press.
+     *
+     * Here are some examples.
+     *
+     * - If you want to know if the activity is in foreground or screen is turned off
+     *   from the in-call UI (i.e. though it is not "foreground" anymore it will become
+     *   so after screen being turned on), check
+     *   {@link #isShowingCallScreenForProximity()} is true or not.
+     *   {@link #updateProximitySensorMode(com.android.internal.telephony.PhoneConstants.State)} is
+     *   doing this.
+     *
+     * - If you want to know if the activity is not in foreground just because screen
+     *   is turned off (not due to other activity's interference), check
+     *   {@link #isShowingCallScreen()} is false *and* {@link #isShowingCallScreenForProximity()}
+     *   is true. InCallScreen#onDisconnect() is doing this check.
+     *
+     * @see #isShowingCallScreen()
+     *
+     * TODO: come up with better naming..
+     */
+    boolean isShowingCallScreenForProximity() {
+        if (mInCallScreen == null) return false;
+        return mInCallScreen.isForegroundActivityForProximity();
+    }
+
+    /**
+     * Dismisses the in-call UI.
+     *
+     * This also ensures that you won't be able to get back to the in-call
+     * UI via the BACK button (since this call removes the InCallScreen
+     * from the activity history.)
+     * For OTA Call, it call InCallScreen api to handle OTA Call End scenario
+     * to display OTA Call End screen.
+     */
+    /* package */ void dismissCallScreen() {
+        if (mInCallScreen != null) {
+            if ((TelephonyCapabilities.supportsOtasp(phone)) &&
+                    (mInCallScreen.isOtaCallInActiveState()
+                    || mInCallScreen.isOtaCallInEndState()
+                    || ((cdmaOtaScreenState != null)
+                    && (cdmaOtaScreenState.otaScreenState
+                            != CdmaOtaScreenState.OtaScreenState.OTA_STATUS_UNDEFINED)))) {
+                // TODO: During OTA Call, display should not become dark to
+                // allow user to see OTA UI update. Phone app needs to hold
+                // a SCREEN_DIM_WAKE_LOCK wake lock during the entire OTA call.
+                wakeUpScreen();
+                // If InCallScreen is not in foreground we resume it to show the OTA call end screen
+                // Fire off the InCallScreen intent
+                displayCallScreen();
+
+                mInCallScreen.handleOtaCallEnd();
+                return;
+            } else {
+                mInCallScreen.finish();
+            }
+        }
+    }
+
+    /**
+     * Handles OTASP-related events from the telephony layer.
+     *
+     * While an OTASP call is active, the CallNotifier forwards
+     * OTASP-related telephony events to this method.
+     */
+    void handleOtaspEvent(Message msg) {
+        if (DBG) Log.d(LOG_TAG, "handleOtaspEvent(message " + msg + ")...");
+
+        if (otaUtils == null) {
+            // We shouldn't be getting OTASP events without ever
+            // having started the OTASP call in the first place!
+            Log.w(LOG_TAG, "handleOtaEvents: got an event but otaUtils is null! "
+                  + "message = " + msg);
+            return;
+        }
+
+        otaUtils.onOtaProvisionStatusChanged((AsyncResult) msg.obj);
+    }
+
+    /**
+     * Similarly, handle the disconnect event of an OTASP call
+     * by forwarding it to the OtaUtils instance.
+     */
+    /* package */ void handleOtaspDisconnect() {
+        if (DBG) Log.d(LOG_TAG, "handleOtaspDisconnect()...");
+
+        if (otaUtils == null) {
+            // We shouldn't be getting OTASP events without ever
+            // having started the OTASP call in the first place!
+            Log.w(LOG_TAG, "handleOtaspDisconnect: otaUtils is null!");
+            return;
+        }
+
+        otaUtils.onOtaspDisconnect();
+    }
+
+    /**
+     * Sets the activity responsible for un-PUK-blocking the device
+     * so that we may close it when we receive a positive result.
+     * mPUKEntryActivity is also used to indicate to the device that
+     * we are trying to un-PUK-lock the phone. In other words, iff
+     * it is NOT null, then we are trying to unlock and waiting for
+     * the SIM to move to READY state.
+     *
+     * @param activity is the activity to close when PUK has
+     * finished unlocking. Can be set to null to indicate the unlock
+     * or SIM READYing process is over.
+     */
+    void setPukEntryActivity(Activity activity) {
+        mPUKEntryActivity = activity;
+    }
+
+    Activity getPUKEntryActivity() {
+        return mPUKEntryActivity;
+    }
+
+    /**
+     * Sets the dialog responsible for notifying the user of un-PUK-
+     * blocking - SIM READYing progress, so that we may dismiss it
+     * when we receive a positive result.
+     *
+     * @param dialog indicates the progress dialog informing the user
+     * of the state of the device.  Dismissed upon completion of
+     * READYing process
+     */
+    void setPukEntryProgressDialog(ProgressDialog dialog) {
+        mPUKEntryProgressDialog = dialog;
+    }
+
+    ProgressDialog getPUKEntryProgressDialog() {
+        return mPUKEntryProgressDialog;
+    }
+
+    /**
+     * 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.
+     */
+    /* package */ void wakeUpScreen() {
+        synchronized (this) {
+            if (mWakeState == WakeState.SLEEP) {
+                if (DBG) Log.d(LOG_TAG, "pulse screen lock");
+                mPowerManager.wakeUp(SystemClock.uptimeMillis());
+            }
+        }
+    }
+
+    /**
+     * 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 in-call UI is the foreground activity.
+        // (Note this will be false if the screen is currently off,
+        // since in that case *no* activity is in the foreground.)
+        boolean isShowingCallScreen = isShowingCallScreen();
+
+        // True if the InCallScreen's DTMF dialer is currently opened.
+        // (Note this does NOT imply whether or not the InCallScreen
+        // itself is visible.)
+        boolean isDialerOpened = (mInCallScreen != null) && mInCallScreen.isDialerOpened();
+
+        // 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.)
+
+        if (DBG) Log.d(LOG_TAG, "updateWakeState: callscreen " + isShowingCallScreen
+                       + ", dialer " + isDialerOpened
+                       + ", speaker " + isSpeakerInUse + "...");
+
+        //
+        // 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 = (phone.getForegroundCall().getState() == Call.State.DIALING);
+        boolean showingQuickResponseDialog = (mInCallScreen != null) &&
+                mInCallScreen.isQuickResponseDialogShowing();
+        boolean showingDisconnectedConnection =
+                PhoneUtils.hasDisconnectedConnections(phone) && isShowingCallScreen;
+        boolean keepScreenOn = isRinging || isDialing ||
+                (showingDisconnectedConnection && !showingQuickResponseDialog);
+        if (DBG) Log.d(LOG_TAG, "updateWakeState: keepScreenOn = " + keepScreenOn
+                       + " (isRinging " + isRinging
+                       + ", isDialing " + isDialing
+                       + ", showingQuickResponse " + showingQuickResponseDialog
+                       + ", showingDisc " + showingDisconnectedConnection + ")");
+        // keepScreenOn == true means we'll hold a full wake lock:
+        requestWakeState(keepScreenOn ? WakeState.FULL : WakeState.SLEEP);
+    }
+
+    /**
+     * Manually pokes the PowerManager's userActivity method.  Since we
+     * set the {@link WindowManager.LayoutParams#INPUT_FEATURE_DISABLE_USER_ACTIVITY}
+     * flag while the InCallScreen is active when there is no proximity sensor,
+     * we need to do this for touch events that really do count as user activity
+     * (like pressing any onscreen UI elements.)
+     */
+    /* package */ void pokeUserActivity() {
+        if (VDBG) Log.d(LOG_TAG, "pokeUserActivity()...");
+        mPowerManager.userActivity(SystemClock.uptimeMillis(), false);
+    }
+
+    /**
+     * Set when a new outgoing call is beginning, so we can update
+     * the proximity sensor state.
+     * Cleared when the InCallScreen is no longer in the foreground,
+     * in case the call fails without changing the telephony state.
+     */
+    /* package */ void setBeginningCall(boolean beginning) {
+        // Note that we are beginning a new call, for proximity sensor support
+        mBeginningCall = beginning;
+        // Update the Proximity sensor based on mBeginningCall state
+        updateProximitySensorMode(mCM.getState());
+    }
+
+    /**
+     * Updates the wake lock used to control proximity sensor behavior,
+     * based on the current state of the phone.  This method is called
+     * from the CallNotifier on any phone state change.
+     *
+     * On devices that have a proximity sensor, to avoid false touches
+     * during a call, we hold a PROXIMITY_SCREEN_OFF_WAKE_LOCK wake lock
+     * whenever the phone is off hook.  (When held, that wake lock causes
+     * the screen to turn off automatically when the sensor detects an
+     * object close to the screen.)
+     *
+     * This method is a no-op for devices that don't have a proximity
+     * sensor.
+     *
+     * Note this method doesn't care if the InCallScreen is the foreground
+     * activity or not.  That's because we want the proximity sensor to be
+     * enabled any time the phone is in use, to avoid false cheek events
+     * for whatever app you happen to be running.
+     *
+     * Proximity wake lock will *not* be held if any one of the
+     * conditions is true while on a call:
+     * 1) If the audio is routed via Bluetooth
+     * 2) If a wired headset is connected
+     * 3) if the speaker is ON
+     * 4) If the slider is open(i.e. the hardkeyboard is *not* hidden)
+     *
+     * @param state current state of the phone (see {@link Phone#State})
+     */
+    /* package */ void updateProximitySensorMode(PhoneConstants.State state) {
+        if (VDBG) Log.d(LOG_TAG, "updateProximitySensorMode: state = " + state);
+
+        if (proximitySensorModeEnabled()) {
+            synchronized (mProximityWakeLock) {
+                // turn proximity sensor off and turn screen on immediately if
+                // we are using a headset, the keyboard is open, or the device
+                // is being held in a horizontal position.
+                boolean screenOnImmediately = (isHeadsetPlugged()
+                                               || PhoneUtils.isSpeakerOn(this)
+                                               || isBluetoothHeadsetAudioOn()
+                                               || mIsHardKeyboardOpen);
+
+                // We do not keep the screen off when the user is outside in-call screen and we are
+                // horizontal, but we do not force it on when we become horizontal until the
+                // proximity sensor goes negative.
+                boolean horizontal =
+                        (mOrientation == AccelerometerListener.ORIENTATION_HORIZONTAL);
+                screenOnImmediately |= !isShowingCallScreenForProximity() && horizontal;
+
+                // We do not keep the screen off when dialpad is visible, we are horizontal, and
+                // the in-call screen is being shown.
+                // At that moment we're pretty sure users want to use it, instead of letting the
+                // proximity sensor turn off the screen by their hands.
+                boolean dialpadVisible = false;
+                if (mInCallScreen != null) {
+                    dialpadVisible =
+                            mInCallScreen.getUpdatedInCallControlState().dialpadEnabled
+                            && mInCallScreen.getUpdatedInCallControlState().dialpadVisible
+                            && isShowingCallScreen();
+                }
+                screenOnImmediately |= dialpadVisible && horizontal;
+
+                if (((state == PhoneConstants.State.OFFHOOK) || mBeginningCall) && !screenOnImmediately) {
+                    // Phone is in use!  Arrange for the screen to turn off
+                    // automatically when the sensor detects a close object.
+                    if (!mProximityWakeLock.isHeld()) {
+                        if (DBG) Log.d(LOG_TAG, "updateProximitySensorMode: acquiring...");
+                        mProximityWakeLock.acquire();
+                    } else {
+                        if (VDBG) Log.d(LOG_TAG, "updateProximitySensorMode: lock already held.");
+                    }
+                } else {
+                    // Phone is either idle, or ringing.  We don't want any
+                    // special proximity sensor behavior in either case.
+                    if (mProximityWakeLock.isHeld()) {
+                        if (DBG) Log.d(LOG_TAG, "updateProximitySensorMode: releasing...");
+                        // Wait until user has moved the phone away from his head if we are
+                        // releasing due to the phone call ending.
+                        // Qtherwise, turn screen on immediately
+                        int flags =
+                            (screenOnImmediately ? 0 : PowerManager.WAIT_FOR_PROXIMITY_NEGATIVE);
+                        mProximityWakeLock.release(flags);
+                    } else {
+                        if (VDBG) {
+                            Log.d(LOG_TAG, "updateProximitySensorMode: lock already released.");
+                        }
+                    }
+                }
+            }
+        }
+    }
+
+    @Override
+    public void orientationChanged(int orientation) {
+        mOrientation = orientation;
+        updateProximitySensorMode(mCM.getState());
+    }
+
+    /**
+     * Notifies the phone app when the phone state changes.
+     *
+     * This method will updates various states inside Phone app (e.g. proximity sensor mode,
+     * accelerometer listener state, update-lock state, etc.)
+     */
+    /* package */ void updatePhoneState(PhoneConstants.State state) {
+        if (state != mLastPhoneState) {
+            mLastPhoneState = state;
+            updateProximitySensorMode(state);
+
+            // Try to acquire or release UpdateLock.
+            //
+            // Watch out: we don't release the lock here when the screen is still in foreground.
+            // At that time InCallScreen will release it on onPause().
+            if (state != PhoneConstants.State.IDLE) {
+                // UpdateLock is a recursive lock, while we may get "acquire" request twice and
+                // "release" request once for a single call (RINGING + OFFHOOK and IDLE).
+                // We need to manually ensure the lock is just acquired once for each (and this
+                // will prevent other possible buggy situations too).
+                if (!mUpdateLock.isHeld()) {
+                    mUpdateLock.acquire();
+                }
+            } else {
+                if (!isShowingCallScreen()) {
+                    if (!mUpdateLock.isHeld()) {
+                        mUpdateLock.release();
+                    }
+                } else {
+                    // For this case InCallScreen will take care of the release() call.
+                }
+            }
+
+            if (mAccelerometerListener != null) {
+                // use accelerometer to augment proximity sensor when in call
+                mOrientation = AccelerometerListener.ORIENTATION_UNKNOWN;
+                mAccelerometerListener.enable(state == PhoneConstants.State.OFFHOOK);
+            }
+            // clear our beginning call flag
+            mBeginningCall = false;
+            // While we are in call, the in-call screen should dismiss the keyguard.
+            // This allows the user to press Home to go directly home without going through
+            // an insecure lock screen.
+            // But we do not want to do this if there is no active call so we do not
+            // bypass the keyguard if the call is not answered or declined.
+            if (mInCallScreen != null) {
+                mInCallScreen.updateKeyguardPolicy(state == PhoneConstants.State.OFFHOOK);
+            }
+        }
+    }
+
+    /* package */ PhoneConstants.State getPhoneState() {
+        return mLastPhoneState;
+    }
+
+    /**
+     * Returns UpdateLock object.
+     */
+    /* package */ UpdateLock getUpdateLock() {
+        return mUpdateLock;
+    }
+
+    /**
+     * @return true if this device supports the "proximity sensor
+     * auto-lock" feature while in-call (see updateProximitySensorMode()).
+     */
+    /* package */ boolean proximitySensorModeEnabled() {
+        return (mProximityWakeLock != null);
+    }
+
+    KeyguardManager getKeyguardManager() {
+        return mKeyguardManager;
+    }
+
+    private void onMMIComplete(AsyncResult r) {
+        if (VDBG) Log.d(LOG_TAG, "onMMIComplete()...");
+        MmiCode mmiCode = (MmiCode) r.result;
+        PhoneUtils.displayMMIComplete(phone, getInstance(), mmiCode, null, null);
+    }
+
+    private void initForNewRadioTechnology() {
+        if (DBG) Log.d(LOG_TAG, "initForNewRadioTechnology...");
+
+         if (phone.getPhoneType() == PhoneConstants.PHONE_TYPE_CDMA) {
+            // Create an instance of CdmaPhoneCallState and initialize it to IDLE
+            cdmaPhoneCallState = new CdmaPhoneCallState();
+            cdmaPhoneCallState.CdmaPhoneCallStateInit();
+        }
+        if (TelephonyCapabilities.supportsOtasp(phone)) {
+            //create instances of CDMA OTA data classes
+            if (cdmaOtaProvisionData == null) {
+                cdmaOtaProvisionData = new OtaUtils.CdmaOtaProvisionData();
+            }
+            if (cdmaOtaConfigData == null) {
+                cdmaOtaConfigData = new OtaUtils.CdmaOtaConfigData();
+            }
+            if (cdmaOtaScreenState == null) {
+                cdmaOtaScreenState = new OtaUtils.CdmaOtaScreenState();
+            }
+            if (cdmaOtaInCallScreenUiState == null) {
+                cdmaOtaInCallScreenUiState = new OtaUtils.CdmaOtaInCallScreenUiState();
+            }
+        } else {
+            //Clean up OTA data in GSM/UMTS. It is valid only for CDMA
+            clearOtaState();
+        }
+
+        ringer.updateRingerContextAfterRadioTechnologyChange(this.phone);
+        notifier.updateCallNotifierRegistrationsAfterRadioTechnologyChange();
+        if (mBluetoothPhone != null) {
+            try {
+                mBluetoothPhone.updateBtHandsfreeAfterRadioTechnologyChange();
+            } catch (RemoteException e) {
+                Log.e(LOG_TAG, Log.getStackTraceString(new Throwable()));
+            }
+        }
+        if (mInCallScreen != null) {
+            mInCallScreen.updateAfterRadioTechnologyChange();
+        }
+
+        // Update registration for ICC status after radio technology change
+        IccCard sim = phone.getIccCard();
+        if (sim != null) {
+            if (DBG) Log.d(LOG_TAG, "Update registration for ICC status...");
+
+            //Register all events new to the new active phone
+            sim.registerForNetworkLocked(mHandler, EVENT_SIM_NETWORK_LOCKED, null);
+        }
+    }
+
+
+    /**
+     * @return true if a wired headset is currently plugged in.
+     *
+     * @see Intent.ACTION_HEADSET_PLUG (which we listen for in mReceiver.onReceive())
+     */
+    boolean isHeadsetPlugged() {
+        return mIsHeadsetPlugged;
+    }
+
+    /**
+     * @return true if the onscreen UI should currently be showing the
+     * special "bluetooth is active" indication in a couple of places (in
+     * which UI elements turn blue and/or show the bluetooth logo.)
+     *
+     * This depends on the BluetoothHeadset state *and* the current
+     * telephony state; see shouldShowBluetoothIndication().
+     *
+     * @see CallCard
+     * @see NotificationMgr.updateInCallNotification
+     */
+    /* package */ boolean showBluetoothIndication() {
+        return mShowBluetoothIndication;
+    }
+
+    /**
+     * Recomputes the mShowBluetoothIndication flag based on the current
+     * bluetooth state and current telephony state.
+     *
+     * This needs to be called any time the bluetooth headset state or the
+     * telephony state changes.
+     *
+     * @param forceUiUpdate if true, force the UI elements that care
+     *                      about this flag to update themselves.
+     */
+    /* package */ void updateBluetoothIndication(boolean forceUiUpdate) {
+        mShowBluetoothIndication = shouldShowBluetoothIndication(mBluetoothHeadsetState,
+                                                                 mBluetoothHeadsetAudioState,
+                                                                 mCM);
+        if (forceUiUpdate) {
+            // Post Handler messages to the various components that might
+            // need to be refreshed based on the new state.
+            if (isShowingCallScreen()) mInCallScreen.requestUpdateBluetoothIndication();
+            if (DBG) Log.d (LOG_TAG, "- updating in-call notification for BT state change...");
+            mHandler.sendEmptyMessage(EVENT_UPDATE_INCALL_NOTIFICATION);
+        }
+
+        // Update the Proximity sensor based on Bluetooth audio state
+        updateProximitySensorMode(mCM.getState());
+    }
+
+    /**
+     * UI policy helper function for the couple of places in the UI that
+     * have some way of indicating that "bluetooth is in use."
+     *
+     * @return true if the onscreen UI should indicate that "bluetooth is in use",
+     *         based on the specified bluetooth headset state, and the
+     *         current state of the phone.
+     * @see showBluetoothIndication()
+     */
+    private static boolean shouldShowBluetoothIndication(int bluetoothState,
+                                                         int bluetoothAudioState,
+                                                         CallManager cm) {
+        // We want the UI to indicate that "bluetooth is in use" in two
+        // slightly different cases:
+        //
+        // (a) The obvious case: if a bluetooth headset is currently in
+        //     use for an ongoing call.
+        //
+        // (b) The not-so-obvious case: if an incoming call is ringing,
+        //     and we expect that audio *will* be routed to a bluetooth
+        //     headset once the call is answered.
+
+        switch (cm.getState()) {
+            case OFFHOOK:
+                // This covers normal active calls, and also the case if
+                // the foreground call is DIALING or ALERTING.  In this
+                // case, bluetooth is considered "active" if a headset
+                // is connected *and* audio is being routed to it.
+                return ((bluetoothState == BluetoothHeadset.STATE_CONNECTED)
+                        && (bluetoothAudioState == BluetoothHeadset.STATE_AUDIO_CONNECTED));
+
+            case RINGING:
+                // If an incoming call is ringing, we're *not* yet routing
+                // audio to the headset (since there's no in-call audio
+                // yet!)  In this case, if a bluetooth headset is
+                // connected at all, we assume that it'll become active
+                // once the user answers the phone.
+                return (bluetoothState == BluetoothHeadset.STATE_CONNECTED);
+
+            default:  // Presumably IDLE
+                return false;
+        }
+    }
+
+
+    /**
+     * Receiver for misc intent broadcasts the Phone app cares about.
+     */
+    private class PhoneAppBroadcastReceiver extends BroadcastReceiver {
+        @Override
+        public void onReceive(Context context, Intent intent) {
+            String action = intent.getAction();
+            if (action.equals(Intent.ACTION_AIRPLANE_MODE_CHANGED)) {
+                boolean enabled = System.getInt(getContentResolver(),
+                        System.AIRPLANE_MODE_ON, 0) == 0;
+                phone.setRadioPower(enabled);
+            } else if (action.equals(BluetoothHeadset.ACTION_CONNECTION_STATE_CHANGED)) {
+                mBluetoothHeadsetState = intent.getIntExtra(BluetoothHeadset.EXTRA_STATE,
+                                                          BluetoothHeadset.STATE_DISCONNECTED);
+                if (VDBG) Log.d(LOG_TAG, "mReceiver: HEADSET_STATE_CHANGED_ACTION");
+                if (VDBG) Log.d(LOG_TAG, "==> new state: " + mBluetoothHeadsetState);
+                updateBluetoothIndication(true);  // Also update any visible UI if necessary
+            } else if (action.equals(BluetoothHeadset.ACTION_AUDIO_STATE_CHANGED)) {
+                mBluetoothHeadsetAudioState =
+                        intent.getIntExtra(BluetoothHeadset.EXTRA_STATE,
+                                           BluetoothHeadset.STATE_AUDIO_DISCONNECTED);
+                if (VDBG) Log.d(LOG_TAG, "mReceiver: HEADSET_AUDIO_STATE_CHANGED_ACTION");
+                if (VDBG) Log.d(LOG_TAG, "==> new state: " + mBluetoothHeadsetAudioState);
+                updateBluetoothIndication(true);  // Also update any visible UI if necessary
+            } else if (action.equals(TelephonyIntents.ACTION_ANY_DATA_CONNECTION_STATE_CHANGED)) {
+                if (VDBG) Log.d(LOG_TAG, "mReceiver: ACTION_ANY_DATA_CONNECTION_STATE_CHANGED");
+                if (VDBG) Log.d(LOG_TAG, "- state: " + intent.getStringExtra(PhoneConstants.STATE_KEY));
+                if (VDBG) Log.d(LOG_TAG, "- reason: "
+                                + intent.getStringExtra(PhoneConstants.STATE_CHANGE_REASON_KEY));
+
+                // The "data disconnected due to roaming" notification is shown
+                // if (a) you have the "data roaming" feature turned off, and
+                // (b) you just lost data connectivity because you're roaming.
+                boolean disconnectedDueToRoaming =
+                        !phone.getDataRoamingEnabled()
+                        && "DISCONNECTED".equals(intent.getStringExtra(PhoneConstants.STATE_KEY))
+                        && Phone.REASON_ROAMING_ON.equals(
+                            intent.getStringExtra(PhoneConstants.STATE_CHANGE_REASON_KEY));
+                mHandler.sendEmptyMessage(disconnectedDueToRoaming
+                                          ? EVENT_DATA_ROAMING_DISCONNECTED
+                                          : EVENT_DATA_ROAMING_OK);
+            } else if (action.equals(Intent.ACTION_HEADSET_PLUG)) {
+                if (VDBG) Log.d(LOG_TAG, "mReceiver: ACTION_HEADSET_PLUG");
+                if (VDBG) Log.d(LOG_TAG, "    state: " + intent.getIntExtra("state", 0));
+                if (VDBG) Log.d(LOG_TAG, "    name: " + intent.getStringExtra("name"));
+                mIsHeadsetPlugged = (intent.getIntExtra("state", 0) == 1);
+                mHandler.sendMessage(mHandler.obtainMessage(EVENT_WIRED_HEADSET_PLUG, 0));
+            } else if ((action.equals(TelephonyIntents.ACTION_SIM_STATE_CHANGED)) &&
+                    (mPUKEntryActivity != null)) {
+                // if an attempt to un-PUK-lock the device was made, while we're
+                // receiving this state change notification, notify the handler.
+                // NOTE: This is ONLY triggered if an attempt to un-PUK-lock has
+                // been attempted.
+                mHandler.sendMessage(mHandler.obtainMessage(EVENT_SIM_STATE_CHANGED,
+                        intent.getStringExtra(IccCardConstants.INTENT_KEY_ICC_STATE)));
+            } else if (action.equals(TelephonyIntents.ACTION_RADIO_TECHNOLOGY_CHANGED)) {
+                String newPhone = intent.getStringExtra(PhoneConstants.PHONE_NAME_KEY);
+                Log.d(LOG_TAG, "Radio technology switched. Now " + newPhone + " is active.");
+                initForNewRadioTechnology();
+            } else if (action.equals(TelephonyIntents.ACTION_SERVICE_STATE_CHANGED)) {
+                handleServiceStateChanged(intent);
+            } else if (action.equals(TelephonyIntents.ACTION_EMERGENCY_CALLBACK_MODE_CHANGED)) {
+                if (TelephonyCapabilities.supportsEcm(phone)) {
+                    Log.d(LOG_TAG, "Emergency Callback Mode arrived in PhoneApp.");
+                    // Start Emergency Callback Mode service
+                    if (intent.getBooleanExtra("phoneinECMState", false)) {
+                        context.startService(new Intent(context,
+                                EmergencyCallbackModeService.class));
+                    }
+                } else {
+                    // It doesn't make sense to get ACTION_EMERGENCY_CALLBACK_MODE_CHANGED
+                    // on a device that doesn't support ECM in the first place.
+                    Log.e(LOG_TAG, "Got ACTION_EMERGENCY_CALLBACK_MODE_CHANGED, "
+                          + "but ECM isn't supported for phone: " + phone.getPhoneName());
+                }
+            } else if (action.equals(Intent.ACTION_DOCK_EVENT)) {
+                mDockState = intent.getIntExtra(Intent.EXTRA_DOCK_STATE,
+                        Intent.EXTRA_DOCK_STATE_UNDOCKED);
+                if (VDBG) Log.d(LOG_TAG, "ACTION_DOCK_EVENT -> mDockState = " + mDockState);
+                mHandler.sendMessage(mHandler.obtainMessage(EVENT_DOCK_STATE_CHANGED, 0));
+            } else if (action.equals(TtyIntent.TTY_PREFERRED_MODE_CHANGE_ACTION)) {
+                mPreferredTtyMode = intent.getIntExtra(TtyIntent.TTY_PREFFERED_MODE,
+                                                       Phone.TTY_MODE_OFF);
+                if (VDBG) Log.d(LOG_TAG, "mReceiver: TTY_PREFERRED_MODE_CHANGE_ACTION");
+                if (VDBG) Log.d(LOG_TAG, "    mode: " + mPreferredTtyMode);
+                mHandler.sendMessage(mHandler.obtainMessage(EVENT_TTY_PREFERRED_MODE_CHANGED, 0));
+            } else if (action.equals(AudioManager.RINGER_MODE_CHANGED_ACTION)) {
+                int ringerMode = intent.getIntExtra(AudioManager.EXTRA_RINGER_MODE,
+                        AudioManager.RINGER_MODE_NORMAL);
+                if (ringerMode == AudioManager.RINGER_MODE_SILENT) {
+                    notifier.silenceRinger();
+                }
+            }
+        }
+    }
+
+    /**
+     * Broadcast receiver for the ACTION_MEDIA_BUTTON broadcast intent.
+     *
+     * This functionality isn't lumped in with the other intents in
+     * PhoneAppBroadcastReceiver because we instantiate this as a totally
+     * separate BroadcastReceiver instance, since we need to manually
+     * adjust its IntentFilter's priority (to make sure we get these
+     * intents *before* the media player.)
+     */
+    private class MediaButtonBroadcastReceiver extends BroadcastReceiver {
+        @Override
+        public void onReceive(Context context, Intent intent) {
+            KeyEvent event = (KeyEvent) intent.getParcelableExtra(Intent.EXTRA_KEY_EVENT);
+            if (VDBG) Log.d(LOG_TAG,
+                           "MediaButtonBroadcastReceiver.onReceive()...  event = " + event);
+            if ((event != null)
+                && (event.getKeyCode() == KeyEvent.KEYCODE_HEADSETHOOK)) {
+                if (VDBG) Log.d(LOG_TAG, "MediaButtonBroadcastReceiver: HEADSETHOOK");
+                boolean consumed = PhoneUtils.handleHeadsetHook(phone, event);
+                if (VDBG) Log.d(LOG_TAG, "==> handleHeadsetHook(): consumed = " + consumed);
+                if (consumed) {
+                    // If a headset is attached and the press is consumed, also update
+                    // any UI items (such as an InCallScreen mute button) that may need to
+                    // be updated if their state changed.
+                    updateInCallScreen();  // Has no effect if the InCallScreen isn't visible
+                    abortBroadcast();
+                }
+            } else {
+                if (mCM.getState() != PhoneConstants.State.IDLE) {
+                    // If the phone is anything other than completely idle,
+                    // then we consume and ignore any media key events,
+                    // Otherwise it is too easy to accidentally start
+                    // playing music while a phone call is in progress.
+                    if (VDBG) Log.d(LOG_TAG, "MediaButtonBroadcastReceiver: consumed");
+                    abortBroadcast();
+                }
+            }
+        }
+    }
+
+    /**
+     * Accepts broadcast Intents which will be prepared by {@link NotificationMgr} and thus
+     * sent from framework's notification mechanism (which is outside Phone context).
+     * This should be visible from outside, but shouldn't be in "exported" state.
+     *
+     * TODO: If possible merge this into PhoneAppBroadcastReceiver.
+     */
+    public static class NotificationBroadcastReceiver extends BroadcastReceiver {
+        @Override
+        public void onReceive(Context context, Intent intent) {
+            String action = intent.getAction();
+            // TODO: use "if (VDBG)" here.
+            Log.d(LOG_TAG, "Broadcast from Notification: " + action);
+
+            if (action.equals(ACTION_HANG_UP_ONGOING_CALL)) {
+                PhoneUtils.hangup(PhoneGlobals.getInstance().mCM);
+            } else if (action.equals(ACTION_CALL_BACK_FROM_NOTIFICATION)) {
+                // Collapse the expanded notification and the notification item itself.
+                closeSystemDialogs(context);
+                clearMissedCallNotification(context);
+
+                Intent callIntent = new Intent(Intent.ACTION_CALL_PRIVILEGED, intent.getData());
+                callIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK
+                        | Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
+                context.startActivity(callIntent);
+            } else if (action.equals(ACTION_SEND_SMS_FROM_NOTIFICATION)) {
+                // Collapse the expanded notification and the notification item itself.
+                closeSystemDialogs(context);
+                clearMissedCallNotification(context);
+
+                Intent smsIntent = new Intent(Intent.ACTION_SENDTO, intent.getData());
+                smsIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+                context.startActivity(smsIntent);
+            } else {
+                Log.w(LOG_TAG, "Received hang-up request from notification,"
+                        + " but there's no call the system can hang up.");
+            }
+        }
+
+        private void closeSystemDialogs(Context context) {
+            Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
+            context.sendBroadcastAsUser(intent, UserHandle.ALL);
+        }
+
+        private void clearMissedCallNotification(Context context) {
+            Intent clearIntent = new Intent(context, ClearMissedCallsService.class);
+            clearIntent.setAction(ClearMissedCallsService.ACTION_CLEAR_MISSED_CALLS);
+            context.startService(clearIntent);
+        }
+    }
+
+    private void handleServiceStateChanged(Intent intent) {
+        /**
+         * This used to handle updating EriTextWidgetProvider this routine
+         * and and listening for ACTION_SERVICE_STATE_CHANGED intents could
+         * be removed. But leaving just in case it might be needed in the near
+         * future.
+         */
+
+        // If service just returned, start sending out the queued messages
+        ServiceState ss = ServiceState.newFromBundle(intent.getExtras());
+
+        if (ss != null) {
+            int state = ss.getState();
+            notificationMgr.updateNetworkSelection(state);
+        }
+    }
+
+    public boolean isOtaCallInActiveState() {
+        boolean otaCallActive = false;
+        if (mInCallScreen != null) {
+            otaCallActive = mInCallScreen.isOtaCallInActiveState();
+        }
+        if (VDBG) Log.d(LOG_TAG, "- isOtaCallInActiveState " + otaCallActive);
+        return otaCallActive;
+    }
+
+    public boolean isOtaCallInEndState() {
+        boolean otaCallEnded = false;
+        if (mInCallScreen != null) {
+            otaCallEnded = mInCallScreen.isOtaCallInEndState();
+        }
+        if (VDBG) Log.d(LOG_TAG, "- isOtaCallInEndState " + otaCallEnded);
+        return otaCallEnded;
+    }
+
+    // it is safe to call clearOtaState() even if the InCallScreen isn't active
+    public void clearOtaState() {
+        if (DBG) Log.d(LOG_TAG, "- clearOtaState ...");
+        if ((mInCallScreen != null)
+                && (otaUtils != null)) {
+            otaUtils.cleanOtaScreen(true);
+            if (DBG) Log.d(LOG_TAG, "  - clearOtaState clears OTA screen");
+        }
+    }
+
+    // it is safe to call dismissOtaDialogs() even if the InCallScreen isn't active
+    public void dismissOtaDialogs() {
+        if (DBG) Log.d(LOG_TAG, "- dismissOtaDialogs ...");
+        if ((mInCallScreen != null)
+                && (otaUtils != null)) {
+            otaUtils.dismissAllOtaDialogs();
+            if (DBG) Log.d(LOG_TAG, "  - dismissOtaDialogs clears OTA dialogs");
+        }
+    }
+
+    // it is safe to call clearInCallScreenMode() even if the InCallScreen isn't active
+    public void clearInCallScreenMode() {
+        if (DBG) Log.d(LOG_TAG, "- clearInCallScreenMode ...");
+        if (mInCallScreen != null) {
+            mInCallScreen.resetInCallScreenMode();
+        }
+    }
+
+    /**
+     * Force the in-call UI to refresh itself, if it's currently visible.
+     *
+     * This method can be used any time there's a state change anywhere in
+     * the phone app that needs to be reflected in the onscreen UI.
+     *
+     * Note that it's *not* necessary to manually refresh the in-call UI
+     * (via this method) for regular telephony state changes like
+     * DIALING -> ALERTING -> ACTIVE, since the InCallScreen already
+     * listens for those state changes itself.
+     *
+     * This method does *not* force the in-call UI to come up if it's not
+     * already visible.  To do that, use displayCallScreen().
+     */
+    /* package */ void updateInCallScreen() {
+        if (DBG) Log.d(LOG_TAG, "- updateInCallScreen()...");
+        if (mInCallScreen != null) {
+            // Post an updateScreen() request.  Note that the
+            // updateScreen() call will end up being a no-op if the
+            // InCallScreen isn't the foreground activity.
+            mInCallScreen.requestUpdateScreen();
+        }
+    }
+
+    private void handleQueryTTYModeResponse(Message msg) {
+        AsyncResult ar = (AsyncResult) msg.obj;
+        if (ar.exception != null) {
+            if (DBG) Log.d(LOG_TAG, "handleQueryTTYModeResponse: Error getting TTY state.");
+        } else {
+            if (DBG) Log.d(LOG_TAG,
+                           "handleQueryTTYModeResponse: TTY enable state successfully queried.");
+
+            int ttymode = ((int[]) ar.result)[0];
+            if (DBG) Log.d(LOG_TAG, "handleQueryTTYModeResponse:ttymode=" + ttymode);
+
+            Intent ttyModeChanged = new Intent(TtyIntent.TTY_ENABLED_CHANGE_ACTION);
+            ttyModeChanged.putExtra("ttyEnabled", ttymode != Phone.TTY_MODE_OFF);
+            sendBroadcastAsUser(ttyModeChanged, UserHandle.ALL);
+
+            String audioTtyMode;
+            switch (ttymode) {
+            case Phone.TTY_MODE_FULL:
+                audioTtyMode = "tty_full";
+                break;
+            case Phone.TTY_MODE_VCO:
+                audioTtyMode = "tty_vco";
+                break;
+            case Phone.TTY_MODE_HCO:
+                audioTtyMode = "tty_hco";
+                break;
+            case Phone.TTY_MODE_OFF:
+            default:
+                audioTtyMode = "tty_off";
+                break;
+            }
+            AudioManager audioManager = (AudioManager) getSystemService(Context.AUDIO_SERVICE);
+            audioManager.setParameters("tty_mode="+audioTtyMode);
+        }
+    }
+
+    private void handleSetTTYModeResponse(Message msg) {
+        AsyncResult ar = (AsyncResult) msg.obj;
+
+        if (ar.exception != null) {
+            if (DBG) Log.d (LOG_TAG,
+                    "handleSetTTYModeResponse: Error setting TTY mode, ar.exception"
+                    + ar.exception);
+        }
+        phone.queryTTYMode(mHandler.obtainMessage(EVENT_TTY_MODE_GET));
+    }
+
+    /**
+     * "Call origin" may be used by Contacts app to specify where the phone call comes from.
+     * Currently, the only permitted value for this extra is {@link #ALLOWED_EXTRA_CALL_ORIGIN}.
+     * Any other value will be ignored, to make sure that malicious apps can't trick the in-call
+     * UI into launching some random other app after a call ends.
+     *
+     * TODO: make this more generic. Note that we should let the "origin" specify its package
+     * while we are now assuming it is "com.android.contacts"
+     */
+    public static final String EXTRA_CALL_ORIGIN = "com.android.phone.CALL_ORIGIN";
+    private static final String DEFAULT_CALL_ORIGIN_PACKAGE = "com.android.contacts";
+    private static final String ALLOWED_EXTRA_CALL_ORIGIN =
+            "com.android.contacts.activities.DialtactsActivity";
+    /**
+     * Used to determine if the preserved call origin is fresh enough.
+     */
+    private static final long CALL_ORIGIN_EXPIRATION_MILLIS = 30 * 1000;
+
+    public void setLatestActiveCallOrigin(String callOrigin) {
+        inCallUiState.latestActiveCallOrigin = callOrigin;
+        if (callOrigin != null) {
+            inCallUiState.latestActiveCallOriginTimeStamp = SystemClock.elapsedRealtime();
+        } else {
+            inCallUiState.latestActiveCallOriginTimeStamp = 0;
+        }
+    }
+
+    /**
+     * Reset call origin depending on its timestamp.
+     *
+     * See if the current call origin preserved by the app is fresh enough or not. If it is,
+     * previous call origin will be used as is. If not, call origin will be reset.
+     *
+     * This will be effective especially for 3rd party apps which want to bypass phone calls with
+     * their own telephone lines. In that case Phone app may finish the phone call once and make
+     * another for the external apps, which will drop call origin information in Intent.
+     * Even in that case we are sure the second phone call should be initiated just after the first
+     * phone call, so here we restore it from the previous information iff the second call is done
+     * fairly soon.
+     */
+    public void resetLatestActiveCallOrigin() {
+        final long callOriginTimestamp = inCallUiState.latestActiveCallOriginTimeStamp;
+        final long currentTimestamp = SystemClock.elapsedRealtime();
+        if (VDBG) {
+            Log.d(LOG_TAG, "currentTimeMillis: " + currentTimestamp
+                    + ", saved timestamp for call origin: " + callOriginTimestamp);
+        }
+        if (inCallUiState.latestActiveCallOriginTimeStamp > 0
+                && (currentTimestamp - callOriginTimestamp < CALL_ORIGIN_EXPIRATION_MILLIS)) {
+            if (VDBG) {
+                Log.d(LOG_TAG, "Resume previous call origin (" +
+                        inCallUiState.latestActiveCallOrigin + ")");
+            }
+            // Do nothing toward call origin itself but update the timestamp just in case.
+            inCallUiState.latestActiveCallOriginTimeStamp = currentTimestamp;
+        } else {
+            if (VDBG) Log.d(LOG_TAG, "Drop previous call origin and set the current one to null");
+            setLatestActiveCallOrigin(null);
+        }
+    }
+
+    /**
+     * @return Intent which will be used when in-call UI is shown and the phone call is hang up.
+     * By default CallLog screen will be introduced, but the destination may change depending on
+     * its latest call origin state.
+     */
+    public Intent createPhoneEndIntentUsingCallOrigin() {
+        if (TextUtils.equals(inCallUiState.latestActiveCallOrigin, ALLOWED_EXTRA_CALL_ORIGIN)) {
+            if (VDBG) Log.d(LOG_TAG, "Valid latestActiveCallOrigin("
+                    + inCallUiState.latestActiveCallOrigin + ") was found. "
+                    + "Go back to the previous screen.");
+            // Right now we just launch the Activity which launched in-call UI. Note that we're
+            // assuming the origin is from "com.android.contacts", which may be incorrect in the
+            // future.
+            final Intent intent = new Intent();
+            intent.setClassName(DEFAULT_CALL_ORIGIN_PACKAGE, inCallUiState.latestActiveCallOrigin);
+            return intent;
+        } else {
+            if (VDBG) Log.d(LOG_TAG, "Current latestActiveCallOrigin ("
+                    + inCallUiState.latestActiveCallOrigin + ") is not valid. "
+                    + "Just use CallLog as a default destination.");
+            return PhoneGlobals.createCallLogIntent();
+        }
+    }
+
+    /** Service connection */
+    private final ServiceConnection mBluetoothPhoneConnection = new ServiceConnection() {
+
+        /** Handle the task of binding the local object to the service */
+        public void onServiceConnected(ComponentName className, IBinder service) {
+            Log.i(LOG_TAG, "Headset phone created, binding local service.");
+            mBluetoothPhone = IBluetoothHeadsetPhone.Stub.asInterface(service);
+        }
+
+        /** Handle the task of cleaning up the local binding */
+        public void onServiceDisconnected(ComponentName className) {
+            Log.i(LOG_TAG, "Headset phone disconnected, cleaning local binding.");
+            mBluetoothPhone = null;
+        }
+    };
+}
diff --git a/src/com/android/phone/PhoneInterfaceManager.java b/src/com/android/phone/PhoneInterfaceManager.java
index a5bb130..441270a 100644
--- a/src/com/android/phone/PhoneInterfaceManager.java
+++ b/src/com/android/phone/PhoneInterfaceManager.java
@@ -16,6 +16,7 @@
 
 package com.android.phone;
 
+import android.app.ActivityManager;
 import android.content.ActivityNotFoundException;
 import android.content.Context;
 import android.content.Intent;
@@ -27,11 +28,12 @@
 import android.os.Handler;
 import android.os.Looper;
 import android.os.Message;
+import android.os.Process;
 import android.os.ServiceManager;
+import android.os.UserHandle;
 import android.telephony.NeighboringCellInfo;
 import android.telephony.CellInfo;
 import android.telephony.ServiceState;
-import android.telephony.TelephonyManager;
 import android.text.TextUtils;
 import android.util.Log;
 
@@ -50,7 +52,8 @@
  */
 public class PhoneInterfaceManager extends ITelephony.Stub {
     private static final String LOG_TAG = "PhoneInterfaceManager";
-    private static final boolean DBG = (PhoneApp.DBG_LEVEL >= 2);
+    private static final boolean DBG = (PhoneGlobals.DBG_LEVEL >= 2);
+    private static final boolean DBG_LOC = false;
 
     // Message codes used with mMainThreadHandler
     private static final int CMD_HANDLE_PIN_MMI = 1;
@@ -63,7 +66,7 @@
     /** The singleton instance. */
     private static PhoneInterfaceManager sInstance;
 
-    PhoneApp mApp;
+    PhoneGlobals mApp;
     Phone mPhone;
     CallManager mCM;
     MainThreadHandler mMainThreadHandler;
@@ -213,7 +216,7 @@
      * Initialize the singleton PhoneInterfaceManager instance.
      * This is only done once, at startup, from PhoneApp.onCreate().
      */
-    /* package */ static PhoneInterfaceManager init(PhoneApp app, Phone phone) {
+    /* package */ static PhoneInterfaceManager init(PhoneGlobals app, Phone phone) {
         synchronized (PhoneInterfaceManager.class) {
             if (sInstance == null) {
                 sInstance = new PhoneInterfaceManager(app, phone);
@@ -225,10 +228,10 @@
     }
 
     /** Private constructor; @see init() */
-    private PhoneInterfaceManager(PhoneApp app, Phone phone) {
+    private PhoneInterfaceManager(PhoneGlobals app, Phone phone) {
         mApp = app;
         mPhone = phone;
-        mCM = PhoneApp.getInstance().mCM;
+        mCM = PhoneGlobals.getInstance().mCM;
         mMainThreadHandler = new MainThreadHandler();
         publish();
     }
@@ -283,7 +286,7 @@
 
     private boolean showCallScreenInternal(boolean specifyInitialDialpadState,
                                            boolean initialDialpadState) {
-        if (!PhoneApp.sVoiceCapable) {
+        if (!PhoneGlobals.sVoiceCapable) {
             // Never allow the InCallScreen to appear on data-only devices.
             return false;
         }
@@ -295,9 +298,9 @@
         try {
             Intent intent;
             if (specifyInitialDialpadState) {
-                intent = PhoneApp.createInCallIntent(initialDialpadState);
+                intent = PhoneGlobals.createInCallIntent(initialDialpadState);
             } else {
-                intent = PhoneApp.createInCallIntent();
+                intent = PhoneGlobals.createInCallIntent();
             }
             try {
                 mApp.startActivity(intent);
@@ -420,7 +423,7 @@
 
     public boolean isSimPinEnabled() {
         enforceReadPermission();
-        return (PhoneApp.getInstance().isSimPinEnabled());
+        return (PhoneGlobals.getInstance().isSimPinEnabled());
     }
 
     public boolean supplyPin(String pin) {
@@ -596,6 +599,7 @@
         return DefaultPhoneNotifier.convertDataActivityState(mPhone.getDataActivityState());
     }
 
+    @Override
     public Bundle getCellLocation() {
         try {
             mApp.enforceCallingOrSelfPermission(
@@ -607,23 +611,33 @@
             mApp.enforceCallingOrSelfPermission(
                 android.Manifest.permission.ACCESS_COARSE_LOCATION, null);
         }
-        Bundle data = new Bundle();
-        mPhone.getCellLocation().fillInNotifierBundle(data);
-        return data;
+
+        if (checkIfCallerIsSelfOrForegoundUser()) {
+            if (DBG_LOC) log("getCellLocation: is active user");
+            Bundle data = new Bundle();
+            mPhone.getCellLocation().fillInNotifierBundle(data);
+            return data;
+        } else {
+            if (DBG_LOC) log("getCellLocation: suppress non-active user");
+            return null;
+        }
     }
 
+    @Override
     public void enableLocationUpdates() {
         mApp.enforceCallingOrSelfPermission(
                 android.Manifest.permission.CONTROL_LOCATION_UPDATES, null);
         mPhone.enableLocationUpdates();
     }
 
+    @Override
     public void disableLocationUpdates() {
         mApp.enforceCallingOrSelfPermission(
                 android.Manifest.permission.CONTROL_LOCATION_UPDATES, null);
         mPhone.disableLocationUpdates();
     }
 
+    @Override
     @SuppressWarnings("unchecked")
     public List<NeighboringCellInfo> getNeighboringCellInfo() {
         try {
@@ -638,19 +652,26 @@
                     android.Manifest.permission.ACCESS_COARSE_LOCATION, null);
         }
 
-        ArrayList<NeighboringCellInfo> cells = null;
+        if (checkIfCallerIsSelfOrForegoundUser()) {
+            if (DBG_LOC) log("getNeighboringCellInfo: is active user");
 
-        try {
-            cells = (ArrayList<NeighboringCellInfo>) sendRequest(
-                    CMD_HANDLE_NEIGHBORING_CELL, null);
-        } catch (RuntimeException e) {
-            Log.e(LOG_TAG, "getNeighboringCellInfo " + e);
+            ArrayList<NeighboringCellInfo> cells = null;
+
+            try {
+                cells = (ArrayList<NeighboringCellInfo>) sendRequest(
+                        CMD_HANDLE_NEIGHBORING_CELL, null);
+            } catch (RuntimeException e) {
+                Log.e(LOG_TAG, "getNeighboringCellInfo " + e);
+            }
+            return cells;
+        } else {
+            if (DBG_LOC) log("getNeighboringCellInfo: suppress non-active user");
+            return null;
         }
-
-        return (List <NeighboringCellInfo>) cells;
     }
 
 
+    @Override
     public List<CellInfo> getAllCellInfo() {
         try {
             mApp.enforceCallingOrSelfPermission(
@@ -663,14 +684,51 @@
                 android.Manifest.permission.ACCESS_COARSE_LOCATION, null);
         }
 
-        // TODO return cell info list got from mPhone
-        return null;
+        if (checkIfCallerIsSelfOrForegoundUser()) {
+            if (DBG_LOC) log("getAllCellInfo: is active user");
+            return mPhone.getAllCellInfo();
+        } else {
+            if (DBG_LOC) log("getAllCellInfo: suppress non-active user");
+            return null;
+        }
     }
 
     //
     // Internal helper methods.
     //
 
+    private boolean checkIfCallerIsSelfOrForegoundUser() {
+        boolean ok;
+
+        boolean self = Binder.getCallingUid() == Process.myUid();
+        if (!self) {
+            // Get the caller's user id then clear the calling identity
+            // which will be restored in the finally clause.
+            int callingUser = UserHandle.getCallingUserId();
+            long ident = Binder.clearCallingIdentity();
+
+            try {
+                // With calling identity cleared the current user is the foreground user.
+                int foregroundUser = ActivityManager.getCurrentUser();
+                ok = (foregroundUser == callingUser);
+                if (DBG_LOC) {
+                    log("checkIfCallerIsSelfOrForegoundUser: foregroundUser=" + foregroundUser
+                            + " callingUser=" + callingUser + " ok=" + ok);
+                }
+            } catch (Exception ex) {
+                if (DBG_LOC) loge("checkIfCallerIsSelfOrForegoundUser: Exception ex=" + ex);
+                ok = false;
+            } finally {
+                Binder.restoreCallingIdentity(ident);
+            }
+        } else {
+            if (DBG_LOC) log("checkIfCallerIsSelfOrForegoundUser: is self");
+            ok = true;
+        }
+        if (DBG_LOC) log("checkIfCallerIsSelfOrForegoundUser: ret=" + ok);
+        return ok;
+    }
+
     /**
      * Make sure the caller has the READ_PHONE_STATE permission.
      *
@@ -713,6 +771,10 @@
         Log.d(LOG_TAG, "[PhoneIntfMgr] " + msg);
     }
 
+    private void loge(String msg) {
+        Log.e(LOG_TAG, "[PhoneIntfMgr] " + msg);
+    }
+
     public int getActivePhoneType() {
         return mPhone.getPhoneType();
     }
diff --git a/src/com/android/phone/PhoneUtils.java b/src/com/android/phone/PhoneUtils.java
index 616bd40..b71ae35 100644
--- a/src/com/android/phone/PhoneUtils.java
+++ b/src/com/android/phone/PhoneUtils.java
@@ -19,6 +19,7 @@
 import android.app.AlertDialog;
 import android.app.Dialog;
 import android.app.ProgressDialog;
+import android.bluetooth.IBluetoothHeadsetPhone;
 import android.content.ActivityNotFoundException;
 import android.content.ComponentName;
 import android.content.Context;
@@ -27,6 +28,7 @@
 import android.content.ServiceConnection;
 import android.content.pm.ApplicationInfo;
 import android.content.pm.PackageManager;
+import android.content.res.Configuration;
 import android.graphics.drawable.Drawable;
 import android.media.AudioManager;
 import android.net.Uri;
@@ -75,7 +77,7 @@
  */
 public class PhoneUtils {
     private static final String LOG_TAG = "PhoneUtils";
-    private static final boolean DBG = (PhoneApp.DBG_LEVEL >= 2);
+    private static final boolean DBG = (PhoneGlobals.DBG_LEVEL >= 2);
 
     // Do not check in with VDBG = true, since that may write PII to the system log.
     private static final boolean VDBG = false;
@@ -244,7 +246,7 @@
      */
     /* package */ static boolean answerCall(Call ringing) {
         log("answerCall(" + ringing + ")...");
-        final PhoneApp app = PhoneApp.getInstance();
+        final PhoneGlobals app = PhoneGlobals.getInstance();
 
         // If the ringer is currently ringing and/or vibrating, stop it
         // right now (before actually answering the call.)
@@ -253,7 +255,7 @@
         final Phone phone = ringing.getPhone();
         final boolean phoneIsCdma = (phone.getPhoneType() == PhoneConstants.PHONE_TYPE_CDMA);
         boolean answered = false;
-        BluetoothHandsfree bluetoothHandsfree = null;
+        IBluetoothHeadsetPhone btPhone = null;
 
         if (phoneIsCdma) {
             // Stop any signalInfo tone being played when a Call waiting gets answered
@@ -283,14 +285,18 @@
                         // drops off
                         app.cdmaPhoneCallState.setAddCallMenuStateAfterCallWaiting(true);
 
-                        // If a BluetoothHandsfree is valid we need to set the second call state
+                        // If a BluetoothPhoneService is valid we need to set the second call state
                         // so that the Bluetooth client can update the Call state correctly when
                         // a call waiting is answered from the Phone.
-                        bluetoothHandsfree = app.getBluetoothHandsfree();
-                        if (bluetoothHandsfree != null) {
-                            bluetoothHandsfree.cdmaSetSecondCallState(true);
+                        btPhone = app.getBluetoothPhoneService();
+                        if (btPhone != null) {
+                            try {
+                                btPhone.cdmaSetSecondCallState(true);
+                            } catch (RemoteException e) {
+                                Log.e(LOG_TAG, Log.getStackTraceString(new Throwable()));
+                            }
                         }
-                    }
+                  }
                 }
 
                 final boolean isRealIncomingCall = isRealIncomingCall(ringing.getState());
@@ -316,7 +322,7 @@
                 // - we did not activate speaker by ourselves during the process above, and
                 // - Bluetooth headset is not in use.
                 if (isRealIncomingCall && !speakerActivated && isSpeakerOn(app)
-                        && !(bluetoothHandsfree != null && bluetoothHandsfree.isAudioOn())) {
+                        && !app.isBluetoothHeadsetAudioOn()) {
                     // This is not an error but might cause users' confusion. Add log just in case.
                     Log.i(LOG_TAG, "Forcing speaker off due to new incoming call...");
                     turnOnSpeaker(app, false, true);
@@ -325,11 +331,15 @@
                 Log.w(LOG_TAG, "answerCall: caught " + ex, ex);
 
                 if (phoneIsCdma) {
-                    // restore the cdmaPhoneCallState and bthf.cdmaSetSecondCallState:
+                    // restore the cdmaPhoneCallState and btPhone.cdmaSetSecondCallState:
                     app.cdmaPhoneCallState.setCurrentCallState(
                             app.cdmaPhoneCallState.getPreviousCallState());
-                    if (bluetoothHandsfree != null) {
-                        bluetoothHandsfree.cdmaSetSecondCallState(false);
+                    if (btPhone != null) {
+                        try {
+                            btPhone.cdmaSetSecondCallState(false);
+                        } catch (RemoteException e) {
+                            Log.e(LOG_TAG, Log.getStackTraceString(new Throwable()));
+                        }
                     }
                 }
             }
@@ -398,7 +408,7 @@
                 // For Call waiting we DO NOT call the conventional hangup(call) function
                 // as in CDMA we just want to hangup the Call waiting connection.
                 log("hangupRingingCall(): CDMA-specific call-waiting hangup");
-                final CallNotifier notifier = PhoneApp.getInstance().notifier;
+                final CallNotifier notifier = PhoneGlobals.getInstance().notifier;
                 notifier.sendCdmaCallWaitingReject();
                 return true;
             } else {
@@ -464,7 +474,7 @@
      */
     static boolean hangup(Call call) {
         try {
-            CallManager cm = PhoneApp.getInstance().mCM;
+            CallManager cm = PhoneGlobals.getInstance().mCM;
 
             if (call.getState() == Call.State.ACTIVE && cm.hasActiveBgCall()) {
                 // handle foreground call hangup while there is background call
@@ -560,7 +570,7 @@
      * </pre>
      * @param app The phone instance.
      */
-    private static void updateCdmaCallStateOnNewOutgoingCall(PhoneApp app) {
+    private static void updateCdmaCallStateOnNewOutgoingCall(PhoneGlobals app) {
         if (app.cdmaPhoneCallState.getCurrentCallState() ==
             CdmaPhoneCallState.PhoneCallState.IDLE) {
             // This is the first outgoing call. Set the Phone Call State to ACTIVE
@@ -607,7 +617,7 @@
                     + ", GW: " + (gatewayUri != null ? "non-null" : "null")
                     + ", emergency? " + isEmergencyCall);
         }
-        final PhoneApp app = PhoneApp.getInstance();
+        final PhoneGlobals app = PhoneGlobals.getInstance();
 
         boolean useGateway = false;
         if (null != gatewayUri &&
@@ -736,9 +746,8 @@
             final boolean speakerActivated = activateSpeakerIfDocked(phone);
 
             // See also similar logic in answerCall().
-            final BluetoothHandsfree bluetoothHandsfree = app.getBluetoothHandsfree();
             if (initiallyIdle && !speakerActivated && isSpeakerOn(app)
-                    && !(bluetoothHandsfree != null && bluetoothHandsfree.isAudioOn())) {
+                    && !app.isBluetoothHeadsetAudioOn()) {
                 // This is not an error but might cause users' confusion. Add log just in case.
                 Log.i(LOG_TAG, "Forcing speaker off when initiating a new outgoing call...");
                 PhoneUtils.turnOnSpeaker(app, false, true);
@@ -790,7 +799,7 @@
     static void switchHoldingAndActive(Call heldCall) {
         log("switchHoldingAndActive()...");
         try {
-            CallManager cm = PhoneApp.getInstance().mCM;
+            CallManager cm = PhoneGlobals.getInstance().mCM;
             if (heldCall.isIdle()) {
                 // no heldCall, so it is to hold active call
                 cm.switchHoldingAndActive(cm.getFgPhone().getBackgroundCall());
@@ -809,7 +818,7 @@
      * foreground call.
      */
     static Boolean restoreMuteState() {
-        Phone phone = PhoneApp.getInstance().mCM.getFgPhone();
+        Phone phone = PhoneGlobals.getInstance().mCM.getFgPhone();
 
         //get the earliest connection
         Connection c = phone.getForegroundCall().getEarliestConnection();
@@ -846,14 +855,14 @@
     }
 
     static void mergeCalls() {
-        mergeCalls(PhoneApp.getInstance().mCM);
+        mergeCalls(PhoneGlobals.getInstance().mCM);
     }
 
     static void mergeCalls(CallManager cm) {
         int phoneType = cm.getFgPhone().getPhoneType();
         if (phoneType == PhoneConstants.PHONE_TYPE_CDMA) {
             log("mergeCalls(): CDMA...");
-            PhoneApp app = PhoneApp.getInstance();
+            PhoneGlobals app = PhoneGlobals.getInstance();
             if (app.cdmaPhoneCallState.getCurrentCallState()
                     == CdmaPhoneCallState.PhoneCallState.THRWAY_ACTIVE) {
                 // Set the Phone Call State to conference
@@ -1000,7 +1009,7 @@
     static void displayMMIComplete(final Phone phone, Context context, final MmiCode mmiCode,
             Message dismissCallbackMessage,
             AlertDialog previousAlert) {
-        final PhoneApp app = PhoneApp.getInstance();
+        final PhoneGlobals app = PhoneGlobals.getInstance();
         CharSequence text;
         int title = 0;  // title for the progress dialog, if needed.
         MmiCode.State state = mmiCode.getState();
@@ -1297,7 +1306,7 @@
             return actualNumberToDial;
         }
 
-        return getNumberFromIntent(PhoneApp.getInstance(), intent);
+        return getNumberFromIntent(PhoneGlobals.getInstance(), intent);
     }
 
     /**
@@ -1790,7 +1799,7 @@
         // 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 PhoneApp app = PhoneApp.getInstance();
+        final PhoneGlobals app = PhoneGlobals.getInstance();
         int phoneType = call.getPhone().getPhoneType();
         if (phoneType == PhoneConstants.PHONE_TYPE_CDMA) {
             CdmaPhoneCallState.PhoneCallState state = app.cdmaPhoneCallState.getCurrentCallState();
@@ -1832,7 +1841,7 @@
      * This is just a wrapper around the ACTION_DIAL intent.
      */
     /* package */ static boolean startNewCall(final CallManager cm) {
-        final PhoneApp app = PhoneApp.getInstance();
+        final PhoneGlobals app = PhoneGlobals.getInstance();
 
         // Sanity-check that this is OK given the current state of the phone.
         if (!okToAddCall(cm)) {
@@ -1878,7 +1887,7 @@
      */
     /* package */ static void turnOnSpeaker(Context context, boolean flag, boolean store) {
         if (DBG) log("turnOnSpeaker(flag=" + flag + ", store=" + store + ")...");
-        final PhoneApp app = PhoneApp.getInstance();
+        final PhoneGlobals app = PhoneGlobals.getInstance();
 
         AudioManager audioManager = (AudioManager) context.getSystemService(Context.AUDIO_SERVICE);
         audioManager.setSpeakerphoneOn(flag);
@@ -1986,7 +1995,7 @@
      *
      */
     static void setMute(boolean muted) {
-        CallManager cm = PhoneApp.getInstance().mCM;
+        CallManager cm = PhoneGlobals.getInstance().mCM;
 
         // make the call to mute the audio
         setMuteInternal(cm.getFgPhone(), muted);
@@ -2005,7 +2014,7 @@
      * Internally used muting function.
      */
     private static void setMuteInternal(Phone phone, boolean muted) {
-        final PhoneApp app = PhoneApp.getInstance();
+        final PhoneGlobals app = PhoneGlobals.getInstance();
         Context context = phone.getContext();
         boolean routeToAudioManager =
             context.getResources().getBoolean(R.bool.send_mic_mute_to_AudioManager);
@@ -2026,7 +2035,7 @@
      * foreground call
      */
     static boolean getMute() {
-        final PhoneApp app = PhoneApp.getInstance();
+        final PhoneGlobals app = PhoneGlobals.getInstance();
 
         boolean routeToAudioManager =
             app.getResources().getBoolean(R.bool.send_mic_mute_to_AudioManager);
@@ -2040,7 +2049,7 @@
     }
 
     /* package */ static void setAudioMode() {
-        setAudioMode(PhoneApp.getInstance().mCM);
+        setAudioMode(PhoneGlobals.getInstance().mCM);
     }
 
     /**
@@ -2049,7 +2058,7 @@
     /* package */ static void setAudioMode(CallManager cm) {
         if (DBG) Log.d(LOG_TAG, "setAudioMode()..." + cm.getState());
 
-        Context context = PhoneApp.getInstance();
+        Context context = PhoneGlobals.getInstance();
         AudioManager audioManager = (AudioManager)
                 context.getSystemService(Context.AUDIO_SERVICE);
         int modeBefore = audioManager.getMode();
@@ -2087,7 +2096,7 @@
      */
     /* package */ static boolean handleHeadsetHook(Phone phone, KeyEvent event) {
         if (DBG) log("handleHeadsetHook()..." + event.getAction() + " " + event.getRepeatCount());
-        final PhoneApp app = PhoneApp.getInstance();
+        final PhoneGlobals app = PhoneGlobals.getInstance();
 
         // If the phone is totally idle, we ignore HEADSETHOOK events
         // (and instead let them fall through to the media player.)
@@ -2140,7 +2149,7 @@
                 Connection c = phone.getForegroundCall().getLatestConnection();
                 // If it is NOT an emg #, toggle the mute state. Otherwise, ignore the hook.
                 if (c != null && !PhoneNumberUtils.isLocalEmergencyNumber(c.getAddress(),
-                                                                          PhoneApp.getInstance())) {
+                                                                          PhoneGlobals.getInstance())) {
                     if (getMute()) {
                         if (DBG) log("handleHeadsetHook: UNmuting...");
                         setMute(false);
@@ -2212,7 +2221,7 @@
         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
-            PhoneApp app = PhoneApp.getInstance();
+            PhoneGlobals app = PhoneGlobals.getInstance();
             return (app.cdmaPhoneCallState.getCurrentCallState()
                     == CdmaPhoneCallState.PhoneCallState.CONF_CALL);
         } else if ((phoneType == PhoneConstants.PHONE_TYPE_GSM)
@@ -2238,7 +2247,7 @@
         int phoneType = cm.getFgPhone().getPhoneType();
         if (phoneType == PhoneConstants.PHONE_TYPE_CDMA) {
             // CDMA: "Merge" is enabled only when the user is in a 3Way call.
-            PhoneApp app = PhoneApp.getInstance();
+            PhoneGlobals app = PhoneGlobals.getInstance();
             return ((app.cdmaPhoneCallState.getCurrentCallState()
                     == CdmaPhoneCallState.PhoneCallState.THRWAY_ACTIVE)
                     && !app.cdmaPhoneCallState.IsThreeWayCallOrigStateDialing());
@@ -2271,7 +2280,7 @@
            // CDMA: "Add call" button is only enabled when:
            // - ForegroundCall is in ACTIVE state
            // - After 30 seconds of user Ignoring/Missing a Call Waiting call.
-            PhoneApp app = PhoneApp.getInstance();
+            PhoneGlobals app = PhoneGlobals.getInstance();
             return ((fgCallState == Call.State.ACTIVE)
                     && (app.cdmaPhoneCallState.getAddCallMenuStateAfterCallWaiting()));
         } else if ((phoneType == PhoneConstants.PHONE_TYPE_GSM)
@@ -2518,12 +2527,11 @@
         if (DBG) log("activateSpeakerIfDocked()...");
 
         boolean activated = false;
-        if (PhoneApp.mDockState != Intent.EXTRA_DOCK_STATE_UNDOCKED) {
+        if (PhoneGlobals.mDockState != Intent.EXTRA_DOCK_STATE_UNDOCKED) {
             if (DBG) log("activateSpeakerIfDocked(): In a dock -> may need to turn on speaker.");
-            PhoneApp app = PhoneApp.getInstance();
-            BluetoothHandsfree bthf = app.getBluetoothHandsfree();
+            PhoneGlobals app = PhoneGlobals.getInstance();
 
-            if (!app.isHeadsetPlugged() && !(bthf != null && bthf.isAudioOn())) {
+            if (!app.isHeadsetPlugged() && !app.isBluetoothHeadsetAudioOn()) {
                 turnOnSpeaker(phone.getContext(), true, true);
                 activated = true;
             }
@@ -2595,12 +2603,12 @@
      * meaning the call is the first real incoming call the phone is having.
      */
     public static boolean isRealIncomingCall(Call.State state) {
-        return (state == Call.State.INCOMING && !PhoneApp.getInstance().mCM.hasActiveFgCall());
+        return (state == Call.State.INCOMING && !PhoneGlobals.getInstance().mCM.hasActiveFgCall());
     }
 
     private static boolean sVoipSupported = false;
     static {
-        PhoneApp app = PhoneApp.getInstance();
+        PhoneGlobals app = PhoneGlobals.getInstance();
         sVoipSupported = SipManager.isVoipSupported(app)
                 && app.getResources().getBoolean(com.android.internal.R.bool.config_built_in_sip_phone)
                 && app.getResources().getBoolean(com.android.internal.R.bool.config_voice_capable);
@@ -2661,7 +2669,7 @@
     //
 
     /* package */ static void dumpCallState(Phone phone) {
-        PhoneApp app = PhoneApp.getInstance();
+        PhoneGlobals app = PhoneGlobals.getInstance();
         Log.d(LOG_TAG, "dumpCallState():");
         Log.d(LOG_TAG, "- Phone: " + phone + ", name = " + phone.getPhoneName()
               + ", state = " + phone.getState());
@@ -2733,7 +2741,7 @@
 
     static void dumpCallManager() {
         Call call;
-        CallManager cm = PhoneApp.getInstance().mCM;
+        CallManager cm = PhoneGlobals.getInstance().mCM;
         StringBuilder b = new StringBuilder(128);
 
 
@@ -2795,4 +2803,12 @@
 
         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;
+    }
 }
diff --git a/src/com/android/phone/Profiler.java b/src/com/android/phone/Profiler.java
index 186d126..234073c 100644
--- a/src/com/android/phone/Profiler.java
+++ b/src/com/android/phone/Profiler.java
@@ -26,7 +26,7 @@
  * Profiling utilities for the Phone app.
  */
 public class Profiler {
-    private static final String LOG_TAG = PhoneApp.LOG_TAG;
+    private static final String LOG_TAG = PhoneGlobals.LOG_TAG;
 
     // Let the compiler optimize all this code out unless we're actively
     // doing profiling runs.
diff --git a/src/com/android/phone/RespondViaSmsManager.java b/src/com/android/phone/RespondViaSmsManager.java
index bc2ee7b..003c56f 100644
--- a/src/com/android/phone/RespondViaSmsManager.java
+++ b/src/com/android/phone/RespondViaSmsManager.java
@@ -49,12 +49,13 @@
 
 /**
  * Helper class to manage the "Respond via SMS" feature for incoming calls.
+ *
  * @see InCallScreen.internalRespondViaSms()
  */
 public class RespondViaSmsManager {
     private static final String TAG = "RespondViaSmsManager";
     private static final boolean DBG =
-            (PhoneApp.DBG_LEVEL >= 1) && (SystemProperties.getInt("ro.debuggable", 0) == 1);
+            (PhoneGlobals.DBG_LEVEL >= 1) && (SystemProperties.getInt("ro.debuggable", 0) == 1);
     // Do not check in with VDBG = true, since that may write PII to the system log.
     private static final boolean VDBG = false;
 
@@ -118,6 +119,13 @@
     public void showRespondViaSmsPopup(Call ringingCall) {
         if (DBG) log("showRespondViaSmsPopup()...");
 
+        // Very quick succession of clicks can cause this to run twice.
+        // Stop here to avoid creating more than one popup.
+        if (isShowingPopup()) {
+            if (DBG) log("Skip showing popup when one is already shown.");
+            return;
+        }
+
         ListView lv = new ListView(mInCallScreen);
 
         // Refresh the array of "canned responses".
@@ -259,10 +267,10 @@
 
             dismissPopup();
 
-            final PhoneConstants.State state = PhoneApp.getInstance().mCM.getState();
+            final PhoneConstants.State state = PhoneGlobals.getInstance().mCM.getState();
             if (state == PhoneConstants.State.IDLE) {
                 // There's no other phone call to interact. Exit the entire in-call screen.
-                PhoneApp.getInstance().dismissCallScreen();
+                PhoneGlobals.getInstance().dismissCallScreen();
             } else {
                 // The user is still in the middle of other phone calls, so we should keep the
                 // in-call screen.
@@ -288,11 +296,11 @@
 
             dismissPopup();
 
-            final PhoneConstants.State state = PhoneApp.getInstance().mCM.getState();
+            final PhoneConstants.State state = PhoneGlobals.getInstance().mCM.getState();
             if (state == PhoneConstants.State.IDLE) {
                 // This means the incoming call is already hung up when the user chooses not to
                 // use "Respond via SMS" feature. Let's just exit the whole in-call screen.
-                PhoneApp.getInstance().dismissCallScreen();
+                PhoneGlobals.getInstance().dismissCallScreen();
             } else {
 
                 // If the user cancels the popup, this presumably means that
@@ -303,7 +311,7 @@
                 // call UI.
 
                 // This will have no effect if the incoming call isn't still ringing.
-                PhoneApp.getInstance().notifier.restartRinger();
+                PhoneGlobals.getInstance().notifier.restartRinger();
 
                 // We hid the GlowPadView widget way back in
                 // InCallTouchUi.onTrigger(), when the user first selected
diff --git a/src/com/android/phone/Ringer.java b/src/com/android/phone/Ringer.java
index edbcdfa..e97716f 100644
--- a/src/com/android/phone/Ringer.java
+++ b/src/com/android/phone/Ringer.java
@@ -41,7 +41,7 @@
 public class Ringer {
     private static final String LOG_TAG = "Ringer";
     private static final boolean DBG =
-            (PhoneApp.DBG_LEVEL >= 1) && (SystemProperties.getInt("ro.debuggable", 0) == 1);
+            (PhoneGlobals.DBG_LEVEL >= 1) && (SystemProperties.getInt("ro.debuggable", 0) == 1);
 
     private static final int PLAY_RING_ONCE = 1;
     private static final int STOP_RING = 3;
@@ -149,7 +149,7 @@
 
         synchronized (this) {
             try {
-                if (PhoneApp.getInstance().showBluetoothIndication()) {
+                if (PhoneGlobals.getInstance().showBluetoothIndication()) {
                     mPowerManager.setAttentionLight(true, 0x000000ff);
                 } else {
                     mPowerManager.setAttentionLight(true, 0x00ffffff);
diff --git a/src/com/android/phone/SipBroadcastReceiver.java b/src/com/android/phone/SipBroadcastReceiver.java
index 0717c72..c33c5e1 100644
--- a/src/com/android/phone/SipBroadcastReceiver.java
+++ b/src/com/android/phone/SipBroadcastReceiver.java
@@ -91,7 +91,7 @@
     }
 
     private void takeCall(Intent intent) {
-        Context phoneContext = PhoneApp.getInstance();
+        Context phoneContext = PhoneGlobals.getInstance();
         try {
             SipAudioCall sipAudioCall = SipManager.newInstance(phoneContext)
                     .takeAudioCall(intent, null);
@@ -107,7 +107,7 @@
     }
 
     private void registerAllProfiles() {
-        final Context context = PhoneApp.getInstance();
+        final Context context = PhoneGlobals.getInstance();
         new Thread(new Runnable() {
             public void run() {
                 SipManager sipManager = SipManager.newInstance(context);
diff --git a/src/com/android/phone/SipCallOptionHandler.java b/src/com/android/phone/SipCallOptionHandler.java
index 64d18c5..500f322 100644
--- a/src/com/android/phone/SipCallOptionHandler.java
+++ b/src/com/android/phone/SipCallOptionHandler.java
@@ -64,7 +64,7 @@
         CompoundButton.OnCheckedChangeListener {
     static final String TAG = "SipCallOptionHandler";
     private static final boolean DBG =
-            (PhoneApp.DBG_LEVEL >= 1) && (SystemProperties.getInt("ro.debuggable", 0) == 1);
+            (PhoneGlobals.DBG_LEVEL >= 1) && (SystemProperties.getInt("ro.debuggable", 0) == 1);
 
     static final int DIALOG_SELECT_PHONE_TYPE = 0;
     static final int DIALOG_SELECT_OUTGOING_SIP_PHONE = 1;
@@ -147,7 +147,7 @@
         Uri uri = mIntent.getData();
         String scheme = uri.getScheme();
         mNumber = PhoneNumberUtils.getNumberFromIntent(mIntent, this);
-        boolean isInCellNetwork = PhoneApp.getInstance().phoneMgr.isRadioOn();
+        boolean isInCellNetwork = PhoneGlobals.getInstance().phoneMgr.isRadioOn();
         boolean isKnownCallScheme = Constants.SCHEME_TEL.equals(scheme)
                 || Constants.SCHEME_SIP.equals(scheme);
         boolean isRegularCall = Constants.SCHEME_TEL.equals(scheme)
@@ -351,7 +351,7 @@
     }
 
     private void createSipPhoneIfNeeded(SipProfile p) {
-        CallManager cm = PhoneApp.getInstance().mCM;
+        CallManager cm = PhoneGlobals.getInstance().mCM;
         if (PhoneUtils.getSipPhoneFromUri(cm, p.getUriString()) != null) return;
 
         // Create the phone since we can not find it in CallManager
@@ -392,7 +392,7 @@
                     return;
                 } else {
                     // Woo hoo -- it's finally OK to initiate the outgoing call!
-                    PhoneApp.getInstance().callController.placeCall(mIntent);
+                    PhoneGlobals.getInstance().callController.placeCall(mIntent);
                 }
                 finish();
             }
diff --git a/src/com/android/phone/SipUtil.java b/src/com/android/phone/SipUtil.java
index 85a3110..a901d58 100644
--- a/src/com/android/phone/SipUtil.java
+++ b/src/com/android/phone/SipUtil.java
@@ -26,7 +26,7 @@
     }
 
     public static PendingIntent createIncomingCallPendingIntent() {
-        Context phoneContext = PhoneApp.getInstance();
+        Context phoneContext = PhoneGlobals.getInstance();
         Intent intent = new Intent(phoneContext, SipBroadcastReceiver.class);
         intent.setAction(SipManager.ACTION_SIP_INCOMING_CALL);
         return PendingIntent.getBroadcast(phoneContext, 0, intent,
diff --git a/src/com/android/phone/SpecialCharSequenceMgr.java b/src/com/android/phone/SpecialCharSequenceMgr.java
index 0bda10a..a61b378 100644
--- a/src/com/android/phone/SpecialCharSequenceMgr.java
+++ b/src/com/android/phone/SpecialCharSequenceMgr.java
@@ -50,7 +50,7 @@
  * unify these two classes (in the framework? in a common shared library?)
  */
 public class SpecialCharSequenceMgr {
-    private static final String TAG = PhoneApp.LOG_TAG;
+    private static final String TAG = PhoneGlobals.LOG_TAG;
     private static final boolean DBG = false;
 
     private static final String MMI_IMEI_DISPLAY = "*#06#";
@@ -164,7 +164,7 @@
         // input.  We want to make sure that sim card contacts are NOT
         // exposed unless the phone is unlocked, and this code can be
         // accessed from the emergency dialer.
-        if (PhoneApp.getInstance().getKeyguardManager().inKeyguardRestrictedInputMode()) {
+        if (PhoneGlobals.getInstance().getKeyguardManager().inKeyguardRestrictedInputMode()) {
             return false;
         }
 
@@ -178,7 +178,7 @@
                                     "com.android.phone.SimContacts");
                 intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
                 intent.putExtra("index", index);
-                PhoneApp.getInstance().startActivity(intent);
+                PhoneGlobals.getInstance().startActivity(intent);
 
                 return true;
             } catch (NumberFormatException ex) {}
@@ -193,7 +193,7 @@
         // if a dialstring is an MMI code.
         if ((input.startsWith("**04") || input.startsWith("**05"))
                 && input.endsWith("#")) {
-            PhoneApp app = PhoneApp.getInstance();
+            PhoneGlobals app = PhoneGlobals.getInstance();
             boolean isMMIHandled = app.phone.handlePinMmi(input);
 
             // if the PUK code is recognized then indicate to the
@@ -222,7 +222,7 @@
     static private void showDeviceIdPanel(Context context) {
         if (DBG) log("showDeviceIdPanel()...");
 
-        Phone phone = PhoneApp.getPhone();
+        Phone phone = PhoneGlobals.getPhone();
         int labelId = TelephonyCapabilities.getDeviceIdLabel(phone);
         String deviceId = phone.getDeviceId();
 
diff --git a/src/com/android/phone/TimeConsumingPreferenceActivity.java b/src/com/android/phone/TimeConsumingPreferenceActivity.java
index 89275e7..19c4dda 100644
--- a/src/com/android/phone/TimeConsumingPreferenceActivity.java
+++ b/src/com/android/phone/TimeConsumingPreferenceActivity.java
@@ -24,7 +24,7 @@
                         implements TimeConsumingPreferenceListener,
                         DialogInterface.OnCancelListener {
     private static final String LOG_TAG = "TimeConsumingPreferenceActivity";
-    private final boolean DBG = (PhoneApp.DBG_LEVEL >= 2);
+    private final boolean DBG = (PhoneGlobals.DBG_LEVEL >= 2);
 
     private class DismissOnClickListener implements DialogInterface.OnClickListener {
         @Override
diff --git a/src/com/android/phone/Use2GOnlyCheckBoxPreference.java b/src/com/android/phone/Use2GOnlyCheckBoxPreference.java
index a25882e..4da238b 100644
--- a/src/com/android/phone/Use2GOnlyCheckBoxPreference.java
+++ b/src/com/android/phone/Use2GOnlyCheckBoxPreference.java
@@ -42,7 +42,7 @@
 
     public Use2GOnlyCheckBoxPreference(Context context, AttributeSet attrs, int defStyle) {
         super(context, attrs, defStyle);
-        mPhone = PhoneApp.getPhone();
+        mPhone = PhoneGlobals.getPhone();
         mHandler = new MyHandler();
         mPhone.getPreferredNetworkType(
                 mHandler.obtainMessage(MyHandler.MESSAGE_GET_PREFERRED_NETWORK_TYPE));
@@ -54,8 +54,8 @@
 
         int networkType = isChecked() ? Phone.NT_MODE_GSM_ONLY : Phone.NT_MODE_WCDMA_PREF;
         Log.i(LOG_TAG, "set preferred network type="+networkType);
-        android.provider.Settings.Secure.putInt(mPhone.getContext().getContentResolver(),
-                android.provider.Settings.Secure.PREFERRED_NETWORK_MODE, networkType);
+        android.provider.Settings.Global.putInt(mPhone.getContext().getContentResolver(),
+                android.provider.Settings.Global.PREFERRED_NETWORK_MODE, networkType);
         mPhone.setPreferredNetworkType(networkType, mHandler
                 .obtainMessage(MyHandler.MESSAGE_SET_PREFERRED_NETWORK_TYPE));
    }
@@ -89,8 +89,8 @@
                 }
                 Log.i(LOG_TAG, "get preferred network type="+type);
                 setChecked(type == Phone.NT_MODE_GSM_ONLY);
-                android.provider.Settings.Secure.putInt(mPhone.getContext().getContentResolver(),
-                        android.provider.Settings.Secure.PREFERRED_NETWORK_MODE, type);
+                android.provider.Settings.Global.putInt(mPhone.getContext().getContentResolver(),
+                        android.provider.Settings.Global.PREFERRED_NETWORK_MODE, type);
             } else {
                 // Weird state, disable the setting
                 Log.i(LOG_TAG, "get preferred network type, exception="+ar.exception);
