merge in KFS78N (no-op)
diff --git a/Android.mk b/Android.mk
index a425dcc..b12d32e 100644
--- a/Android.mk
+++ b/Android.mk
@@ -16,7 +16,6 @@
src/com/android/phone/INetworkQueryServiceCallback.aidl
LOCAL_PACKAGE_NAME := TeleService
-LOCAL_OVERRIDES_PACKAGES := Phone
LOCAL_CERTIFICATE := platform
LOCAL_PRIVILEGED_MODULE := true
diff --git a/AndroidManifest.xml b/AndroidManifest.xml
index fe71d4c..5615b85 100644
--- a/AndroidManifest.xml
+++ b/AndroidManifest.xml
@@ -40,6 +40,7 @@
<protected-broadcast android:name="com.android.internal.telephony.data-restart-trysetup" />
<protected-broadcast android:name="com.android.internal.telephony.data-stall" />
+ <uses-permission android:name="android.permission.BIND_CALL_SERVICE" />
<uses-permission android:name="android.permission.BROADCAST_STICKY" />
<uses-permission android:name="android.permission.CALL_PHONE" />
<uses-permission android:name="android.permission.CALL_PRIVILEGED" />
@@ -514,9 +515,10 @@
</activity>
<activity android:name="HfaActivity"
- android:excludeFromRecents="true"
+ android:configChanges="orientation|screenSize|keyboardHidden"
android:launchMode="singleInstance"
- android:theme="@style/Empty">
+ android:theme="@style/Empty"
+ android:exported="false">
</activity>
<receiver android:name="CallerInfoCacheUpdateReceiver">
@@ -534,5 +536,8 @@
</intent-filter>
</receiver>
+ <!-- service to dump telephony information -->
+ <service android:name="HfaService" android:exported="false"/>
+
</application>
</manifest>
diff --git a/common/src/com/android/services/telephony/common/Call.java b/common/src/com/android/services/telephony/common/Call.java
index b2774ec..4a74114 100644
--- a/common/src/com/android/services/telephony/common/Call.java
+++ b/common/src/com/android/services/telephony/common/Call.java
@@ -47,9 +47,11 @@
public static final int INCOMING = 3; /* A normal incoming phone call */
public static final int CALL_WAITING = 4; /* Incoming call while another is active */
public static final int DIALING = 5; /* An outgoing call during dial phase */
- public static final int ONHOLD = 6; /* An active phone call placed on hold */
- public static final int DISCONNECTED = 7; /* State after a call disconnects */
- public static final int CONFERENCED = 8; /* Call part of a conference call */
+ public static final int REDIALING = 6; /* Subsequent dialing attempt after a failure */
+ public static final int ONHOLD = 7; /* An active phone call placed on hold */
+ public static final int DISCONNECTING = 8; /* A call is being ended. */
+ public static final int DISCONNECTED = 9; /* State after a call disconnects */
+ public static final int CONFERENCED = 10; /* Call part of a conference call */
public static boolean isConnected(int state) {
switch(state) {
@@ -57,6 +59,7 @@
case INCOMING:
case CALL_WAITING:
case DIALING:
+ case REDIALING:
case ONHOLD:
case CONFERENCED:
return true;
@@ -64,21 +67,30 @@
}
return false;
}
+
+ public static boolean isDialing(int state) {
+ return state == DIALING || state == REDIALING;
+ }
}
/**
* Defines a set of capabilities that a call can have as a bit mask.
* TODO: Should some of these be capabilities of the Phone instead of the call?
+ * TODO: This is starting to be a mix of capabilities and call properties. Capabilities
+ * and properties should be separated.
*/
public static class Capabilities {
- public static final int HOLD = 0x00000001; /* has ability to hold the call */
- public static final int MERGE_CALLS = 0x00000002; /* has ability to merge calls */
- public static final int SWAP_CALLS = 0x00000004; /* swap with a background call */
- public static final int ADD_CALL = 0x00000008; /* add another call to this one */
- public static final int RESPOND_VIA_TEXT = 0x00000010; /* has respond via text option */
+ public static final int HOLD = 0x00000001; /* has ability to hold the call */
+ public static final int SUPPORT_HOLD = 0x00000002; /* can show the hold button */
+ public static final int MERGE_CALLS = 0x00000004; /* has ability to merge calls */
+ public static final int SWAP_CALLS = 0x00000008; /* swap with a background call */
+ public static final int ADD_CALL = 0x00000010; /* add another call to this one */
+ public static final int RESPOND_VIA_TEXT = 0x00000020; /* has respond via text option */
+ public static final int MUTE = 0x00000040; /* can mute the call */
+ public static final int GENERIC_CONFERENCE = 0x00000080; /* Generic conference mode */
- public static final int ALL = HOLD | MERGE_CALLS | SWAP_CALLS | ADD_CALL
- | RESPOND_VIA_TEXT;
+ public static final int ALL = HOLD | SUPPORT_HOLD | MERGE_CALLS | SWAP_CALLS | ADD_CALL
+ | RESPOND_VIA_TEXT | MUTE | GENERIC_CONFERENCE;
}
/**
@@ -135,10 +147,12 @@
.put(Call.State.ACTIVE, "ACTIVE")
.put(Call.State.CALL_WAITING, "CALL_WAITING")
.put(Call.State.DIALING, "DIALING")
+ .put(Call.State.REDIALING, "REDIALING")
.put(Call.State.IDLE, "IDLE")
.put(Call.State.INCOMING, "INCOMING")
.put(Call.State.ONHOLD, "ONHOLD")
.put(Call.State.INVALID, "INVALID")
+ .put(Call.State.DISCONNECTING, "DISCONNECTING")
.put(Call.State.DISCONNECTED, "DISCONNECTED")
.put(Call.State.CONFERENCED, "CONFERENCED")
.build();
diff --git a/common/src/com/android/services/telephony/common/ICallCommandService.aidl b/common/src/com/android/services/telephony/common/ICallCommandService.aidl
index 660d8aa..cb3b674 100644
--- a/common/src/com/android/services/telephony/common/ICallCommandService.aidl
+++ b/common/src/com/android/services/telephony/common/ICallCommandService.aidl
@@ -16,6 +16,8 @@
package com.android.services.telephony.common;
+import com.android.services.telephony.common.Call;
+
/**
* Service implemented by TelephonyService and used by In-call UI to control
* phone calls on the device.
@@ -32,7 +34,7 @@
/**
* Reject a ringing call.
*/
- void rejectCall(int callId, boolean rejectWithMessage, String message);
+ void rejectCall(in Call call, boolean rejectWithMessage, String message);
/**
* Disconnect an active call.
@@ -96,4 +98,12 @@
void postDialCancel(int callId);
void postDialWaitContinue(int callId);
+
+ /**
+ * Enables or disables navigation using the system bar, and also prevents the
+ * notification shade from being dragged down.
+ * Hides or shows the home, recent and back buttons in the navigation bar if the
+ * device has soft navigation buttons.
+ */
+ void setSystemBarNavigationEnabled(boolean enable);
}
diff --git a/common/src/com/android/services/telephony/common/ICallHandlerService.aidl b/common/src/com/android/services/telephony/common/ICallHandlerService.aidl
index 0cbd9b9..c4f0961 100644
--- a/common/src/com/android/services/telephony/common/ICallHandlerService.aidl
+++ b/common/src/com/android/services/telephony/common/ICallHandlerService.aidl
@@ -67,7 +67,7 @@
/**
* Called when the system wants to bring the in-call UI into the foreground.
*/
- void bringToForeground();
+ void bringToForeground(boolean showDialpad);
void onPostDialWait(int callId, String remainingChars);
}
diff --git a/proguard.flags b/proguard.flags
index c5f4c72..c4af490 100644
--- a/proguard.flags
+++ b/proguard.flags
@@ -1,6 +1 @@
-# Keep names that are used only by animation framework.
--keepclasseswithmembers class com.android.phone.AnimationUtils$CrossFadeDrawable {
- *** setCrossFadeAlpha(...);
-}
-
--verbose
\ No newline at end of file
+-verbose
diff --git a/res/anim/activity_close_enter.xml b/res/anim/activity_close_enter.xml
deleted file mode 100644
index a526fe1..0000000
--- a/res/anim/activity_close_enter.xml
+++ /dev/null
@@ -1,24 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-/*
-** Copyright 2009, 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.
-*/
--->
-
-<set xmlns:android="http://schemas.android.com/apk/res/android" android:zAdjustment="normal">
- <alpha android:fromAlpha="1.0" android:toAlpha="1.0"
- android:fillEnabled="true" android:fillBefore="true" android:fillAfter="true"
- android:duration="300"/>
-</set>
diff --git a/res/anim/activity_close_exit.xml b/res/anim/activity_close_exit.xml
deleted file mode 100644
index b879bdb..0000000
--- a/res/anim/activity_close_exit.xml
+++ /dev/null
@@ -1,32 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-/*
-** Copyright 2009, 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.
-*/
--->
-
-<set xmlns:android="http://schemas.android.com/apk/res/android"
- android:shareInterpolator="false" android:zAdjustment="top">
- <alpha android:fromAlpha="1.0" android:toAlpha="0.0"
- android:interpolator="@*android:interpolator/decelerate_cubic"
- android:fillEnabled="true" android:fillBefore="true" android:fillAfter="true"
- android:duration="300"/>
- <scale android:fromXScale="1.0" android:toXScale=".8"
- android:fromYScale="1.0" android:toYScale=".8"
- android:pivotX="50%p" android:pivotY="50%p"
- android:interpolator="@*android:interpolator/decelerate_cubic"
- android:fillEnabled="true" android:fillBefore="true" android:fillAfter="true"
- android:duration="300"/>
-</set>
diff --git a/res/drawable-hdpi/endcall_active.png b/res/drawable-hdpi/endcall_active.png
deleted file mode 100644
index 38f1e1c..0000000
--- a/res/drawable-hdpi/endcall_active.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-hdpi/endcall_background_texture.png b/res/drawable-hdpi/endcall_background_texture.png
deleted file mode 100644
index 095b0b6..0000000
--- a/res/drawable-hdpi/endcall_background_texture.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-hdpi/endcall_disable.png b/res/drawable-hdpi/endcall_disable.png
deleted file mode 100644
index 6a0f658..0000000
--- a/res/drawable-hdpi/endcall_disable.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-hdpi/ic_ab_dialer_holo_dark.png b/res/drawable-hdpi/ic_ab_dialer_holo_dark.png
deleted file mode 100644
index ecfeb2d..0000000
--- a/res/drawable-hdpi/ic_ab_dialer_holo_dark.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-hdpi/ic_add_contact_holo_dark.png b/res/drawable-hdpi/ic_add_contact_holo_dark.png
deleted file mode 100644
index 88ff33b..0000000
--- a/res/drawable-hdpi/ic_add_contact_holo_dark.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-hdpi/ic_bluetooth_holo_dark.png b/res/drawable-hdpi/ic_bluetooth_holo_dark.png
deleted file mode 100644
index ba22b0f..0000000
--- a/res/drawable-hdpi/ic_bluetooth_holo_dark.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-hdpi/ic_dial_end_call.png b/res/drawable-hdpi/ic_dial_end_call.png
deleted file mode 100644
index ab3adb4..0000000
--- a/res/drawable-hdpi/ic_dial_end_call.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-hdpi/ic_dialpad_holo_dark.png b/res/drawable-hdpi/ic_dialpad_holo_dark.png
deleted file mode 100644
index a0ab6c4..0000000
--- a/res/drawable-hdpi/ic_dialpad_holo_dark.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-hdpi/ic_end_call_holo_dark.png b/res/drawable-hdpi/ic_end_call_holo_dark.png
deleted file mode 100644
index 0f373bb..0000000
--- a/res/drawable-hdpi/ic_end_call_holo_dark.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-hdpi/ic_groups_holo_dark.png b/res/drawable-hdpi/ic_groups_holo_dark.png
deleted file mode 100644
index 6194506..0000000
--- a/res/drawable-hdpi/ic_groups_holo_dark.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-hdpi/ic_hold_pause_holo_dark.png b/res/drawable-hdpi/ic_hold_pause_holo_dark.png
deleted file mode 100644
index 2b3ff3d..0000000
--- a/res/drawable-hdpi/ic_hold_pause_holo_dark.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-hdpi/ic_in_call_touch_handle_normal.png b/res/drawable-hdpi/ic_in_call_touch_handle_normal.png
deleted file mode 100644
index e8525348..0000000
--- a/res/drawable-hdpi/ic_in_call_touch_handle_normal.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-hdpi/ic_incall_switch_holo_dark.png b/res/drawable-hdpi/ic_incall_switch_holo_dark.png
deleted file mode 100644
index 429511b..0000000
--- a/res/drawable-hdpi/ic_incall_switch_holo_dark.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-hdpi/ic_incoming_call_bluetooth.png b/res/drawable-hdpi/ic_incoming_call_bluetooth.png
deleted file mode 100644
index 050c3e7..0000000
--- a/res/drawable-hdpi/ic_incoming_call_bluetooth.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-hdpi/ic_lockscreen_answer_activated.png b/res/drawable-hdpi/ic_lockscreen_answer_activated.png
deleted file mode 100644
index 3d2752f..0000000
--- a/res/drawable-hdpi/ic_lockscreen_answer_activated.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-hdpi/ic_lockscreen_answer_normal.png b/res/drawable-hdpi/ic_lockscreen_answer_normal.png
deleted file mode 100644
index 9e26eda..0000000
--- a/res/drawable-hdpi/ic_lockscreen_answer_normal.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-hdpi/ic_lockscreen_decline_activated.png b/res/drawable-hdpi/ic_lockscreen_decline_activated.png
deleted file mode 100644
index b7a438f..0000000
--- a/res/drawable-hdpi/ic_lockscreen_decline_activated.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-hdpi/ic_lockscreen_decline_normal.png b/res/drawable-hdpi/ic_lockscreen_decline_normal.png
deleted file mode 100644
index a687ae3..0000000
--- a/res/drawable-hdpi/ic_lockscreen_decline_normal.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-hdpi/ic_lockscreen_text_activated.png b/res/drawable-hdpi/ic_lockscreen_text_activated.png
deleted file mode 100644
index 22cf07c..0000000
--- a/res/drawable-hdpi/ic_lockscreen_text_activated.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-hdpi/ic_lockscreen_text_normal.png b/res/drawable-hdpi/ic_lockscreen_text_normal.png
deleted file mode 100644
index db6c05d..0000000
--- a/res/drawable-hdpi/ic_lockscreen_text_normal.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-hdpi/ic_merge_holo_dark.png b/res/drawable-hdpi/ic_merge_holo_dark.png
deleted file mode 100644
index 5069cbe..0000000
--- a/res/drawable-hdpi/ic_merge_holo_dark.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-hdpi/ic_more_indicator_holo_dark.png b/res/drawable-hdpi/ic_more_indicator_holo_dark.png
deleted file mode 100644
index 554f7e9..0000000
--- a/res/drawable-hdpi/ic_more_indicator_holo_dark.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-hdpi/ic_mute_holo_dark.png b/res/drawable-hdpi/ic_mute_holo_dark.png
deleted file mode 100644
index f17a2da..0000000
--- a/res/drawable-hdpi/ic_mute_holo_dark.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-hdpi/ic_sound_bluetooth_holo_dark.png b/res/drawable-hdpi/ic_sound_bluetooth_holo_dark.png
deleted file mode 100644
index c7f2402..0000000
--- a/res/drawable-hdpi/ic_sound_bluetooth_holo_dark.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-hdpi/ic_sound_handset_holo_dark.png b/res/drawable-hdpi/ic_sound_handset_holo_dark.png
deleted file mode 100644
index 288141a..0000000
--- a/res/drawable-hdpi/ic_sound_handset_holo_dark.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-hdpi/ic_sound_holo_dark.png b/res/drawable-hdpi/ic_sound_holo_dark.png
deleted file mode 100644
index 08ee3e8..0000000
--- a/res/drawable-hdpi/ic_sound_holo_dark.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-hdpi/ic_sound_off_speakerphone_holo_dark.png b/res/drawable-hdpi/ic_sound_off_speakerphone_holo_dark.png
deleted file mode 100644
index 6f12d52..0000000
--- a/res/drawable-hdpi/ic_sound_off_speakerphone_holo_dark.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-hdpi/ic_sound_speakerphone_holo_dark.png b/res/drawable-hdpi/ic_sound_speakerphone_holo_dark.png
deleted file mode 100644
index eadd0cd..0000000
--- a/res/drawable-hdpi/ic_sound_speakerphone_holo_dark.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-hdpi/ic_split_holo_dark.png b/res/drawable-hdpi/ic_split_holo_dark.png
deleted file mode 100644
index 5b10cf9..0000000
--- a/res/drawable-hdpi/ic_split_holo_dark.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-hdpi/ic_videocall_holo_dark.png b/res/drawable-hdpi/ic_videocall_holo_dark.png
deleted file mode 100644
index 7aa3222..0000000
--- a/res/drawable-hdpi/ic_videocall_holo_dark.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-hdpi/list_pressed_holo_dark.9.png b/res/drawable-hdpi/list_pressed_holo_dark.9.png
index 5654cd6..596accb 100644
--- a/res/drawable-hdpi/list_pressed_holo_dark.9.png
+++ b/res/drawable-hdpi/list_pressed_holo_dark.9.png
Binary files differ
diff --git a/res/drawable-hdpi/picture_busy.png b/res/drawable-hdpi/picture_busy.png
deleted file mode 100644
index 98deacf..0000000
--- a/res/drawable-hdpi/picture_busy.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-hdpi/picture_conference.png b/res/drawable-hdpi/picture_conference.png
deleted file mode 100644
index 93743e6..0000000
--- a/res/drawable-hdpi/picture_conference.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-hdpi/picture_dialing.png b/res/drawable-hdpi/picture_dialing.png
deleted file mode 100644
index 6311f69..0000000
--- a/res/drawable-hdpi/picture_dialing.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-hdpi/picture_unknown.png b/res/drawable-hdpi/picture_unknown.png
deleted file mode 100644
index 278c121..0000000
--- a/res/drawable-hdpi/picture_unknown.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-ldrtl-hdpi/ic_ab_dialer_holo_dark.png b/res/drawable-ldrtl-hdpi/ic_ab_dialer_holo_dark.png
deleted file mode 100644
index 7ec3709..0000000
--- a/res/drawable-ldrtl-hdpi/ic_ab_dialer_holo_dark.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-ldrtl-hdpi/ic_add_contact_holo_dark.png b/res/drawable-ldrtl-hdpi/ic_add_contact_holo_dark.png
deleted file mode 100644
index b6a1381..0000000
--- a/res/drawable-ldrtl-hdpi/ic_add_contact_holo_dark.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-ldrtl-hdpi/ic_groups_holo_dark.png b/res/drawable-ldrtl-hdpi/ic_groups_holo_dark.png
deleted file mode 100644
index 185c55b..0000000
--- a/res/drawable-ldrtl-hdpi/ic_groups_holo_dark.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-ldrtl-hdpi/ic_in_call_touch_handle_normal.png b/res/drawable-ldrtl-hdpi/ic_in_call_touch_handle_normal.png
deleted file mode 100644
index 4a3628b..0000000
--- a/res/drawable-ldrtl-hdpi/ic_in_call_touch_handle_normal.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-ldrtl-hdpi/ic_lockscreen_answer_activated.png b/res/drawable-ldrtl-hdpi/ic_lockscreen_answer_activated.png
deleted file mode 100644
index f1deb75..0000000
--- a/res/drawable-ldrtl-hdpi/ic_lockscreen_answer_activated.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-ldrtl-hdpi/ic_lockscreen_answer_normal.png b/res/drawable-ldrtl-hdpi/ic_lockscreen_answer_normal.png
deleted file mode 100644
index 3c23fe9..0000000
--- a/res/drawable-ldrtl-hdpi/ic_lockscreen_answer_normal.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-ldrtl-hdpi/ic_lockscreen_text_activated.png b/res/drawable-ldrtl-hdpi/ic_lockscreen_text_activated.png
deleted file mode 100644
index 63afb5e..0000000
--- a/res/drawable-ldrtl-hdpi/ic_lockscreen_text_activated.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-ldrtl-hdpi/ic_lockscreen_text_normal.png b/res/drawable-ldrtl-hdpi/ic_lockscreen_text_normal.png
deleted file mode 100644
index 7443030..0000000
--- a/res/drawable-ldrtl-hdpi/ic_lockscreen_text_normal.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-ldrtl-hdpi/ic_more_indicator_holo_dark.png b/res/drawable-ldrtl-hdpi/ic_more_indicator_holo_dark.png
deleted file mode 100644
index adb18ae..0000000
--- a/res/drawable-ldrtl-hdpi/ic_more_indicator_holo_dark.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-ldrtl-hdpi/ic_sound_handset_holo_dark.png b/res/drawable-ldrtl-hdpi/ic_sound_handset_holo_dark.png
deleted file mode 100644
index 207d941..0000000
--- a/res/drawable-ldrtl-hdpi/ic_sound_handset_holo_dark.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-ldrtl-hdpi/ic_sound_holo_dark.png b/res/drawable-ldrtl-hdpi/ic_sound_holo_dark.png
deleted file mode 100644
index c2e8adb..0000000
--- a/res/drawable-ldrtl-hdpi/ic_sound_holo_dark.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-ldrtl-hdpi/ic_sound_off_speakerphone_holo_dark.png b/res/drawable-ldrtl-hdpi/ic_sound_off_speakerphone_holo_dark.png
deleted file mode 100644
index 2f2b674..0000000
--- a/res/drawable-ldrtl-hdpi/ic_sound_off_speakerphone_holo_dark.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-ldrtl-hdpi/ic_sound_speakerphone_holo_dark.png b/res/drawable-ldrtl-hdpi/ic_sound_speakerphone_holo_dark.png
deleted file mode 100644
index 135c7f3..0000000
--- a/res/drawable-ldrtl-hdpi/ic_sound_speakerphone_holo_dark.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-ldrtl-hdpi/picture_conference.png b/res/drawable-ldrtl-hdpi/picture_conference.png
deleted file mode 100644
index ca250fd..0000000
--- a/res/drawable-ldrtl-hdpi/picture_conference.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-ldrtl-hdpi/picture_dialing.png b/res/drawable-ldrtl-hdpi/picture_dialing.png
deleted file mode 100644
index cb587a8..0000000
--- a/res/drawable-ldrtl-hdpi/picture_dialing.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-ldrtl-hdpi/picture_unknown.png b/res/drawable-ldrtl-hdpi/picture_unknown.png
deleted file mode 100644
index 3b81ff3..0000000
--- a/res/drawable-ldrtl-hdpi/picture_unknown.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-ldrtl-mdpi/ic_ab_dialer_holo_dark.png b/res/drawable-ldrtl-mdpi/ic_ab_dialer_holo_dark.png
deleted file mode 100644
index 6020b3d..0000000
--- a/res/drawable-ldrtl-mdpi/ic_ab_dialer_holo_dark.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-ldrtl-mdpi/ic_add_contact_holo_dark.png b/res/drawable-ldrtl-mdpi/ic_add_contact_holo_dark.png
deleted file mode 100644
index 72abb91..0000000
--- a/res/drawable-ldrtl-mdpi/ic_add_contact_holo_dark.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-ldrtl-mdpi/ic_groups_holo_dark.png b/res/drawable-ldrtl-mdpi/ic_groups_holo_dark.png
deleted file mode 100644
index 844bed3..0000000
--- a/res/drawable-ldrtl-mdpi/ic_groups_holo_dark.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-ldrtl-mdpi/ic_in_call_touch_handle_normal.png b/res/drawable-ldrtl-mdpi/ic_in_call_touch_handle_normal.png
deleted file mode 100644
index 13b2ecf..0000000
--- a/res/drawable-ldrtl-mdpi/ic_in_call_touch_handle_normal.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-ldrtl-mdpi/ic_lockscreen_answer_activated.png b/res/drawable-ldrtl-mdpi/ic_lockscreen_answer_activated.png
deleted file mode 100644
index 3d68ff9..0000000
--- a/res/drawable-ldrtl-mdpi/ic_lockscreen_answer_activated.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-ldrtl-mdpi/ic_lockscreen_answer_normal.png b/res/drawable-ldrtl-mdpi/ic_lockscreen_answer_normal.png
deleted file mode 100644
index 2a223ea..0000000
--- a/res/drawable-ldrtl-mdpi/ic_lockscreen_answer_normal.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-ldrtl-mdpi/ic_lockscreen_text_activated.png b/res/drawable-ldrtl-mdpi/ic_lockscreen_text_activated.png
deleted file mode 100644
index 8e9c3b6..0000000
--- a/res/drawable-ldrtl-mdpi/ic_lockscreen_text_activated.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-ldrtl-mdpi/ic_lockscreen_text_normal.png b/res/drawable-ldrtl-mdpi/ic_lockscreen_text_normal.png
deleted file mode 100644
index 8d4cb28..0000000
--- a/res/drawable-ldrtl-mdpi/ic_lockscreen_text_normal.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-ldrtl-mdpi/ic_more_indicator_holo_dark.png b/res/drawable-ldrtl-mdpi/ic_more_indicator_holo_dark.png
deleted file mode 100644
index 2de388f..0000000
--- a/res/drawable-ldrtl-mdpi/ic_more_indicator_holo_dark.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-ldrtl-mdpi/ic_sound_handset_holo_dark.png b/res/drawable-ldrtl-mdpi/ic_sound_handset_holo_dark.png
deleted file mode 100644
index 6bf0e8d..0000000
--- a/res/drawable-ldrtl-mdpi/ic_sound_handset_holo_dark.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-ldrtl-mdpi/ic_sound_holo_dark.png b/res/drawable-ldrtl-mdpi/ic_sound_holo_dark.png
deleted file mode 100644
index 561e8fa..0000000
--- a/res/drawable-ldrtl-mdpi/ic_sound_holo_dark.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-ldrtl-mdpi/ic_sound_off_speakerphone_holo_dark.png b/res/drawable-ldrtl-mdpi/ic_sound_off_speakerphone_holo_dark.png
deleted file mode 100644
index 3f330ac..0000000
--- a/res/drawable-ldrtl-mdpi/ic_sound_off_speakerphone_holo_dark.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-ldrtl-mdpi/ic_sound_speakerphone_holo_dark.png b/res/drawable-ldrtl-mdpi/ic_sound_speakerphone_holo_dark.png
deleted file mode 100644
index 6cf2e3c..0000000
--- a/res/drawable-ldrtl-mdpi/ic_sound_speakerphone_holo_dark.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-ldrtl-mdpi/picture_conference.png b/res/drawable-ldrtl-mdpi/picture_conference.png
deleted file mode 100644
index 2876d0f..0000000
--- a/res/drawable-ldrtl-mdpi/picture_conference.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-ldrtl-mdpi/picture_dialing.png b/res/drawable-ldrtl-mdpi/picture_dialing.png
deleted file mode 100644
index 4047b22..0000000
--- a/res/drawable-ldrtl-mdpi/picture_dialing.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-ldrtl-mdpi/picture_unknown.png b/res/drawable-ldrtl-mdpi/picture_unknown.png
deleted file mode 100644
index 062faf5..0000000
--- a/res/drawable-ldrtl-mdpi/picture_unknown.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-ldrtl-xhdpi/ic_ab_dialer_holo_dark.png b/res/drawable-ldrtl-xhdpi/ic_ab_dialer_holo_dark.png
deleted file mode 100644
index c42e7e3..0000000
--- a/res/drawable-ldrtl-xhdpi/ic_ab_dialer_holo_dark.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-ldrtl-xhdpi/ic_add_contact_holo_dark.png b/res/drawable-ldrtl-xhdpi/ic_add_contact_holo_dark.png
deleted file mode 100644
index 60068fd..0000000
--- a/res/drawable-ldrtl-xhdpi/ic_add_contact_holo_dark.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-ldrtl-xhdpi/ic_groups_holo_dark.png b/res/drawable-ldrtl-xhdpi/ic_groups_holo_dark.png
deleted file mode 100644
index 38ea395..0000000
--- a/res/drawable-ldrtl-xhdpi/ic_groups_holo_dark.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-ldrtl-xhdpi/ic_in_call_touch_handle_normal.png b/res/drawable-ldrtl-xhdpi/ic_in_call_touch_handle_normal.png
deleted file mode 100644
index c707950..0000000
--- a/res/drawable-ldrtl-xhdpi/ic_in_call_touch_handle_normal.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-ldrtl-xhdpi/ic_lockscreen_answer_activated.png b/res/drawable-ldrtl-xhdpi/ic_lockscreen_answer_activated.png
deleted file mode 100644
index 1acdc59..0000000
--- a/res/drawable-ldrtl-xhdpi/ic_lockscreen_answer_activated.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-ldrtl-xhdpi/ic_lockscreen_answer_normal.png b/res/drawable-ldrtl-xhdpi/ic_lockscreen_answer_normal.png
deleted file mode 100644
index 72c2afa..0000000
--- a/res/drawable-ldrtl-xhdpi/ic_lockscreen_answer_normal.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-ldrtl-xhdpi/ic_lockscreen_text_activated.png b/res/drawable-ldrtl-xhdpi/ic_lockscreen_text_activated.png
deleted file mode 100644
index d292a7f..0000000
--- a/res/drawable-ldrtl-xhdpi/ic_lockscreen_text_activated.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-ldrtl-xhdpi/ic_lockscreen_text_normal.png b/res/drawable-ldrtl-xhdpi/ic_lockscreen_text_normal.png
deleted file mode 100644
index 8318590..0000000
--- a/res/drawable-ldrtl-xhdpi/ic_lockscreen_text_normal.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-ldrtl-xhdpi/ic_more_indicator_holo_dark.png b/res/drawable-ldrtl-xhdpi/ic_more_indicator_holo_dark.png
deleted file mode 100644
index 6fe45cd..0000000
--- a/res/drawable-ldrtl-xhdpi/ic_more_indicator_holo_dark.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-ldrtl-xhdpi/ic_sound_handset_holo_dark.png b/res/drawable-ldrtl-xhdpi/ic_sound_handset_holo_dark.png
deleted file mode 100644
index 1c1f1ad..0000000
--- a/res/drawable-ldrtl-xhdpi/ic_sound_handset_holo_dark.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-ldrtl-xhdpi/ic_sound_holo_dark.png b/res/drawable-ldrtl-xhdpi/ic_sound_holo_dark.png
deleted file mode 100644
index ac38205..0000000
--- a/res/drawable-ldrtl-xhdpi/ic_sound_holo_dark.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-ldrtl-xhdpi/ic_sound_off_speakerphone_holo_dark.png b/res/drawable-ldrtl-xhdpi/ic_sound_off_speakerphone_holo_dark.png
deleted file mode 100644
index 5bc066a..0000000
--- a/res/drawable-ldrtl-xhdpi/ic_sound_off_speakerphone_holo_dark.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-ldrtl-xhdpi/ic_sound_speakerphone_holo_dark.png b/res/drawable-ldrtl-xhdpi/ic_sound_speakerphone_holo_dark.png
deleted file mode 100644
index 3999712..0000000
--- a/res/drawable-ldrtl-xhdpi/ic_sound_speakerphone_holo_dark.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-ldrtl-xhdpi/picture_conference.png b/res/drawable-ldrtl-xhdpi/picture_conference.png
deleted file mode 100644
index 50b4e35..0000000
--- a/res/drawable-ldrtl-xhdpi/picture_conference.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-ldrtl-xhdpi/picture_dialing.png b/res/drawable-ldrtl-xhdpi/picture_dialing.png
deleted file mode 100644
index f167ecb..0000000
--- a/res/drawable-ldrtl-xhdpi/picture_dialing.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-ldrtl-xhdpi/picture_unknown.png b/res/drawable-ldrtl-xhdpi/picture_unknown.png
deleted file mode 100644
index 1f57aa1..0000000
--- a/res/drawable-ldrtl-xhdpi/picture_unknown.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-mdpi/endcall_active.png b/res/drawable-mdpi/endcall_active.png
deleted file mode 100644
index a82738b..0000000
--- a/res/drawable-mdpi/endcall_active.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-mdpi/endcall_background_texture.png b/res/drawable-mdpi/endcall_background_texture.png
deleted file mode 100644
index efa6502..0000000
--- a/res/drawable-mdpi/endcall_background_texture.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-mdpi/endcall_disable.png b/res/drawable-mdpi/endcall_disable.png
deleted file mode 100644
index bd1a2f3..0000000
--- a/res/drawable-mdpi/endcall_disable.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-mdpi/ic_ab_dialer_holo_dark.png b/res/drawable-mdpi/ic_ab_dialer_holo_dark.png
deleted file mode 100644
index 51ad9e3..0000000
--- a/res/drawable-mdpi/ic_ab_dialer_holo_dark.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-mdpi/ic_add_contact_holo_dark.png b/res/drawable-mdpi/ic_add_contact_holo_dark.png
deleted file mode 100644
index 867f494..0000000
--- a/res/drawable-mdpi/ic_add_contact_holo_dark.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-mdpi/ic_bluetooth_holo_dark.png b/res/drawable-mdpi/ic_bluetooth_holo_dark.png
deleted file mode 100644
index fb69031..0000000
--- a/res/drawable-mdpi/ic_bluetooth_holo_dark.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-mdpi/ic_dial_end_call.png b/res/drawable-mdpi/ic_dial_end_call.png
deleted file mode 100644
index c476642..0000000
--- a/res/drawable-mdpi/ic_dial_end_call.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-mdpi/ic_dialpad_holo_dark.png b/res/drawable-mdpi/ic_dialpad_holo_dark.png
deleted file mode 100644
index b57fcf3..0000000
--- a/res/drawable-mdpi/ic_dialpad_holo_dark.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-mdpi/ic_end_call_holo_dark.png b/res/drawable-mdpi/ic_end_call_holo_dark.png
deleted file mode 100644
index e090cc8..0000000
--- a/res/drawable-mdpi/ic_end_call_holo_dark.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-mdpi/ic_groups_holo_dark.png b/res/drawable-mdpi/ic_groups_holo_dark.png
deleted file mode 100644
index fefee32..0000000
--- a/res/drawable-mdpi/ic_groups_holo_dark.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-mdpi/ic_hold_pause_holo_dark.png b/res/drawable-mdpi/ic_hold_pause_holo_dark.png
deleted file mode 100644
index 7d550de..0000000
--- a/res/drawable-mdpi/ic_hold_pause_holo_dark.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-mdpi/ic_in_call_touch_handle_normal.png b/res/drawable-mdpi/ic_in_call_touch_handle_normal.png
deleted file mode 100644
index cebdc4d..0000000
--- a/res/drawable-mdpi/ic_in_call_touch_handle_normal.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-mdpi/ic_incall_switch_holo_dark.png b/res/drawable-mdpi/ic_incall_switch_holo_dark.png
deleted file mode 100644
index 5b35ef1..0000000
--- a/res/drawable-mdpi/ic_incall_switch_holo_dark.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-mdpi/ic_incoming_call_bluetooth.png b/res/drawable-mdpi/ic_incoming_call_bluetooth.png
deleted file mode 100644
index 4b317c1..0000000
--- a/res/drawable-mdpi/ic_incoming_call_bluetooth.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-mdpi/ic_lockscreen_answer_activated.png b/res/drawable-mdpi/ic_lockscreen_answer_activated.png
deleted file mode 100644
index 6a78f81..0000000
--- a/res/drawable-mdpi/ic_lockscreen_answer_activated.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-mdpi/ic_lockscreen_answer_normal.png b/res/drawable-mdpi/ic_lockscreen_answer_normal.png
deleted file mode 100644
index da15c33..0000000
--- a/res/drawable-mdpi/ic_lockscreen_answer_normal.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-mdpi/ic_lockscreen_decline_activated.png b/res/drawable-mdpi/ic_lockscreen_decline_activated.png
deleted file mode 100644
index 6496626..0000000
--- a/res/drawable-mdpi/ic_lockscreen_decline_activated.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-mdpi/ic_lockscreen_decline_normal.png b/res/drawable-mdpi/ic_lockscreen_decline_normal.png
deleted file mode 100644
index 27fe093..0000000
--- a/res/drawable-mdpi/ic_lockscreen_decline_normal.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-mdpi/ic_lockscreen_text_activated.png b/res/drawable-mdpi/ic_lockscreen_text_activated.png
deleted file mode 100644
index e3e4fc1..0000000
--- a/res/drawable-mdpi/ic_lockscreen_text_activated.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-mdpi/ic_lockscreen_text_normal.png b/res/drawable-mdpi/ic_lockscreen_text_normal.png
deleted file mode 100644
index 4a2a54b..0000000
--- a/res/drawable-mdpi/ic_lockscreen_text_normal.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-mdpi/ic_merge_holo_dark.png b/res/drawable-mdpi/ic_merge_holo_dark.png
deleted file mode 100644
index bd34def..0000000
--- a/res/drawable-mdpi/ic_merge_holo_dark.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-mdpi/ic_more_indicator_holo_dark.png b/res/drawable-mdpi/ic_more_indicator_holo_dark.png
deleted file mode 100644
index 27b6d33..0000000
--- a/res/drawable-mdpi/ic_more_indicator_holo_dark.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-mdpi/ic_mute_holo_dark.png b/res/drawable-mdpi/ic_mute_holo_dark.png
deleted file mode 100644
index 801d1e0..0000000
--- a/res/drawable-mdpi/ic_mute_holo_dark.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-mdpi/ic_sound_bluetooth_holo_dark.png b/res/drawable-mdpi/ic_sound_bluetooth_holo_dark.png
deleted file mode 100644
index c0e95cb..0000000
--- a/res/drawable-mdpi/ic_sound_bluetooth_holo_dark.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-mdpi/ic_sound_handset_holo_dark.png b/res/drawable-mdpi/ic_sound_handset_holo_dark.png
deleted file mode 100644
index e5fce57..0000000
--- a/res/drawable-mdpi/ic_sound_handset_holo_dark.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-mdpi/ic_sound_holo_dark.png b/res/drawable-mdpi/ic_sound_holo_dark.png
deleted file mode 100644
index 060f926..0000000
--- a/res/drawable-mdpi/ic_sound_holo_dark.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-mdpi/ic_sound_off_speakerphone_holo_dark.png b/res/drawable-mdpi/ic_sound_off_speakerphone_holo_dark.png
deleted file mode 100644
index adaff60..0000000
--- a/res/drawable-mdpi/ic_sound_off_speakerphone_holo_dark.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-mdpi/ic_sound_speakerphone_holo_dark.png b/res/drawable-mdpi/ic_sound_speakerphone_holo_dark.png
deleted file mode 100644
index 2b9600b..0000000
--- a/res/drawable-mdpi/ic_sound_speakerphone_holo_dark.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-mdpi/ic_split_holo_dark.png b/res/drawable-mdpi/ic_split_holo_dark.png
deleted file mode 100644
index 3980acb..0000000
--- a/res/drawable-mdpi/ic_split_holo_dark.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-mdpi/ic_videocall_holo_dark.png b/res/drawable-mdpi/ic_videocall_holo_dark.png
deleted file mode 100644
index 776d27a..0000000
--- a/res/drawable-mdpi/ic_videocall_holo_dark.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-mdpi/list_pressed_holo_dark.9.png b/res/drawable-mdpi/list_pressed_holo_dark.9.png
index 6e77525..fd0e8d7 100644
--- a/res/drawable-mdpi/list_pressed_holo_dark.9.png
+++ b/res/drawable-mdpi/list_pressed_holo_dark.9.png
Binary files differ
diff --git a/res/drawable-mdpi/picture_busy.png b/res/drawable-mdpi/picture_busy.png
deleted file mode 100644
index ca1c6bf..0000000
--- a/res/drawable-mdpi/picture_busy.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-mdpi/picture_conference.png b/res/drawable-mdpi/picture_conference.png
deleted file mode 100644
index 8f7ecd5..0000000
--- a/res/drawable-mdpi/picture_conference.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-mdpi/picture_dialing.png b/res/drawable-mdpi/picture_dialing.png
deleted file mode 100644
index b81b603..0000000
--- a/res/drawable-mdpi/picture_dialing.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-mdpi/picture_unknown.png b/res/drawable-mdpi/picture_unknown.png
deleted file mode 100644
index cc5dd09..0000000
--- a/res/drawable-mdpi/picture_unknown.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xhdpi/endcall_active.png b/res/drawable-xhdpi/endcall_active.png
deleted file mode 100644
index 5347ed2..0000000
--- a/res/drawable-xhdpi/endcall_active.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xhdpi/endcall_background_texture.png b/res/drawable-xhdpi/endcall_background_texture.png
deleted file mode 100644
index c94eeec..0000000
--- a/res/drawable-xhdpi/endcall_background_texture.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xhdpi/endcall_disable.png b/res/drawable-xhdpi/endcall_disable.png
deleted file mode 100644
index fa10196..0000000
--- a/res/drawable-xhdpi/endcall_disable.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xhdpi/ic_ab_dialer_holo_dark.png b/res/drawable-xhdpi/ic_ab_dialer_holo_dark.png
deleted file mode 100644
index 3f43a82..0000000
--- a/res/drawable-xhdpi/ic_ab_dialer_holo_dark.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xhdpi/ic_add_contact_holo_dark.png b/res/drawable-xhdpi/ic_add_contact_holo_dark.png
deleted file mode 100644
index 7298882..0000000
--- a/res/drawable-xhdpi/ic_add_contact_holo_dark.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xhdpi/ic_bluetooth_holo_dark.png b/res/drawable-xhdpi/ic_bluetooth_holo_dark.png
deleted file mode 100644
index 24cb893..0000000
--- a/res/drawable-xhdpi/ic_bluetooth_holo_dark.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xhdpi/ic_dial_end_call.png b/res/drawable-xhdpi/ic_dial_end_call.png
deleted file mode 100644
index c24ec98..0000000
--- a/res/drawable-xhdpi/ic_dial_end_call.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xhdpi/ic_dialpad_holo_dark.png b/res/drawable-xhdpi/ic_dialpad_holo_dark.png
deleted file mode 100644
index f9a002c..0000000
--- a/res/drawable-xhdpi/ic_dialpad_holo_dark.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xhdpi/ic_end_call_holo_dark.png b/res/drawable-xhdpi/ic_end_call_holo_dark.png
deleted file mode 100644
index f64f5e3..0000000
--- a/res/drawable-xhdpi/ic_end_call_holo_dark.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xhdpi/ic_groups_holo_dark.png b/res/drawable-xhdpi/ic_groups_holo_dark.png
deleted file mode 100644
index 470ca27..0000000
--- a/res/drawable-xhdpi/ic_groups_holo_dark.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xhdpi/ic_hold_pause_holo_dark.png b/res/drawable-xhdpi/ic_hold_pause_holo_dark.png
deleted file mode 100644
index d296675..0000000
--- a/res/drawable-xhdpi/ic_hold_pause_holo_dark.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xhdpi/ic_in_call_touch_handle_normal.png b/res/drawable-xhdpi/ic_in_call_touch_handle_normal.png
deleted file mode 100644
index 1d112f2..0000000
--- a/res/drawable-xhdpi/ic_in_call_touch_handle_normal.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xhdpi/ic_incall_switch_holo_dark.png b/res/drawable-xhdpi/ic_incall_switch_holo_dark.png
deleted file mode 100644
index 9168c32..0000000
--- a/res/drawable-xhdpi/ic_incall_switch_holo_dark.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xhdpi/ic_incoming_call_bluetooth.png b/res/drawable-xhdpi/ic_incoming_call_bluetooth.png
deleted file mode 100644
index 662e7bb..0000000
--- a/res/drawable-xhdpi/ic_incoming_call_bluetooth.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xhdpi/ic_lockscreen_answer_activated.png b/res/drawable-xhdpi/ic_lockscreen_answer_activated.png
deleted file mode 100644
index cd6a6ab..0000000
--- a/res/drawable-xhdpi/ic_lockscreen_answer_activated.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xhdpi/ic_lockscreen_answer_normal.png b/res/drawable-xhdpi/ic_lockscreen_answer_normal.png
deleted file mode 100644
index 983d5d9..0000000
--- a/res/drawable-xhdpi/ic_lockscreen_answer_normal.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xhdpi/ic_lockscreen_decline_activated.png b/res/drawable-xhdpi/ic_lockscreen_decline_activated.png
deleted file mode 100644
index 317b329..0000000
--- a/res/drawable-xhdpi/ic_lockscreen_decline_activated.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xhdpi/ic_lockscreen_decline_normal.png b/res/drawable-xhdpi/ic_lockscreen_decline_normal.png
deleted file mode 100644
index 2cb03e7..0000000
--- a/res/drawable-xhdpi/ic_lockscreen_decline_normal.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xhdpi/ic_lockscreen_text_activated.png b/res/drawable-xhdpi/ic_lockscreen_text_activated.png
deleted file mode 100644
index 41ea18a..0000000
--- a/res/drawable-xhdpi/ic_lockscreen_text_activated.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xhdpi/ic_lockscreen_text_normal.png b/res/drawable-xhdpi/ic_lockscreen_text_normal.png
deleted file mode 100644
index 15e4779..0000000
--- a/res/drawable-xhdpi/ic_lockscreen_text_normal.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xhdpi/ic_merge_holo_dark.png b/res/drawable-xhdpi/ic_merge_holo_dark.png
deleted file mode 100644
index 57baa20..0000000
--- a/res/drawable-xhdpi/ic_merge_holo_dark.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xhdpi/ic_more_indicator_holo_dark.png b/res/drawable-xhdpi/ic_more_indicator_holo_dark.png
deleted file mode 100644
index 3d9897a..0000000
--- a/res/drawable-xhdpi/ic_more_indicator_holo_dark.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xhdpi/ic_mute_holo_dark.png b/res/drawable-xhdpi/ic_mute_holo_dark.png
deleted file mode 100644
index a882a76..0000000
--- a/res/drawable-xhdpi/ic_mute_holo_dark.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xhdpi/ic_sound_bluetooth_holo_dark.png b/res/drawable-xhdpi/ic_sound_bluetooth_holo_dark.png
deleted file mode 100644
index 867d87d..0000000
--- a/res/drawable-xhdpi/ic_sound_bluetooth_holo_dark.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xhdpi/ic_sound_handset_holo_dark.png b/res/drawable-xhdpi/ic_sound_handset_holo_dark.png
deleted file mode 100644
index 42e19bd..0000000
--- a/res/drawable-xhdpi/ic_sound_handset_holo_dark.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xhdpi/ic_sound_holo_dark.png b/res/drawable-xhdpi/ic_sound_holo_dark.png
deleted file mode 100644
index aa2a5af..0000000
--- a/res/drawable-xhdpi/ic_sound_holo_dark.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xhdpi/ic_sound_off_speakerphone_holo_dark.png b/res/drawable-xhdpi/ic_sound_off_speakerphone_holo_dark.png
deleted file mode 100644
index 98a449f..0000000
--- a/res/drawable-xhdpi/ic_sound_off_speakerphone_holo_dark.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xhdpi/ic_sound_speakerphone_holo_dark.png b/res/drawable-xhdpi/ic_sound_speakerphone_holo_dark.png
deleted file mode 100644
index 71aad97..0000000
--- a/res/drawable-xhdpi/ic_sound_speakerphone_holo_dark.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xhdpi/ic_split_holo_dark.png b/res/drawable-xhdpi/ic_split_holo_dark.png
deleted file mode 100644
index db558e4..0000000
--- a/res/drawable-xhdpi/ic_split_holo_dark.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xhdpi/ic_videocall_holo_dark.png b/res/drawable-xhdpi/ic_videocall_holo_dark.png
deleted file mode 100644
index 2b7dcab..0000000
--- a/res/drawable-xhdpi/ic_videocall_holo_dark.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xhdpi/list_pressed_holo_dark.9.png b/res/drawable-xhdpi/list_pressed_holo_dark.9.png
index e4b3393..29037a0 100644
--- a/res/drawable-xhdpi/list_pressed_holo_dark.9.png
+++ b/res/drawable-xhdpi/list_pressed_holo_dark.9.png
Binary files differ
diff --git a/res/drawable-xhdpi/picture_busy.png b/res/drawable-xhdpi/picture_busy.png
deleted file mode 100644
index 0e4f13e..0000000
--- a/res/drawable-xhdpi/picture_busy.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xhdpi/picture_conference.png b/res/drawable-xhdpi/picture_conference.png
deleted file mode 100644
index 1906b9b..0000000
--- a/res/drawable-xhdpi/picture_conference.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xhdpi/picture_dialing.png b/res/drawable-xhdpi/picture_dialing.png
deleted file mode 100644
index 792cd8e..0000000
--- a/res/drawable-xhdpi/picture_dialing.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xhdpi/picture_unknown.png b/res/drawable-xhdpi/picture_unknown.png
deleted file mode 100644
index b8ee922..0000000
--- a/res/drawable-xhdpi/picture_unknown.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable/btn_compound_audio.xml b/res/drawable/btn_compound_audio.xml
deleted file mode 100644
index c348c98..0000000
--- a/res/drawable/btn_compound_audio.xml
+++ /dev/null
@@ -1,105 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2011 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.
--->
-
-<!-- Layers used to render the in-call "Audio mode" compound button.
-
- This is a multi-mode button:
-
- - If no bluetooth headset is connected, it behaves like a simple
- "compound button" that switches the speaker on and off. (This is why
- the button itself is a ToggleButton instance.)
-
- - But if a bluetooth headset is connected, this becomes a simple
- action button (with no concept of a "checked" state) that brings
- up a popup menu offering you a 3-way choice between earpiece /
- speaker / bluetooth.
-
- See InCallTouchUi.updateAudioButton() for the corresponding code. -->
-
-<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
-
- <!-- The standard "compound button" background, used to distinguish
- between the "checked" and "unchecked" states when this button is
- simply an on/off toggle for the speaker.
- (In states where the audio button *not* a toggle, we explicitly
- hide this layer.) -->
- <item android:id="@+id/compoundBackgroundItem"
- android:drawable="@drawable/btn_compound_background" />
-
- <!-- The little triangle that indicates that this isn't a plain
- button, but will instead pop up a menu. This layer is *not*
- shown when the audio button is simply an on/off toggle. -->
- <!-- Use an explicit <bitmap> to avoid scaling the icon up to the full
- size of the button. -->
- <item android:id="@+id/moreIndicatorItem">
- <bitmap android:src="@drawable/ic_more_indicator_holo_dark"
- android:gravity="center" />
- </item>
-
- <!-- Finally, the button icon.
-
- When the audio button is simply an on/off toggle for the speaker,
- the icon is a "speakerphone" regardless of whether the speaker is
- active. (Instead, the "on/off" indication comes from the
- btn_compound_background selector.)
-
- But when the audio button is connected to the 3-way popup menu,
- we use the button's icon to indicate the current audio mode
- (i.e. one of { earpiece (or wired headset) , speaker , bluetooth }).
-
- Here we have separate layers for each possible foreground icon,
- and in InCallTouchUi.updateAudioButton() we hide them all
- *except* the one needed for the current state. -->
-
- <!-- These all use an explicit <bitmap> to avoid scaling the icon up
- to the full size of the button. -->
-
- <!-- Bluetooth is active -->
- <item android:id="@+id/bluetoothItem">
- <bitmap android:src="@drawable/ic_sound_bluetooth_holo_dark"
- android:gravity="center" />
- </item>
-
-
- <!-- Handset earpiece is active -->
- <item android:id="@+id/handsetItem">
- <bitmap android:src="@drawable/ic_sound_handset_holo_dark"
- android:gravity="center" />
- </item>
-
- <!-- Speakerphone icon showing 'speaker on' state -->
- <item android:id="@+id/speakerphoneOnItem">
- <bitmap android:src="@drawable/ic_sound_speakerphone_holo_dark"
- android:gravity="center" />
- </item>
-
- <!-- Speakerphone icon showing 'speaker off' state -->
- <item android:id="@+id/speakerphoneOffItem">
- <bitmap android:src="@drawable/ic_sound_off_speakerphone_holo_dark"
- android:gravity="center" />
- </item>
-
- <!-- Generic "audio mode" icon. Looks almost identical to
- ic_sound_speakerphone_holo_dark.png -->
- <!-- TODO: is this actually needed? -->
- <!--
- <item android:id="@+id/soundItem">
- <bitmap android:src="@drawable/ic_sound_holo_dark"
- android:gravity="center" />
- </item>
- -->
-
-</layer-list>
diff --git a/res/drawable/btn_compound_dialpad.xml b/res/drawable/btn_compound_dialpad.xml
deleted file mode 100644
index b44f2fa..0000000
--- a/res/drawable/btn_compound_dialpad.xml
+++ /dev/null
@@ -1,30 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2011 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.
--->
-
-<!-- Layers used to render the in-call "Dialpad" compound button. -->
-<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
-
- <!-- The standard "compound button" background. -->
- <item android:drawable="@drawable/btn_compound_background" />
-
- <!-- ...and the actual icon on top. Use an explicit <bitmap> to avoid scaling
- the icon up to the full size of the button. -->
- <item>
- <bitmap android:src="@drawable/ic_dialpad_holo_dark"
- android:gravity="center" />
- </item>
-
-</layer-list>
diff --git a/res/drawable/btn_compound_hold.xml b/res/drawable/btn_compound_hold.xml
deleted file mode 100644
index 50161ea..0000000
--- a/res/drawable/btn_compound_hold.xml
+++ /dev/null
@@ -1,30 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2011 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.
--->
-
-<!-- Layers used to render the in-call "Hold" compound button. -->
-<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
-
- <!-- The standard "compound button" background. -->
- <item android:drawable="@drawable/btn_compound_background" />
-
- <!-- ...and the actual icon on top. Use an explicit <bitmap> to avoid scaling
- the icon up to the full size of the button. -->
- <item>
- <bitmap android:src="@drawable/ic_hold_pause_holo_dark"
- android:gravity="center" />
- </item>
-
-</layer-list>
diff --git a/res/drawable/btn_compound_mute.xml b/res/drawable/btn_compound_mute.xml
deleted file mode 100644
index 4e09bd9..0000000
--- a/res/drawable/btn_compound_mute.xml
+++ /dev/null
@@ -1,30 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2011 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.
--->
-
-<!-- Layers used to render the in-call "Mute" compound button. -->
-<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
-
- <!-- The standard "compound button" background. -->
- <item android:drawable="@drawable/btn_compound_background" />
-
- <!-- ...and the actual icon on top. Use an explicit <bitmap> to avoid scaling
- the icon up to the full size of the button. -->
- <item>
- <bitmap android:src="@drawable/ic_mute_holo_dark"
- android:gravity="center" />
- </item>
-
-</layer-list>
diff --git a/res/drawable/clickable_dim_effect.xml b/res/drawable/clickable_dim_effect.xml
deleted file mode 100644
index e4b4f6f..0000000
--- a/res/drawable/clickable_dim_effect.xml
+++ /dev/null
@@ -1,24 +0,0 @@
-<?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.
--->
-
-<!-- Background drawable used with dim effect for secondary photo. -->
-<selector xmlns:android="http://schemas.android.com/apk/res/android">
-
- <item android:state_pressed="true" android:state_enabled="true"
- android:drawable="@drawable/list_pressed_holo_dark" />
- <item android:drawable="@color/on_hold_dim_effect" />
-
-</selector>
diff --git a/res/drawable/dialpad_background_opaque.xml b/res/drawable/dialpad_background_opaque.xml
deleted file mode 100644
index d8792f2..0000000
--- a/res/drawable/dialpad_background_opaque.xml
+++ /dev/null
@@ -1,30 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2011 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.
--->
-
-<!-- Opaque version of dialpad_background.xml. -->
-<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
-
- <!-- An opaque black layer underneath. -->
- <item android:drawable="@android:color/black" />
-
- <!-- ...and the "dial_background_texture" tiled on top. -->
- <item>
- <bitmap xmlns:android="http://schemas.android.com/apk/res/android"
- android:src="@drawable/dial_background_texture"
- android:tileMode="repeat" />
- </item>
-
-</layer-list>
diff --git a/res/drawable/end_call_background.xml b/res/drawable/end_call_background.xml
deleted file mode 100644
index 33ec22f..0000000
--- a/res/drawable/end_call_background.xml
+++ /dev/null
@@ -1,45 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2011 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.
--->
-
-<!-- Background drawable used to render the "end call" button. -->
-<selector xmlns:android="http://schemas.android.com/apk/res/android">
-
- <item android:state_enabled="false">
- <bitmap
- android:src="@drawable/endcall_disable"
- android:tileMode="repeat" />
- </item>
-
- <item android:state_pressed="true">
- <bitmap
- android:src="@drawable/endcall_active"
- android:tileMode="repeat" />
- </item>
-
- <item>
- <layer-list>
- <item>
- <bitmap
- android:src="@drawable/endcall_background_texture"
- android:tileMode="repeat" />
- </item>
-
- <!-- The standard "compound button" background. -->
- <item android:drawable="@drawable/btn_compound_background" />
- </layer-list>
- </item>
-
-</selector>
diff --git a/res/drawable/ic_in_call_touch_handle.xml b/res/drawable/ic_in_call_touch_handle.xml
deleted file mode 100644
index e657e92..0000000
--- a/res/drawable/ic_in_call_touch_handle.xml
+++ /dev/null
@@ -1,33 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2011 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.
--->
-
-<!-- Touch handle for the GlowPadView widget on the incoming call screen -->
-<selector xmlns:android="http://schemas.android.com/apk/res/android">
-
- <item
- android:state_enabled="true"
- android:state_active="false"
- android:state_focused="false"
- android:drawable="@drawable/ic_in_call_touch_handle_normal" />
-
- <!-- "Pressed" state uses the same simple "ring" image as on the lockscreen -->
- <item
- android:state_enabled="true"
- android:state_active="true"
- android:state_focused="false"
- android:drawable="@*android:drawable/ic_lockscreen_handle_pressed" />
-
-</selector>
diff --git a/res/drawable/ic_lockscreen_answer.xml b/res/drawable/ic_lockscreen_answer.xml
deleted file mode 100644
index 3184111..0000000
--- a/res/drawable/ic_lockscreen_answer.xml
+++ /dev/null
@@ -1,27 +0,0 @@
-<?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.
--->
-<!-- Used with incoming call wigdet. -->
-<selector xmlns:android="http://schemas.android.com/apk/res/android">
- <item
- android:state_enabled="true" android:state_active="false" android:state_focused="false"
- android:drawable="@drawable/ic_lockscreen_answer_normal_layer"/>
- <item
- android:state_enabled="true" android:state_active="true" android:state_focused="false"
- android:drawable="@drawable/ic_lockscreen_answer_activated_layer" />
- <item
- android:state_enabled="true" android:state_active="false" android:state_focused="true"
- android:drawable="@drawable/ic_lockscreen_answer_activated_layer" />
-</selector>
diff --git a/res/drawable/ic_lockscreen_answer_activated_layer.xml b/res/drawable/ic_lockscreen_answer_activated_layer.xml
deleted file mode 100644
index 6889581..0000000
--- a/res/drawable/ic_lockscreen_answer_activated_layer.xml
+++ /dev/null
@@ -1,31 +0,0 @@
-<?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.
--->
-<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
- <item>
- <shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="oval">
- <solid android:color="#99cc00"/>
- <size
- android:width="@dimen/incoming_call_widget_circle_size"
- android:height="@dimen/incoming_call_widget_circle_size" />
- </shape>
- </item>
- <item
- android:top="@dimen/incoming_call_widget_asset_margin"
- android:right="@dimen/incoming_call_widget_asset_margin"
- android:bottom="@dimen/incoming_call_widget_asset_margin"
- android:left="@dimen/incoming_call_widget_asset_margin"
- android:drawable="@drawable/ic_lockscreen_answer_activated" />
-</layer-list>
diff --git a/res/drawable/ic_lockscreen_answer_normal_layer.xml b/res/drawable/ic_lockscreen_answer_normal_layer.xml
deleted file mode 100644
index 083fe3f..0000000
--- a/res/drawable/ic_lockscreen_answer_normal_layer.xml
+++ /dev/null
@@ -1,32 +0,0 @@
-<?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.
--->
-<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
- <!-- A fake circle to fix the size of this layer asset. -->
- <item>
- <shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="oval">
- <solid android:color="#00000000"/>
- <size
- android:width="@dimen/incoming_call_widget_circle_size"
- android:height="@dimen/incoming_call_widget_circle_size" />
- </shape>
- </item>
- <item
- android:top="@dimen/incoming_call_widget_asset_margin"
- android:right="@dimen/incoming_call_widget_asset_margin"
- android:bottom="@dimen/incoming_call_widget_asset_margin"
- android:left="@dimen/incoming_call_widget_asset_margin"
- android:drawable="@drawable/ic_lockscreen_answer_normal" />
-</layer-list>
diff --git a/res/drawable/ic_lockscreen_decline.xml b/res/drawable/ic_lockscreen_decline.xml
deleted file mode 100644
index 6643816..0000000
--- a/res/drawable/ic_lockscreen_decline.xml
+++ /dev/null
@@ -1,27 +0,0 @@
-<?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.
--->
-<!-- Used with incoming call wigdet. -->
-<selector xmlns:android="http://schemas.android.com/apk/res/android">
- <item
- android:state_enabled="true" android:state_active="false" android:state_focused="false"
- android:drawable="@drawable/ic_lockscreen_decline_normal_layer" />
- <item
- android:state_enabled="true" android:state_active="true" android:state_focused="false"
- android:drawable="@drawable/ic_lockscreen_decline_activated_layer" />
- <item
- android:state_enabled="true" android:state_active="false" android:state_focused="true"
- android:drawable="@drawable/ic_lockscreen_decline_activated_layer" />
-</selector>
diff --git a/res/drawable/ic_lockscreen_decline_activated_layer.xml b/res/drawable/ic_lockscreen_decline_activated_layer.xml
deleted file mode 100644
index e3606d1..0000000
--- a/res/drawable/ic_lockscreen_decline_activated_layer.xml
+++ /dev/null
@@ -1,31 +0,0 @@
-<?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.
--->
-<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
- <item>
- <shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="oval">
- <solid android:color="#ff4040"/>
- <size
- android:width="@dimen/incoming_call_widget_circle_size"
- android:height="@dimen/incoming_call_widget_circle_size" />
- </shape>
- </item>
- <item
- android:top="@dimen/incoming_call_widget_asset_margin"
- android:right="@dimen/incoming_call_widget_asset_margin"
- android:bottom="@dimen/incoming_call_widget_asset_margin"
- android:left="@dimen/incoming_call_widget_asset_margin"
- android:drawable="@drawable/ic_lockscreen_decline_activated" />
-</layer-list>
diff --git a/res/drawable/ic_lockscreen_decline_normal_layer.xml b/res/drawable/ic_lockscreen_decline_normal_layer.xml
deleted file mode 100644
index 2896bef..0000000
--- a/res/drawable/ic_lockscreen_decline_normal_layer.xml
+++ /dev/null
@@ -1,32 +0,0 @@
-<?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.
--->
-<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
- <!-- A fake circle to fix the size of this layer asset. -->
- <item>
- <shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="oval">
- <solid android:color="#00000000"/>
- <size
- android:width="@dimen/incoming_call_widget_circle_size"
- android:height="@dimen/incoming_call_widget_circle_size" />
- </shape>
- </item>
- <item
- android:top="@dimen/incoming_call_widget_asset_margin"
- android:right="@dimen/incoming_call_widget_asset_margin"
- android:bottom="@dimen/incoming_call_widget_asset_margin"
- android:left="@dimen/incoming_call_widget_asset_margin"
- android:drawable="@drawable/ic_lockscreen_decline_normal" />
-</layer-list>
diff --git a/res/drawable/ic_lockscreen_text.xml b/res/drawable/ic_lockscreen_text.xml
deleted file mode 100644
index f9caac8..0000000
--- a/res/drawable/ic_lockscreen_text.xml
+++ /dev/null
@@ -1,27 +0,0 @@
-<?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.
--->
-<!-- Used with incoming call wigdet. -->
-<selector xmlns:android="http://schemas.android.com/apk/res/android">
- <item
- android:state_enabled="true" android:state_active="false" android:state_focused="false"
- android:drawable="@drawable/ic_lockscreen_text_normal_layer" />
- <item
- android:state_enabled="true" android:state_active="true" android:state_focused="false"
- android:drawable="@drawable/ic_lockscreen_text_activated_layer" />
- <item
- android:state_enabled="true" android:state_active="false" android:state_focused="true"
- android:drawable="@drawable/ic_lockscreen_text_activated_layer" />
-</selector>
diff --git a/res/drawable/ic_lockscreen_text_activated_layer.xml b/res/drawable/ic_lockscreen_text_activated_layer.xml
deleted file mode 100644
index 95141e5..0000000
--- a/res/drawable/ic_lockscreen_text_activated_layer.xml
+++ /dev/null
@@ -1,31 +0,0 @@
-<?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.
--->
-<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
- <item>
- <shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="oval">
- <solid android:color="#99cc00"/>
- <size
- android:width="@dimen/incoming_call_widget_circle_size"
- android:height="@dimen/incoming_call_widget_circle_size" />
- </shape>
- </item>
- <item
- android:top="@dimen/incoming_call_widget_asset_margin"
- android:right="@dimen/incoming_call_widget_asset_margin"
- android:bottom="@dimen/incoming_call_widget_asset_margin"
- android:left="@dimen/incoming_call_widget_asset_margin"
- android:drawable="@drawable/ic_lockscreen_text_activated" />
-</layer-list>
diff --git a/res/drawable/ic_lockscreen_text_normal_layer.xml b/res/drawable/ic_lockscreen_text_normal_layer.xml
deleted file mode 100644
index 42fd51d..0000000
--- a/res/drawable/ic_lockscreen_text_normal_layer.xml
+++ /dev/null
@@ -1,32 +0,0 @@
-<?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.
--->
-<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
- <!-- A fake circle to fix the size of this layer asset. -->
- <item>
- <shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="oval">
- <solid android:color="#00000000"/>
- <size
- android:width="@dimen/incoming_call_widget_circle_size"
- android:height="@dimen/incoming_call_widget_circle_size" />
- </shape>
- </item>
- <item
- android:top="@dimen/incoming_call_widget_asset_margin"
- android:right="@dimen/incoming_call_widget_asset_margin"
- android:bottom="@dimen/incoming_call_widget_asset_margin"
- android:left="@dimen/incoming_call_widget_asset_margin"
- android:drawable="@drawable/ic_lockscreen_text_normal" />
-</layer-list>
diff --git a/res/layout-land/emergency_dialer.xml b/res/layout-land/emergency_dialer.xml
deleted file mode 100644
index 9894a8d..0000000
--- a/res/layout-land/emergency_dialer.xml
+++ /dev/null
@@ -1,79 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- 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.
--->
-
-<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
- android:id="@+id/top"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:orientation="vertical"
- android:layout_marginStart="@dimen/dialpad_horizontal_margin"
- android:layout_marginEnd="@dimen/dialpad_horizontal_margin">
-
- <!-- Text field above the keypad where the digits are displayed -->
- <LinearLayout
- android:id="@+id/digits_container"
- android:layout_width="match_parent"
- android:layout_height="@dimen/emergency_dialer_digits_height"
- android:layout_marginTop="@dimen/dialpad_vertical_margin"
- android:layout_marginBottom="69dip"
- android:gravity="center"
- android:background="@drawable/dialpad_background" >
-
- <EditText
- android:id="@+id/digits"
- android:layout_width="0dip"
- android:layout_weight="1"
- android:layout_height="match_parent"
- android:gravity="center"
- android:scrollHorizontally="true"
- android:textAppearance="@style/DialtactsDigitsTextAppearance"
- android:nextFocusRight="@+id/deleteButton"
- android:background="@android:color/transparent"
- android:hint="@string/dialerKeyboardHintText" />
-
- <ImageButton
- android:id="@+id/deleteButton"
- android:layout_width="56dip"
- android:layout_height="match_parent"
- android:layout_gravity="center_vertical"
- android:gravity="center"
- android:state_enabled="false"
- android:background="?android:attr/selectableItemBackground"
- android:contentDescription="@string/description_delete_button"
- android:src="@drawable/ic_dial_action_delete" />
- </LinearLayout>
-
- <FrameLayout
- android:id="@+id/dialButtonContainer"
- android:layout_width="match_parent"
- android:layout_height="0dip"
- android:layout_weight="1"
- android:layout_gravity="center_horizontal"
- android:background="@drawable/dialpad_background">
-
- <ImageButton
- android:id="@+id/dialButton"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:layout_gravity="center"
- android:state_enabled="false"
- android:background="@drawable/btn_call"
- android:contentDescription="@string/description_dial_button"
- android:src="@drawable/ic_dial_action_call" />
-
- </FrameLayout>
-
-</LinearLayout>
diff --git a/res/layout-land/incall_screen.xml b/res/layout-land/incall_screen.xml
deleted file mode 100644
index 1278115..0000000
--- a/res/layout-land/incall_screen.xml
+++ /dev/null
@@ -1,80 +0,0 @@
-<?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
deleted file mode 100644
index c6bbe5c..0000000
--- a/res/layout-land/incall_touch_ui.xml
+++ /dev/null
@@ -1,272 +0,0 @@
-<?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">
-
- <LinearLayout
- android:layout_height="0dp"
- android:layout_weight="1"
- android:layout_width="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_width="0dp"
- android:layout_weight="1"
- android:layout_height="match_parent"
- style="@style/InCallCompoundButton"
- android:background="@drawable/btn_compound_audio"
- android:contentDescription="@string/onscreenAudioText" />
-
- <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/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" />
-
- <!-- "Video call" -->
- <ImageButton
- android:id="@+id/videoCallButton"
- android:layout_width="0dp"
- android:layout_weight="1"
- android:layout_height="match_parent"
- style="@style/InCallButton"
- android:src="@drawable/ic_videocall_holo_dark"
- android:contentDescription="@string/onscreenVideoCallText" />
- </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
deleted file mode 100644
index 6b95164..0000000
--- a/res/layout-land/incall_touch_ui_cdma.xml
+++ /dev/null
@@ -1,250 +0,0 @@
-<?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>
-
- <!-- "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" />
-
- <!-- 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">
-
-
- <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" />
-
- <!-- 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" />
-
- </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/call_card.xml b/res/layout/call_card.xml
deleted file mode 100644
index 3803957..0000000
--- a/res/layout/call_card.xml
+++ /dev/null
@@ -1,54 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
- ~ Copyright (C) 2013 The Android Open Source Project
- ~
- ~ Licensed under the Apache License, Version 2.0 (the "License");
- ~ you may not use this file except in compliance with the License.
- ~ You may obtain a copy of the License at
- ~
- ~ http://www.apache.org/licenses/LICENSE-2.0
- ~
- ~ Unless required by applicable law or agreed to in writing, software
- ~ distributed under the License is distributed on an "AS IS" BASIS,
- ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- ~ See the License for the specific language governing permissions and
- ~ limitations under the License
- -->
-
-<!-- XML resource file for the CallCard used in the Phone app.
-
- Note that the CallCard is technically the size of the full screen (since
- our parent container is full-screen, and the layout_width and layout_height
- here are both "match_parent"), but we manually adjust its bottom margin
- in CallCard.updateCallInfoLayout() to make sure it doesn't overlap with
- the onscreen buttons from incall_touch_ui.xml. -->
-<com.android.phone.CallCard xmlns:android="http://schemas.android.com/apk/res/android"
- android:id="@+id/call_info_container"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:orientation="vertical">
-
- <!-- The main content of the CallCard is either one or two "call info"
- blocks, depending on whether one or two lines are in use.
-
- The call_info blocks are stacked vertically inside a CallCard (LinearLayout),
- each with layout_weight="1". If only one line is in use (i.e. the
- common case) then the 2nd call info will be GONE and thus the 1st one
- will expand to fill the full height of the CallCard.
-
- We set a bottom margin on this element dynamically (see
- updateCallInfoLayout()) to make sure it doesn't overlap with either
- the bottom button cluster or the incoming-call widget. -->
-
- <!-- Primary "Call info" block, for the foreground call. -->
- <include android:id="@+id/primary_call_info"
- layout="@layout/primary_call_info" />
-
- <!-- Secondary "Call info" block , for the background ("on hold") call. -->
- <ViewStub android:id="@+id/secondary_call_info"
- android:layout="@layout/secondary_call_info"
- android:layout_width="match_parent"
- android:layout_height="0dp"
- android:layout_weight="1" />
-
-</com.android.phone.CallCard>
diff --git a/res/layout/caller_in_conference.xml b/res/layout/caller_in_conference.xml
deleted file mode 100644
index c2c68c8..0000000
--- a/res/layout/caller_in_conference.xml
+++ /dev/null
@@ -1,107 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- 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.
--->
-
-<LinearLayout
- xmlns:android="http://schemas.android.com/apk/res/android"
- android:layout_width="match_parent"
- android:layout_height="64dp"
- android:orientation="horizontal"
- android:gravity="center_vertical">
-
- <!-- Caller information -->
- <LinearLayout
- android:id="@+id/conferenceCallerSeparate"
- android:layout_width="0dp"
- android:layout_weight="1"
- android:layout_height="match_parent"
- android:background="?android:attr/selectableItemBackground"
- android:paddingStart="16dp"
- android:orientation="horizontal"
- android:gravity="center_vertical">
-
- <!-- "Separate" (i.e. "go private") button for this caller -->
- <ImageView
- android:src="@drawable/ic_split_holo_dark"
- android:layout_width="46dp"
- android:layout_height="46dp"
- android:scaleType="center"
- android:contentDescription="@string/goPrivate"/>
-
- <LinearLayout
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:paddingStart="8dp"
- android:gravity="center_vertical"
- android:orientation="vertical">
-
- <!-- Name or number of this caller -->
- <TextView
- android:id="@+id/conferenceCallerName"
- android:textAppearance="?android:attr/textAppearanceLarge"
- android:textSize="18sp"
- android:singleLine="true"
- android:layout_width="wrap_content"
- android:layout_height="match_parent"
- android:layout_marginEnd="2dp"
- />
-
- <!-- Number of this caller if name is supplied above -->
- <LinearLayout
- android:layout_width="wrap_content"
- android:layout_height="match_parent"
- android:orientation="horizontal"
- android:gravity="bottom">
-
- <!-- Number -->
- <TextView
- android:id="@+id/conferenceCallerNumber"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:textSize="14sp"
- android:ellipsize="marquee"
- android:textColor="@color/manage_conference_secondary_text_color"
- android:singleLine="true"
- android:layout_marginEnd="8dp" />
-
- <!-- Number type -->
- <TextView
- android:id="@+id/conferenceCallerNumberType"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:textSize="12sp"
- android:textColor="@color/manage_conference_secondary_text_color"
- android:ellipsize="marquee"
- android:singleLine="true"
- android:textAllCaps="true"
- android:gravity="start" />
-
- </LinearLayout> <!-- End of caller number -->
-
- </LinearLayout> <!-- End of caller information -->
- </LinearLayout>
-
- <!-- "End" button for this caller which should look like the
- "end call" button in the main in-call UI screen -->
- <ImageButton
- android:id="@+id/conferenceCallerDisconnect"
- android:layout_width="80dp"
- android:layout_height="match_parent"
- android:src="@drawable/ic_end_call_holo_dark"
- android:background="@drawable/end_call_background"
- android:scaleType="center"
- android:contentDescription="@string/onscreenEndCallText" />
-
-</LinearLayout> <!-- End of single list element -->
diff --git a/res/layout/dtmf_twelve_key_dialer_view.xml b/res/layout/dtmf_twelve_key_dialer_view.xml
deleted file mode 100644
index f1d7c8d..0000000
--- a/res/layout/dtmf_twelve_key_dialer_view.xml
+++ /dev/null
@@ -1,67 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2009 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.
--->
-
-<!-- Onscreen in-call DTMF dialpad. This element contains the grid of
- DTMF buttons (dialpad.xml) along with a TextView showing
- the digits you've typed.
-
- When the user presses the "Dialpad" button, this UI appears in the
- upper part of the in-call screen, covering up the "call card" area.
- The regular in-call controls (i.e. the InCallTouchUi widget) are
- still visible at the lower part of the screen.
-
- This layout is inflated in place of dtmf_twelve_key_dialer_stub
- in incall_touch_ui.xml. -->
-<com.android.phone.DTMFTwelveKeyDialerView
- xmlns:android="http://schemas.android.com/apk/res/android"
- android:id="@+id/dtmf_twelve_key_dialer_view"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:orientation="vertical"
- android:layout_marginTop="1dip"
- android:visibility="gone"
- >
-
- <!-- Display of the digits you've typed so far.
- This widget appears completely non-interactive to the user: you
- can't edit or "hit backspace" since these are DTMF tones you've
- already sent over the network. But it's still an EditText rather
- than a TextView because it needs to receive key events from a
- hard keyboard, if present (see mDialerKeyListener). -->
- <EditText
- android:id="@+id/dtmfDialerField"
- android:layout_width="match_parent"
- android:layout_height="32dp"
- android:layout_marginTop="10dp"
- android:layout_marginBottom="5dp"
- android:layout_marginStart="32dp"
- android:layout_marginEnd="32dp"
- android:paddingEnd="16dp"
- android:paddingStart="16dp"
- android:singleLine="true"
- android:scrollHorizontally="true"
- android:textSize="24sp"
- android:gravity="center"
- android:freezesText="true"
- android:background="@null"
- android:textColor="@color/dtmf_dialer_display_text"
- android:focusableInTouchMode="false"
- android:clickable="false"/>
-
- <!-- The dialpad itself -->
- <include layout="@layout/dialpad" />
-
-</com.android.phone.DTMFTwelveKeyDialerView>
diff --git a/res/layout/extra_button_row.xml b/res/layout/extra_button_row.xml
deleted file mode 100644
index 3f7e18c..0000000
--- a/res/layout/extra_button_row.xml
+++ /dev/null
@@ -1,70 +0,0 @@
-<?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.
--->
-
-<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:background="@drawable/dialpad_background_opaque">
- <!-- The buttons here have a text label floating off to the side
- (which is necessary because these buttons are used only in
- a few rare states, and the meaning of the icon might not be
- obvious.) The entire row (button + text) is clickable. -->
-
- <!-- "Manage conference" -->
- <!-- This button is used only on GSM devices, during a conference call. -->
- <LinearLayout android:id="@+id/manageConferenceButton"
- android:orientation="horizontal"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:paddingStart="@dimen/button_cluster_side_padding"
- android:paddingEnd="@dimen/button_cluster_side_padding"
- android:background="?android:attr/selectableItemBackground">
- <!-- The entire LinearLayout here is clickable, so we don't
- care about clicks on the ImageButton itself. -->
- <ImageButton android:id="@+id/manageConferenceButtonImage"
- android:clickable="false"
- style="@style/InCallExtraRowButton"
- android:src="@drawable/ic_groups_holo_dark"
- android:contentDescription="@string/onscreenManageConferenceText" />
- <TextView android:id="@+id/manageConferenceButtonLabel"
- style="@style/InCallExtraRowButtonLabel"
- android:text="@string/onscreenManageConferenceText" />
- </LinearLayout>
-
- <!-- CDMA-specific "Merge" -->
- <!-- This button is used only on CDMA devices, where we can't use
- the Merge button in the main button row (because the "Add Call"
- button might need to be enabled at the same time.) -->
- <LinearLayout android:id="@+id/cdmaMergeButton"
- android:orientation="horizontal"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:paddingStart="@dimen/button_cluster_side_padding"
- android:paddingEnd="@dimen/button_cluster_side_padding"
- android:background="?android:attr/selectableItemBackground">
- <!-- The entire LinearLayout here is clickable, so we don't
- care about clicks on the ImageButton itself. -->
- <ImageButton android:id="@+id/cdmaMergeButtonImage"
- android:clickable="false"
- style="@style/InCallExtraRowButton"
- android:src="@drawable/ic_merge_holo_dark"
- android:contentDescription="@string/onscreenMergeCallsText" />
- <TextView android:id="@+id/cdmaMergeButtonLabel"
- style="@style/InCallExtraRowButtonLabel"
- android:text="@string/onscreenMergeCallsText" />
- </LinearLayout>
-
-</FrameLayout>
diff --git a/res/layout/incall_touch_ui.xml b/res/layout/incall_touch_ui.xml
deleted file mode 100644
index 6099f41..0000000
--- a/res/layout/incall_touch_ui.xml
+++ /dev/null
@@ -1,244 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
- ~ Copyright (C) 2013 The Android Open Source Project
- ~
- ~ Licensed under the Apache License, Version 2.0 (the "License");
- ~ you may not use this file except in compliance with the License.
- ~ You may obtain a copy of the License at
- ~
- ~ http://www.apache.org/licenses/LICENSE-2.0
- ~
- ~ Unless required by applicable law or agreed to in writing, software
- ~ distributed under the License is distributed on an "AS IS" BASIS,
- ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- ~ See the License for the specific language governing permissions and
- ~ limitations under the License
- -->
-
-<!-- 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
- -->
- <RelativeLayout android:id="@+id/inCallControls"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:visibility="gone"
- >
- <!-- DTMF dialpad shown in the upper part of the screen
- (above the main cluster of buttons.) -->
- <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"
- android:layout_above="@+id/bottomButtons"
- android:layout_marginBottom="@dimen/dialpad_vertical_margin" />
-
- <!-- Main cluster of onscreen buttons on the lower part of the screen. -->
- <LinearLayout android:id="@+id/bottomButtons"
- android:orientation="vertical"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:layout_alignParentBottom="true">
-
- <!-- Row 1, the "extra button row": A couple of relatively rare
- buttons used only in certain call states.
- Most of the time this whole row is GONE.
- For now, at least, there's only ever one button visible here
- at a time, so this can be a simple FrameLayout. -->
- <ViewStub android:id="@+id/extraButtonRow"
- android:layout="@layout/extra_button_row"
- android:layout_width="match_parent"
- android:layout_height="wrap_content" />
-
- <!-- Row 2: The "End call" button. -->
- <ImageButton android:id="@+id/endButton"
- style="@style/InCallEndButton"
- android:layout_width="match_parent"
- android:src="@drawable/ic_dial_end_call"
- android:background="@drawable/end_call_background"
- android:contentDescription="@string/onscreenEndCallText" />
-
- <!-- Row 3: The main batch of in-call buttons:
- Dialpad / Audio mode / Mute / Hold / Add call
- Visible in all states except while an incoming call is
- ringing. -->
- <LinearLayout
- android:orientation="horizontal"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:background="@drawable/dialpad_background"
- android:paddingStart="@dimen/button_cluster_side_padding"
- android:paddingEnd="@dimen/button_cluster_side_padding"
- >
-
- <!-- This row has either 4 or 5 buttons, depending on
- whether the device supports "Hold" (i.e. 4 buttons on
- CDMA devices, 5 buttons on GSM devices.) The buttons
- are interspersed with 'layout_weight="1"' placeholder
- views so that they'll be spaced evenly in both cases.
-
- But note there are a couple of *pairs* of buttons that share a
- single "slot", namely Hold/Swap and Add/Merge. For these, the
- code in InCallTouchUi is responsible for making sure that at any
- point exactly one of the pair is VISIBLE and the other is
- GONE. -->
-
- <!-- Separator between left padding and 1st button -->
- <View style="@style/VerticalSeparator" />
-
- <!-- "Dialpad" -->
- <!-- This is a "compound button": it has checked and unchecked states. -->
- <ToggleButton android:id="@+id/dialpadButton"
- style="@style/InCallCompoundButton"
- android:background="@drawable/btn_compound_dialpad"
- android:contentDescription="@string/onscreenShowDialpadText"
- />
-
- <!-- Separator between 1st and 2nd button -->
- <View style="@style/VerticalSeparator" />
-
- <!-- "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"
- style="@style/InCallCompoundButton"
- android:background="@drawable/btn_compound_audio"
- android:contentDescription="@string/onscreenAudioText"
- />
-
- <!-- Separator between 2nd and 3rd button -->
- <View style="@style/VerticalSeparator" />
-
- <!-- "Mute" -->
- <!-- This is a "compound button": it has checked and unchecked states. -->
- <ToggleButton android:id="@+id/muteButton"
- style="@style/InCallCompoundButton"
- android:background="@drawable/btn_compound_mute"
- android:contentDescription="@string/onscreenMuteText"
- />
-
- <!-- Separator between 3rd and 4th button -->
- <View style="@style/VerticalSeparator" />
-
- <!-- 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"
- 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"
- style="@style/InCallButton"
- android:src="@drawable/ic_incall_switch_holo_dark"
- android:contentDescription="@string/onscreenSwapCallsText"
- />
-
- <!-- Separator between 4th and 5th button (if 5th exists) -->
- <View android:id="@+id/holdSwapSpacer"
- style="@style/VerticalSeparator" />
-
- <!-- 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"
- 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"
- style="@style/InCallButton"
- android:src="@drawable/ic_merge_holo_dark"
- android:contentDescription="@string/onscreenMergeCallsText"
- />
-
- <!-- Separator between 5th and 6th button (if 6th exists) -->
- <View android:id="@+id/videoCallSpacer"
- style="@style/VerticalSeparator" />
-
- <!-- This button is use for converting an ongoing call into a video call. -->
- <ImageButton android:id="@+id/videoCallButton"
- style="@style/InCallButton"
- android:src="@drawable/ic_videocall_holo_dark"
- android:contentDescription="@string/onscreenVideoCallText"
- />
-
- <!-- Separator between 4th (or 5th) button and right padding -->
- <View style="@style/VerticalSeparator" />
-
- </LinearLayout>
-
- </LinearLayout>
-
- </RelativeLayout>
-
- <!--
- (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="match_parent"
- android:layout_height="wrap_content"
- android:layout_gravity="center|bottom"
- android:layout_marginTop="20dip"
- android:layout_marginBottom="-46dp"
- 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/manage_conference_panel.xml b/res/layout/manage_conference_panel.xml
deleted file mode 100644
index f1fbfdf..0000000
--- a/res/layout/manage_conference_panel.xml
+++ /dev/null
@@ -1,132 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2009 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.
--->
-
-<!-- The "Manage conference" UI. This panel is displayed (instead of
- the inCallPanel) when the user clicks the "Manage conference"
- 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"
- >
- <!-- This original header (with timer) is currently not being used,
- but may be of use in the future. -->
- <!-- Header, including chronometer and List divider -->
- <Chronometer
- android:id="@+id/manageConferencePanelHeader"
- android:textAppearance="?android:attr/textAppearanceLarge"
- android:textSize="24sp"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:gravity="center_horizontal"
- android:layout_alignParentTop="true"
- android:layout_marginTop="5dip"
- android:layout_marginBottom="5dip"
- android:visibility="gone"/>
-
- <ImageView
- android:id="@+id/manageConferencePanelDivider"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:src="@android:drawable/divider_horizontal_dark"
- android:scaleType="fitXY"
- android:layout_below="@id/manageConferencePanelHeader"
- android:visibility="gone"/>
- <!-- End of the original header -->
-
- <!-- Header which looks like ActionBar. -->
- <FrameLayout
- android:id="@+id/manageConferenceHeader"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:background="@*android:drawable/ab_transparent_dark_holo">
-
- <LinearLayout
- android:id="@+id/manage_done"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:background="?android:attr/selectableItemBackground"
- android:clickable="true"
- android:orientation="horizontal">
-
- <ImageView
- android:src="?android:attr/homeAsUpIndicator"
- android:layout_gravity="center_vertical|left"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content" />
-
- <TextView
- android:layout_width="match_parent"
- android:layout_height="?android:attr/actionBarSize"
- style="@*android:style/TextAppearance.Holo.Widget.ActionBar.Title"
- android:gravity="center_vertical"
- android:text="@string/manageConferenceLabel"/>
- </LinearLayout>
-
- </FrameLayout> <!-- End of header -->
-
- <!-- The scrollview wrapper for the list of callers on
- the conference call (in case the list gets too long). -->
- <ScrollView
- android:id="@+id/conferenceList"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:layout_below="@id/manageConferenceHeader">
-
- <!-- The actual list of callers; this embedded LinearLayout
- required since scrollview only supports a single child. -->
- <LinearLayout
- android:orientation="vertical"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:showDividers="middle|end"
- android:divider="?android:attr/listDivider">
-
- <!-- A conference can have at most MAX_CALLERS_IN_CONFERENCE (= 5) callers,
- so just define all those UI elements here. -->
-
- <!-- Caller 0 -->
- <include
- layout="@layout/caller_in_conference"
- android:id="@+id/caller0"/>
-
- <!-- Caller 1 -->
- <include
- layout="@layout/caller_in_conference"
- android:id="@+id/caller1"/>
-
- <!-- Caller 2 -->
- <include
- layout="@layout/caller_in_conference"
- android:id="@+id/caller2"/>
-
- <!-- Caller 3 -->
- <include
- layout="@layout/caller_in_conference"
- android:id="@+id/caller3"/>
-
- <!-- Caller 4 -->
- <include
- layout="@layout/caller_in_conference"
- android:id="@+id/caller4"/>
-
- </LinearLayout> <!-- End of "list of callers on conference call" -->
-
- </ScrollView> <!-- End of scrolling list wrapper for the linear layout -->
-
-</RelativeLayout>
diff --git a/res/layout/primary_call_info.xml b/res/layout/primary_call_info.xml
deleted file mode 100644
index aeeeec5..0000000
--- a/res/layout/primary_call_info.xml
+++ /dev/null
@@ -1,212 +0,0 @@
-<?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.
--->
-
-<!-- XML resource file for primary call info, which will be used by CallCard.
- See also call_card.xml. -->
-<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
- android:layout_width="match_parent"
- android:layout_height="0dp"
- android:layout_weight="1">
-
- <!-- Contact photo for primary call info -->
- <ImageView android:id="@+id/photo"
- android:layout_alignParentStart="true"
- android:layout_alignParentTop="true"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:gravity="top|center_horizontal"
- android:scaleType="centerCrop"
- android:contentDescription="@string/contactPhoto" />
-
- <!-- Used when the phone call is on hold, dimming the primary photo
-
- Note: Theoretically it is possible to achieve this effect using
- Drawable#setColorFilter().
-
- But watch out: we also use cross fade between primary and
- secondary photo, which may interfere with the dim effect with
- setColorFilter(). To try it out, use GSM phones and do multiple
- calls.
-
- Detail: during the cross-fade effect we are currently using
- TransitionDrawable. TransitionDrawable#setColorFilter() will call
- the equivalent method for *both* drawables which are shared by
- the two ImageViews. If we set setColorFilter() for "on hold" effect
- during the cross-fade, *both* primary and secondary photos become
- dim.
-
- Theoretically it can be avoided (by copying drawable, or carefully
- calling setColorFilter() conditionally. But it doesn't bang for the
- buck for now.
-
- TODO: try that. It may be smoother with slower devices.
- -->
- <View android:id="@+id/dim_effect_for_primary_photo"
- android:layout_alignParentStart="true"
- android:layout_alignParentTop="true"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:background="@color/on_hold_dim_effect"
- android:visibility="gone" />
-
- <!-- "Call Banner" for primary call, the foregound or ringing call.
- The "call banner" is a block of info about a single call,
- including the contact name, phone number, call time counter,
- 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"
- style="@style/PrimaryCallInfoPrimaryCallBanner"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:minHeight="@dimen/call_banner_height"
- android:paddingStart="@dimen/call_banner_side_padding"
- android:paddingEnd="@dimen/call_banner_side_padding"
- android:paddingTop="@dimen/call_banner_top_bottom_padding"
- android:paddingBottom="@dimen/call_banner_top_bottom_padding"
- android:background="@color/incall_call_banner_background">
-
- <!-- Name (or the phone number, if we don't have a name to display). -->
- <TextView android:id="@+id/name"
- android:layout_alignParentTop="true"
- android:layout_alignParentStart="true"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:paddingEnd="@dimen/call_banner_name_number_right_padding"
- android:textAppearance="?android:attr/textAppearanceMedium"
- android:textColor="@color/incall_call_banner_text_color"
- android:singleLine="true"
- android:textAlignment="viewStart"/>
-
- <!-- Label (like "Mobile" or "Work", if present) and phone number, side by side -->
- <LinearLayout android:id="@+id/labelAndNumber"
- android:layout_below="@id/name"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:paddingEnd="@dimen/call_banner_name_number_right_padding"
- android:orientation="horizontal">
- <TextView android:id="@+id/phoneNumber"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:textAppearance="?android:attr/textAppearanceSmall"
- android:textColor="@color/incall_call_banner_text_color"
- android:singleLine="true"
- android:textDirection="ltr" />
- <TextView android:id="@+id/label"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:textAppearance="?android:attr/textAppearanceSmall"
- android:textColor="@color/incall_call_banner_text_color"
- android:textAllCaps="true"
- android:singleLine="true"
- android:layout_marginStart="6dp" />
- </LinearLayout>
-
- <!-- Elapsed time indication for a call in progress. -->
- <TextView android:id="@+id/elapsedTime"
- android:layout_alignParentEnd="true"
- android:layout_centerVertical="true"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:textAppearance="?android:attr/textAppearanceMedium"
- android:textColor="@color/incall_call_banner_text_color"
- android:singleLine="true"
- android:visibility="invisible" />
-
- <!-- Call type indication: a special label and/or branding
- for certain kinds of calls (like "Internet call" for a SIP call.) -->
- <TextView android:id="@+id/callTypeLabel"
- android:layout_below="@id/labelAndNumber"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:textAppearance="?android:attr/textAppearanceSmall"
- android:textColor="@color/incall_call_banner_text_color"
- android:maxLines="1"
- android:ellipsize="end" />
-
- </RelativeLayout> <!-- End of call_banner -->
-
- <LinearLayout android:id="@+id/secondary_info_container"
- style="@style/PrimaryCallInfoSecondaryInfoContainer"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:layout_gravity="center_vertical|right"
- android:orientation="vertical"
- android:background="@color/incall_secondary_info_background"
- android:animateLayoutChanges="true">
-
- <!-- Shown when a gateway provider is used during any outgoing call. -->
- <LinearLayout android:id="@+id/providerInfo"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:paddingTop="@dimen/provider_info_top_bottom_padding"
- android:paddingBottom="@dimen/provider_info_top_bottom_padding"
- android:paddingStart="@dimen/call_banner_side_padding"
- android:paddingEnd="@dimen/call_banner_side_padding"
- android:gravity="end"
- android:orientation="horizontal"
- android:background="@android:color/transparent">
- <TextView android:id="@+id/providerLabel"
- android:layout_width="0px"
- android:layout_height="wrap_content"
- android:layout_weight="6"
- android:textAppearance="?android:attr/textAppearanceSmall"
- android:textAllCaps="true"
- android:textColor="@color/incall_call_banner_text_color"
- android:singleLine="true"
- android:ellipsize="marquee" />
- <TextView android:id="@+id/providerAddress"
- android:layout_width="0px"
- android:layout_height="wrap_content"
- android:layout_weight="4"
- android:gravity="end"
- android:paddingStart="8dp"
- android:textAppearance="?android:attr/textAppearanceSmall"
- android:textAllCaps="true"
- android:textColor="@color/incall_call_banner_text_color"
- android:singleLine="true"
- android:ellipsize="middle" />
- </LinearLayout>
-
- <!-- The "call state label": In some states, this shows a special
- indication like "Dialing" or "Incoming call" or "Call ended".
- It's unused for the normal case of an active ongoing call. -->
- <TextView android:id="@+id/callStateLabel"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:paddingTop="@dimen/provider_info_top_bottom_padding"
- android:paddingBottom="@dimen/provider_info_top_bottom_padding"
- android:paddingStart="@dimen/call_banner_side_padding"
- android:paddingEnd="@dimen/call_banner_side_padding"
- android:gravity="end"
- android:textAppearance="?android:attr/textAppearanceSmall"
- android:textColor="@color/incall_call_banner_text_color"
- android:textAllCaps="true"
- android:background="@android:color/transparent"
- android:singleLine="true"
- android:ellipsize="end" />
- </LinearLayout>
-
- <!-- Social status (currently unused) -->
- <!-- <TextView android:id="@+id/socialStatus"
- android:layout_below="@id/callTypeLabel"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:textAppearance="?android:attr/textAppearanceSmall"
- android:textColor="@color/incall_call_banner_text_color"
- android:maxLines="2"
- android:ellipsize="end"
- /> -->
-</RelativeLayout>
diff --git a/res/layout/secondary_call_info.xml b/res/layout/secondary_call_info.xml
deleted file mode 100644
index b84ba82..0000000
--- a/res/layout/secondary_call_info.xml
+++ /dev/null
@@ -1,73 +0,0 @@
-<?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.
--->
-
-<!-- XML resource file for secondary call info, which will be used by CallCard.
- See also call_card.xml.
-
- This should look similar to primary call info (primary_call_info.xml), but
- to optimize the view usage, the structure is different. -->
-<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
- android:layout_width="match_parent"
- android:layout_height="match_parent">
-
- <!-- Contact photo for call_info #2 -->
- <ImageView android:id="@+id/secondaryCallPhoto"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:gravity="top|center_horizontal"
- android:scaleType="centerCrop"
- android:contentDescription="@string/onHold" />
-
- <!-- Overlaps secondary photo when the secondary call is in HOLD state.
-
- TODO: We could do better. See equivalent in primary xml. -->
- <View android:id="@+id/dim_effect_for_secondary_photo"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:background="@drawable/clickable_dim_effect"
- android:visibility="gone" />
-
- <!-- 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|start"
- android:paddingStart="@dimen/call_banner_side_padding"
- android:paddingEnd="@dimen/call_banner_side_padding"
- android:paddingTop="@dimen/call_banner_top_bottom_padding"
- android:paddingBottom="@dimen/call_banner_top_bottom_padding"
- android:textAppearance="?android:attr/textAppearanceMedium"
- android:textColor="@color/incall_call_banner_text_color"
- android:singleLine="true"
- android:background="@color/incall_call_banner_background" />
-
- <!-- 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:gravity="top|end"
- android:paddingStart="@dimen/call_banner_side_padding"
- android:paddingEnd="@dimen/call_banner_side_padding"
- android:paddingTop="@dimen/call_banner_top_bottom_padding"
- android:paddingBottom="@dimen/call_banner_top_bottom_padding"
- android:text="@string/onHold"
- android:textAppearance="?android:attr/textAppearanceSmall"
- android:textColor="@color/incall_call_banner_text_color"
- android:textAllCaps="true"
- android:singleLine="true" />
-</FrameLayout>
diff --git a/res/menu/incall_audio_mode_menu.xml b/res/menu/incall_audio_mode_menu.xml
deleted file mode 100644
index 0139895..0000000
--- a/res/menu/incall_audio_mode_menu.xml
+++ /dev/null
@@ -1,38 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2011 Google Inc.
-
- 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.
--->
-
-<!-- "Audio mode" popup menu for the in-call UI. -->
-<menu xmlns:android="http://schemas.android.com/apk/res/android">
- <!-- TODO: Need final icon assets. Also, PopupMenu currently ignores the
- android:icon attribute anyway(!) -->
- <item android:id="@+id/audio_mode_speaker"
- android:icon="@drawable/ic_sound_holo_dark"
- android:title="@string/audio_mode_speaker" />
-
- <!-- We display *either* "earpiece" or "wired headset", never both,
- depending on whether a wired headset is physically plugged in
- (see InCallTouchUi.showAudioModePopup().) -->
- <item android:id="@+id/audio_mode_earpiece"
- android:icon="@drawable/ic_ab_dialer_holo_dark"
- android:title="@string/audio_mode_earpiece" />
- <item android:id="@+id/audio_mode_wired_headset"
- android:icon="@drawable/ic_ab_dialer_holo_dark"
- android:title="@string/audio_mode_wired_headset" />
-
- <item android:id="@+id/audio_mode_bluetooth"
- android:icon="@drawable/ic_bluetooth_holo_dark"
- android:title="@string/audio_mode_bluetooth" />
-</menu>
diff --git a/res/mipmap-xxxhdpi/ic_launcher_contacts.png b/res/mipmap-xxxhdpi/ic_launcher_contacts.png
new file mode 100644
index 0000000..7d07add
--- /dev/null
+++ b/res/mipmap-xxxhdpi/ic_launcher_contacts.png
Binary files differ
diff --git a/res/mipmap-xxxhdpi/ic_launcher_phone.png b/res/mipmap-xxxhdpi/ic_launcher_phone.png
new file mode 100644
index 0000000..8c92ac1
--- /dev/null
+++ b/res/mipmap-xxxhdpi/ic_launcher_phone.png
Binary files differ
diff --git a/res/values-af/strings.xml b/res/values-af/strings.xml
index 8b1cb17..63bfaac 100644
--- a/res/values-af/strings.xml
+++ b/res/values-af/strings.xml
@@ -454,10 +454,8 @@
<string name="network_message" msgid="4483886461245213802">"Netwerkboodskap"</string>
<string name="ota_title_activate" msgid="8616918561356194398">"Aktiveer jou foon"</string>
<string name="ota_touch_activate" msgid="6553212803262586244">"\'n Spesiale oproep moet gemaak word om jou foondiens te aktiveer. \n\nDruk \"Aktiveer\" en luister dan na die instruksies om jou foon te aktiveer."</string>
- <!-- no translation found for ota_hfa_activation_title (2234246934160473981) -->
- <skip />
- <!-- no translation found for ota_hfa_activation_dialog_message (8092479227918463415) -->
- <skip />
+ <string name="ota_hfa_activation_title" msgid="2234246934160473981">"Aktiveer tans…"</string>
+ <string name="ota_hfa_activation_dialog_message" msgid="8092479227918463415">"Die foon aktiveer tans jou mobiele datadiens.\n\nDit kan tot 5 minute neem."</string>
<string name="ota_skip_activation_dialog_title" msgid="2943366608272261306">"Slaan aktivering oor?"</string>
<string name="ota_skip_activation_dialog_message" msgid="2440770373498870550">"As jy aktivering oorslaan, kan jy nie oproepe maak of aan mobiele datanetwerke koppel nie (hoewel jy aan Wi-Fi-netwerke kan koppel). Tot tyd en wyl jy jou foon aktiveer, word jy gevra om dit te aktiveer elke keer wat jy dit aanskakel."</string>
<string name="ota_skip_activation_dialog_skip_label" msgid="3458532775091563208">"Slaan oor"</string>
@@ -585,8 +583,7 @@
<string name="respond_via_sms_setting_title_2" msgid="6104662227299493906">"Redigeer vinnige antwoorde"</string>
<string name="respond_via_sms_setting_summary" msgid="9150281183930613065"></string>
<string name="respond_via_sms_edittext_dialog_title" msgid="20379890418289778">"Vinnige antwoord"</string>
- <!-- no translation found for respond_via_sms_menu_reset_default_activity (4029277930090150223) -->
- <skip />
+ <string name="respond_via_sms_menu_reset_default_activity" msgid="4029277930090150223">"Herstel verstekke"</string>
<string name="respond_via_sms_confirmation_format" msgid="7229149977515784269">"Boodskap gestuur na <xliff:g id="PHONE_NUMBER">%s</xliff:g>."</string>
<string name="description_image_button_one" msgid="5502718871331943463">"een"</string>
<string name="description_image_button_two" msgid="4903738528222924522">"twee"</string>
diff --git a/res/values-am/strings.xml b/res/values-am/strings.xml
index c4d2dba..21269c3 100644
--- a/res/values-am/strings.xml
+++ b/res/values-am/strings.xml
@@ -28,7 +28,7 @@
<string name="mmiStarted" msgid="6347869857061147003">"የMMI ኮድ ጀምሯል"</string>
<string name="ussdRunning" msgid="485588686340541690">"የUSSD ኮድ አሂድ ላይ ነው..."</string>
<string name="mmiCancelled" msgid="2771923949751842276">"የMMI ኮድ ቀርቷል"</string>
- <string name="cancel" msgid="5044513931633602634">"ይቅር"</string>
+ <string name="cancel" msgid="5044513931633602634">"ሰርዝ"</string>
<string name="enter_input" msgid="1810529547726803893">"የUSSD መልዕክት በ<xliff:g id="MIN_LEN">%d</xliff:g> እና <xliff:g id="MAX_LEN">%d</xliff:g> ቁምፊዎች መካከል መሆን አለበት። እባክዎ እንደገና ይሞክሩ።"</string>
<string name="manageConferenceLabel" msgid="4691922394301969053">"የስብሰባስልክ ጥሪ አደራጅ"</string>
<string name="ok" msgid="3811371167865772377">"እሺ"</string>
@@ -450,10 +450,8 @@
<string name="network_message" msgid="4483886461245213802">"የአውታረ መረብ መልዕክት"</string>
<string name="ota_title_activate" msgid="8616918561356194398">"ስልክዎን ያግብሩ"</string>
<string name="ota_touch_activate" msgid="6553212803262586244">"የስልክዎን አገለግሎት ለማግበር ልዩ ጥሪ ያስፈልጋል።\n\n \"አግብር\" ከተጫኑ በኋላ ስልክዎን ለማግበር የቀረቡትን መመሪያዎች ያዳምጡ።"</string>
- <!-- no translation found for ota_hfa_activation_title (2234246934160473981) -->
- <skip />
- <!-- no translation found for ota_hfa_activation_dialog_message (8092479227918463415) -->
- <skip />
+ <string name="ota_hfa_activation_title" msgid="2234246934160473981">"በማንቃት ላይ..."</string>
+ <string name="ota_hfa_activation_dialog_message" msgid="8092479227918463415">"ስልኩ የሞባይል ውሂብ አገልግሎትዎን እያነቃ ነው።\n\nይህ እስከ 5 ደቂቃዎች ድረስ ሊወስድ ይችላል።"</string>
<string name="ota_skip_activation_dialog_title" msgid="2943366608272261306">"አግብር ይዝለል?"</string>
<string name="ota_skip_activation_dialog_message" msgid="2440770373498870550">"ማግበር ካዘለሉ፣ ጥሪ ማድረግ ወይም ተንቀሳቃሽ ስልክ ውሂብ አውታረ መረብ(በWi-Fi አውታረ መረቦች ማያያዝ ቢችሉም እንኳን ) ማያያዝ አይችሉም። ስልክዎን እስኪያገብሩ ድረስ፣ ባበሩት ቁጥር እንዲያገብሩት ይጠየቃሉ።"</string>
<string name="ota_skip_activation_dialog_skip_label" msgid="3458532775091563208">"ዝለል"</string>
@@ -581,8 +579,7 @@
<string name="respond_via_sms_setting_title_2" msgid="6104662227299493906">"ፈጣን ምላሾች አርትዕ"</string>
<string name="respond_via_sms_setting_summary" msgid="9150281183930613065"></string>
<string name="respond_via_sms_edittext_dialog_title" msgid="20379890418289778">"ፈጣን ምላሽ"</string>
- <!-- no translation found for respond_via_sms_menu_reset_default_activity (4029277930090150223) -->
- <skip />
+ <string name="respond_via_sms_menu_reset_default_activity" msgid="4029277930090150223">"ነባሪዎችን መልስ"</string>
<string name="respond_via_sms_confirmation_format" msgid="7229149977515784269">"ለ <xliff:g id="PHONE_NUMBER">%s</xliff:g> የተላከ መልዕክት"</string>
<string name="description_image_button_one" msgid="5502718871331943463">"አንድ"</string>
<string name="description_image_button_two" msgid="4903738528222924522">"ሁለት"</string>
diff --git a/res/values-ar/strings.xml b/res/values-ar/strings.xml
index e403f1e..af10fc1 100644
--- a/res/values-ar/strings.xml
+++ b/res/values-ar/strings.xml
@@ -450,10 +450,8 @@
<string name="network_message" msgid="4483886461245213802">"رسالة الشبكة"</string>
<string name="ota_title_activate" msgid="8616918561356194398">"تنشيط الهاتف"</string>
<string name="ota_touch_activate" msgid="6553212803262586244">"يلزم إجراء اتصال خاص لتنشيط خدمة الهاتف. \n\nبعد الضغط على \"تنشيط\"، استمع إلى الإرشادات المقدمة لتنشيط هاتفك."</string>
- <!-- no translation found for ota_hfa_activation_title (2234246934160473981) -->
- <skip />
- <!-- no translation found for ota_hfa_activation_dialog_message (8092479227918463415) -->
- <skip />
+ <string name="ota_hfa_activation_title" msgid="2234246934160473981">"جارٍ التنشيط..."</string>
+ <string name="ota_hfa_activation_dialog_message" msgid="8092479227918463415">"يُجري الهاتف تنشيطًا لخدمة بيانات الجوّال.\n\nقد يستغرق هذا الأمر ما يصل إلى 5 دقائق."</string>
<string name="ota_skip_activation_dialog_title" msgid="2943366608272261306">"هل تريد تخطي التنشيط؟"</string>
<string name="ota_skip_activation_dialog_message" msgid="2440770373498870550">"إذا تخطيت التنشيط، فلن تتمكن من إجراء مكالمات أو الاتصال بشبكات بيانات الجوال (ومع ذلك، يمكنك الاتصال بشبكات Wi-Fi). إلى أن تنشط هاتفك، ستتم مطالبتك بتنشيطه في كل مرة تشغله فيها."</string>
<string name="ota_skip_activation_dialog_skip_label" msgid="3458532775091563208">"تخطٍ"</string>
@@ -581,8 +579,7 @@
<string name="respond_via_sms_setting_title_2" msgid="6104662227299493906">"تعديل الردود السريعة"</string>
<string name="respond_via_sms_setting_summary" msgid="9150281183930613065"></string>
<string name="respond_via_sms_edittext_dialog_title" msgid="20379890418289778">"رد سريع"</string>
- <!-- no translation found for respond_via_sms_menu_reset_default_activity (4029277930090150223) -->
- <skip />
+ <string name="respond_via_sms_menu_reset_default_activity" msgid="4029277930090150223">"استعادة الإعدادات الافتراضية"</string>
<string name="respond_via_sms_confirmation_format" msgid="7229149977515784269">"تم إرسال الرسالة إلى <xliff:g id="PHONE_NUMBER">%s</xliff:g>."</string>
<string name="description_image_button_one" msgid="5502718871331943463">"واحد"</string>
<string name="description_image_button_two" msgid="4903738528222924522">"اثنان"</string>
diff --git a/res/values-bg/strings.xml b/res/values-bg/strings.xml
index 0cfe315..4834667 100644
--- a/res/values-bg/strings.xml
+++ b/res/values-bg/strings.xml
@@ -450,10 +450,8 @@
<string name="network_message" msgid="4483886461245213802">"Мрежово съобщение"</string>
<string name="ota_title_activate" msgid="8616918561356194398">"Активиране на вашия телефон"</string>
<string name="ota_touch_activate" msgid="6553212803262586244">"За активиране на телефонните услуги трябва да направите специално обаждане. \n\nСлед като натиснете „Активиране“, чуйте предоставените инструкции за тази цел."</string>
- <!-- no translation found for ota_hfa_activation_title (2234246934160473981) -->
- <skip />
- <!-- no translation found for ota_hfa_activation_dialog_message (8092479227918463415) -->
- <skip />
+ <string name="ota_hfa_activation_title" msgid="2234246934160473981">"Активира се..."</string>
+ <string name="ota_hfa_activation_dialog_message" msgid="8092479227918463415">"Телефонът активира услугата ви за мобилни данни.\n\nТова може да отнеме до 5 минути."</string>
<string name="ota_skip_activation_dialog_title" msgid="2943366608272261306">"Да се пропусне ли активацията?"</string>
<string name="ota_skip_activation_dialog_message" msgid="2440770373498870550">"Ако пропуснете активирането, не може да осъществявате обаждания или свързване към мобилни мрежи с данни (възможно е свързване към мрежи с Wi-Fi). Докато не активирате телефона си, от вас ще се иска да го правите при всяко включване."</string>
<string name="ota_skip_activation_dialog_skip_label" msgid="3458532775091563208">"Пропускане"</string>
@@ -581,8 +579,7 @@
<string name="respond_via_sms_setting_title_2" msgid="6104662227299493906">"Редактиране на бързи отговори"</string>
<string name="respond_via_sms_setting_summary" msgid="9150281183930613065"></string>
<string name="respond_via_sms_edittext_dialog_title" msgid="20379890418289778">"Бърз отговор"</string>
- <!-- no translation found for respond_via_sms_menu_reset_default_activity (4029277930090150223) -->
- <skip />
+ <string name="respond_via_sms_menu_reset_default_activity" msgid="4029277930090150223">"Стандартни настройки: Възст."</string>
<string name="respond_via_sms_confirmation_format" msgid="7229149977515784269">"До <xliff:g id="PHONE_NUMBER">%s</xliff:g> бе изпратено съобщение."</string>
<string name="description_image_button_one" msgid="5502718871331943463">"едно"</string>
<string name="description_image_button_two" msgid="4903738528222924522">"две"</string>
diff --git a/res/values-ca/strings.xml b/res/values-ca/strings.xml
index 00c3beb..48d3ae3 100644
--- a/res/values-ca/strings.xml
+++ b/res/values-ca/strings.xml
@@ -450,10 +450,8 @@
<string name="network_message" msgid="4483886461245213802">"Missatge de xarxa"</string>
<string name="ota_title_activate" msgid="8616918561356194398">"Activació del telèfon"</string>
<string name="ota_touch_activate" msgid="6553212803262586244">"Cal fer una trucada especial per activar el servei del telèfon. \n\nDesprés de prémer \"Activa\", escolteu les instruccions proporcionades per activar el telèfon."</string>
- <!-- no translation found for ota_hfa_activation_title (2234246934160473981) -->
- <skip />
- <!-- no translation found for ota_hfa_activation_dialog_message (8092479227918463415) -->
- <skip />
+ <string name="ota_hfa_activation_title" msgid="2234246934160473981">"S\'està activant..."</string>
+ <string name="ota_hfa_activation_dialog_message" msgid="8092479227918463415">"El telèfon està activant el vostre servei de dades per a mòbils.\n\nAquest procés pot durar fins a 5 minuts."</string>
<string name="ota_skip_activation_dialog_title" msgid="2943366608272261306">"Voleu ometre l\'activació?"</string>
<string name="ota_skip_activation_dialog_message" msgid="2440770373498870550">"Si ometeu l\'activació, no podreu fer trucades ni connectar-vos a xarxes de dades mòbils (tot i que podreu connectar-vos a xarxes Wi-fi). Fins que activeu el telèfon, se us demanarà que ho feu cada cop que l\'engegueu."</string>
<string name="ota_skip_activation_dialog_skip_label" msgid="3458532775091563208">"Omet"</string>
@@ -494,7 +492,7 @@
<string name="voicemail_provider" msgid="5135942703327136909">"Servei"</string>
<string name="voicemail_settings" msgid="72448049107749316">"Configuració"</string>
<string name="voicemail_number_not_set" msgid="6724904736891087856">"<No definit>"</string>
- <string name="other_settings" msgid="3672912580359716394">"Altres opcions de configuració de trucades"</string>
+ <string name="other_settings" msgid="3672912580359716394">"Altres opcions de trucades"</string>
<string name="calling_via_template" msgid="4839419581866928142">"Trucada mitjançant <xliff:g id="PROVIDER_NAME">%s</xliff:g>"</string>
<string name="contactPhoto" msgid="4713193418046639466">"foto de contacte"</string>
<string name="goPrivate" msgid="865837794424530980">"passa a privat"</string>
@@ -513,7 +511,7 @@
<string name="pick_outgoing_call_phone_type" msgid="5622916534828338675">"Fes una trucada"</string>
<string name="pick_outgoing_sip_phone" msgid="7012322118236208875">"Utilitza el compte per a trucades per Internet:"</string>
<string name="remember_my_choice" msgid="7058059586169290705">"Utilitza-ho sempre per fer trucades per Internet"</string>
- <string name="reset_my_choice_hint" msgid="5523030209803567922">"Pots canviar quin compte vols utilitzar com a opció predeterminada per a les trucades per Internet del telèfon a la pantalla > Configuració > Configuració de les trucades per Internet > Comptes."</string>
+ <string name="reset_my_choice_hint" msgid="5523030209803567922">"Pots canviar el compte de trucades per Internet que vols utilitzar de manera predeterminada, accedeix a Telèfon > Configuració > Configuració de trucades per Internet > Comptes."</string>
<string name="pstn_phone" msgid="8782554491484326429">"Trucada amb telèfon mòbil"</string>
<string name="internet_phone" msgid="1147922660195095810">"Trucada per Internet"</string>
<string name="no_sip_account_found_title" msgid="6266249392379373628">"No hi ha cap compte per a trucades per Internet"</string>
@@ -581,8 +579,7 @@
<string name="respond_via_sms_setting_title_2" msgid="6104662227299493906">"Edita les respostes ràpides"</string>
<string name="respond_via_sms_setting_summary" msgid="9150281183930613065"></string>
<string name="respond_via_sms_edittext_dialog_title" msgid="20379890418289778">"Resposta ràpida"</string>
- <!-- no translation found for respond_via_sms_menu_reset_default_activity (4029277930090150223) -->
- <skip />
+ <string name="respond_via_sms_menu_reset_default_activity" msgid="4029277930090150223">"Restaura els valors predeterminats"</string>
<string name="respond_via_sms_confirmation_format" msgid="7229149977515784269">"Missatge enviat a <xliff:g id="PHONE_NUMBER">%s</xliff:g>."</string>
<string name="description_image_button_one" msgid="5502718871331943463">"un"</string>
<string name="description_image_button_two" msgid="4903738528222924522">"dos"</string>
@@ -607,9 +604,9 @@
<string name="voicemail_notification_vibarte_when_dialog_title" msgid="5739583146522136440">"Vibra"</string>
<string name="voicemail_notification_ringtone_title" msgid="2609519527849101590">"So"</string>
<string name="default_notification_description" msgid="78174796906240970">"So predeterminat (<xliff:g id="DEFAULT_SOUND_TITLE">%1$s</xliff:g>)"</string>
- <string name="ringtone_title" msgid="6374978286202084684">"To del telèfon"</string>
+ <string name="ringtone_title" msgid="6374978286202084684">"So de trucada"</string>
<string name="vibrate_on_ring_title" msgid="9197564612065258960">"Vibrar en sonar"</string>
<string name="dtmf_tone_enable_title" msgid="827601042915852989">"Sonar en marcar els números"</string>
<string name="dial_pad_autocomplete" msgid="494525952035761075">"Autocompletar amb teclat"</string>
- <string name="preference_category_ringtone" msgid="5197960752529332721">"To i vibració"</string>
+ <string name="preference_category_ringtone" msgid="5197960752529332721">"So i vibració"</string>
</resources>
diff --git a/res/values-cs/strings.xml b/res/values-cs/strings.xml
index 61c8e6c..7bc2cd2 100644
--- a/res/values-cs/strings.xml
+++ b/res/values-cs/strings.xml
@@ -450,10 +450,8 @@
<string name="network_message" msgid="4483886461245213802">"Zpráva sítě"</string>
<string name="ota_title_activate" msgid="8616918561356194398">"Aktivujte svůj telefon"</string>
<string name="ota_touch_activate" msgid="6553212803262586244">"K aktivaci telefonní služby je potřeba uskutečnit speciální hovor. \n\nStiskněte tlačítko Aktivovat a aktivujte telefon podle pokynů, které vám budou sděleny."</string>
- <!-- no translation found for ota_hfa_activation_title (2234246934160473981) -->
- <skip />
- <!-- no translation found for ota_hfa_activation_dialog_message (8092479227918463415) -->
- <skip />
+ <string name="ota_hfa_activation_title" msgid="2234246934160473981">"Aktivace..."</string>
+ <string name="ota_hfa_activation_dialog_message" msgid="8092479227918463415">"V telefonu se aktivuje mobilní datová služba.\n\nMůže to trvat až 5 minut."</string>
<string name="ota_skip_activation_dialog_title" msgid="2943366608272261306">"Přeskočit aktivaci?"</string>
<string name="ota_skip_activation_dialog_message" msgid="2440770373498870550">"Pokud přeskočíte aktivaci, nemůžete volat ani se připojovat k mobilním datovým sítím (můžete se ale připojit k sítím Wi-Fi). Dokud svůj telefon neaktivujete, bude se zobrazovat výzva k aktivaci při každém zapnutí."</string>
<string name="ota_skip_activation_dialog_skip_label" msgid="3458532775091563208">"Přeskočit"</string>
@@ -581,8 +579,7 @@
<string name="respond_via_sms_setting_title_2" msgid="6104662227299493906">"Upravit rychlé odpovědi"</string>
<string name="respond_via_sms_setting_summary" msgid="9150281183930613065"></string>
<string name="respond_via_sms_edittext_dialog_title" msgid="20379890418289778">"Rychlá odpověď"</string>
- <!-- no translation found for respond_via_sms_menu_reset_default_activity (4029277930090150223) -->
- <skip />
+ <string name="respond_via_sms_menu_reset_default_activity" msgid="4029277930090150223">"Obnovit výchozí nastavení"</string>
<string name="respond_via_sms_confirmation_format" msgid="7229149977515784269">"Zpráva byla odeslána na číslo <xliff:g id="PHONE_NUMBER">%s</xliff:g>."</string>
<string name="description_image_button_one" msgid="5502718871331943463">"jedna"</string>
<string name="description_image_button_two" msgid="4903738528222924522">"dvě"</string>
diff --git a/res/values-da/strings.xml b/res/values-da/strings.xml
index 51416c6..e46ac25 100644
--- a/res/values-da/strings.xml
+++ b/res/values-da/strings.xml
@@ -56,7 +56,7 @@
<string name="labelCDMAMore" msgid="1630676740428229339">"Indstillinger for CDMA-opkald"</string>
<string name="apn_settings" msgid="9043423184895642077">"Navn på adgangspunkt"</string>
<string name="settings_label" msgid="3876743539816984008">"Indstillinger for netværk"</string>
- <string name="voicemail" msgid="8693759337917898954">"Voicemail"</string>
+ <string name="voicemail" msgid="8693759337917898954">"Telefonsvarer"</string>
<string name="voicemail_abbreviated" msgid="2215592488517217448">"VM:"</string>
<string name="networks" msgid="8873030692174541976">"Netværksudbydere"</string>
<string name="call_settings" msgid="6112441768261754562">"Indstillinger for opkald"</string>
@@ -119,7 +119,7 @@
<string name="fw_change_failed" msgid="5298103228470214665">"Telefonsvarernummeret kunne ikke ændres.\nKontakt dit mobilselskab, hvis problemet vedbliver."</string>
<string name="fw_get_in_vm_failed" msgid="8862896836093833973">"De aktuelle indstillinger til viderestillingsnummer kunne ikke hentes og gemmes.\nVil du skifte til den nye udbyder alligevel?"</string>
<string name="no_change" msgid="3186040086622435212">"Der blev ikke foretaget nogen ændringer."</string>
- <string name="sum_voicemail_choose_provider" msgid="59911196126278922">"Vælg voicemail-tjeneste"</string>
+ <string name="sum_voicemail_choose_provider" msgid="59911196126278922">"Vælg telefonsvarertjeneste"</string>
<string name="voicemail_default" msgid="5902099213882352338">"Min udbyder"</string>
<string name="mobile_networks" msgid="5540397602919106177">"Indstillinger for mobilnetværk"</string>
<string name="label_available" msgid="1181658289009300430">"Tilgængelige netværk"</string>
@@ -395,8 +395,8 @@
<string name="notification_ongoing_call" msgid="7068688957273482989">"Igangværende opkald"</string>
<string name="notification_on_hold" msgid="3480694969511790465">"Ventende"</string>
<string name="notification_incoming_call" msgid="2820429205043529642">"Indgående opkald"</string>
- <string name="notification_voicemail_title" msgid="8933468752045550523">"Ny voicemail"</string>
- <string name="notification_voicemail_title_count" msgid="4366360747660929916">"Ny voicemail (<xliff:g id="COUNT">%d</xliff:g>)"</string>
+ <string name="notification_voicemail_title" msgid="8933468752045550523">"Ny telefonsvarerbesked"</string>
+ <string name="notification_voicemail_title_count" msgid="4366360747660929916">"Nye telefonsvarerbeskeder (<xliff:g id="COUNT">%d</xliff:g>)"</string>
<string name="notification_voicemail_text_format" msgid="4447323569453981685">"Ring til <xliff:g id="VOICEMAIL_NUMBER">%s</xliff:g>"</string>
<string name="notification_voicemail_no_vm_number" msgid="760963466895609716">"Voicemailnummeret er ukendt"</string>
<string name="notification_network_selection_title" msgid="4224455487793492772">"Ingen dækning"</string>
@@ -456,10 +456,8 @@
<string name="network_message" msgid="4483886461245213802">"Netværksbesked"</string>
<string name="ota_title_activate" msgid="8616918561356194398">"Aktivér din telefon"</string>
<string name="ota_touch_activate" msgid="6553212803262586244">"Der skal foretages et særligt opkald for at aktivere din telefontjeneste. \n\n Lyt til instruktionerne, når du har trykket på “Aktivér” for at aktivere din telefon."</string>
- <!-- no translation found for ota_hfa_activation_title (2234246934160473981) -->
- <skip />
- <!-- no translation found for ota_hfa_activation_dialog_message (8092479227918463415) -->
- <skip />
+ <string name="ota_hfa_activation_title" msgid="2234246934160473981">"Aktiverer..."</string>
+ <string name="ota_hfa_activation_dialog_message" msgid="8092479227918463415">"Telefonen er ved at aktivere din mobildatatjeneste.\n\nDette kan tage op til fem minutter."</string>
<string name="ota_skip_activation_dialog_title" msgid="2943366608272261306">"Spring aktivering over?"</string>
<string name="ota_skip_activation_dialog_message" msgid="2440770373498870550">"Hvis du springer aktiveringen over, kan du ikke foretage opkald eller oprette forbindelse til mobildatanetværk (du kan dog godt oprette forbindelse til Wi-Fi-netværk). Du vil blive bedt om at aktivere din telefon, hver gang du tænder den, indtil du gør det."</string>
<string name="ota_skip_activation_dialog_skip_label" msgid="3458532775091563208">"Spring over"</string>
@@ -587,8 +585,7 @@
<string name="respond_via_sms_setting_title_2" msgid="6104662227299493906">"Rediger hurtige svar"</string>
<string name="respond_via_sms_setting_summary" msgid="9150281183930613065"></string>
<string name="respond_via_sms_edittext_dialog_title" msgid="20379890418289778">"Hurtigt svar"</string>
- <!-- no translation found for respond_via_sms_menu_reset_default_activity (4029277930090150223) -->
- <skip />
+ <string name="respond_via_sms_menu_reset_default_activity" msgid="4029277930090150223">"Gendan standarder"</string>
<string name="respond_via_sms_confirmation_format" msgid="7229149977515784269">"Meddelelsen er sendt til <xliff:g id="PHONE_NUMBER">%s</xliff:g>."</string>
<string name="description_image_button_one" msgid="5502718871331943463">"en"</string>
<string name="description_image_button_two" msgid="4903738528222924522">"to"</string>
diff --git a/res/values-de/strings.xml b/res/values-de/strings.xml
index 556e8d0..f4f926e 100644
--- a/res/values-de/strings.xml
+++ b/res/values-de/strings.xml
@@ -454,10 +454,8 @@
<string name="network_message" msgid="4483886461245213802">"Netzwerknachricht"</string>
<string name="ota_title_activate" msgid="8616918561356194398">"Ihr Telefon aktivieren"</string>
<string name="ota_touch_activate" msgid="6553212803262586244">"Zur Aktivierung Ihres Telefondienstes muss ein spezieller Anruf getätigt werden. \n\nWählen Sie \"Aktivieren\" und folgen Sie der Anleitung zur Aktivierung Ihres Telefons."</string>
- <!-- no translation found for ota_hfa_activation_title (2234246934160473981) -->
- <skip />
- <!-- no translation found for ota_hfa_activation_dialog_message (8092479227918463415) -->
- <skip />
+ <string name="ota_hfa_activation_title" msgid="2234246934160473981">"Wird aktiviert..."</string>
+ <string name="ota_hfa_activation_dialog_message" msgid="8092479227918463415">"Der mobile Datendienst wird jetzt auf Ihrem Telefon aktiviert.\n\nDies kann bis zu 5 Minuten dauern."</string>
<string name="ota_skip_activation_dialog_title" msgid="2943366608272261306">"Aktivierung überspringen?"</string>
<string name="ota_skip_activation_dialog_message" msgid="2440770373498870550">"Wenn Sie die Aktivierung überspringen, können Sie keine Anrufe tätigen oder sich mit mobilen Datennetzwerken verbinden (Sie können sich allerdings mit WLAN-Netzwerken verbinden). Bis Sie Ihr Telefon aktivieren, werden Sie bei jedem Einschalten zur Aktivierung aufgefordert."</string>
<string name="ota_skip_activation_dialog_skip_label" msgid="3458532775091563208">"Überspringen"</string>
@@ -585,8 +583,7 @@
<string name="respond_via_sms_setting_title_2" msgid="6104662227299493906">"Kurzantworten bearbeiten"</string>
<string name="respond_via_sms_setting_summary" msgid="9150281183930613065"></string>
<string name="respond_via_sms_edittext_dialog_title" msgid="20379890418289778">"Kurzantwort"</string>
- <!-- no translation found for respond_via_sms_menu_reset_default_activity (4029277930090150223) -->
- <skip />
+ <string name="respond_via_sms_menu_reset_default_activity" msgid="4029277930090150223">"Standard wiederherstellen"</string>
<string name="respond_via_sms_confirmation_format" msgid="7229149977515784269">"Nachricht an <xliff:g id="PHONE_NUMBER">%s</xliff:g> gesendet"</string>
<string name="description_image_button_one" msgid="5502718871331943463">"Eins"</string>
<string name="description_image_button_two" msgid="4903738528222924522">"Zwei"</string>
diff --git a/res/values-el/strings.xml b/res/values-el/strings.xml
index fccd8e9..b841f68 100644
--- a/res/values-el/strings.xml
+++ b/res/values-el/strings.xml
@@ -450,10 +450,8 @@
<string name="network_message" msgid="4483886461245213802">"Μήνυμα δικτύου"</string>
<string name="ota_title_activate" msgid="8616918561356194398">"Ενεργοποίηση του τηλεφώνου σας"</string>
<string name="ota_touch_activate" msgid="6553212803262586244">"Πρέπει να γίνει ειδική κλήση για την ενεργοποίηση της υπηρεσίας του τηλεφώνου που διαθέτετε. \n\nΑφού πατήσετε την \"Ενεργοποίηση\", ακούστε τις οδηγίες που παρέχονται για να ενεργοποιήσετε το τηλέφωνό σας."</string>
- <!-- no translation found for ota_hfa_activation_title (2234246934160473981) -->
- <skip />
- <!-- no translation found for ota_hfa_activation_dialog_message (8092479227918463415) -->
- <skip />
+ <string name="ota_hfa_activation_title" msgid="2234246934160473981">"Ενεργοποίηση…"</string>
+ <string name="ota_hfa_activation_dialog_message" msgid="8092479227918463415">"Γίνεται ενεργοποίηση της υπηρεσίας δεδομένων κινητής τηλεφωνίας.\n \nΑυτό μπορεί να διαρκέσει έως και 5 λεπτά."</string>
<string name="ota_skip_activation_dialog_title" msgid="2943366608272261306">"Παράβλεψη ενεργοποίησης;"</string>
<string name="ota_skip_activation_dialog_message" msgid="2440770373498870550">"Εάν παραλείψετε την ενεργοποίηση, δεν θα μπορείτε να πραγματοποιήσετε κλήσεις ή να συνδεθείτε σε δίκτυα δεδομένων κινητής τηλεφωνίας (αν και θα μπορείτε να συνδεθείτε σε δίκτυα Wi-Fi). Μέχρι να ενεργοποιήσετε το τηλέφωνό σας, θα σας ζητείται να το ενεργοποιήσετε κάθε φορά που θα το θέτετε σε λειτουργία."</string>
<string name="ota_skip_activation_dialog_skip_label" msgid="3458532775091563208">"Παράλειψη"</string>
@@ -581,8 +579,7 @@
<string name="respond_via_sms_setting_title_2" msgid="6104662227299493906">"Επεξεργασία γρήγορων απαντήσεων"</string>
<string name="respond_via_sms_setting_summary" msgid="9150281183930613065"></string>
<string name="respond_via_sms_edittext_dialog_title" msgid="20379890418289778">"Γρήγορη απάντηση"</string>
- <!-- no translation found for respond_via_sms_menu_reset_default_activity (4029277930090150223) -->
- <skip />
+ <string name="respond_via_sms_menu_reset_default_activity" msgid="4029277930090150223">"Επαναφορά προεπιλογών"</string>
<string name="respond_via_sms_confirmation_format" msgid="7229149977515784269">"Το μήνυμα εστάλη στο <xliff:g id="PHONE_NUMBER">%s</xliff:g>."</string>
<string name="description_image_button_one" msgid="5502718871331943463">"ένα"</string>
<string name="description_image_button_two" msgid="4903738528222924522">"δύο"</string>
diff --git a/res/values-en-rGB/strings.xml b/res/values-en-rGB/strings.xml
index 2e80121..76cc187 100644
--- a/res/values-en-rGB/strings.xml
+++ b/res/values-en-rGB/strings.xml
@@ -450,10 +450,8 @@
<string name="network_message" msgid="4483886461245213802">"Network message"</string>
<string name="ota_title_activate" msgid="8616918561356194398">"Activate your phone"</string>
<string name="ota_touch_activate" msgid="6553212803262586244">"A special call needs to be made to activate your phone service. \n\nAfter pressing “Activate”, listen to the instructions provided to activate your phone."</string>
- <!-- no translation found for ota_hfa_activation_title (2234246934160473981) -->
- <skip />
- <!-- no translation found for ota_hfa_activation_dialog_message (8092479227918463415) -->
- <skip />
+ <string name="ota_hfa_activation_title" msgid="2234246934160473981">"Activating..."</string>
+ <string name="ota_hfa_activation_dialog_message" msgid="8092479227918463415">"The phone is activating your mobile data service.\n\nThis can take up to 5 minutes."</string>
<string name="ota_skip_activation_dialog_title" msgid="2943366608272261306">"Skip activation?"</string>
<string name="ota_skip_activation_dialog_message" msgid="2440770373498870550">"If you skip activation, you can\'t place calls or connect to mobile data networks (though you can connect to Wi-Fi networks). Until you activate your phone, you are asked to activate it each time that you turn it on."</string>
<string name="ota_skip_activation_dialog_skip_label" msgid="3458532775091563208">"Skip"</string>
@@ -581,8 +579,7 @@
<string name="respond_via_sms_setting_title_2" msgid="6104662227299493906">"Edit quick responses"</string>
<string name="respond_via_sms_setting_summary" msgid="9150281183930613065"></string>
<string name="respond_via_sms_edittext_dialog_title" msgid="20379890418289778">"Quick response"</string>
- <!-- no translation found for respond_via_sms_menu_reset_default_activity (4029277930090150223) -->
- <skip />
+ <string name="respond_via_sms_menu_reset_default_activity" msgid="4029277930090150223">"Restore defaults"</string>
<string name="respond_via_sms_confirmation_format" msgid="7229149977515784269">"Message sent to <xliff:g id="PHONE_NUMBER">%s</xliff:g>."</string>
<string name="description_image_button_one" msgid="5502718871331943463">"one"</string>
<string name="description_image_button_two" msgid="4903738528222924522">"two"</string>
diff --git a/res/values-en-rIN/strings.xml b/res/values-en-rIN/strings.xml
index 2e80121..76cc187 100644
--- a/res/values-en-rIN/strings.xml
+++ b/res/values-en-rIN/strings.xml
@@ -450,10 +450,8 @@
<string name="network_message" msgid="4483886461245213802">"Network message"</string>
<string name="ota_title_activate" msgid="8616918561356194398">"Activate your phone"</string>
<string name="ota_touch_activate" msgid="6553212803262586244">"A special call needs to be made to activate your phone service. \n\nAfter pressing “Activate”, listen to the instructions provided to activate your phone."</string>
- <!-- no translation found for ota_hfa_activation_title (2234246934160473981) -->
- <skip />
- <!-- no translation found for ota_hfa_activation_dialog_message (8092479227918463415) -->
- <skip />
+ <string name="ota_hfa_activation_title" msgid="2234246934160473981">"Activating..."</string>
+ <string name="ota_hfa_activation_dialog_message" msgid="8092479227918463415">"The phone is activating your mobile data service.\n\nThis can take up to 5 minutes."</string>
<string name="ota_skip_activation_dialog_title" msgid="2943366608272261306">"Skip activation?"</string>
<string name="ota_skip_activation_dialog_message" msgid="2440770373498870550">"If you skip activation, you can\'t place calls or connect to mobile data networks (though you can connect to Wi-Fi networks). Until you activate your phone, you are asked to activate it each time that you turn it on."</string>
<string name="ota_skip_activation_dialog_skip_label" msgid="3458532775091563208">"Skip"</string>
@@ -581,8 +579,7 @@
<string name="respond_via_sms_setting_title_2" msgid="6104662227299493906">"Edit quick responses"</string>
<string name="respond_via_sms_setting_summary" msgid="9150281183930613065"></string>
<string name="respond_via_sms_edittext_dialog_title" msgid="20379890418289778">"Quick response"</string>
- <!-- no translation found for respond_via_sms_menu_reset_default_activity (4029277930090150223) -->
- <skip />
+ <string name="respond_via_sms_menu_reset_default_activity" msgid="4029277930090150223">"Restore defaults"</string>
<string name="respond_via_sms_confirmation_format" msgid="7229149977515784269">"Message sent to <xliff:g id="PHONE_NUMBER">%s</xliff:g>."</string>
<string name="description_image_button_one" msgid="5502718871331943463">"one"</string>
<string name="description_image_button_two" msgid="4903738528222924522">"two"</string>
diff --git a/res/values-es-rUS/strings.xml b/res/values-es-rUS/strings.xml
index 08111e5..dc22964 100644
--- a/res/values-es-rUS/strings.xml
+++ b/res/values-es-rUS/strings.xml
@@ -74,7 +74,7 @@
<string name="sum_cw_enabled" msgid="8083061901633671397">"Durante una llamada, notificarme sobre las llamadas entrantes"</string>
<string name="sum_cw_disabled" msgid="3648693907300104575">"Durante una llamada, notificarme sobre las llamadas entrantes"</string>
<string name="call_forwarding_settings" msgid="3378927671091537173">"Configuración de reenvío de llamadas"</string>
- <string name="labelCF" msgid="2574386948026924737">"Reenvío de llamada"</string>
+ <string name="labelCF" msgid="2574386948026924737">"Desvío de llamadas"</string>
<string name="labelCFU" msgid="8147177368148660600">"Reenviar siempre"</string>
<string name="messageCFU" msgid="3560082430662923687">"Usar siempre este número"</string>
<string name="sum_cfu_enabled_indicator" msgid="4014187342724130197">"Reenviar todas las llamadas"</string>
@@ -357,7 +357,7 @@
<string name="pin_changed" msgid="4365538014588501049">"El PIN de la tarjeta SIM se modificó correctamente."</string>
<string name="puk_requested" msgid="3898394204193202803">"Contraseña incorrecta. La tarjeta SIM está bloqueada. Se solicitó PUK2."</string>
<string name="enter_pin2_text" msgid="8339444124477720345">"PIN2"</string>
- <string name="oldPin2Label" msgid="8559146795026261502">"Reenviar cuando está ocupado"</string>
+ <string name="oldPin2Label" msgid="8559146795026261502">"PIN2 viejo"</string>
<string name="newPin2Label" msgid="4573956902204349054">"PIN2 nuevo"</string>
<string name="confirmPin2Label" msgid="8100319484454787708">"Confirmar PIN2 nuevo"</string>
<string name="badPuk2" msgid="4851734468010000418">"El PUK2 que ingresaste es incorrecto. Vuelve a intentarlo."</string>
@@ -450,10 +450,8 @@
<string name="network_message" msgid="4483886461245213802">"Mensaje de red"</string>
<string name="ota_title_activate" msgid="8616918561356194398">"Activar tu teléfono"</string>
<string name="ota_touch_activate" msgid="6553212803262586244">"Es necesario realizar una llamada especial para activar tu servicio de teléfono.\n\nLuego de presionar \"Activar\", escucha las instrucciones suministradas para activar tu teléfono."</string>
- <!-- no translation found for ota_hfa_activation_title (2234246934160473981) -->
- <skip />
- <!-- no translation found for ota_hfa_activation_dialog_message (8092479227918463415) -->
- <skip />
+ <string name="ota_hfa_activation_title" msgid="2234246934160473981">"Activando…"</string>
+ <string name="ota_hfa_activation_dialog_message" msgid="8092479227918463415">"El teléfono está activando el servicio de datos móviles.\n\nEsto puede tardar hasta 5 minutos."</string>
<string name="ota_skip_activation_dialog_title" msgid="2943366608272261306">"¿Deseas omitir la activación?"</string>
<string name="ota_skip_activation_dialog_message" msgid="2440770373498870550">"Si omites la activación, no puedes colocar llamadas o conectarte con redes móviles de datos (a pesar de que te puedes conectar a redes de Wi-Fi). Hasta que actives tu teléfono, se te solicitará que lo actives cada vez que lo enciendas."</string>
<string name="ota_skip_activation_dialog_skip_label" msgid="3458532775091563208">"Omitir"</string>
@@ -581,8 +579,7 @@
<string name="respond_via_sms_setting_title_2" msgid="6104662227299493906">"Editar respuestas rápidas"</string>
<string name="respond_via_sms_setting_summary" msgid="9150281183930613065"></string>
<string name="respond_via_sms_edittext_dialog_title" msgid="20379890418289778">"Respuesta rápida"</string>
- <!-- no translation found for respond_via_sms_menu_reset_default_activity (4029277930090150223) -->
- <skip />
+ <string name="respond_via_sms_menu_reset_default_activity" msgid="4029277930090150223">"Restaurar config. predet."</string>
<string name="respond_via_sms_confirmation_format" msgid="7229149977515784269">"Mensaje enviado a <xliff:g id="PHONE_NUMBER">%s</xliff:g>"</string>
<string name="description_image_button_one" msgid="5502718871331943463">"uno"</string>
<string name="description_image_button_two" msgid="4903738528222924522">"dos"</string>
@@ -609,7 +606,7 @@
<string name="default_notification_description" msgid="78174796906240970">"Sonido predeterminado (<xliff:g id="DEFAULT_SOUND_TITLE">%1$s</xliff:g>)"</string>
<string name="ringtone_title" msgid="6374978286202084684">"Tono del dispositivo"</string>
<string name="vibrate_on_ring_title" msgid="9197564612065258960">"Vibrar al sonar"</string>
- <string name="dtmf_tone_enable_title" msgid="827601042915852989">"Tonos táctiles del teclado de marcado"</string>
+ <string name="dtmf_tone_enable_title" msgid="827601042915852989">"Tonos táctiles del teclado"</string>
<string name="dial_pad_autocomplete" msgid="494525952035761075">"Completar automáticamente con teclado"</string>
<string name="preference_category_ringtone" msgid="5197960752529332721">"Tono y vibración"</string>
</resources>
diff --git a/res/values-es/strings.xml b/res/values-es/strings.xml
index 6aeba0a..db4abd9 100644
--- a/res/values-es/strings.xml
+++ b/res/values-es/strings.xml
@@ -454,10 +454,8 @@
<string name="network_message" msgid="4483886461245213802">"Mensaje de red"</string>
<string name="ota_title_activate" msgid="8616918561356194398">"Activar tu teléfono"</string>
<string name="ota_touch_activate" msgid="6553212803262586244">"Es necesario realizar una llamada especial para activar el servicio telefónico. \n\nTras pulsar \"Activar\", escucha las instrucciones sobre cómo activar el teléfono."</string>
- <!-- no translation found for ota_hfa_activation_title (2234246934160473981) -->
- <skip />
- <!-- no translation found for ota_hfa_activation_dialog_message (8092479227918463415) -->
- <skip />
+ <string name="ota_hfa_activation_title" msgid="2234246934160473981">"Activando..."</string>
+ <string name="ota_hfa_activation_dialog_message" msgid="8092479227918463415">"El teléfono está activando el servicio de datos móviles.\n\nEste proceso puede tardar hasta 5 minutos."</string>
<string name="ota_skip_activation_dialog_title" msgid="2943366608272261306">"¿Quieres omitir la activación?"</string>
<string name="ota_skip_activation_dialog_message" msgid="2440770373498870550">"Si omites la activación, no podrás realizar llamadas ni conectarte a las redes de datos móviles (aunque sí podrás conectarte a las redes Wi-Fi). Se te pedirá que actives el teléfono cada vez que lo enciendas hasta que realices la activación."</string>
<string name="ota_skip_activation_dialog_skip_label" msgid="3458532775091563208">"Omitir"</string>
@@ -511,7 +509,7 @@
<string name="sip_call_options_title" msgid="27433718808839672">"Llamadas por Internet"</string>
<string name="sip_call_options_wifi_only_title" msgid="145572394529090811">"Llamadas por Internet (Wi-Fi)"</string>
<string name="sip_call_options_entry_1" msgid="6556668894178520760">"Para todas las llamadas cuando haya redes de datos disponibles"</string>
- <string name="sip_call_options_entry_2" msgid="6789764029719494361">"Solo llamadas Internet"</string>
+ <string name="sip_call_options_entry_2" msgid="6789764029719494361">"Solo para llamadas de Internet"</string>
<string name="sip_call_options_entry_3" msgid="7474809001402649185">"Preguntar cada vez"</string>
<string name="sip_call_options_wifi_only_entry_1" msgid="7423523864471650069">"En todas las llamadas"</string>
<string name="pick_outgoing_call_phone_type" msgid="5622916534828338675">"Llamadas"</string>
@@ -585,8 +583,7 @@
<string name="respond_via_sms_setting_title_2" msgid="6104662227299493906">"Editar respuestas rápidas"</string>
<string name="respond_via_sms_setting_summary" msgid="9150281183930613065"></string>
<string name="respond_via_sms_edittext_dialog_title" msgid="20379890418289778">"Respuestas rápidas"</string>
- <!-- no translation found for respond_via_sms_menu_reset_default_activity (4029277930090150223) -->
- <skip />
+ <string name="respond_via_sms_menu_reset_default_activity" msgid="4029277930090150223">"Restaurar predeterminados"</string>
<string name="respond_via_sms_confirmation_format" msgid="7229149977515784269">"Mensaje enviado a <xliff:g id="PHONE_NUMBER">%s</xliff:g>"</string>
<string name="description_image_button_one" msgid="5502718871331943463">"uno"</string>
<string name="description_image_button_two" msgid="4903738528222924522">"dos"</string>
diff --git a/res/values-et-rEE/strings.xml b/res/values-et-rEE/strings.xml
index 36e8ad8..1652fc0 100644
--- a/res/values-et-rEE/strings.xml
+++ b/res/values-et-rEE/strings.xml
@@ -450,10 +450,8 @@
<string name="network_message" msgid="4483886461245213802">"Võrgusõnum"</string>
<string name="ota_title_activate" msgid="8616918561356194398">"Telefoni aktiveerimine"</string>
<string name="ota_touch_activate" msgid="6553212803262586244">"Telefoniteenuse aktiveerimiseks peate valima konkreetse kõne. \n\nPärast käsu “Aktiveeri“ puudutamist kuulake telefoni aktiveerimise juhiseid."</string>
- <!-- no translation found for ota_hfa_activation_title (2234246934160473981) -->
- <skip />
- <!-- no translation found for ota_hfa_activation_dialog_message (8092479227918463415) -->
- <skip />
+ <string name="ota_hfa_activation_title" msgid="2234246934160473981">"Aktiveerimine ..."</string>
+ <string name="ota_hfa_activation_dialog_message" msgid="8092479227918463415">"Telefon aktiveerib mobiilse andmesideteenuse.\n\nSelleks võib kuluda kuni 5 minutit."</string>
<string name="ota_skip_activation_dialog_title" msgid="2943366608272261306">"Jätan aktiveerimise vahele?"</string>
<string name="ota_skip_activation_dialog_message" msgid="2440770373498870550">"Aktiveerimise vahelejätmisel ei saa te kõnesid valida ega luua ühendust mobiilsete andmevõrkudega (kuid saate luua ühenduse WiFi-võrkudega). Telefoni aktiveerimisprotsessi ajal palutakse teil see aktiveerida iga kord, kui telefoni sisse lülitate."</string>
<string name="ota_skip_activation_dialog_skip_label" msgid="3458532775091563208">"Jäta vahele"</string>
@@ -581,8 +579,7 @@
<string name="respond_via_sms_setting_title_2" msgid="6104662227299493906">"Kiirvastuste muutmine"</string>
<string name="respond_via_sms_setting_summary" msgid="9150281183930613065"></string>
<string name="respond_via_sms_edittext_dialog_title" msgid="20379890418289778">"Kiirvastus"</string>
- <!-- no translation found for respond_via_sms_menu_reset_default_activity (4029277930090150223) -->
- <skip />
+ <string name="respond_via_sms_menu_reset_default_activity" msgid="4029277930090150223">"Taasta vaikeseaded"</string>
<string name="respond_via_sms_confirmation_format" msgid="7229149977515784269">"Sõnum on saadetud numbrile <xliff:g id="PHONE_NUMBER">%s</xliff:g>."</string>
<string name="description_image_button_one" msgid="5502718871331943463">"üks"</string>
<string name="description_image_button_two" msgid="4903738528222924522">"kaks"</string>
diff --git a/res/values-fa/strings.xml b/res/values-fa/strings.xml
index 44944de..09d6b5f 100644
--- a/res/values-fa/strings.xml
+++ b/res/values-fa/strings.xml
@@ -450,10 +450,8 @@
<string name="network_message" msgid="4483886461245213802">"پیام شبکه"</string>
<string name="ota_title_activate" msgid="8616918561356194398">"فعال کردن گوشی خود"</string>
<string name="ota_touch_activate" msgid="6553212803262586244">"برای فعال کردن سرویس گوشی خود، باید یک تماس ویژه برقرار کنید. \n\nبعد از فشردن \"فعال سازی\"، به دستورالعملهای ارائه شده جهت فعال کردن گوشی، گوش کنید."</string>
- <!-- no translation found for ota_hfa_activation_title (2234246934160473981) -->
- <skip />
- <!-- no translation found for ota_hfa_activation_dialog_message (8092479227918463415) -->
- <skip />
+ <string name="ota_hfa_activation_title" msgid="2234246934160473981">"درحال فعالسازی…"</string>
+ <string name="ota_hfa_activation_dialog_message" msgid="8092479227918463415">"این تلفن در حال فعال کردن خدمات داده دستگاه همراه شما است.\n\nاین کار حداکثر ۵ دقیقه زمان میبرد."</string>
<string name="ota_skip_activation_dialog_title" msgid="2943366608272261306">"از مرحله فعال سازی رد میشوید؟"</string>
<string name="ota_skip_activation_dialog_message" msgid="2440770373498870550">"در صورت رد شدن از مرحله فعال سازی، نمیتوانید تماسی برقرار کنید یا به شبکههای دادهای تلفن همراه متصل شوید (با این وجود میتوانید به شبکههای Wi-Fi متصل شوید). تا زمانی که گوشی خود را فعال نکنید، هر بار که تلفن را روشن میکنید از شما درخواست میشود آنرا فعال کنید."</string>
<string name="ota_skip_activation_dialog_skip_label" msgid="3458532775091563208">"رد شدن"</string>
@@ -581,8 +579,7 @@
<string name="respond_via_sms_setting_title_2" msgid="6104662227299493906">"ویرایش پاسخهای سریع"</string>
<string name="respond_via_sms_setting_summary" msgid="9150281183930613065"></string>
<string name="respond_via_sms_edittext_dialog_title" msgid="20379890418289778">"پاسخ سریع"</string>
- <!-- no translation found for respond_via_sms_menu_reset_default_activity (4029277930090150223) -->
- <skip />
+ <string name="respond_via_sms_menu_reset_default_activity" msgid="4029277930090150223">"بازیابی پیشفرضها"</string>
<string name="respond_via_sms_confirmation_format" msgid="7229149977515784269">"پیام به <xliff:g id="PHONE_NUMBER">%s</xliff:g> ارسال شد."</string>
<string name="description_image_button_one" msgid="5502718871331943463">"یک"</string>
<string name="description_image_button_two" msgid="4903738528222924522">"دو"</string>
diff --git a/res/values-fi/strings.xml b/res/values-fi/strings.xml
index 5c151a9..8a72df4 100644
--- a/res/values-fi/strings.xml
+++ b/res/values-fi/strings.xml
@@ -454,10 +454,8 @@
<string name="network_message" msgid="4483886461245213802">"Verkkoviesti"</string>
<string name="ota_title_activate" msgid="8616918561356194398">"Aktivoi puhelin"</string>
<string name="ota_touch_activate" msgid="6553212803262586244">"Sinun täytyy soittaa erityinen puhelu aktivoidaksesi puhelimesi palvelun. \n\nPaina Aktivoi ja aktivoi puhelimesi kuulemiesi ohjeiden avulla."</string>
- <!-- no translation found for ota_hfa_activation_title (2234246934160473981) -->
- <skip />
- <!-- no translation found for ota_hfa_activation_dialog_message (8092479227918463415) -->
- <skip />
+ <string name="ota_hfa_activation_title" msgid="2234246934160473981">"Aktivoidaan…"</string>
+ <string name="ota_hfa_activation_dialog_message" msgid="8092479227918463415">"Puhelimen mobiilitiedonsiirtopalvelua aktivoidaan.\n\nAktivointi voi kestää viisi minuuttia."</string>
<string name="ota_skip_activation_dialog_title" msgid="2943366608272261306">"Ohitetaanko aktivointi?"</string>
<string name="ota_skip_activation_dialog_message" msgid="2440770373498870550">"Jos ohitat aktivoinnin, et voi soittaa puheluita etkä muodostaa verkkoyhteyttä (voit tosin muodostaa yhteyden wifi-verkkoihin). Sinua pyydetään aktivoimaan puhelimesi aina kun käynnistät sen siihen saakka, että aktivoit sen."</string>
<string name="ota_skip_activation_dialog_skip_label" msgid="3458532775091563208">"Ohita"</string>
@@ -585,8 +583,7 @@
<string name="respond_via_sms_setting_title_2" msgid="6104662227299493906">"Muokkaa pikavastausta"</string>
<string name="respond_via_sms_setting_summary" msgid="9150281183930613065"></string>
<string name="respond_via_sms_edittext_dialog_title" msgid="20379890418289778">"Pikavastaukset"</string>
- <!-- no translation found for respond_via_sms_menu_reset_default_activity (4029277930090150223) -->
- <skip />
+ <string name="respond_via_sms_menu_reset_default_activity" msgid="4029277930090150223">"Palauta oletukset"</string>
<string name="respond_via_sms_confirmation_format" msgid="7229149977515784269">"Viesti lähetetty numeroon <xliff:g id="PHONE_NUMBER">%s</xliff:g>."</string>
<string name="description_image_button_one" msgid="5502718871331943463">"yksi"</string>
<string name="description_image_button_two" msgid="4903738528222924522">"kaksi"</string>
diff --git a/res/values-fr-rCA/strings.xml b/res/values-fr-rCA/strings.xml
index 7ccf062..e3ccd57 100644
--- a/res/values-fr-rCA/strings.xml
+++ b/res/values-fr-rCA/strings.xml
@@ -454,10 +454,8 @@
<string name="network_message" msgid="4483886461245213802">"Message réseau"</string>
<string name="ota_title_activate" msgid="8616918561356194398">"Activer votre téléphone"</string>
<string name="ota_touch_activate" msgid="6553212803262586244">"Vous devez passer un appel spécial pour activer le service de téléphonie. \n\nAprès avoir appuyé sur \"Activer\", écoutez les instructions qui vous permettront d\'activer votre téléphone."</string>
- <!-- no translation found for ota_hfa_activation_title (2234246934160473981) -->
- <skip />
- <!-- no translation found for ota_hfa_activation_dialog_message (8092479227918463415) -->
- <skip />
+ <string name="ota_hfa_activation_title" msgid="2234246934160473981">"Activation en cours…"</string>
+ <string name="ota_hfa_activation_dialog_message" msgid="8092479227918463415">"Le téléphone est en train d\'activer votre service de données cellulaires.\n\nCela peut prendre jusqu\'à cinq minutes."</string>
<string name="ota_skip_activation_dialog_title" msgid="2943366608272261306">"Ignorer l\'activation?"</string>
<string name="ota_skip_activation_dialog_message" msgid="2440770373498870550">"Si vous poursuivez sans activer votre mobile, vous ne pourrez ni téléphoner, ni vous connecter à des réseaux de données mobiles. La connexion à un réseau Wi-Fi reste possible. Vous serez invité à effectuer l\'activation à chaque démarrage du téléphone."</string>
<string name="ota_skip_activation_dialog_skip_label" msgid="3458532775091563208">"Passer"</string>
@@ -585,8 +583,7 @@
<string name="respond_via_sms_setting_title_2" msgid="6104662227299493906">"Modif. rép. rapides"</string>
<string name="respond_via_sms_setting_summary" msgid="9150281183930613065"></string>
<string name="respond_via_sms_edittext_dialog_title" msgid="20379890418289778">"Réponse rapide"</string>
- <!-- no translation found for respond_via_sms_menu_reset_default_activity (4029277930090150223) -->
- <skip />
+ <string name="respond_via_sms_menu_reset_default_activity" msgid="4029277930090150223">"Rétablir les param. par défaut"</string>
<string name="respond_via_sms_confirmation_format" msgid="7229149977515784269">"Message envoyé à <xliff:g id="PHONE_NUMBER">%s</xliff:g>."</string>
<string name="description_image_button_one" msgid="5502718871331943463">"une"</string>
<string name="description_image_button_two" msgid="4903738528222924522">"deux"</string>
diff --git a/res/values-fr/strings.xml b/res/values-fr/strings.xml
index 3be5e3b..8023a5a 100644
--- a/res/values-fr/strings.xml
+++ b/res/values-fr/strings.xml
@@ -450,10 +450,8 @@
<string name="network_message" msgid="4483886461245213802">"Message réseau"</string>
<string name="ota_title_activate" msgid="8616918561356194398">"Activer votre téléphone"</string>
<string name="ota_touch_activate" msgid="6553212803262586244">"Vous devez passer un appel spécial pour activer le service de téléphonie. \n\nAprès avoir appuyé sur \"Activer\", écoutez les instructions qui vous permettront d\'activer votre téléphone."</string>
- <!-- no translation found for ota_hfa_activation_title (2234246934160473981) -->
- <skip />
- <!-- no translation found for ota_hfa_activation_dialog_message (8092479227918463415) -->
- <skip />
+ <string name="ota_hfa_activation_title" msgid="2234246934160473981">"Activation en cours…"</string>
+ <string name="ota_hfa_activation_dialog_message" msgid="8092479227918463415">"Le service de données mobiles est en cours d\'activation sur le téléphone…\n\nCette opération peut prendre jusqu\'à cinq minutes."</string>
<string name="ota_skip_activation_dialog_title" msgid="2943366608272261306">"Ignorer l\'activation ?"</string>
<string name="ota_skip_activation_dialog_message" msgid="2440770373498870550">"Si vous poursuivez sans activer votre mobile, vous ne pourrez ni téléphoner, ni vous connecter à des réseaux de données mobiles. La connexion à un réseau Wi-Fi reste possible. Vous serez invité à effectuer l\'activation à chaque démarrage du téléphone."</string>
<string name="ota_skip_activation_dialog_skip_label" msgid="3458532775091563208">"Ignorer"</string>
@@ -581,8 +579,7 @@
<string name="respond_via_sms_setting_title_2" msgid="6104662227299493906">"Modifier les réponses rapides"</string>
<string name="respond_via_sms_setting_summary" msgid="9150281183930613065"></string>
<string name="respond_via_sms_edittext_dialog_title" msgid="20379890418289778">"Réponse rapide"</string>
- <!-- no translation found for respond_via_sms_menu_reset_default_activity (4029277930090150223) -->
- <skip />
+ <string name="respond_via_sms_menu_reset_default_activity" msgid="4029277930090150223">"Rétablir paramètres par défaut"</string>
<string name="respond_via_sms_confirmation_format" msgid="7229149977515784269">"Message envoyé à <xliff:g id="PHONE_NUMBER">%s</xliff:g>."</string>
<string name="description_image_button_one" msgid="5502718871331943463">"un"</string>
<string name="description_image_button_two" msgid="4903738528222924522">"deux"</string>
diff --git a/res/values-hi/strings.xml b/res/values-hi/strings.xml
index 469d014..704b517 100644
--- a/res/values-hi/strings.xml
+++ b/res/values-hi/strings.xml
@@ -99,16 +99,16 @@
<string name="updating_title" msgid="6146755386174019046">"कॉल सेटिंग"</string>
<string name="error_updating_title" msgid="7970259216988931777">"कॉल सेटिंग त्रुटि"</string>
<string name="reading_settings" msgid="1920291699287055284">"सेटिंग पढ़ रहा है..."</string>
- <string name="updating_settings" msgid="8171225533884883252">"सेटिंग अपडेट कर रहा है..."</string>
+ <string name="updating_settings" msgid="8171225533884883252">"सेटिंग के लिए नई जानकारी मिल रही है..."</string>
<string name="reverting_settings" msgid="4752151682666912828">"सेटिंग वापस ला रहा है..."</string>
<string name="response_error" msgid="6674110501330139405">"नेटवर्क से अनपेक्षित प्रतिसाद."</string>
<string name="exception_error" msgid="7027667130619518211">"नेटवर्क या सिम कार्ड त्रुटि."</string>
- <string name="fdn_check_failure" msgid="18200614306525434">"आपके फ़ोन एप्लिकेशन की फ़िक्स्ड डायलिंग नंबर सेटिंग चालू है. इसके परिणामस्वरूप, कॉल से संबंधित कुछ सुविधाएं कार्य नहीं कर रही हैं."</string>
+ <string name="fdn_check_failure" msgid="18200614306525434">"आपके फ़ोन एप्स की फ़िक्स्ड डायलिंग नंबर सेटिंग चालू है. इसके परिणामस्वरूप, कॉल से संबंधित कुछ सुविधाएं कार्य नहीं कर रही हैं."</string>
<string name="radio_off_error" msgid="2304459933248513376">"इन सेटिंग को देखने के पहले रेडियो चालू करें."</string>
<string name="close_dialog" msgid="2365884406356986917">"ठीक है"</string>
<string name="enable" msgid="1059008390636773574">"सक्षम करें"</string>
<string name="disable" msgid="7274240979164762320">"अक्षम करें"</string>
- <string name="change_num" msgid="239476305819844391">"अपडेट करें"</string>
+ <string name="change_num" msgid="239476305819844391">"नई जानकारी पाएं"</string>
<string-array name="clir_display_values">
<item msgid="5560134294467334594">"नेटवर्क सामान्य"</item>
<item msgid="7876195870037833661">"नंबर छुपाएं"</item>
@@ -327,14 +327,14 @@
<string name="adding_fdn_contact" msgid="7627379633721940991">"फ़िक्स्ड डायलिंग नंबर जोड़ रहा है..."</string>
<string name="fdn_contact_added" msgid="7458335758501736665">"फ़िक्स्ड डायलिंग नंबर जोड़ा गया."</string>
<string name="edit_fdn_contact" msgid="7976936035587081480">"फ़िक्स्ड डायलिंग नंबर संपादित करें"</string>
- <string name="updating_fdn_contact" msgid="8370929876849803600">"फ़िक्स्ड डायलिंग नंबर अपडेट कर रहा है…"</string>
- <string name="fdn_contact_updated" msgid="5497828782609005017">"फ़िक्स्ड डायलिंग नंबर अपडेट किया गया."</string>
+ <string name="updating_fdn_contact" msgid="8370929876849803600">"फ़िक्स्ड डायलिंग नंबर के लिए नई जानकारी…"</string>
+ <string name="fdn_contact_updated" msgid="5497828782609005017">"फ़िक्स्ड डायलिंग नंबर के लिए नई जानकारी."</string>
<string name="delete_fdn_contact" msgid="6668958073074151717">"फ़िक्स्ड डायलिंग नंबर हटाएं"</string>
<string name="deleting_fdn_contact" msgid="5669163206349319969">"फ़िक्स्ड डायलिंग नंबर हटा रहा है..."</string>
<string name="fdn_contact_deleted" msgid="7154162327112259569">"फ़िक्स्ड डायलिंग नंबर हटाया गया."</string>
- <string name="pin2_invalid" msgid="5470854099230755944">"FDN अपडेट नहीं किया गया था क्योंकि आपने गलत पिन लिखा है."</string>
- <string name="fdn_invalid_number" msgid="1494755047900009147">"FDN अपडेट नहीं था क्योंकि नंबर में 20 से अधिक अंक नहीं हो सकते."</string>
- <string name="pin2_or_fdn_invalid" msgid="6025144083384701197">"FDN अपडेट नहीं किया गया था. PIN2 गलत था, या फ़ोन नंबर अस्वीकृत था."</string>
+ <string name="pin2_invalid" msgid="5470854099230755944">"FDN पे नई जानकारी नहीं है क्योंकि आपने गलत पिन लिखा है."</string>
+ <string name="fdn_invalid_number" msgid="1494755047900009147">"FDN पे नई जानकारी नहीं है क्योंकि नंबर में 20 से अधिक अंक नहीं हो सकते."</string>
+ <string name="pin2_or_fdn_invalid" msgid="6025144083384701197">"FDN पे नई जानकारी नहीं है. PIN2 गलत था, या फ़ोन नंबर अस्वीकृत था."</string>
<string name="simContacts_emptyLoading" msgid="2203331234764498011">"सिम कार्ड से पढ़ रहा है…"</string>
<string name="simContacts_empty" msgid="5270660846489561932">"आपके सिम कार्ड पर कोई संपर्क नहीं है."</string>
<string name="simContacts_title" msgid="1861472842524839921">"आयात करने के लिए संपर्कों को चुनें"</string>
@@ -450,10 +450,8 @@
<string name="network_message" msgid="4483886461245213802">"नेटवर्क संदेश"</string>
<string name="ota_title_activate" msgid="8616918561356194398">"अपना फ़ोन सक्रिय करें"</string>
<string name="ota_touch_activate" msgid="6553212803262586244">"आपकी फ़ोन सेवा को सक्रिय करने के लिए एक विशेष कॉल करने की आवश्यकता है. \n\n\"सक्रिय करें\" दबाने के बाद, अपने फ़ोन को सक्रिय करने के लिए दिए जाने वाले निर्देश सुनें."</string>
- <!-- no translation found for ota_hfa_activation_title (2234246934160473981) -->
- <skip />
- <!-- no translation found for ota_hfa_activation_dialog_message (8092479227918463415) -->
- <skip />
+ <string name="ota_hfa_activation_title" msgid="2234246934160473981">"सक्रिय हो रहा है..."</string>
+ <string name="ota_hfa_activation_dialog_message" msgid="8092479227918463415">"फ़ोन आपकी मोबाइल डेटा सेवा सक्रिय कर रहा है.\n\nइसमें 5 मिनट तक लग सकते हैं."</string>
<string name="ota_skip_activation_dialog_title" msgid="2943366608272261306">"सक्रियण छोड़ें?"</string>
<string name="ota_skip_activation_dialog_message" msgid="2440770373498870550">"यदि आप सक्रियण छोड़ देते हैं, तो आप कॉल नहीं कर सकते या मोबाइल डेटा नेटवर्क से कनेक्ट (हालांकि आप Wi-Fi नेटवर्क से कनेक्ट हो सकते हैं) नहीं हो सकते हैं. जब तक आप अपने फ़ोन को सक्रिय नहीं करते, आपको प्रत्येक बार उसे चालू करने पर उसे सक्रिय करने के लिए कहा जाएगा."</string>
<string name="ota_skip_activation_dialog_skip_label" msgid="3458532775091563208">"छोड़ें"</string>
@@ -479,8 +477,8 @@
<item quantity="other" msgid="3122217344579273583">"<xliff:g id="COUNT">%s</xliff:g> मिनट के लिए कोई डेटा कनेक्शन नहीं"</item>
</plurals>
<plurals name="alert_dialog_exit_ecm">
- <item quantity="one" msgid="8060210887681426682">"फ़ोन <xliff:g id="COUNT">%s</xliff:g> मिनट के लिए आपातकालीन कॉलबैक मोड में रहेगा. हालांकि, इस मोड में होने पर डेटा कनेक्शन का उपयोग करने वाले किसी एप्लिकेशन का उपयोग नहीं किया जा सकता. क्या आप अभी बाहर निकलना चाहते हैं?"</item>
- <item quantity="other" msgid="8617116564023933114">"फ़ोन <xliff:g id="COUNT">%s</xliff:g> मिनट के लिए आपातकालीन कॉलबैक मोड में रहेगा. हालांकि, इस मोड में होने पर डेटा कनेक्शन का उपयोग करने वाले किसी एप्लिकेशन का उपयोग नहीं किया जा सकता. क्या आप अभी बाहर निकलना चाहते हैं?"</item>
+ <item quantity="one" msgid="8060210887681426682">"फ़ोन <xliff:g id="COUNT">%s</xliff:g> मिनट के लिए आपातकालीन कॉलबैक मोड में रहेगा. हालांकि, इस मोड में होने पर डेटा कनेक्शन का उपयोग करने वाले किसी एप्स का उपयोग नहीं किया जा सकता. क्या आप अभी बाहर निकलना चाहते हैं?"</item>
+ <item quantity="other" msgid="8617116564023933114">"फ़ोन <xliff:g id="COUNT">%s</xliff:g> मिनट के लिए आपातकालीन कॉलबैक मोड में रहेगा. हालांकि, इस मोड में होने पर डेटा कनेक्शन का उपयोग करने वाले किसी एप्स का उपयोग नहीं किया जा सकता. क्या आप अभी बाहर निकलना चाहते हैं?"</item>
</plurals>
<plurals name="alert_dialog_not_avaialble_in_ecm">
<item quantity="one" msgid="2585506997024726599">"आपातकालीन कॉलबैक मोड के समय चयनित क्रिया उपलब्ध नहीं है. फ़ोन <xliff:g id="COUNT">%s</xliff:g> मिनट तक इस मोड में रहेगा. क्या आप अभी बाहर निकलना चाहते हैं?"</item>
@@ -541,7 +539,7 @@
<string name="registration_status_failed_try_later" msgid="5214474354451220581">"खाता पंजीकरण विफल: (<xliff:g id="REGISTRATION_ERROR_MESSAGE">%s</xliff:g>); बाद में पुन: प्रयास किया जाएगा"</string>
<string name="registration_status_invalid_credentials" msgid="4908446367559341757">"खाता पंजीकरण विफल: गलत उपयोगकर्ता नाम या पासवर्ड."</string>
<string name="registration_status_server_unreachable" msgid="5733421582468991276">"खाता पंजीकरण विफल: सर्वर नाम जांचें."</string>
- <string name="third_party_account_summary" msgid="2532526738862533028">"वर्तमान में इस खाते का उपयोग <xliff:g id="ACCOUNT_OWNER">%s</xliff:g> एप्लिकेशन द्वारा किया जा रहा है."</string>
+ <string name="third_party_account_summary" msgid="2532526738862533028">"वर्तमान में इस खाते का उपयोग <xliff:g id="ACCOUNT_OWNER">%s</xliff:g> एप्स द्वारा किया जा रहा है."</string>
<string name="sip_edit_title" msgid="489288416435014385">"SIP खाता विवरण"</string>
<string name="sip_edit_new_title" msgid="3659149255856520385">"SIP खाता विवरण"</string>
<string name="domain_address_title" msgid="9071787581316160480">"सर्वर"</string>
@@ -581,8 +579,7 @@
<string name="respond_via_sms_setting_title_2" msgid="6104662227299493906">"त्वरित प्रतिसाद संपादित करें"</string>
<string name="respond_via_sms_setting_summary" msgid="9150281183930613065"></string>
<string name="respond_via_sms_edittext_dialog_title" msgid="20379890418289778">"त्वरित प्रतिसाद"</string>
- <!-- no translation found for respond_via_sms_menu_reset_default_activity (4029277930090150223) -->
- <skip />
+ <string name="respond_via_sms_menu_reset_default_activity" msgid="4029277930090150223">"डिफ़ॉल्ट पुनर्स्थापित करें"</string>
<string name="respond_via_sms_confirmation_format" msgid="7229149977515784269">"<xliff:g id="PHONE_NUMBER">%s</xliff:g> को संदेश भेजा गया."</string>
<string name="description_image_button_one" msgid="5502718871331943463">"एक"</string>
<string name="description_image_button_two" msgid="4903738528222924522">"दो"</string>
diff --git a/res/values-hr/strings.xml b/res/values-hr/strings.xml
index 0c2827e..68cbc44 100644
--- a/res/values-hr/strings.xml
+++ b/res/values-hr/strings.xml
@@ -450,10 +450,8 @@
<string name="network_message" msgid="4483886461245213802">"Mrežna poruka"</string>
<string name="ota_title_activate" msgid="8616918561356194398">"Aktivirajte svoj telefon"</string>
<string name="ota_touch_activate" msgid="6553212803262586244">"Poseban poziv upućen je za aktiviranje telefonske usluge. \n\nNakon što pritisnete “Aktiviraj”, poslušajte upute za aktiviranje telefona."</string>
- <!-- no translation found for ota_hfa_activation_title (2234246934160473981) -->
- <skip />
- <!-- no translation found for ota_hfa_activation_dialog_message (8092479227918463415) -->
- <skip />
+ <string name="ota_hfa_activation_title" msgid="2234246934160473981">"Aktivacija..."</string>
+ <string name="ota_hfa_activation_dialog_message" msgid="8092479227918463415">"Telefon aktivira vašu podatkovnu mobilnu uslugu.\n\nTo može potrajati do 5 minuta."</string>
<string name="ota_skip_activation_dialog_title" msgid="2943366608272261306">"Preskoči aktivaciju?"</string>
<string name="ota_skip_activation_dialog_message" msgid="2440770373498870550">"Ako preskočite aktivaciju, ne možete pozivati niti se povezivati na mobilne podatkovne mreže (premda se možete prijaviti na Wi-Fi mreže).Sve dok ne aktivirate telefon prikazivat će se upit za aktiviranje kod svakog prijavljivanja."</string>
<string name="ota_skip_activation_dialog_skip_label" msgid="3458532775091563208">"Preskoči"</string>
@@ -581,8 +579,7 @@
<string name="respond_via_sms_setting_title_2" msgid="6104662227299493906">"Uređivanje brzih odgovora"</string>
<string name="respond_via_sms_setting_summary" msgid="9150281183930613065"></string>
<string name="respond_via_sms_edittext_dialog_title" msgid="20379890418289778">"Brzi odgovor"</string>
- <!-- no translation found for respond_via_sms_menu_reset_default_activity (4029277930090150223) -->
- <skip />
+ <string name="respond_via_sms_menu_reset_default_activity" msgid="4029277930090150223">"Vrati zadano"</string>
<string name="respond_via_sms_confirmation_format" msgid="7229149977515784269">"Poruka poslana na broj <xliff:g id="PHONE_NUMBER">%s</xliff:g>."</string>
<string name="description_image_button_one" msgid="5502718871331943463">"jedan"</string>
<string name="description_image_button_two" msgid="4903738528222924522">"dva"</string>
diff --git a/res/values-hu/strings.xml b/res/values-hu/strings.xml
index 06ee7f5..6c19eb8 100644
--- a/res/values-hu/strings.xml
+++ b/res/values-hu/strings.xml
@@ -450,10 +450,8 @@
<string name="network_message" msgid="4483886461245213802">"Hálózati üzenet"</string>
<string name="ota_title_activate" msgid="8616918561356194398">"Aktiválja telefonját"</string>
<string name="ota_touch_activate" msgid="6553212803262586244">"A telefonszolgáltatás aktiválásához egy speciális hívást kell indítania. \n\nAz \"Aktiválás\" megnyomása után kövesse az utasításokat."</string>
- <!-- no translation found for ota_hfa_activation_title (2234246934160473981) -->
- <skip />
- <!-- no translation found for ota_hfa_activation_dialog_message (8092479227918463415) -->
- <skip />
+ <string name="ota_hfa_activation_title" msgid="2234246934160473981">"Aktiválás..."</string>
+ <string name="ota_hfa_activation_dialog_message" msgid="8092479227918463415">"A telefon aktiválja a mobiladat-szolgáltatást.\n\nEz akár 5 percet is igénybe vehet."</string>
<string name="ota_skip_activation_dialog_title" msgid="2943366608272261306">"Kihagyja az aktiválást?"</string>
<string name="ota_skip_activation_dialog_message" msgid="2440770373498870550">"Ha kihagyja az aktiválást, nem indíthat hívásokat és nem kapcsolódhat mobil adathálózatokhoz (de csatlakozhat Wi-Fi hálózatokhoz). Amíg nem aktiválja telefonját, az minden egyes bekapcsoláskor felkéri Önt erre."</string>
<string name="ota_skip_activation_dialog_skip_label" msgid="3458532775091563208">"Átugrás"</string>
@@ -581,8 +579,7 @@
<string name="respond_via_sms_setting_title_2" msgid="6104662227299493906">"Gyors válaszok szerkesztése"</string>
<string name="respond_via_sms_setting_summary" msgid="9150281183930613065"></string>
<string name="respond_via_sms_edittext_dialog_title" msgid="20379890418289778">"Gyors válasz"</string>
- <!-- no translation found for respond_via_sms_menu_reset_default_activity (4029277930090150223) -->
- <skip />
+ <string name="respond_via_sms_menu_reset_default_activity" msgid="4029277930090150223">"Alapbeállítások visszaállítása"</string>
<string name="respond_via_sms_confirmation_format" msgid="7229149977515784269">"Üzenet elküldve ide: <xliff:g id="PHONE_NUMBER">%s</xliff:g>."</string>
<string name="description_image_button_one" msgid="5502718871331943463">"egy"</string>
<string name="description_image_button_two" msgid="4903738528222924522">"kettő"</string>
diff --git a/res/values-hy-rAM/strings.xml b/res/values-hy-rAM/strings.xml
index 70d93ab..fb592f6 100644
--- a/res/values-hy-rAM/strings.xml
+++ b/res/values-hy-rAM/strings.xml
@@ -456,10 +456,8 @@
<string name="network_message" msgid="4483886461245213802">"Ցանցային հաղորդագրություն"</string>
<string name="ota_title_activate" msgid="8616918561356194398">"Ակտիվացրեք ձեր հեռախոսը"</string>
<string name="ota_touch_activate" msgid="6553212803262586244">"Հատուկ զանգ է հարկավոր կատարել՝ ձեր հեռախոսի ծառայությունն ակտիվացնելու համար: \n\n«Ակտիվացնել» կոճակը սեղմելուց հետո լսեք հրահանգները, որոնք տրվում են ձեր հեռախոսն ակտիվացնելու համար:"</string>
- <!-- no translation found for ota_hfa_activation_title (2234246934160473981) -->
- <skip />
- <!-- no translation found for ota_hfa_activation_dialog_message (8092479227918463415) -->
- <skip />
+ <string name="ota_hfa_activation_title" msgid="2234246934160473981">"Ակտիվացվում է..."</string>
+ <string name="ota_hfa_activation_dialog_message" msgid="8092479227918463415">"Հեռախոսը ակտիվացնում է ձեր բջջային տվյալների ծառայությունը:\n\nՍա կարող է տևել մինչև 5 րոպե:"</string>
<string name="ota_skip_activation_dialog_title" msgid="2943366608272261306">"Բաց թողնե՞լ ակտիվացումը"</string>
<string name="ota_skip_activation_dialog_message" msgid="2440770373498870550">"Եթե դուք բաց թողնեք ակտիվացումը, դուք չեք կարող կատարել զանգեր կամ միանալ բջջային տվյալների ցանցերին (թեև դուք կարող եք միանալ Wi-Fi ցանցերին): Մինչև դուք չակտիվացնեեք ձեր հեռախոսը, ձեզ հարցվելու է ակտիվացնել յուրաքանչյուր անգամ, երբ դուք միացնեք այն:"</string>
<string name="ota_skip_activation_dialog_skip_label" msgid="3458532775091563208">"Բաց թողնել"</string>
@@ -573,7 +571,7 @@
<string name="no_internet_available_title" msgid="3327109242858406165">"Ինտերնետ կապ չկա"</string>
<string name="no_wifi_available_title" msgid="747881033089378758">"Wi-Fi կապ չկա"</string>
<string name="no_internet_available" msgid="7877142631803238549">"Ինտերնետային զանգի կատարման համար նախ ստուգեք ձեր ինտերնետ կապը:"</string>
- <string name="no_wifi_available" msgid="1225073547318465713">"Ինտերնետային զանգերի համար դուք պետք է միացված լինեք Wi-Fi ցանցին (օգտագործեք Անլար & Ցանցային կարգավորումները):"</string>
+ <string name="no_wifi_available" msgid="1225073547318465713">"Ինտերնետային զանգերի համար դուք պետք է միացված լինեք Wi-Fi ցանցին (օգտագործեք Անլար կապ և Ցանցեր կարգավորումները):"</string>
<string name="no_voip" msgid="8901474054537199865">"Ինտերնետային զանգերը չեն սպասարկվում"</string>
<string name="sip_system_decide" msgid="368030746310423471">"Ավտոմատ"</string>
<string name="sip_always_send_keepalive" msgid="8192080724632877132">"Միշտ ուղարկել"</string>
@@ -587,8 +585,7 @@
<string name="respond_via_sms_setting_title_2" msgid="6104662227299493906">"Խմբագրել արագ պատասխանները"</string>
<string name="respond_via_sms_setting_summary" msgid="9150281183930613065"></string>
<string name="respond_via_sms_edittext_dialog_title" msgid="20379890418289778">"Արագ պատասխան"</string>
- <!-- no translation found for respond_via_sms_menu_reset_default_activity (4029277930090150223) -->
- <skip />
+ <string name="respond_via_sms_menu_reset_default_activity" msgid="4029277930090150223">"Վերականգնել լռելյայն կարգավորումները"</string>
<string name="respond_via_sms_confirmation_format" msgid="7229149977515784269">"Հաղորդագրությունն ուղարկվել է <xliff:g id="PHONE_NUMBER">%s</xliff:g>-ին:"</string>
<string name="description_image_button_one" msgid="5502718871331943463">"մեկ"</string>
<string name="description_image_button_two" msgid="4903738528222924522">"երկու"</string>
diff --git a/res/values-in/strings.xml b/res/values-in/strings.xml
index 2f750a7..8100c05 100644
--- a/res/values-in/strings.xml
+++ b/res/values-in/strings.xml
@@ -450,10 +450,8 @@
<string name="network_message" msgid="4483886461245213802">"Pesan jaringan"</string>
<string name="ota_title_activate" msgid="8616918561356194398">"Aktifkan ponsel Anda"</string>
<string name="ota_touch_activate" msgid="6553212803262586244">"Perlu dilakukan panggilan khusus untuk mengaktifkan layanan ponsel Anda. \n\nSetelah menekan “Aktifkan”, dengarkan instruksi yang diberikan untuk mengaktifkan ponsel."</string>
- <!-- no translation found for ota_hfa_activation_title (2234246934160473981) -->
- <skip />
- <!-- no translation found for ota_hfa_activation_dialog_message (8092479227918463415) -->
- <skip />
+ <string name="ota_hfa_activation_title" msgid="2234246934160473981">"Mengaktifkan..."</string>
+ <string name="ota_hfa_activation_dialog_message" msgid="8092479227918463415">"Ponsel mengaktifkan layanan data seluler Anda.\n\nIni dapat memakan waktu sampai 5 menit."</string>
<string name="ota_skip_activation_dialog_title" msgid="2943366608272261306">"Lewati aktivasi?"</string>
<string name="ota_skip_activation_dialog_message" msgid="2440770373498870550">"Jika Anda mengabaikan aktivasi, Anda tidak dapat melakukan panggilan atau menyambung ke jaringan data seluler (walaupun dapat menyambung ke jaringan Wi-Fi). Sampai ponsel diaktifkan, Anda akan diminta mengaktifkannya setiap kali ponsel dihidupkan."</string>
<string name="ota_skip_activation_dialog_skip_label" msgid="3458532775091563208">"Lewati"</string>
@@ -581,8 +579,7 @@
<string name="respond_via_sms_setting_title_2" msgid="6104662227299493906">"Edit tanggapan cepat"</string>
<string name="respond_via_sms_setting_summary" msgid="9150281183930613065"></string>
<string name="respond_via_sms_edittext_dialog_title" msgid="20379890418289778">"Tanggapan cepat"</string>
- <!-- no translation found for respond_via_sms_menu_reset_default_activity (4029277930090150223) -->
- <skip />
+ <string name="respond_via_sms_menu_reset_default_activity" msgid="4029277930090150223">"Kembalikan ke default"</string>
<string name="respond_via_sms_confirmation_format" msgid="7229149977515784269">"Pesan dikirim ke <xliff:g id="PHONE_NUMBER">%s</xliff:g>."</string>
<string name="description_image_button_one" msgid="5502718871331943463">"satu"</string>
<string name="description_image_button_two" msgid="4903738528222924522">"dua"</string>
diff --git a/res/values-it/strings.xml b/res/values-it/strings.xml
index a3ad5cc..9a83821 100644
--- a/res/values-it/strings.xml
+++ b/res/values-it/strings.xml
@@ -454,10 +454,8 @@
<string name="network_message" msgid="4483886461245213802">"Messaggio di rete"</string>
<string name="ota_title_activate" msgid="8616918561356194398">"Attiva il telefono"</string>
<string name="ota_touch_activate" msgid="6553212803262586244">"È necessario effettuare una chiamata speciale per attivare il servizio telefonico. \n\nDopo avere premuto \"Attiva\", ascolta le istruzioni fornite per attivare il telefono."</string>
- <!-- no translation found for ota_hfa_activation_title (2234246934160473981) -->
- <skip />
- <!-- no translation found for ota_hfa_activation_dialog_message (8092479227918463415) -->
- <skip />
+ <string name="ota_hfa_activation_title" msgid="2234246934160473981">"Attivazione..."</string>
+ <string name="ota_hfa_activation_dialog_message" msgid="8092479227918463415">"Attivazione del servizio dati mobili sul telefono in corso.\n\nL\'operazione potrebbe richiedere fino a cinque minuti."</string>
<string name="ota_skip_activation_dialog_title" msgid="2943366608272261306">"Saltare l\'attivazione?"</string>
<string name="ota_skip_activation_dialog_message" msgid="2440770373498870550">"Se salti l\'attivazione, non potrai effettuare chiamate o connetterti a reti di dati mobili (ma potrai connetterti a reti Wi-Fi). Finché non attiverai il telefono, ti verrà chiesto di attivarlo ogni volta che lo accendi."</string>
<string name="ota_skip_activation_dialog_skip_label" msgid="3458532775091563208">"Ignora"</string>
@@ -585,8 +583,7 @@
<string name="respond_via_sms_setting_title_2" msgid="6104662227299493906">"Modifica risposte rapide"</string>
<string name="respond_via_sms_setting_summary" msgid="9150281183930613065"></string>
<string name="respond_via_sms_edittext_dialog_title" msgid="20379890418289778">"Risposta rapida"</string>
- <!-- no translation found for respond_via_sms_menu_reset_default_activity (4029277930090150223) -->
- <skip />
+ <string name="respond_via_sms_menu_reset_default_activity" msgid="4029277930090150223">"Ripristina predefinite"</string>
<string name="respond_via_sms_confirmation_format" msgid="7229149977515784269">"Messaggio inviato a <xliff:g id="PHONE_NUMBER">%s</xliff:g>."</string>
<string name="description_image_button_one" msgid="5502718871331943463">"uno"</string>
<string name="description_image_button_two" msgid="4903738528222924522">"due"</string>
diff --git a/res/values-iw/strings.xml b/res/values-iw/strings.xml
index 018bd92..003f4d0 100644
--- a/res/values-iw/strings.xml
+++ b/res/values-iw/strings.xml
@@ -103,7 +103,7 @@
<string name="reverting_settings" msgid="4752151682666912828">"מאחזר הגדרות הקודמות…"</string>
<string name="response_error" msgid="6674110501330139405">"תגובה לא צפויה מהרשת."</string>
<string name="exception_error" msgid="7027667130619518211">"שגיאת רשת או שגיאה של כרטיס SIM."</string>
- <string name="fdn_check_failure" msgid="18200614306525434">"הגדרת מספרי החיוג הקבועים של יישום הטלפון שלך מופעלת. כתוצאה מכך, חלק מהתכונות הקשורות לשיחות לא פועלות."</string>
+ <string name="fdn_check_failure" msgid="18200614306525434">"הגדרת מספרי החיוג הקבועים של אפליקציית הטלפון שלך מופעלת. כתוצאה מכך, חלק מהתכונות הקשורות לשיחות לא פועלות."</string>
<string name="radio_off_error" msgid="2304459933248513376">"הפעל את הרדיו לפני ההצגה של הגדרות אלה."</string>
<string name="close_dialog" msgid="2365884406356986917">"אישור"</string>
<string name="enable" msgid="1059008390636773574">"הפעל"</string>
@@ -450,10 +450,8 @@
<string name="network_message" msgid="4483886461245213802">"הודעת רשת"</string>
<string name="ota_title_activate" msgid="8616918561356194398">"הפעל את הטלפון"</string>
<string name="ota_touch_activate" msgid="6553212803262586244">"יש לבצע שיחה מיוחדת כדי להפעיל את השירות לטלפון. \n\nלאחר הלחיצה על \'הפעל\', הקשב להוראות להפעלת הטלפון."</string>
- <!-- no translation found for ota_hfa_activation_title (2234246934160473981) -->
- <skip />
- <!-- no translation found for ota_hfa_activation_dialog_message (8092479227918463415) -->
- <skip />
+ <string name="ota_hfa_activation_title" msgid="2234246934160473981">"מפעיל..."</string>
+ <string name="ota_hfa_activation_dialog_message" msgid="8092479227918463415">"הטלפון מפעיל את שירותי הנתונים שלך לנייד.\n\nהתהליך עשוי לארוך עד 5 דקות."</string>
<string name="ota_skip_activation_dialog_title" msgid="2943366608272261306">"לדלג על ההפעלה?"</string>
<string name="ota_skip_activation_dialog_message" msgid="2440770373498870550">"אם תדלג על ההפעלה, לא תוכל להתקשר או להתחבר לרשתות נתונים לנייד (אך תוכל להתחבר לרשתות Wi-Fi). עד שתפעיל את הטלפון, תתבקש להפעיל אותו בכל פעם שתדליק אותו."</string>
<string name="ota_skip_activation_dialog_skip_label" msgid="3458532775091563208">"דלג"</string>
@@ -479,8 +477,8 @@
<item quantity="other" msgid="3122217344579273583">"אין חיבור נתונים במשך <xliff:g id="COUNT">%s</xliff:g> דקות"</item>
</plurals>
<plurals name="alert_dialog_exit_ecm">
- <item quantity="one" msgid="8060210887681426682">"הטלפון יהיה במצב התקשרות חזרה בחירום למשך דקה <xliff:g id="COUNT">%s</xliff:g>. במצב זה לא ניתן להשתמש ביישומים המשתמשים בחיבור נתונים. האם אתה רוצה לצאת כעת?"</item>
- <item quantity="other" msgid="8617116564023933114">"הטלפון יהיה במצב התקשרות חזרה בחירום למשך <xliff:g id="COUNT">%s</xliff:g> דקות. במצב זה לא ניתן להשתמש ביישומים המשתמשים בחיבור נתונים. האם אתה רוצה לצאת כעת?"</item>
+ <item quantity="one" msgid="8060210887681426682">"הטלפון יהיה במצב התקשרות חזרה בחירום למשך דקה <xliff:g id="COUNT">%s</xliff:g>. במצב זה לא ניתן להשתמש באפליקציות המשתמשות בחיבור נתונים. האם אתה רוצה לצאת כעת?"</item>
+ <item quantity="other" msgid="8617116564023933114">"הטלפון יהיה במצב התקשרות חזרה בחירום למשך <xliff:g id="COUNT">%s</xliff:g> דקות. במצב זה לא ניתן להשתמש באפליקציות המשתמשים בחיבור נתונים. האם אתה רוצה לצאת כעת?"</item>
</plurals>
<plurals name="alert_dialog_not_avaialble_in_ecm">
<item quantity="one" msgid="2585506997024726599">"הפעולה שנבחרה אינה זמינה במצב התקשרות חזרה בחירום. הטלפון יהיה במצב זה במשך <xliff:g id="COUNT">%s</xliff:g> דקות. האם אתה רוצה לצאת כעת?"</item>
@@ -541,7 +539,7 @@
<string name="registration_status_failed_try_later" msgid="5214474354451220581">"הרשמת החשבון נכשלה: (<xliff:g id="REGISTRATION_ERROR_MESSAGE">%s</xliff:g>); יתבצע ניסיון חוזר מאוחר יותר"</string>
<string name="registration_status_invalid_credentials" msgid="4908446367559341757">"רישום החשבון נכשל: שם המשתמש או הסיסמה שגויים."</string>
<string name="registration_status_server_unreachable" msgid="5733421582468991276">"רישום החשבון נכשל: בדוק את שם השרת."</string>
- <string name="third_party_account_summary" msgid="2532526738862533028">"היישום <xliff:g id="ACCOUNT_OWNER">%s</xliff:g> משתמש כרגע בחשבון זה."</string>
+ <string name="third_party_account_summary" msgid="2532526738862533028">"האפליקציה <xliff:g id="ACCOUNT_OWNER">%s</xliff:g> משתמש כרגע בחשבון זה."</string>
<string name="sip_edit_title" msgid="489288416435014385">"פרטי חשבון SIP"</string>
<string name="sip_edit_new_title" msgid="3659149255856520385">"פרטי חשבון SIP"</string>
<string name="domain_address_title" msgid="9071787581316160480">"שרת"</string>
@@ -581,8 +579,7 @@
<string name="respond_via_sms_setting_title_2" msgid="6104662227299493906">"ערוך תגובות מהירות"</string>
<string name="respond_via_sms_setting_summary" msgid="9150281183930613065"></string>
<string name="respond_via_sms_edittext_dialog_title" msgid="20379890418289778">"תגובה מהירה"</string>
- <!-- no translation found for respond_via_sms_menu_reset_default_activity (4029277930090150223) -->
- <skip />
+ <string name="respond_via_sms_menu_reset_default_activity" msgid="4029277930090150223">"שחזר ברירות מחדל"</string>
<string name="respond_via_sms_confirmation_format" msgid="7229149977515784269">"הודעה נשלחה אל <xliff:g id="PHONE_NUMBER">%s</xliff:g>."</string>
<string name="description_image_button_one" msgid="5502718871331943463">"אחת"</string>
<string name="description_image_button_two" msgid="4903738528222924522">"שתיים"</string>
diff --git a/res/values-ja/strings.xml b/res/values-ja/strings.xml
index ef26bf5..7715a5e 100644
--- a/res/values-ja/strings.xml
+++ b/res/values-ja/strings.xml
@@ -450,10 +450,8 @@
<string name="network_message" msgid="4483886461245213802">"ネットワークメッセージ"</string>
<string name="ota_title_activate" msgid="8616918561356194398">"携帯電話を有効にする"</string>
<string name="ota_touch_activate" msgid="6553212803262586244">"通話サービスを有効にするには特別な通話が必要です。\n\n[有効にする]を押してから、流れてくる音声に従って電話を有効にしてください。"</string>
- <!-- no translation found for ota_hfa_activation_title (2234246934160473981) -->
- <skip />
- <!-- no translation found for ota_hfa_activation_dialog_message (8092479227918463415) -->
- <skip />
+ <string name="ota_hfa_activation_title" msgid="2234246934160473981">"有効にしています..."</string>
+ <string name="ota_hfa_activation_dialog_message" msgid="8092479227918463415">"端末はモバイルデータサービスを有効にしています。\n\nこの処理には5分ほどかかることがあります。"</string>
<string name="ota_skip_activation_dialog_title" msgid="2943366608272261306">"スキップして有効にしない"</string>
<string name="ota_skip_activation_dialog_message" msgid="2440770373498870550">"スキップして有効にしない場合、通話やモバイルデータネットワークの接続ができません(Wi-Fiネットワークには接続できます)。携帯を有効にするまでは、電源を入れるたびに有効にするかどうかを尋ねるメッセージが表示されます。"</string>
<string name="ota_skip_activation_dialog_skip_label" msgid="3458532775091563208">"スキップ"</string>
@@ -581,8 +579,7 @@
<string name="respond_via_sms_setting_title_2" msgid="6104662227299493906">"クイック返信の編集"</string>
<string name="respond_via_sms_setting_summary" msgid="9150281183930613065"></string>
<string name="respond_via_sms_edittext_dialog_title" msgid="20379890418289778">"クイック返信"</string>
- <!-- no translation found for respond_via_sms_menu_reset_default_activity (4029277930090150223) -->
- <skip />
+ <string name="respond_via_sms_menu_reset_default_activity" msgid="4029277930090150223">"初期設定に戻す"</string>
<string name="respond_via_sms_confirmation_format" msgid="7229149977515784269">"<xliff:g id="PHONE_NUMBER">%s</xliff:g>にメッセージを送信しました。"</string>
<string name="description_image_button_one" msgid="5502718871331943463">"1"</string>
<string name="description_image_button_two" msgid="4903738528222924522">"2"</string>
diff --git a/res/values-ka-rGE/strings.xml b/res/values-ka-rGE/strings.xml
index d1da77a..fb7c26b 100644
--- a/res/values-ka-rGE/strings.xml
+++ b/res/values-ka-rGE/strings.xml
@@ -450,10 +450,8 @@
<string name="network_message" msgid="4483886461245213802">"ქსელის შეტყობინება"</string>
<string name="ota_title_activate" msgid="8616918561356194398">"თქვენი ტელეფონის აქტივაცია"</string>
<string name="ota_touch_activate" msgid="6553212803262586244">"თქვენი ტელეფონის სერვისის გასააქტიურებლად აუცილებელია საგანგებო ზარის განხორციელება. \n\nტექსტზე „აქტივაცია“ დაჭერის შემდეგ, მოუსმინეთ ინსტრუქციებს თქვენი ტელეფონის აქტივაციისათვის."</string>
- <!-- no translation found for ota_hfa_activation_title (2234246934160473981) -->
- <skip />
- <!-- no translation found for ota_hfa_activation_dialog_message (8092479227918463415) -->
- <skip />
+ <string name="ota_hfa_activation_title" msgid="2234246934160473981">"მიმდინარეობს გააქტიურება..."</string>
+ <string name="ota_hfa_activation_dialog_message" msgid="8092479227918463415">"ტელეფონი თქვენს მობილური ინტერნეტის სერვისს ააქტიურებს.\n\nამას შესაძლოა 5 წუთამდე დაჭირდეს."</string>
<string name="ota_skip_activation_dialog_title" msgid="2943366608272261306">"გსურთ აქტივაციის გამოტოვება?"</string>
<string name="ota_skip_activation_dialog_message" msgid="2440770373498870550">"თუ აქტივაციას გამოტოვებთ, ზარების განხორციელებას ან მობილური ინტერნეტის გამოყენებას ვერ შეძლებთ (თუმცა, შესაძლებელია Wi-Fi ქსელებთან დაკავშირება). სანამ ტელეფონს გაააქტიურებდეთ, მოგეთხოვებათ გაააქტიუროთ ის, სანამ ჩართავდეთ."</string>
<string name="ota_skip_activation_dialog_skip_label" msgid="3458532775091563208">"გამოტოვება"</string>
@@ -581,8 +579,7 @@
<string name="respond_via_sms_setting_title_2" msgid="6104662227299493906">"სწრაფი პასუხის რედაქტირება"</string>
<string name="respond_via_sms_setting_summary" msgid="9150281183930613065"></string>
<string name="respond_via_sms_edittext_dialog_title" msgid="20379890418289778">"სწრაფი პასუხი"</string>
- <!-- no translation found for respond_via_sms_menu_reset_default_activity (4029277930090150223) -->
- <skip />
+ <string name="respond_via_sms_menu_reset_default_activity" msgid="4029277930090150223">"ნაგულისხმევი პარამეტრების აღდგენა"</string>
<string name="respond_via_sms_confirmation_format" msgid="7229149977515784269">"შეტყობინება გაიგზავნა <xliff:g id="PHONE_NUMBER">%s</xliff:g>-თან."</string>
<string name="description_image_button_one" msgid="5502718871331943463">"ერთ"</string>
<string name="description_image_button_two" msgid="4903738528222924522">"ორი"</string>
diff --git a/res/values-km-rKH/strings.xml b/res/values-km-rKH/strings.xml
index a520979..4c0d6e2 100644
--- a/res/values-km-rKH/strings.xml
+++ b/res/values-km-rKH/strings.xml
@@ -338,7 +338,7 @@
<string name="simContacts_emptyLoading" msgid="2203331234764498011">"កំពុងអានពីស៊ីមកាត…"</string>
<string name="simContacts_empty" msgid="5270660846489561932">"គ្មានទំនាក់ទំនងនៅលើស៊ីមកាតរបស់អ្នកទេ។"</string>
<string name="simContacts_title" msgid="1861472842524839921">"ជ្រើសទំនាក់ទំនងដើម្បីនាំចូល"</string>
- <string name="simContacts_airplaneMode" msgid="1846161429087789936">"ដើម្បីនាំចូលទំនាក់ទំនងពីស៊ីមកាត ដំបូងបិទរបៀបពេលជិះយន្តហោះ។"</string>
+ <string name="simContacts_airplaneMode" msgid="1846161429087789936">"ដើម្បីនាំចូលទំនាក់ទំនងពីស៊ីមកាត ដំបូងត្រូវបិទរបៀបពេលជិះយន្តហោះ។"</string>
<string name="enable_pin" msgid="5422767284133234860">"បិទ/បើកកូដ PIN ស៊ីមកាត"</string>
<string name="change_pin" msgid="9174186126330785343">"ប្ដូរកូដ PIN ស៊ីមកាត"</string>
<string name="enter_pin_text" msgid="8532615714751931951">"កូដ PIN ស៊ីមកាត៖"</string>
@@ -450,10 +450,8 @@
<string name="network_message" msgid="4483886461245213802">"សារបណ្ដាញ"</string>
<string name="ota_title_activate" msgid="8616918561356194398">"បានធ្វើឲ្យទូរស័ព្ទរបស់អ្នកសកម្ម"</string>
<string name="ota_touch_activate" msgid="6553212803262586244">"ការហៅពិសេសចាំបាច់ធ្វើឲ្យសេវាទូរស័ព្ទរបស់អ្នកសកម្ម។ \n\n បន្ទាប់ពីចុច “ធ្វើឲ្យសកម្ម” ស្ដាប់សេចក្ដីណែនាំដែលបានផ្ដល់ដើម្បីធ្វើឲ្យទូរស័ព្ទរបស់អ្នកសកម្ម។"</string>
- <!-- no translation found for ota_hfa_activation_title (2234246934160473981) -->
- <skip />
- <!-- no translation found for ota_hfa_activation_dialog_message (8092479227918463415) -->
- <skip />
+ <string name="ota_hfa_activation_title" msgid="2234246934160473981">"កំពុងធ្វើឲ្យសកម្ម..."</string>
+ <string name="ota_hfa_activation_dialog_message" msgid="8092479227918463415">"ទូរស័ព្ទនេះកំពុងធ្វើឲ្យសេវាកម្មទិន្នន័យចល័តរបស់អ្នកសកម្ម។ \n \n វាអាចប្រើពេលប្រហែល ៥នាទី។"</string>
<string name="ota_skip_activation_dialog_title" msgid="2943366608272261306">"រំលងការធ្វើឲ្យសកម្ម?"</string>
<string name="ota_skip_activation_dialog_message" msgid="2440770373498870550">"ប្រសិនបើអ្នករំលងការធ្វើឲ្យសកម្ម អ្នកមិនអាចកំណត់ការហៅ ឬតភ្ជាប់បណ្ដាញទិន្នន័យឧបករណ៍ចល័តបានទេ (អ្នកអាចតភ្ជាប់តាមបណ្ដាញវ៉ាយហ្វាយ )។ លុះត្រាតែអ្នកធ្វើឲ្យទូរស័ព្ទរបស់អ្នកសកម្ម អ្នកត្រូវបានស្នើធ្វើឲ្យវាសកម្មនៅពេលដែលអ្នកបិទវា។"</string>
<string name="ota_skip_activation_dialog_skip_label" msgid="3458532775091563208">"រំលង"</string>
@@ -581,8 +579,7 @@
<string name="respond_via_sms_setting_title_2" msgid="6104662227299493906">"កែការឆ្លើយតបរហ័ស"</string>
<string name="respond_via_sms_setting_summary" msgid="9150281183930613065"></string>
<string name="respond_via_sms_edittext_dialog_title" msgid="20379890418289778">"ឆ្លើយតបរហ័ស"</string>
- <!-- no translation found for respond_via_sms_menu_reset_default_activity (4029277930090150223) -->
- <skip />
+ <string name="respond_via_sms_menu_reset_default_activity" msgid="4029277930090150223">"ស្ដារលំនាំដើម"</string>
<string name="respond_via_sms_confirmation_format" msgid="7229149977515784269">"បានផ្ញើសារទៅ <xliff:g id="PHONE_NUMBER">%s</xliff:g> ។"</string>
<string name="description_image_button_one" msgid="5502718871331943463">"មួយ"</string>
<string name="description_image_button_two" msgid="4903738528222924522">"ពីរ"</string>
diff --git a/res/values-ko/strings.xml b/res/values-ko/strings.xml
index a50d971..8a0a508 100644
--- a/res/values-ko/strings.xml
+++ b/res/values-ko/strings.xml
@@ -450,10 +450,8 @@
<string name="network_message" msgid="4483886461245213802">"네트워크 메시지"</string>
<string name="ota_title_activate" msgid="8616918561356194398">"전화 활성화"</string>
<string name="ota_touch_activate" msgid="6553212803262586244">"전화 서비스를 활성화하려면 특수 통화를 해야 합니다. \n\n\'활성화\'를 누른 다음 지시사항을 듣고 전화를 활성화하세요."</string>
- <!-- no translation found for ota_hfa_activation_title (2234246934160473981) -->
- <skip />
- <!-- no translation found for ota_hfa_activation_dialog_message (8092479227918463415) -->
- <skip />
+ <string name="ota_hfa_activation_title" msgid="2234246934160473981">"활성화 중..."</string>
+ <string name="ota_hfa_activation_dialog_message" msgid="8092479227918463415">"휴대전화에서 모바일 데이터 서비스를 활성화하고 있습니다.\n\n최대 5분 정도 소요될 수 있습니다."</string>
<string name="ota_skip_activation_dialog_title" msgid="2943366608272261306">"활성화를 건너뛰시겠습니까?"</string>
<string name="ota_skip_activation_dialog_message" msgid="2440770373498870550">"활성화를 건너뛰면 Wi-Fi 네트워크에는 연결할 수 있지만 전화를 걸거나 모바일 데이터 네트워크에 연결할 수 없습니다. 휴대전화를 활성화할 때까지 휴대전화를 켤 때마다 활성화하라는 메시지가 표시됩니다."</string>
<string name="ota_skip_activation_dialog_skip_label" msgid="3458532775091563208">"건너뛰기"</string>
@@ -581,8 +579,7 @@
<string name="respond_via_sms_setting_title_2" msgid="6104662227299493906">"빠른 응답 수정"</string>
<string name="respond_via_sms_setting_summary" msgid="9150281183930613065"></string>
<string name="respond_via_sms_edittext_dialog_title" msgid="20379890418289778">"빠른 응답"</string>
- <!-- no translation found for respond_via_sms_menu_reset_default_activity (4029277930090150223) -->
- <skip />
+ <string name="respond_via_sms_menu_reset_default_activity" msgid="4029277930090150223">"기본값 복원"</string>
<string name="respond_via_sms_confirmation_format" msgid="7229149977515784269">"<xliff:g id="PHONE_NUMBER">%s</xliff:g>(으)로 메시지를 보냈습니다."</string>
<string name="description_image_button_one" msgid="5502718871331943463">"1"</string>
<string name="description_image_button_two" msgid="4903738528222924522">"2"</string>
diff --git a/res/values-land/dimens.xml b/res/values-land/dimens.xml
deleted file mode 100644
index 9eb531d..0000000
--- a/res/values-land/dimens.xml
+++ /dev/null
@@ -1,21 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2011 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>
- <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
deleted file mode 100644
index 0626a15..0000000
--- a/res/values-land/styles.xml
+++ /dev/null
@@ -1,31 +0,0 @@
-<?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-lo-rLA/strings.xml b/res/values-lo-rLA/strings.xml
index 5428d12..2923f60 100644
--- a/res/values-lo-rLA/strings.xml
+++ b/res/values-lo-rLA/strings.xml
@@ -54,7 +54,7 @@
<string name="unlock_success" msgid="6770085622238180152">"ການປົດລັອກເຄືອຂ່າຍບໍ່ສຳເລັດ."</string>
<string name="labelGSMMore" msgid="5930842194056092106">"ການຕັ້ງຄ່າການໂທ GSM"</string>
<string name="labelCDMAMore" msgid="1630676740428229339">"ການຕັ້ງຄ່າໂທ CDMA"</string>
- <string name="apn_settings" msgid="9043423184895642077">"ຊື່ຂອງຈຸດການເຂົ້າເຖິງ"</string>
+ <string name="apn_settings" msgid="9043423184895642077">"ຊື່ຂອງຈຸດການເຂົ້າເຖິງ (APN)"</string>
<string name="settings_label" msgid="3876743539816984008">"ການຕັ້ງຄ່າເຄືອຂ່າຍ"</string>
<string name="voicemail" msgid="8693759337917898954">"ຂໍ້ຄວາມສຽງ"</string>
<string name="voicemail_abbreviated" msgid="2215592488517217448">"VM:"</string>
@@ -168,7 +168,7 @@
<item msgid="1524224863879435516">"GSM ເທົ່ານັ້ນ"</item>
<item msgid="3817924849415716259">"ຕ້ອງການ GSM/WCDMA"</item>
</string-array>
- <string name="data_enabled" msgid="5972538663568715366">"ເປີດໃຊ້ຂໍ້ມູນແລ້ວ"</string>
+ <string name="data_enabled" msgid="5972538663568715366">"ເປີດໃຊ້ເດຕາ"</string>
<string name="data_enable_summary" msgid="5022018967714633874">"ເປີດໃຊ້ການເຂົ້າເຖິງຂໍ້ມູນຜ່ານເຄືອຂ່າຍມືຖື"</string>
<string name="roaming" msgid="8871412572928323707">"ການໂຣມມິງຂໍ້ມູນ"</string>
<string name="roaming_enable" msgid="7331106985174381987">"ເຊື່ອມຕໍ່ບໍລິການຂໍ້ມູນເມື່ອໂຣມມິງ"</string>
@@ -450,10 +450,8 @@
<string name="network_message" msgid="4483886461245213802">"ຂໍ້ຄວາມເຄືອຂ່າຍ"</string>
<string name="ota_title_activate" msgid="8616918561356194398">"ເປີດນຳໃຊ້ໂທລະສັບຂອງທ່ານ"</string>
<string name="ota_touch_activate" msgid="6553212803262586244">"ຕ້ອງໃຊ້ການໂທພິເສດ ເພື່ອເປີດນຳໃຊ້ບໍລິການໂທລະສັບຂອງທ່ານ. \n\nຫຼັງຈາກກົດປຸ່ມ “ເປີດນຳໃຊ້” ແລ້ວ, ໃຫ້ຟັງຄຳແນະນຳທີ່ລະບຸເພື່ອເປີດນຳໃຊ້ໂທລະສັບຂອງທ່ານ."</string>
- <!-- no translation found for ota_hfa_activation_title (2234246934160473981) -->
- <skip />
- <!-- no translation found for ota_hfa_activation_dialog_message (8092479227918463415) -->
- <skip />
+ <string name="ota_hfa_activation_title" msgid="2234246934160473981">"ກຳລັງເປີດນຳໃຊ້..."</string>
+ <string name="ota_hfa_activation_dialog_message" msgid="8092479227918463415">"ໂທລະສັບກຳລັງເປີດນຳໃຊ້ບໍລິການຂໍ້ມູນມືຖືຂອງທ່ານ.\n\nຂັ້ນຕອນນີ້ອາດໃຊ້ເວລາເຖິງ 5 ນາທີ."</string>
<string name="ota_skip_activation_dialog_title" msgid="2943366608272261306">"ຂ້າມການເປີດນຳໃຊ້?"</string>
<string name="ota_skip_activation_dialog_message" msgid="2440770373498870550">"ຫາກທ່ານຂ້າມການເປີດນຳໃຊ້, ທ່ານຈະບໍ່ສາມາດໂທອອກ ຫຼືເຊື່ອມຕໍ່ເຄືອຂ່າຍຂໍ້ມູນມືຖືໄດ້ (ເຖິງແມ່ນວ່າ ທ່ານຈະສາມາດເຊື່ອມຕໍ່ຫາເຄືອຂ່າຍ Wi-Fi). ທ່ານຈະຖືກຖາມໃຫ້ເປີດນຳໃຊ້ທຸກຄັ້ງທີ່ທ່ານເປີດເຄື່ອງ, ຈົນກວ່າທ່ານຈະສຳເລັດຂັ້ນຕອນ ການເປີດນຳໃຊ້ໂທລະສັບຂອງທ່ານ."</string>
<string name="ota_skip_activation_dialog_skip_label" msgid="3458532775091563208">"ຂ້າມ"</string>
@@ -581,8 +579,7 @@
<string name="respond_via_sms_setting_title_2" msgid="6104662227299493906">"ແກ້ໄຂຂໍ້ຄວາມຕອບກັບດ່ວນ"</string>
<string name="respond_via_sms_setting_summary" msgid="9150281183930613065"></string>
<string name="respond_via_sms_edittext_dialog_title" msgid="20379890418289778">"ຕອບກັບດ່ວນ"</string>
- <!-- no translation found for respond_via_sms_menu_reset_default_activity (4029277930090150223) -->
- <skip />
+ <string name="respond_via_sms_menu_reset_default_activity" msgid="4029277930090150223">"ຄືນໄປຄ່າເລີ່ມຕົ້ນ"</string>
<string name="respond_via_sms_confirmation_format" msgid="7229149977515784269">"ສົ່ງຂໍ້ຄວາມຫາ <xliff:g id="PHONE_NUMBER">%s</xliff:g> ແລ້ວ."</string>
<string name="description_image_button_one" msgid="5502718871331943463">"ນຶ່ງ"</string>
<string name="description_image_button_two" msgid="4903738528222924522">"ສອງ"</string>
diff --git a/res/values-lt/strings.xml b/res/values-lt/strings.xml
index 092d811..ee9c0d9 100644
--- a/res/values-lt/strings.xml
+++ b/res/values-lt/strings.xml
@@ -450,10 +450,8 @@
<string name="network_message" msgid="4483886461245213802">"Tinklo pranešimas"</string>
<string name="ota_title_activate" msgid="8616918561356194398">"Aktyvinkite savo telefoną"</string>
<string name="ota_touch_activate" msgid="6553212803262586244">"Kad suaktyvintumėte telefono paslaugą, reikia atlikti specialų skambutį. \n\nPaspaudę „Aktyvinti“ klausykite pateikiamų telefono aktyvinimo instrukcijų."</string>
- <!-- no translation found for ota_hfa_activation_title (2234246934160473981) -->
- <skip />
- <!-- no translation found for ota_hfa_activation_dialog_message (8092479227918463415) -->
- <skip />
+ <string name="ota_hfa_activation_title" msgid="2234246934160473981">"Aktyvinama..."</string>
+ <string name="ota_hfa_activation_dialog_message" msgid="8092479227918463415">"Telefonas aktyvina mobiliųjų duomenų paslaugą.\n\nTai gali užtrukti iki 5 min."</string>
<string name="ota_skip_activation_dialog_title" msgid="2943366608272261306">"Praleisti aktyvinimą?"</string>
<string name="ota_skip_activation_dialog_message" msgid="2440770373498870550">"Jei praleisite aktyvinimą, negalėsite skambinti ar prisijungti prie mobilių duomenų tinklų (nors ir galite prisijungti prie „Wi-Fi“ tinklų). Iki tol, kol suaktyvinsite telefoną, aktyvinkite jį kaskart jį įjungdami."</string>
<string name="ota_skip_activation_dialog_skip_label" msgid="3458532775091563208">"Praleisti"</string>
@@ -581,8 +579,7 @@
<string name="respond_via_sms_setting_title_2" msgid="6104662227299493906">"Redaguoti greitus atsakus"</string>
<string name="respond_via_sms_setting_summary" msgid="9150281183930613065"></string>
<string name="respond_via_sms_edittext_dialog_title" msgid="20379890418289778">"Greitas atsakas"</string>
- <!-- no translation found for respond_via_sms_menu_reset_default_activity (4029277930090150223) -->
- <skip />
+ <string name="respond_via_sms_menu_reset_default_activity" msgid="4029277930090150223">"Atkurti numatyt. nustatymus"</string>
<string name="respond_via_sms_confirmation_format" msgid="7229149977515784269">"Pranešimas išsiųstas numeriu <xliff:g id="PHONE_NUMBER">%s</xliff:g>."</string>
<string name="description_image_button_one" msgid="5502718871331943463">"vienas"</string>
<string name="description_image_button_two" msgid="4903738528222924522">"du"</string>
diff --git a/res/values-lv/strings.xml b/res/values-lv/strings.xml
index 3c93d2e..58a5835 100644
--- a/res/values-lv/strings.xml
+++ b/res/values-lv/strings.xml
@@ -452,10 +452,8 @@
<string name="network_message" msgid="4483886461245213802">"Tīkla ziņojums"</string>
<string name="ota_title_activate" msgid="8616918561356194398">"Tālruņa aktivizēšana"</string>
<string name="ota_touch_activate" msgid="6553212803262586244">"Lai aktivizētu tālruņa pakalpojumu, ir jāveic īpašs zvans. \n\nNospiediet uz Aktivizēt un pēc tam klausieties tālruņa aktivizēšanas norādījumus."</string>
- <!-- no translation found for ota_hfa_activation_title (2234246934160473981) -->
- <skip />
- <!-- no translation found for ota_hfa_activation_dialog_message (8092479227918463415) -->
- <skip />
+ <string name="ota_hfa_activation_title" msgid="2234246934160473981">"Notiek aktivizācija..."</string>
+ <string name="ota_hfa_activation_dialog_message" msgid="8092479227918463415">"Tālrunis aktivizē jūsu mobilo datu pakalpojumu.\n\nŠis process var ilgt 5 minūtes."</string>
<string name="ota_skip_activation_dialog_title" msgid="2943366608272261306">"Vai izlaist aktivizāciju?"</string>
<string name="ota_skip_activation_dialog_message" msgid="2440770373498870550">"Ja tiks izlaista aktivizācija, nevarēs veikt zvanus vai izveidot savienojumu ar mobilajiem datu tīkliem (taču varēs izveidot savienojumu ar Wi-Fi tīkliem). Ikreiz ieslēdzot tālruni, tiks prasīts to aktivizēt (līdz brīdim, kad tas tiks aktivizēts)."</string>
<string name="ota_skip_activation_dialog_skip_label" msgid="3458532775091563208">"Izlaist"</string>
@@ -583,8 +581,7 @@
<string name="respond_via_sms_setting_title_2" msgid="6104662227299493906">"Ātro atbilžu rediģēšana"</string>
<string name="respond_via_sms_setting_summary" msgid="9150281183930613065"></string>
<string name="respond_via_sms_edittext_dialog_title" msgid="20379890418289778">"Ātrā atbilde"</string>
- <!-- no translation found for respond_via_sms_menu_reset_default_activity (4029277930090150223) -->
- <skip />
+ <string name="respond_via_sms_menu_reset_default_activity" msgid="4029277930090150223">"Atjaunot noklusējuma iestatījumus"</string>
<string name="respond_via_sms_confirmation_format" msgid="7229149977515784269">"Ziņojums nosūt. uz šādu tālr. nr.: <xliff:g id="PHONE_NUMBER">%s</xliff:g>."</string>
<string name="description_image_button_one" msgid="5502718871331943463">"viens"</string>
<string name="description_image_button_two" msgid="4903738528222924522">"divi"</string>
diff --git a/res/values-mcc234-mnc02/config.xml b/res/values-mcc234-mnc02/config.xml
new file mode 100644
index 0000000..7eccfdc
--- /dev/null
+++ b/res/values-mcc234-mnc02/config.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2013 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+<!-- Telephony service resources that may need to be customized
+ for different hardware or product builds. -->
+<resources>
+ <!-- Configure certain GsmUmtsOptions to be available or not. The
+ default values are in services/Telephony/res/values/config.xml
+ and maybe overridden in operator specific resource directories
+ or device specific overlays. -->
+ <bool name="config_prefer_2g" translatable="false">false</bool>
+</resources>
diff --git a/res/values-mcc234-mnc10/config.xml b/res/values-mcc234-mnc10/config.xml
new file mode 100644
index 0000000..7eccfdc
--- /dev/null
+++ b/res/values-mcc234-mnc10/config.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2013 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+<!-- Telephony service resources that may need to be customized
+ for different hardware or product builds. -->
+<resources>
+ <!-- Configure certain GsmUmtsOptions to be available or not. The
+ default values are in services/Telephony/res/values/config.xml
+ and maybe overridden in operator specific resource directories
+ or device specific overlays. -->
+ <bool name="config_prefer_2g" translatable="false">false</bool>
+</resources>
diff --git a/res/values-mcc234-mnc11/config.xml b/res/values-mcc234-mnc11/config.xml
new file mode 100644
index 0000000..7eccfdc
--- /dev/null
+++ b/res/values-mcc234-mnc11/config.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2013 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+<!-- Telephony service resources that may need to be customized
+ for different hardware or product builds. -->
+<resources>
+ <!-- Configure certain GsmUmtsOptions to be available or not. The
+ default values are in services/Telephony/res/values/config.xml
+ and maybe overridden in operator specific resource directories
+ or device specific overlays. -->
+ <bool name="config_prefer_2g" translatable="false">false</bool>
+</resources>
diff --git a/res/values-mn-rMN/strings.xml b/res/values-mn-rMN/strings.xml
index fa0c84f..1d0da72 100644
--- a/res/values-mn-rMN/strings.xml
+++ b/res/values-mn-rMN/strings.xml
@@ -450,10 +450,8 @@
<string name="network_message" msgid="4483886461245213802">"Сүлжээний зурвас"</string>
<string name="ota_title_activate" msgid="8616918561356194398">"Утсаа идэвхжүүлнэ үү"</string>
<string name="ota_touch_activate" msgid="6553212803262586244">"Таны утасны үйлчилгээ идэвхжүүлэхийн тулд тусгай дуудлага хийх шаардлагатай. \n\n“Идэвхжүүлэх” гэснийг дарсны дараа өгч байгаа зааврыг сонсон утсаа идэвхжүүлнэ үү."</string>
- <!-- no translation found for ota_hfa_activation_title (2234246934160473981) -->
- <skip />
- <!-- no translation found for ota_hfa_activation_dialog_message (8092479227918463415) -->
- <skip />
+ <string name="ota_hfa_activation_title" msgid="2234246934160473981">"Идэвхжүүлж байна..."</string>
+ <string name="ota_hfa_activation_dialog_message" msgid="8092479227918463415">"Утас таны мобайл дата үйлчилгээг идэвхжүүлж байна.\n\nҮүнд 5 хүртэл минут орж болно."</string>
<string name="ota_skip_activation_dialog_title" msgid="2943366608272261306">"Идэвхжүүлэхийг алгасах уу?"</string>
<string name="ota_skip_activation_dialog_message" msgid="2440770373498870550">"Хэрэв та идэвхжүүлэхийг алгасвал дуудлага хийх буюу мобайль дата сүлжээнд холбогдох (хэдийгээр Wi-Fi сүлжээнд холбогдож болох ч) боломжгүй болно. Таныг утсаа идэвхжүүлэх хүртэл утсаа асаах бүрт идэвхжүүлэхийг хүсэх болно."</string>
<string name="ota_skip_activation_dialog_skip_label" msgid="3458532775091563208">"Алгасах"</string>
@@ -581,8 +579,7 @@
<string name="respond_via_sms_setting_title_2" msgid="6104662227299493906">"Шуурхай хариунуудыг засах"</string>
<string name="respond_via_sms_setting_summary" msgid="9150281183930613065"></string>
<string name="respond_via_sms_edittext_dialog_title" msgid="20379890418289778">"Шуурхай хариу"</string>
- <!-- no translation found for respond_via_sms_menu_reset_default_activity (4029277930090150223) -->
- <skip />
+ <string name="respond_via_sms_menu_reset_default_activity" msgid="4029277930090150223">"Үндсэн утгыг сэргээх"</string>
<string name="respond_via_sms_confirmation_format" msgid="7229149977515784269">"Зурвасыг <xliff:g id="PHONE_NUMBER">%s</xliff:g> руу илгээв."</string>
<string name="description_image_button_one" msgid="5502718871331943463">"нэг"</string>
<string name="description_image_button_two" msgid="4903738528222924522">"хоёр"</string>
diff --git a/res/values-ms-rMY/strings.xml b/res/values-ms-rMY/strings.xml
index 51f70ef..cce934d 100644
--- a/res/values-ms-rMY/strings.xml
+++ b/res/values-ms-rMY/strings.xml
@@ -450,10 +450,8 @@
<string name="network_message" msgid="4483886461245213802">"Mesej rangkaian"</string>
<string name="ota_title_activate" msgid="8616918561356194398">"Aktifkan telefon anda"</string>
<string name="ota_touch_activate" msgid="6553212803262586244">"Panggilan khas perlu dibuat untuk mengaktifkan perkhidmatan telefon anda. \n\nSelepas menekan “Aktifkan”, dengar arahan yang diberi untuk mengaktifkan telefon anda."</string>
- <!-- no translation found for ota_hfa_activation_title (2234246934160473981) -->
- <skip />
- <!-- no translation found for ota_hfa_activation_dialog_message (8092479227918463415) -->
- <skip />
+ <string name="ota_hfa_activation_title" msgid="2234246934160473981">"Mengaktifkan..."</string>
+ <string name="ota_hfa_activation_dialog_message" msgid="8092479227918463415">"Telefon sedang mengaktifkan perkhidmatan data mudah alih anda.\n\nIni boleh mengambil masa sehingga 5 minit."</string>
<string name="ota_skip_activation_dialog_title" msgid="2943366608272261306">"Langkau pengaktifan?"</string>
<string name="ota_skip_activation_dialog_message" msgid="2440770373498870550">"Jika anda melangkau pengaktifan, anda tidak boleh membuat panggilan atau bersambung ke rangkaian data mudah alih (walaupun anda boleh bersambung ke rangkaian Wi-Fi). Sehingga anda mengaktifkan telefon anda, anda akan diminta untuk mengaktifkannya setiap kali anda menghidupkannya."</string>
<string name="ota_skip_activation_dialog_skip_label" msgid="3458532775091563208">"Langkau"</string>
@@ -581,8 +579,7 @@
<string name="respond_via_sms_setting_title_2" msgid="6104662227299493906">"Edit respons pantas"</string>
<string name="respond_via_sms_setting_summary" msgid="9150281183930613065"></string>
<string name="respond_via_sms_edittext_dialog_title" msgid="20379890418289778">"Respons pantas"</string>
- <!-- no translation found for respond_via_sms_menu_reset_default_activity (4029277930090150223) -->
- <skip />
+ <string name="respond_via_sms_menu_reset_default_activity" msgid="4029277930090150223">"Pulihkan tetapan asal"</string>
<string name="respond_via_sms_confirmation_format" msgid="7229149977515784269">"Mesej dihantar ke <xliff:g id="PHONE_NUMBER">%s</xliff:g>."</string>
<string name="description_image_button_one" msgid="5502718871331943463">"satu"</string>
<string name="description_image_button_two" msgid="4903738528222924522">"dua"</string>
diff --git a/res/values-nb/strings.xml b/res/values-nb/strings.xml
index e14a9fe..504366a 100644
--- a/res/values-nb/strings.xml
+++ b/res/values-nb/strings.xml
@@ -456,10 +456,8 @@
<string name="network_message" msgid="4483886461245213802">"Nettverksmelding"</string>
<string name="ota_title_activate" msgid="8616918561356194398">"Aktiver telefonen din"</string>
<string name="ota_touch_activate" msgid="6553212803262586244">"Det må foretas en spesifikk oppringning for at telefontjenesten skal aktiveres. \n\nTrykk «Aktiver», og lytt deretter til instruksjonene for å aktivere telefonen."</string>
- <!-- no translation found for ota_hfa_activation_title (2234246934160473981) -->
- <skip />
- <!-- no translation found for ota_hfa_activation_dialog_message (8092479227918463415) -->
- <skip />
+ <string name="ota_hfa_activation_title" msgid="2234246934160473981">"Aktiverer …"</string>
+ <string name="ota_hfa_activation_dialog_message" msgid="8092479227918463415">"Telefonen aktiverer mobildatatjenesten din.\n\nDette kan ta inntil fem minutter."</string>
<string name="ota_skip_activation_dialog_title" msgid="2943366608272261306">"Hopp over aktivering?"</string>
<string name="ota_skip_activation_dialog_message" msgid="2440770373498870550">"Hvis du hopper over aktiveringen, kan du ikke foreta anrop eller koble til mobildatanettverk (du kan imidlertid koble til trådløse nettverk). Du blir bedt om å aktivere hver gang du slår på telefonen, inntil aktivering er fullført."</string>
<string name="ota_skip_activation_dialog_skip_label" msgid="3458532775091563208">"Hopp over"</string>
@@ -587,8 +585,7 @@
<string name="respond_via_sms_setting_title_2" msgid="6104662227299493906">"Rediger hurtigsvar"</string>
<string name="respond_via_sms_setting_summary" msgid="9150281183930613065"></string>
<string name="respond_via_sms_edittext_dialog_title" msgid="20379890418289778">"Hurtigsvar"</string>
- <!-- no translation found for respond_via_sms_menu_reset_default_activity (4029277930090150223) -->
- <skip />
+ <string name="respond_via_sms_menu_reset_default_activity" msgid="4029277930090150223">"Gjenopprett standardinnstillingene"</string>
<string name="respond_via_sms_confirmation_format" msgid="7229149977515784269">"Melding er sendt til <xliff:g id="PHONE_NUMBER">%s</xliff:g>."</string>
<string name="description_image_button_one" msgid="5502718871331943463">"en"</string>
<string name="description_image_button_two" msgid="4903738528222924522">"to"</string>
diff --git a/res/values-nl/strings.xml b/res/values-nl/strings.xml
index 255c4b6..116381d 100644
--- a/res/values-nl/strings.xml
+++ b/res/values-nl/strings.xml
@@ -450,10 +450,8 @@
<string name="network_message" msgid="4483886461245213802">"Netwerkbericht"</string>
<string name="ota_title_activate" msgid="8616918561356194398">"Uw telefoon activeren"</string>
<string name="ota_touch_activate" msgid="6553212803262586244">"U moet een speciale oproep uitvoeren om uw telefoonservice te activeren. \n\nNadat u op \'Activeren\' heeft gedrukt, luistert u naar de instructies om uw telefoon te activeren."</string>
- <!-- no translation found for ota_hfa_activation_title (2234246934160473981) -->
- <skip />
- <!-- no translation found for ota_hfa_activation_dialog_message (8092479227918463415) -->
- <skip />
+ <string name="ota_hfa_activation_title" msgid="2234246934160473981">"Activeren..."</string>
+ <string name="ota_hfa_activation_dialog_message" msgid="8092479227918463415">"De telefoon activeert uw mobiele gegevensservice.\n\nDit kan tot vijf minuten duren."</string>
<string name="ota_skip_activation_dialog_title" msgid="2943366608272261306">"Activering overslaan?"</string>
<string name="ota_skip_activation_dialog_message" msgid="2440770373498870550">"Als u de activering overslaat, kunt u niet bellen of verbinding maken met mobiele gegevensnetwerken (u kunt wel verbinding maken met wifi-netwerken). Tot u de telefoon activeert, wordt u gevraagd deze te activeren telkens wanneer u de telefoon inschakelt."</string>
<string name="ota_skip_activation_dialog_skip_label" msgid="3458532775091563208">"Overslaan"</string>
@@ -581,8 +579,7 @@
<string name="respond_via_sms_setting_title_2" msgid="6104662227299493906">"Snelle reacties bewerken"</string>
<string name="respond_via_sms_setting_summary" msgid="9150281183930613065"></string>
<string name="respond_via_sms_edittext_dialog_title" msgid="20379890418289778">"Snelle reactie"</string>
- <!-- no translation found for respond_via_sms_menu_reset_default_activity (4029277930090150223) -->
- <skip />
+ <string name="respond_via_sms_menu_reset_default_activity" msgid="4029277930090150223">"Standaardwaarden herstellen"</string>
<string name="respond_via_sms_confirmation_format" msgid="7229149977515784269">"Bericht verzonden naar <xliff:g id="PHONE_NUMBER">%s</xliff:g>."</string>
<string name="description_image_button_one" msgid="5502718871331943463">"één"</string>
<string name="description_image_button_two" msgid="4903738528222924522">"twee"</string>
diff --git a/res/values-pl/strings.xml b/res/values-pl/strings.xml
index 4ad9448..dd9b7a6 100644
--- a/res/values-pl/strings.xml
+++ b/res/values-pl/strings.xml
@@ -450,10 +450,8 @@
<string name="network_message" msgid="4483886461245213802">"Komunikat sieciowy"</string>
<string name="ota_title_activate" msgid="8616918561356194398">"Aktywuj telefon"</string>
<string name="ota_touch_activate" msgid="6553212803262586244">"Aby aktywować usługę telekomunikacyjną, należy wykonać połączenie specjalne. \n\nPo naciśnięciu przycisku „Aktywuj” posłuchaj dostępnych instrukcji, aby aktywować telefon."</string>
- <!-- no translation found for ota_hfa_activation_title (2234246934160473981) -->
- <skip />
- <!-- no translation found for ota_hfa_activation_dialog_message (8092479227918463415) -->
- <skip />
+ <string name="ota_hfa_activation_title" msgid="2234246934160473981">"Aktywuję..."</string>
+ <string name="ota_hfa_activation_dialog_message" msgid="8092479227918463415">"Telefon aktywuje komórkową usługę transmisji danych.\n\nMoże to potrwać do 5 minut."</string>
<string name="ota_skip_activation_dialog_title" msgid="2943366608272261306">"Pominąć aktywację?"</string>
<string name="ota_skip_activation_dialog_message" msgid="2440770373498870550">"Jeśli pominiesz aktywację, nie będzie można wykonywać połączeń ani łączyć się z komórkowymi sieciami transmisji danych (łączenie się z sieciami Wi-Fi będzie jednak możliwe). Do momentu dokonania aktywacji odpowiedni monit będzie wyświetlany po każdym włączeniu telefonu."</string>
<string name="ota_skip_activation_dialog_skip_label" msgid="3458532775091563208">"Pomiń"</string>
@@ -581,8 +579,7 @@
<string name="respond_via_sms_setting_title_2" msgid="6104662227299493906">"Edytuj szybkie odpowiedzi"</string>
<string name="respond_via_sms_setting_summary" msgid="9150281183930613065"></string>
<string name="respond_via_sms_edittext_dialog_title" msgid="20379890418289778">"Szybka odpowiedź"</string>
- <!-- no translation found for respond_via_sms_menu_reset_default_activity (4029277930090150223) -->
- <skip />
+ <string name="respond_via_sms_menu_reset_default_activity" msgid="4029277930090150223">"Przywróć wartości domyślne"</string>
<string name="respond_via_sms_confirmation_format" msgid="7229149977515784269">"Wiadomość wysłano na numer <xliff:g id="PHONE_NUMBER">%s</xliff:g>."</string>
<string name="description_image_button_one" msgid="5502718871331943463">"jeden"</string>
<string name="description_image_button_two" msgid="4903738528222924522">"dwa"</string>
diff --git a/res/values-pt-rPT/strings.xml b/res/values-pt-rPT/strings.xml
index 86fe999..c15f8ba 100644
--- a/res/values-pt-rPT/strings.xml
+++ b/res/values-pt-rPT/strings.xml
@@ -169,7 +169,7 @@
<item msgid="3817924849415716259">"GSM/WCDMA preferido"</item>
</string-array>
<string name="data_enabled" msgid="5972538663568715366">"Dados ativados"</string>
- <string name="data_enable_summary" msgid="5022018967714633874">"Activar acesso a dados através de rede móvel"</string>
+ <string name="data_enable_summary" msgid="5022018967714633874">"Ativar acesso a dados através de rede móvel"</string>
<string name="roaming" msgid="8871412572928323707">"Roaming de dados"</string>
<string name="roaming_enable" msgid="7331106985174381987">"Ligar a serviços de dados em roaming"</string>
<string name="roaming_disable" msgid="1843417228755568110">"Ligar a serviços de dados em roaming"</string>
@@ -190,18 +190,18 @@
<string name="throttle_help_subtext" msgid="5217706521499010816">"Mais informações sobre a política de utilização de dados da rede móvel do seu operador."</string>
<string name="cell_broadcast_sms" msgid="5584192824053625842">"Transmissão Celular SMS"</string>
<string name="enable_disable_cell_bc_sms" msgid="4851147873691392255">"Transmissão Celular SMS"</string>
- <string name="cell_bc_sms_enable" msgid="6441688565738921084">"Definições da Transmissão Celular SMS activada"</string>
- <string name="cell_bc_sms_disable" msgid="3398365088309408749">"Transmissão Celular SMS desactivada"</string>
- <string name="cb_sms_settings" msgid="651715019785107312">"Definições da Transmissão Celular SMS"</string>
+ <string name="cell_bc_sms_enable" msgid="6441688565738921084">"Definições da transmissão celular SMS ativada"</string>
+ <string name="cell_bc_sms_disable" msgid="3398365088309408749">"Transmissão Celular SMS desativada"</string>
+ <string name="cb_sms_settings" msgid="651715019785107312">"Definições da transmissão celular SMS"</string>
<string name="enable_disable_emergency_broadcast" msgid="2157014609041245335">"Difusão de Emergência"</string>
<string name="emergency_broadcast_enable" msgid="2645980025414010211">"Difusão de Emergência activada"</string>
- <string name="emergency_broadcast_disable" msgid="3665199821267569426">"Difusão de Emergência desactivada"</string>
+ <string name="emergency_broadcast_disable" msgid="3665199821267569426">"Difusão de Emergência desativada"</string>
<string name="enable_disable_administrative" msgid="6501582322182059412">"Administrativo"</string>
<string name="administrative_enable" msgid="1750086122962032235">"Modo Administrativo ativado"</string>
<string name="administrative_disable" msgid="8433273857248698539">"Modo administrativo desativado"</string>
<string name="enable_disable_maintenance" msgid="1819693083025106678">"Manutenção"</string>
<string name="maintenance_enable" msgid="8566636458770971189">"Manutenção activada"</string>
- <string name="maintenance_disable" msgid="7340189100885066077">"Manutenção desactivada"</string>
+ <string name="maintenance_disable" msgid="7340189100885066077">"Manutenção desativada"</string>
<string name="general_news_settings" msgid="4968779723948432978">"Notícias Gerais"</string>
<string name="bf_news_settings" msgid="3935593091894685267">"Notícias de Negócios e Finanças"</string>
<string name="sports_news_settings" msgid="7649399631270052835">"Notícias Desportivas"</string>
@@ -241,7 +241,7 @@
<string name="list_language_dtitle" msgid="5442908726538951934">"Idiomas"</string>
<string name="enable_disable_local_weather" msgid="986967454867219114">"Informação Meteorológica Local"</string>
<string name="local_weather_enable" msgid="6199315114382448922">"Informação Meteorológica Local activada"</string>
- <string name="local_weather_disable" msgid="2510158089142626480">"Informação meteorológica local desactivada"</string>
+ <string name="local_weather_disable" msgid="2510158089142626480">"Informação meteorológica local desativada"</string>
<string name="enable_disable_atr" msgid="8339572391278872343">"Relatórios de Tráfego de Área"</string>
<string name="atr_enable" msgid="5541757457789181799">"Relatórios de Tráfego de Área ativados"</string>
<string name="atr_disable" msgid="7085558154727596455">"Relatórios de Tráfego de Área desativados"</string>
@@ -256,7 +256,7 @@
<string name="lodgings_disable" msgid="3387879742320682391">"Alojamento desativado"</string>
<string name="enable_disable_retail_directory" msgid="1357809784475660303">"Lista de Retalho"</string>
<string name="retail_directory_enable" msgid="3280626290436111496">"Lista de Retalho activada"</string>
- <string name="retail_directory_disable" msgid="6479739816662879027">"Lista de Retalho desactivada"</string>
+ <string name="retail_directory_disable" msgid="6479739816662879027">"Lista de Retalho desativada"</string>
<string name="enable_disable_advertisements" msgid="5999495926176182128">"Anúncios"</string>
<string name="advertisements_enable" msgid="2050305021264683786">"Anúncios ativados"</string>
<string name="advertisements_disable" msgid="8350985908788707935">"Anúncios desativados"</string>
@@ -295,23 +295,23 @@
<item msgid="7494167883478914080">"0"</item>
<item msgid="6043847456049107742">"1"</item>
</string-array>
- <string name="cdma_activate_device" msgid="3793805892364814518">"Activar dispositivo"</string>
+ <string name="cdma_activate_device" msgid="3793805892364814518">"Ativar dispositivo"</string>
<string name="cdma_lte_data_service" msgid="4255018217292548962">"Configurar serviço de dados"</string>
<string name="fdn" msgid="7878832555095183202">"Números de marcação fixa (FDN)"</string>
<string name="manage_fdn_list" msgid="8777755791892122369">"Lista de números de marcação fixa (FDN)"</string>
<string name="fdn_activation" msgid="2156479741307463576">"Activação de FDN"</string>
<string name="fdn_enabled" msgid="5238109009915521240">"Os números de marcação fixa estão ativados"</string>
<string name="fdn_disabled" msgid="4700049736675368279">"Os números de marcação fixa estão desativados"</string>
- <string name="enable_fdn" msgid="3740191529180493851">"Activar FDN"</string>
- <string name="disable_fdn" msgid="7944020890722540616">"Desactivar FDN"</string>
+ <string name="enable_fdn" msgid="3740191529180493851">"Ativar FDN"</string>
+ <string name="disable_fdn" msgid="7944020890722540616">"Desativar FDN"</string>
<string name="change_pin2" msgid="2153563695382176676">"Alterar PIN2"</string>
- <string name="enable_fdn_ok" msgid="7215588870329688132">"Desactivar FDN"</string>
- <string name="disable_fdn_ok" msgid="5727046928930740173">"Activar FDN"</string>
+ <string name="enable_fdn_ok" msgid="7215588870329688132">"Desativar FDN"</string>
+ <string name="disable_fdn_ok" msgid="5727046928930740173">"Ativar FDN"</string>
<string name="sum_fdn" msgid="1959399454900272878">"Gerir os números de marcação fixa"</string>
<string name="sum_fdn_change_pin" msgid="6666549734792827932">"Alterar o PIN de acesso aos números de marcação fixa"</string>
<string name="sum_fdn_manage_list" msgid="8431088265332628316">"Gerir a lista telefónica"</string>
<string name="voice_privacy" msgid="3776841382844614716">"Privacidade de voz"</string>
- <string name="voice_privacy_summary" msgid="3159383389833516214">"Activar modo de privacidade optimizado"</string>
+ <string name="voice_privacy_summary" msgid="3159383389833516214">"Ativar modo de privacidade optimizado"</string>
<string name="tty_mode_option_title" msgid="9033098925144434669">"Modo TTY"</string>
<string name="tty_mode_option_summary" msgid="1073835131534808732">"Definir modo TTY"</string>
<string name="auto_retry_mode_title" msgid="4073265511427813322">"Nova tentativa automática"</string>
@@ -339,7 +339,7 @@
<string name="simContacts_empty" msgid="5270660846489561932">"Sem contactos no cartão SIM."</string>
<string name="simContacts_title" msgid="1861472842524839921">"Seleccione os contactos a importar"</string>
<string name="simContacts_airplaneMode" msgid="1846161429087789936">"Para importar contactos do cartão SIM, primeiro desative o Modo de Avião."</string>
- <string name="enable_pin" msgid="5422767284133234860">"Activar/desactivar o PIN do cartão SIM"</string>
+ <string name="enable_pin" msgid="5422767284133234860">"Ativar/desativar o PIN do cartão SIM"</string>
<string name="change_pin" msgid="9174186126330785343">"Alterar o PIN do cartão SIM"</string>
<string name="enter_pin_text" msgid="8532615714751931951">"PIN do SIM:"</string>
<string name="oldPinLabel" msgid="5287773661246368314">"PIN antigo"</string>
@@ -348,8 +348,8 @@
<string name="badPin" msgid="8955102849303984935">"O PIN antigo introduzido não está correto. Tente novamente."</string>
<string name="mismatchPin" msgid="5923253370683071889">"Os PINs introduzidos não correspondem. Tente novamente."</string>
<string name="invalidPin" msgid="5981171102258684792">"Introduza um PIN com 4 a 8 números."</string>
- <string name="disable_sim_pin" msgid="3992926931620188855">"Desactivar o PIN do SIM"</string>
- <string name="enable_sim_pin" msgid="5803702443844458831">"Activar o PIN do cartão SIM"</string>
+ <string name="disable_sim_pin" msgid="3992926931620188855">"Desativar o PIN do SIM"</string>
+ <string name="enable_sim_pin" msgid="5803702443844458831">"Ativar o PIN do cartão SIM"</string>
<string name="enable_in_progress" msgid="3695303775100109650">"Queira aguardar..."</string>
<string name="enable_pin_ok" msgid="9166061915030865848">"PIN do SIM ativado"</string>
<string name="disable_pin_ok" msgid="5596999379593924850">"PIN do SIM desativado"</string>
@@ -434,7 +434,7 @@
<string name="importingSimContacts" msgid="7374056215462575769">"A importar contactos do cartão SIM"</string>
<string name="importToFDNfromContacts" msgid="2130620207013368580">"Importar a partir dos contactos"</string>
<string name="hac_mode_title" msgid="8740268574688743289">"Aparelhos auxiliares de audição"</string>
- <string name="hac_mode_summary" msgid="6833851160514929341">"Activar compatibilidade com aparelho auxiliar de audição"</string>
+ <string name="hac_mode_summary" msgid="6833851160514929341">"Ativar compatibilidade com aparelho auxiliar de audição"</string>
<string-array name="tty_mode_entries">
<item msgid="512950011423868021">"TTY desativado"</item>
<item msgid="3971695875449640648">"TTY total"</item>
@@ -448,14 +448,12 @@
<item msgid="2883365539347850535">"Longo"</item>
</string-array>
<string name="network_message" msgid="4483886461245213802">"Mensagem de rede"</string>
- <string name="ota_title_activate" msgid="8616918561356194398">"Activar o seu telefone"</string>
- <string name="ota_touch_activate" msgid="6553212803262586244">"É necessário efectuar uma chamada especial para activar o seu serviço telefónico. \n\nDepois de premir “Activar”, ouça as instruções fornecidas para activar o telefone."</string>
- <!-- no translation found for ota_hfa_activation_title (2234246934160473981) -->
- <skip />
- <!-- no translation found for ota_hfa_activation_dialog_message (8092479227918463415) -->
- <skip />
+ <string name="ota_title_activate" msgid="8616918561356194398">"Ativar o seu telefone"</string>
+ <string name="ota_touch_activate" msgid="6553212803262586244">"É necessário efectuar uma chamada especial para ativar o seu serviço telefónico. \n\nDepois de premir “Ativar”, ouça as instruções fornecidas para activar o telefone."</string>
+ <string name="ota_hfa_activation_title" msgid="2234246934160473981">"A ativar..."</string>
+ <string name="ota_hfa_activation_dialog_message" msgid="8092479227918463415">"O telemóvel está a ativar o serviço de dados móveis.\n\nEste processo poderá demorar até 5 minutos."</string>
<string name="ota_skip_activation_dialog_title" msgid="2943366608272261306">"Ignorar activação?"</string>
- <string name="ota_skip_activation_dialog_message" msgid="2440770373498870550">"Se ignorar a activação, não poderá fazer chamadas nem estabelecer ligação a redes móveis de dados (apesar de poder estabelecer ligação a redes Wi-Fi). Enquanto não activar o telefone, ser-lhe-á solicitada activação sempre que ligar o telefone."</string>
+ <string name="ota_skip_activation_dialog_message" msgid="2440770373498870550">"Se ignorar a ativação, não poderá fazer chamadas nem estabelecer ligação a redes móveis de dados (apesar de poder estabelecer ligação a redes Wi-Fi). Enquanto não ativar o telefone, ser-lhe-á solicitada activação sempre que ligar o telefone."</string>
<string name="ota_skip_activation_dialog_skip_label" msgid="3458532775091563208">"Ignorar"</string>
<string name="ota_activate" msgid="1368528132525626264">"Ativar"</string>
<string name="ota_title_activate_success" msgid="6570240212263372046">"O telemóvel está ativado!"</string>
@@ -473,7 +471,7 @@
<string name="ecm_exit_dialog" msgid="4448531867763097533">"EcmExitDialog"</string>
<string name="phone_entered_ecm_text" msgid="6266424252578731203">"Entrou em Modo de Chamada de Retorno de Emergência"</string>
<string name="phone_in_ecm_notification_title" msgid="3226896828951687085">"Modo de Chamada de Retorno de Emergência"</string>
- <string name="phone_in_ecm_call_notification_text" msgid="4611608947314729773">"Ligação de dados desactivada"</string>
+ <string name="phone_in_ecm_call_notification_text" msgid="4611608947314729773">"Ligação de dados desativada"</string>
<plurals name="phone_in_ecm_notification_time">
<item quantity="one" msgid="4866221796252472622">"Sem ligação de dados durante <xliff:g id="COUNT">%s</xliff:g> minuto"</item>
<item quantity="other" msgid="3122217344579273583">"Sem ligação de dados durante <xliff:g id="COUNT">%s</xliff:g> minutos"</item>
@@ -581,8 +579,7 @@
<string name="respond_via_sms_setting_title_2" msgid="6104662227299493906">"Editar respostas rápidas"</string>
<string name="respond_via_sms_setting_summary" msgid="9150281183930613065"></string>
<string name="respond_via_sms_edittext_dialog_title" msgid="20379890418289778">"Resposta rápida"</string>
- <!-- no translation found for respond_via_sms_menu_reset_default_activity (4029277930090150223) -->
- <skip />
+ <string name="respond_via_sms_menu_reset_default_activity" msgid="4029277930090150223">"Restaurar predefinições"</string>
<string name="respond_via_sms_confirmation_format" msgid="7229149977515784269">"Mensagem enviada para <xliff:g id="PHONE_NUMBER">%s</xliff:g>."</string>
<string name="description_image_button_one" msgid="5502718871331943463">"um"</string>
<string name="description_image_button_two" msgid="4903738528222924522">"dois"</string>
@@ -609,7 +606,7 @@
<string name="default_notification_description" msgid="78174796906240970">"Som predefinido (<xliff:g id="DEFAULT_SOUND_TITLE">%1$s</xliff:g>)"</string>
<string name="ringtone_title" msgid="6374978286202084684">"Toque do telemóvel"</string>
<string name="vibrate_on_ring_title" msgid="9197564612065258960">"Vibrar ao tocar"</string>
- <string name="dtmf_tone_enable_title" msgid="827601042915852989">"Sons dos toques no teclado de marcar"</string>
+ <string name="dtmf_tone_enable_title" msgid="827601042915852989">"Sons dos toques no teclado"</string>
<string name="dial_pad_autocomplete" msgid="494525952035761075">"Preenchimento automático do teclado"</string>
<string name="preference_category_ringtone" msgid="5197960752529332721">"Tocar e Vibrar"</string>
</resources>
diff --git a/res/values-pt/strings.xml b/res/values-pt/strings.xml
index c10005c..ffc0886 100644
--- a/res/values-pt/strings.xml
+++ b/res/values-pt/strings.xml
@@ -450,10 +450,8 @@
<string name="network_message" msgid="4483886461245213802">"Mensagem de rede"</string>
<string name="ota_title_activate" msgid="8616918561356194398">"Ativar o seu telefone"</string>
<string name="ota_touch_activate" msgid="6553212803262586244">"Uma chamada especial precisa ser feita para ativar o serviço do seu telefone. \n\nDepois de pressionar “Ativar”, ouça as instruções fornecidas para ativar o seu telefone."</string>
- <!-- no translation found for ota_hfa_activation_title (2234246934160473981) -->
- <skip />
- <!-- no translation found for ota_hfa_activation_dialog_message (8092479227918463415) -->
- <skip />
+ <string name="ota_hfa_activation_title" msgid="2234246934160473981">"Ativando…"</string>
+ <string name="ota_hfa_activation_dialog_message" msgid="8092479227918463415">"O telefone está ativando o serviço de dados móveis.\n\nIsso pode levar até 5 minutos."</string>
<string name="ota_skip_activation_dialog_title" msgid="2943366608272261306">"Ignorar ativação?"</string>
<string name="ota_skip_activation_dialog_message" msgid="2440770373498870550">"Se você ignorar a ativação, não poderá fazer chamadas ou se conectar a redes móveis de dados (embora possa se conectar a redes Wi-Fi). Até que o seu telefone seja ativado, você receberá solicitações de ativação sempre que o ligar."</string>
<string name="ota_skip_activation_dialog_skip_label" msgid="3458532775091563208">"Ignorar"</string>
@@ -581,8 +579,7 @@
<string name="respond_via_sms_setting_title_2" msgid="6104662227299493906">"Editar respostas rápidas"</string>
<string name="respond_via_sms_setting_summary" msgid="9150281183930613065"></string>
<string name="respond_via_sms_edittext_dialog_title" msgid="20379890418289778">"Resposta rápida"</string>
- <!-- no translation found for respond_via_sms_menu_reset_default_activity (4029277930090150223) -->
- <skip />
+ <string name="respond_via_sms_menu_reset_default_activity" msgid="4029277930090150223">"Restaurar padrões"</string>
<string name="respond_via_sms_confirmation_format" msgid="7229149977515784269">"Mensagem enviada para <xliff:g id="PHONE_NUMBER">%s</xliff:g>."</string>
<string name="description_image_button_one" msgid="5502718871331943463">"um"</string>
<string name="description_image_button_two" msgid="4903738528222924522">"dois"</string>
diff --git a/res/values-ro/strings.xml b/res/values-ro/strings.xml
index 10fd579..6f05e94 100644
--- a/res/values-ro/strings.xml
+++ b/res/values-ro/strings.xml
@@ -450,10 +450,8 @@
<string name="network_message" msgid="4483886461245213802">"Mesaj de reţea"</string>
<string name="ota_title_activate" msgid="8616918561356194398">"Activaţi-vă telefonul"</string>
<string name="ota_touch_activate" msgid="6553212803262586244">"Pentru a vă activa serviciul de telefonie, trebuie să efectuaţi un apel special. \n\nDupă ce apăsaţi „Activaţi”, ascultaţi instrucţiunile furnizate pentru a vă activa telefonul."</string>
- <!-- no translation found for ota_hfa_activation_title (2234246934160473981) -->
- <skip />
- <!-- no translation found for ota_hfa_activation_dialog_message (8092479227918463415) -->
- <skip />
+ <string name="ota_hfa_activation_title" msgid="2234246934160473981">"Se activează..."</string>
+ <string name="ota_hfa_activation_dialog_message" msgid="8092479227918463415">"Serviciul de date mobile este în curs de activare pe telefonul dvs.\n\nAcest proces poate dura până la 5 minute."</string>
<string name="ota_skip_activation_dialog_title" msgid="2943366608272261306">"Omiteţi activarea?"</string>
<string name="ota_skip_activation_dialog_message" msgid="2440770373498870550">"Dacă omiteţi activarea, nu puteţi efectua apeluri şi nici nu vă puteţi conecta la o reţea de date mobilă (deşi vă puteţi conecta la reţele Wi-Fi). Până veţi activa telefonul, vi se va solicita să-l activaţi de fiecare dată când îl porniţi."</string>
<string name="ota_skip_activation_dialog_skip_label" msgid="3458532775091563208">"Omiteţi"</string>
@@ -581,8 +579,7 @@
<string name="respond_via_sms_setting_title_2" msgid="6104662227299493906">"Editaţi răspunsurile rapide"</string>
<string name="respond_via_sms_setting_summary" msgid="9150281183930613065"></string>
<string name="respond_via_sms_edittext_dialog_title" msgid="20379890418289778">"Răspuns rapid"</string>
- <!-- no translation found for respond_via_sms_menu_reset_default_activity (4029277930090150223) -->
- <skip />
+ <string name="respond_via_sms_menu_reset_default_activity" msgid="4029277930090150223">"Restabiliți valorile implicite"</string>
<string name="respond_via_sms_confirmation_format" msgid="7229149977515784269">"Mesajul a fost trimis la <xliff:g id="PHONE_NUMBER">%s</xliff:g>."</string>
<string name="description_image_button_one" msgid="5502718871331943463">"unu"</string>
<string name="description_image_button_two" msgid="4903738528222924522">"doi"</string>
diff --git a/res/values-ru/strings.xml b/res/values-ru/strings.xml
index 00e74fc..c3fc2ba 100644
--- a/res/values-ru/strings.xml
+++ b/res/values-ru/strings.xml
@@ -452,10 +452,8 @@
<string name="network_message" msgid="4483886461245213802">"Сообщение сети"</string>
<string name="ota_title_activate" msgid="8616918561356194398">"Активировать телефон"</string>
<string name="ota_touch_activate" msgid="6553212803262586244">"Необходим специальный звонок для активации службы телефона. \n\nПосле нажатия кнопки \"Активировать\" прослушайте инструкции по активации телефона."</string>
- <!-- no translation found for ota_hfa_activation_title (2234246934160473981) -->
- <skip />
- <!-- no translation found for ota_hfa_activation_dialog_message (8092479227918463415) -->
- <skip />
+ <string name="ota_hfa_activation_title" msgid="2234246934160473981">"Активация..."</string>
+ <string name="ota_hfa_activation_dialog_message" msgid="8092479227918463415">"Активация мобильного Интернета…\n\nВсе будет готово в течение 5 мин."</string>
<string name="ota_skip_activation_dialog_title" msgid="2943366608272261306">"Пропустить активацию?"</string>
<string name="ota_skip_activation_dialog_message" msgid="2440770373498870550">"Если вы пропустите активацию, вы не сможете совершать вызовы и подключаться к мобильным сетям передачи данных (хотя вы сможете подключаться к сетям Wi-Fi). Пока вы не активируете свой телефон, запрос активации будет отображаться при каждом его включении."</string>
<string name="ota_skip_activation_dialog_skip_label" msgid="3458532775091563208">"Пропустить"</string>
@@ -583,8 +581,7 @@
<string name="respond_via_sms_setting_title_2" msgid="6104662227299493906">"Быстрые ответы"</string>
<string name="respond_via_sms_setting_summary" msgid="9150281183930613065"></string>
<string name="respond_via_sms_edittext_dialog_title" msgid="20379890418289778">"Быстрый ответ"</string>
- <!-- no translation found for respond_via_sms_menu_reset_default_activity (4029277930090150223) -->
- <skip />
+ <string name="respond_via_sms_menu_reset_default_activity" msgid="4029277930090150223">"Восстановить настройки по умолчанию"</string>
<string name="respond_via_sms_confirmation_format" msgid="7229149977515784269">"Сообщение отправлено на номер <xliff:g id="PHONE_NUMBER">%s</xliff:g>."</string>
<string name="description_image_button_one" msgid="5502718871331943463">"один"</string>
<string name="description_image_button_two" msgid="4903738528222924522">"два"</string>
diff --git a/res/values-sk/strings.xml b/res/values-sk/strings.xml
index 80a7e30..3239fde 100644
--- a/res/values-sk/strings.xml
+++ b/res/values-sk/strings.xml
@@ -450,10 +450,8 @@
<string name="network_message" msgid="4483886461245213802">"Informácia siete"</string>
<string name="ota_title_activate" msgid="8616918561356194398">"Aktivujte svoj telefón"</string>
<string name="ota_touch_activate" msgid="6553212803262586244">"Telefónnu službu je potrebné aktivovať uskutočnením mimoriadneho hovoru. \n\nStlačte tlačidlo Aktivovať a aktivujte telefón podľa poskytnutých pokynov."</string>
- <!-- no translation found for ota_hfa_activation_title (2234246934160473981) -->
- <skip />
- <!-- no translation found for ota_hfa_activation_dialog_message (8092479227918463415) -->
- <skip />
+ <string name="ota_hfa_activation_title" msgid="2234246934160473981">"Prebieha aktivácia..."</string>
+ <string name="ota_hfa_activation_dialog_message" msgid="8092479227918463415">"V telefóne prebieha aktivácia mobilnej dátovej služby.\n\nMôže to trvať až 5 minút."</string>
<string name="ota_skip_activation_dialog_title" msgid="2943366608272261306">"Preskočiť aktiváciu?"</string>
<string name="ota_skip_activation_dialog_message" msgid="2440770373498870550">"Ak preskočíte aktiváciu, nemôžete volať ani sa pripájať k mobilným dátovým sieťam (môžete sa ale pripojiť k sieťam Wi-Fi). Ak svoj telefón neaktivujete, bude sa pri každom zapnutí zobrazovať výzva na aktiváciu."</string>
<string name="ota_skip_activation_dialog_skip_label" msgid="3458532775091563208">"Preskočiť"</string>
@@ -504,7 +502,7 @@
<string name="sip_accounts_title" msgid="1212889069281054570">"Účty"</string>
<string name="sip_receive_calls" msgid="5635685570889971559">"Prijímať prichádzajúce hovory"</string>
<string name="sip_receive_calls_summary" msgid="8403613238633679184">"Znižuje výdrž batérie"</string>
- <string name="sip_call_options_title" msgid="27433718808839672">"Použiť internetový volanie"</string>
+ <string name="sip_call_options_title" msgid="27433718808839672">"Použiť internetové volanie"</string>
<string name="sip_call_options_wifi_only_title" msgid="145572394529090811">"Použiť internetový hovor (iba s pripojením Wi-Fi)"</string>
<string name="sip_call_options_entry_1" msgid="6556668894178520760">"Pre všetky hovory, pokiaľ je k dispozícii dátová sieť"</string>
<string name="sip_call_options_entry_2" msgid="6789764029719494361">"Iba pre internetové hovory"</string>
@@ -572,7 +570,7 @@
<string name="sip_system_decide" msgid="368030746310423471">"Automatické"</string>
<string name="sip_always_send_keepalive" msgid="8192080724632877132">"Vždy odoslať"</string>
<string name="not_voice_capable" msgid="2739898841461577811">"Hlasové volanie nie je podporované"</string>
- <string name="respond_via_sms_canned_response_1" msgid="2461606462788380215">"Nemôžem telefonovať, čo sa deje?"</string>
+ <string name="respond_via_sms_canned_response_1" msgid="2461606462788380215">"Teraz nemôžem hovoriť, o čo ide?"</string>
<string name="respond_via_sms_canned_response_2" msgid="4074450431532859214">"Zavolám späť."</string>
<string name="respond_via_sms_canned_response_3" msgid="3496079065723960450">"Zavolám neskôr."</string>
<string name="respond_via_sms_canned_response_4" msgid="1698989243040062190">"Teraz nemôžem, zavolajte inokedy."</string>
@@ -581,8 +579,7 @@
<string name="respond_via_sms_setting_title_2" msgid="6104662227299493906">"Upraviť rýchle odpovede"</string>
<string name="respond_via_sms_setting_summary" msgid="9150281183930613065"></string>
<string name="respond_via_sms_edittext_dialog_title" msgid="20379890418289778">"Rýchla odpoveď"</string>
- <!-- no translation found for respond_via_sms_menu_reset_default_activity (4029277930090150223) -->
- <skip />
+ <string name="respond_via_sms_menu_reset_default_activity" msgid="4029277930090150223">"Obnoviť predvolené nastavenia"</string>
<string name="respond_via_sms_confirmation_format" msgid="7229149977515784269">"Správa bola odoslaná na číslo <xliff:g id="PHONE_NUMBER">%s</xliff:g>."</string>
<string name="description_image_button_one" msgid="5502718871331943463">"jeden"</string>
<string name="description_image_button_two" msgid="4903738528222924522">"dva"</string>
@@ -609,7 +606,7 @@
<string name="default_notification_description" msgid="78174796906240970">"Predvolený zvuk (<xliff:g id="DEFAULT_SOUND_TITLE">%1$s</xliff:g>)"</string>
<string name="ringtone_title" msgid="6374978286202084684">"Tón zvonenia telefónu"</string>
<string name="vibrate_on_ring_title" msgid="9197564612065258960">"Vibrovať pri zvonení"</string>
- <string name="dtmf_tone_enable_title" msgid="827601042915852989">"Zvuky pri dotyku na číselnú klávesnicu"</string>
+ <string name="dtmf_tone_enable_title" msgid="827601042915852989">"Zvuky pri dotyku číselníku"</string>
<string name="dial_pad_autocomplete" msgid="494525952035761075">"Automatické dokonč. číselnej klávesnice"</string>
<string name="preference_category_ringtone" msgid="5197960752529332721">"Tón zvonenia a vibrovanie"</string>
</resources>
diff --git a/res/values-sl/strings.xml b/res/values-sl/strings.xml
index 560d129..f2c1849 100644
--- a/res/values-sl/strings.xml
+++ b/res/values-sl/strings.xml
@@ -450,10 +450,8 @@
<string name="network_message" msgid="4483886461245213802">"Sporočilo omrežja"</string>
<string name="ota_title_activate" msgid="8616918561356194398">"Aktivirajte telefon"</string>
<string name="ota_touch_activate" msgid="6553212803262586244">"Izvesti morate poseben klic, da aktivirate telefonsko storitev. \n\nPo pritisku »Aktiviranje« poslušajte navodila za aktiviranje telefona."</string>
- <!-- no translation found for ota_hfa_activation_title (2234246934160473981) -->
- <skip />
- <!-- no translation found for ota_hfa_activation_dialog_message (8092479227918463415) -->
- <skip />
+ <string name="ota_hfa_activation_title" msgid="2234246934160473981">"Aktiviranje ..."</string>
+ <string name="ota_hfa_activation_dialog_message" msgid="8092479227918463415">"Telefon aktivira storitev za prenos podatkov v mobilnem omrežju.\n\nTo lahko traja do 5 minut."</string>
<string name="ota_skip_activation_dialog_title" msgid="2943366608272261306">"Želite preskočiti aktiviranje?"</string>
<string name="ota_skip_activation_dialog_message" msgid="2440770373498870550">"Če preskočite aktiviranje, ne morete klicati oziroma vzpostaviti stika z mobilnimi podatkovnimi omrežji (lahko pa se povežete v brezžična omrežja). Dokler telefona ne aktivirate, boste k aktiviranju pozvani ob vsakem vklopu telefona."</string>
<string name="ota_skip_activation_dialog_skip_label" msgid="3458532775091563208">"Preskoči"</string>
@@ -581,8 +579,7 @@
<string name="respond_via_sms_setting_title_2" msgid="6104662227299493906">"Urejanje hitrih odgovorov"</string>
<string name="respond_via_sms_setting_summary" msgid="9150281183930613065"></string>
<string name="respond_via_sms_edittext_dialog_title" msgid="20379890418289778">"Hiter odgovor"</string>
- <!-- no translation found for respond_via_sms_menu_reset_default_activity (4029277930090150223) -->
- <skip />
+ <string name="respond_via_sms_menu_reset_default_activity" msgid="4029277930090150223">"Ponastavi privzete vrednosti"</string>
<string name="respond_via_sms_confirmation_format" msgid="7229149977515784269">"SMS poslan na številko <xliff:g id="PHONE_NUMBER">%s</xliff:g>."</string>
<string name="description_image_button_one" msgid="5502718871331943463">"ena"</string>
<string name="description_image_button_two" msgid="4903738528222924522">"dve"</string>
diff --git a/res/values-sr/strings.xml b/res/values-sr/strings.xml
index aeb97bb..d77be93 100644
--- a/res/values-sr/strings.xml
+++ b/res/values-sr/strings.xml
@@ -117,7 +117,7 @@
<string name="vm_changed" msgid="380744030726254139">"Промењен је број говорне поште."</string>
<string name="vm_change_failed" msgid="3352934863246208918">"Није могуће променити број говорне поште.\nКонтактирајте мобилног оператера ако се овај проблем настави."</string>
<string name="fw_change_failed" msgid="5298103228470214665">"Није могуће променити број за преусмеравање.\nКонтактирајте мобилног оператера ако се овај проблем настави."</string>
- <string name="fw_get_in_vm_failed" msgid="8862896836093833973">"Није било могуће преузети и сачувати тренутна подешавања броја за прослеђивање.\nЖелите ли да ипак пређете на новог добављача?"</string>
+ <string name="fw_get_in_vm_failed" msgid="8862896836093833973">"Није могуће преузети и сачувати тренутна подешавања броја за прослеђивање.\nЖелите ли да ипак пређете на новог добављача?"</string>
<string name="no_change" msgid="3186040086622435212">"Нису начињене промене."</string>
<string name="sum_voicemail_choose_provider" msgid="59911196126278922">"Одаберите услугу говорне поште"</string>
<string name="voicemail_default" msgid="5902099213882352338">" Мој мобилни оператер"</string>
@@ -450,10 +450,8 @@
<string name="network_message" msgid="4483886461245213802">"Мрежна порука"</string>
<string name="ota_title_activate" msgid="8616918561356194398">"Активирајте телефон"</string>
<string name="ota_touch_activate" msgid="6553212803262586244">"Потребно је да упутите посебан позив да бисте активирали услугу свој телефона. \n\nНакон што притиснете дугме „Активирај“, слушајте дата упутства да бисте да бисте активирали свој телефон."</string>
- <!-- no translation found for ota_hfa_activation_title (2234246934160473981) -->
- <skip />
- <!-- no translation found for ota_hfa_activation_dialog_message (8092479227918463415) -->
- <skip />
+ <string name="ota_hfa_activation_title" msgid="2234246934160473981">"Активирање..."</string>
+ <string name="ota_hfa_activation_dialog_message" msgid="8092479227918463415">"Телефон активира услугу мобилног преноса података.\n\nТо може да потраје и до 5 минута."</string>
<string name="ota_skip_activation_dialog_title" msgid="2943366608272261306">"Желите ли да прескочите активацију?"</string>
<string name="ota_skip_activation_dialog_message" msgid="2440770373498870550">"Ако прескочите активацију, не можете да упућујете позиве или да се повезујете са мрежама за мобилни пренос података (иако можете да се повежете са Wi-Fi мрежама). Све док не активирате свој телефон, бићете упитани да то учините сваки пут када га укључите."</string>
<string name="ota_skip_activation_dialog_skip_label" msgid="3458532775091563208">"Прескочи"</string>
@@ -581,8 +579,7 @@
<string name="respond_via_sms_setting_title_2" msgid="6104662227299493906">"Измена брзих одговора"</string>
<string name="respond_via_sms_setting_summary" msgid="9150281183930613065"></string>
<string name="respond_via_sms_edittext_dialog_title" msgid="20379890418289778">"Брзи одговор"</string>
- <!-- no translation found for respond_via_sms_menu_reset_default_activity (4029277930090150223) -->
- <skip />
+ <string name="respond_via_sms_menu_reset_default_activity" msgid="4029277930090150223">"Врати на подразумевано"</string>
<string name="respond_via_sms_confirmation_format" msgid="7229149977515784269">"Порука је послата на број <xliff:g id="PHONE_NUMBER">%s</xliff:g>."</string>
<string name="description_image_button_one" msgid="5502718871331943463">"један"</string>
<string name="description_image_button_two" msgid="4903738528222924522">"два"</string>
diff --git a/res/values-sv/strings.xml b/res/values-sv/strings.xml
index e9bd672..496322f 100644
--- a/res/values-sv/strings.xml
+++ b/res/values-sv/strings.xml
@@ -456,10 +456,8 @@
<string name="network_message" msgid="4483886461245213802">"Nätverksmeddelande"</string>
<string name="ota_title_activate" msgid="8616918561356194398">"Aktivera telefonen"</string>
<string name="ota_touch_activate" msgid="6553212803262586244">"Du måste ringa ett särskilt samtal för att aktivera telefontjänsten. \n\n Tryck på \"Aktivera\" och lyssna på instruktionerna om hur du aktiverar telefonen."</string>
- <!-- no translation found for ota_hfa_activation_title (2234246934160473981) -->
- <skip />
- <!-- no translation found for ota_hfa_activation_dialog_message (8092479227918463415) -->
- <skip />
+ <string name="ota_hfa_activation_title" msgid="2234246934160473981">"Aktiveras ..."</string>
+ <string name="ota_hfa_activation_dialog_message" msgid="8092479227918463415">"Din mobila datatjänst aktiveras av mobilen.\n\nDetta kan ta upp till fem minuter."</string>
<string name="ota_skip_activation_dialog_title" msgid="2943366608272261306">"Vill du hoppa över aktiveringen?"</string>
<string name="ota_skip_activation_dialog_message" msgid="2440770373498870550">"Om du hoppar över aktiveringen kan du inte ringa samtal eller ansluta till mobila datanätverk (men du kan ansluta till Wi-Fi-nätverk). Du kommer att påminnas om att aktivera telefonen varje gång du sätter på den, tills du har aktiverat den."</string>
<string name="ota_skip_activation_dialog_skip_label" msgid="3458532775091563208">"Hoppa över"</string>
@@ -587,8 +585,7 @@
<string name="respond_via_sms_setting_title_2" msgid="6104662227299493906">"Redigera snabbsvar"</string>
<string name="respond_via_sms_setting_summary" msgid="9150281183930613065"></string>
<string name="respond_via_sms_edittext_dialog_title" msgid="20379890418289778">"Snabbsvar"</string>
- <!-- no translation found for respond_via_sms_menu_reset_default_activity (4029277930090150223) -->
- <skip />
+ <string name="respond_via_sms_menu_reset_default_activity" msgid="4029277930090150223">"Återställ standardinställningar"</string>
<string name="respond_via_sms_confirmation_format" msgid="7229149977515784269">"Meddelandet har skickats till <xliff:g id="PHONE_NUMBER">%s</xliff:g>."</string>
<string name="description_image_button_one" msgid="5502718871331943463">"ett"</string>
<string name="description_image_button_two" msgid="4903738528222924522">"två"</string>
diff --git a/res/values-sw/strings.xml b/res/values-sw/strings.xml
index 1ee8824..6b602e2 100644
--- a/res/values-sw/strings.xml
+++ b/res/values-sw/strings.xml
@@ -36,7 +36,7 @@
<string name="audio_mode_earpiece" msgid="4156527186373869107">"Kipaza sauti cha kichwani"</string>
<string name="audio_mode_wired_headset" msgid="1465350758489175975">"Viskizi vya maskio pasiwaya"</string>
<string name="audio_mode_bluetooth" msgid="3047641300848211128">"Bluetooth"</string>
- <string name="wait_prompt_str" msgid="7601815427707856238">"Tuma toni zinazofuata? \n"</string>
+ <string name="wait_prompt_str" msgid="7601815427707856238">"Ungependa kutuma toni zifuatazo? \n"</string>
<string name="pause_prompt_str" msgid="1789964702154314806">"Inatuma toni\n"</string>
<string name="send_button" msgid="4106860097497818751">"Tuma"</string>
<string name="pause_prompt_yes" msgid="3564467212025151797">"Ndiyo"</string>
@@ -297,16 +297,16 @@
</string-array>
<string name="cdma_activate_device" msgid="3793805892364814518">"Wezesha kifaa"</string>
<string name="cdma_lte_data_service" msgid="4255018217292548962">"Sanidi huduma ya data"</string>
- <string name="fdn" msgid="7878832555095183202">"Nambari zilizopangiwa za Upigaji"</string>
+ <string name="fdn" msgid="7878832555095183202">"Nambari za kupiga zisizobadilishwa"</string>
<string name="manage_fdn_list" msgid="8777755791892122369">"Orodha ya FDN"</string>
<string name="fdn_activation" msgid="2156479741307463576">"Uwezeshaji wa FDN"</string>
<string name="fdn_enabled" msgid="5238109009915521240">"Nambari za upigaji simu zilizobanwa zimelemazwa"</string>
<string name="fdn_disabled" msgid="4700049736675368279">"Nambari za upigaji simu zilizobanwa zimelemazwa"</string>
- <string name="enable_fdn" msgid="3740191529180493851">"Wezesha FDN"</string>
+ <string name="enable_fdn" msgid="3740191529180493851">"Washa FDN"</string>
<string name="disable_fdn" msgid="7944020890722540616">"Lemaza FDN"</string>
<string name="change_pin2" msgid="2153563695382176676">"Badilisha PIN2"</string>
<string name="enable_fdn_ok" msgid="7215588870329688132">"Lemaza FDN"</string>
- <string name="disable_fdn_ok" msgid="5727046928930740173">"Wezesha FDN"</string>
+ <string name="disable_fdn_ok" msgid="5727046928930740173">"Washa FDN"</string>
<string name="sum_fdn" msgid="1959399454900272878">"Dhibiti nambari Za Upigaji simu Zilizobanwa"</string>
<string name="sum_fdn_change_pin" msgid="6666549734792827932">"Badilisha nenosiri la kufikia FDN"</string>
<string name="sum_fdn_manage_list" msgid="8431088265332628316">"Dhibiti orodha ya nambari ya simu"</string>
@@ -335,9 +335,9 @@
<string name="pin2_invalid" msgid="5470854099230755944">"FDN haikusasishwa kwa sababu uliweka PIN isiyo sahihi."</string>
<string name="fdn_invalid_number" msgid="1494755047900009147">"FDN haikusasishwa kwa sababu namba haiwezi kuzidisha herufi 20."</string>
<string name="pin2_or_fdn_invalid" msgid="6025144083384701197">"FDN haikusasishwa. PIN2 haikuwa sahihi, au namba ya simu ilikataliwa."</string>
- <string name="simContacts_emptyLoading" msgid="2203331234764498011">"Inasoma kutoka kwa SIM kadi"</string>
- <string name="simContacts_empty" msgid="5270660846489561932">"Hakuna anwani kwenye kadi yako ya SIM."</string>
- <string name="simContacts_title" msgid="1861472842524839921">"Chagua anwani za kuagiza"</string>
+ <string name="simContacts_emptyLoading" msgid="2203331234764498011">"Inasoma kutoka kwa SIM kadi…"</string>
+ <string name="simContacts_empty" msgid="5270660846489561932">"Hakuna anwani kwenye SIM kadi yako."</string>
+ <string name="simContacts_title" msgid="1861472842524839921">"Chagua anwani za kuingiza"</string>
<string name="simContacts_airplaneMode" msgid="1846161429087789936">"Ili kuleta anwani kutoka kwa SIM kadi, kwanza zima hali ya Ndege."</string>
<string name="enable_pin" msgid="5422767284133234860">"Wezesha/zima nenosiri la SIM"</string>
<string name="change_pin" msgid="9174186126330785343">"Badilisha nenosiri la SIM"</string>
@@ -450,10 +450,8 @@
<string name="network_message" msgid="4483886461245213802">"Ujumbe wa mtandao"</string>
<string name="ota_title_activate" msgid="8616918561356194398">"Wezesha simu yako"</string>
<string name="ota_touch_activate" msgid="6553212803262586244">"Simu maalum inahitaji kupigwa ili kuamilisha huduma ya simu yako. \n\n Baada ya kubonyeza \"Amilisha\", sikiliza maagizo yaliyotolewa ili kuamilisha simu yako."</string>
- <!-- no translation found for ota_hfa_activation_title (2234246934160473981) -->
- <skip />
- <!-- no translation found for ota_hfa_activation_dialog_message (8092479227918463415) -->
- <skip />
+ <string name="ota_hfa_activation_title" msgid="2234246934160473981">"Inawasha..."</string>
+ <string name="ota_hfa_activation_dialog_message" msgid="8092479227918463415">"Simu inawasha huduma yako ya data kwa vifaa vya mkononi.\n \n Hii inaweza kuchukua hadi dakika 5."</string>
<string name="ota_skip_activation_dialog_title" msgid="2943366608272261306">"Ruka uwezeshaji?"</string>
<string name="ota_skip_activation_dialog_message" msgid="2440770373498870550">"Kama utaruka kuwezesha, hauwezi kupiga simu au kuunganisha kwa mitandao ya data ya simu (ingawaje unaweza kuunganisha kwa mitandao-hewa). Hadi uiwezeshe simu yako, utaulizwa uiwezeshe kila utakapoiwasha."</string>
<string name="ota_skip_activation_dialog_skip_label" msgid="3458532775091563208">"Ruka"</string>
@@ -573,16 +571,15 @@
<string name="sip_always_send_keepalive" msgid="8192080724632877132">"Tuma kila wakati"</string>
<string name="not_voice_capable" msgid="2739898841461577811">"Upigaji simu za sauti hauhimiliwi"</string>
<string name="respond_via_sms_canned_response_1" msgid="2461606462788380215">"Siwezi kuongea sasa. Kuna nini?"</string>
- <string name="respond_via_sms_canned_response_2" msgid="4074450431532859214">"Nitakupigia mara moja."</string>
+ <string name="respond_via_sms_canned_response_2" msgid="4074450431532859214">"Nitakupigia sasa hivi."</string>
<string name="respond_via_sms_canned_response_3" msgid="3496079065723960450">"Nitakupigia baadaye."</string>
- <string name="respond_via_sms_canned_response_4" msgid="1698989243040062190">"Siwezi kuongea sasa. Nipigie baadaye?"</string>
+ <string name="respond_via_sms_canned_response_4" msgid="1698989243040062190">"Siwezi kuongea sasa. Nipigie baadaye"</string>
<string name="respond_via_sms_custom_message" msgid="6158880869935281078">"Andika yako binafsi..."</string>
<string name="respond_via_sms_setting_title" msgid="3754000371039709383">"Majibu ya haraka"</string>
<string name="respond_via_sms_setting_title_2" msgid="6104662227299493906">"Hariri majibu ya haraka"</string>
<string name="respond_via_sms_setting_summary" msgid="9150281183930613065"></string>
<string name="respond_via_sms_edittext_dialog_title" msgid="20379890418289778">"Majibu ya haraka"</string>
- <!-- no translation found for respond_via_sms_menu_reset_default_activity (4029277930090150223) -->
- <skip />
+ <string name="respond_via_sms_menu_reset_default_activity" msgid="4029277930090150223">"Rejesha chaguo-msingi"</string>
<string name="respond_via_sms_confirmation_format" msgid="7229149977515784269">"Ujumbe uliotumwa kwa <xliff:g id="PHONE_NUMBER">%s</xliff:g> ."</string>
<string name="description_image_button_one" msgid="5502718871331943463">"moja"</string>
<string name="description_image_button_two" msgid="4903738528222924522">"mbili"</string>
@@ -608,8 +605,8 @@
<string name="voicemail_notification_ringtone_title" msgid="2609519527849101590">"Sauti"</string>
<string name="default_notification_description" msgid="78174796906240970">"Sauti chaguo-msingi (<xliff:g id="DEFAULT_SOUND_TITLE">%1$s</xliff:g>)"</string>
<string name="ringtone_title" msgid="6374978286202084684">"Mlio wa simu"</string>
- <string name="vibrate_on_ring_title" msgid="9197564612065258960">"Tetema wakati wa kuita"</string>
+ <string name="vibrate_on_ring_title" msgid="9197564612065258960">"Tetema wakati wa kulia"</string>
<string name="dtmf_tone_enable_title" msgid="827601042915852989">"Toa sauti vitufe vya kupiga vinapoguswa"</string>
<string name="dial_pad_autocomplete" msgid="494525952035761075">"Jaza nambari kiotomatiki"</string>
- <string name="preference_category_ringtone" msgid="5197960752529332721">"Malio wa simu na Mtetemo"</string>
+ <string name="preference_category_ringtone" msgid="5197960752529332721">"Mlio wa simu na Mtetemo"</string>
</resources>
diff --git a/res/values-th/strings.xml b/res/values-th/strings.xml
index 367a240..4cc609c 100644
--- a/res/values-th/strings.xml
+++ b/res/values-th/strings.xml
@@ -450,10 +450,8 @@
<string name="network_message" msgid="4483886461245213802">"ข้อความจากเครือข่าย"</string>
<string name="ota_title_activate" msgid="8616918561356194398">"เปิดการใช้งานโทรศัพท์ของคุณ"</string>
<string name="ota_touch_activate" msgid="6553212803262586244">"ต้องทำการโทรพิเศษเพื่อเปิดใช้บริการโทรศัพท์ของคุณ \n\nหลังจากกด “เปิดการใช้งาน” ให้ฟังคำแนะนำเพื่อเปิดใช้บริการโทรศัพท์ของคุณ"</string>
- <!-- no translation found for ota_hfa_activation_title (2234246934160473981) -->
- <skip />
- <!-- no translation found for ota_hfa_activation_dialog_message (8092479227918463415) -->
- <skip />
+ <string name="ota_hfa_activation_title" msgid="2234246934160473981">"กำลังเปิดใช้งาน..."</string>
+ <string name="ota_hfa_activation_dialog_message" msgid="8092479227918463415">"โทรศัพท์กำลังเปิดใช้งานบริการข้อมูลโทรศัพท์มือถือ\n\nอาจใช้เวลาถึง 5 นาที"</string>
<string name="ota_skip_activation_dialog_title" msgid="2943366608272261306">"ข้ามการเปิดใช้งานหรือไม่"</string>
<string name="ota_skip_activation_dialog_message" msgid="2440770373498870550">"หากคุณข้ามการเปิดใช้งาน คุณจะโทรออกหรือเชื่อมต่อเครือข่ายข้อมูลมือถือไม่ได้ (แม้จะเชื่อมต่อเครือข่าย WiFi ได้ก็ตาม) และระบบจะขอให้คุณเปิดใช้งานทุกครั้งที่คุณเปิดเครื่องจนกว่าคุณจะเปิดใช้งานโทรศัพท์"</string>
<string name="ota_skip_activation_dialog_skip_label" msgid="3458532775091563208">"ข้าม"</string>
@@ -581,8 +579,7 @@
<string name="respond_via_sms_setting_title_2" msgid="6104662227299493906">"แก้ไขคำตอบด่วน"</string>
<string name="respond_via_sms_setting_summary" msgid="9150281183930613065"></string>
<string name="respond_via_sms_edittext_dialog_title" msgid="20379890418289778">"คำตอบด่วน"</string>
- <!-- no translation found for respond_via_sms_menu_reset_default_activity (4029277930090150223) -->
- <skip />
+ <string name="respond_via_sms_menu_reset_default_activity" msgid="4029277930090150223">"คืนค่าเริ่มต้น"</string>
<string name="respond_via_sms_confirmation_format" msgid="7229149977515784269">"ส่งข้อความไปยัง <xliff:g id="PHONE_NUMBER">%s</xliff:g> แล้ว"</string>
<string name="description_image_button_one" msgid="5502718871331943463">"หนึ่ง"</string>
<string name="description_image_button_two" msgid="4903738528222924522">"สอง"</string>
diff --git a/res/values-tl/strings.xml b/res/values-tl/strings.xml
index 844a6e0..ff1bc3b 100644
--- a/res/values-tl/strings.xml
+++ b/res/values-tl/strings.xml
@@ -450,10 +450,8 @@
<string name="network_message" msgid="4483886461245213802">"Mensahe ng network"</string>
<string name="ota_title_activate" msgid="8616918561356194398">"I-activate ang iyong telepono"</string>
<string name="ota_touch_activate" msgid="6553212803262586244">"Kailangang maisagawa ang isang espesyal na tawag upang i-activate ang iyong serbisyo ng telepono. \n\nPagkatapos pindutin ang “I-activate”, makinig sa mga ibinigay na tagubilin upang i-activate ang iyong telepono."</string>
- <!-- no translation found for ota_hfa_activation_title (2234246934160473981) -->
- <skip />
- <!-- no translation found for ota_hfa_activation_dialog_message (8092479227918463415) -->
- <skip />
+ <string name="ota_hfa_activation_title" msgid="2234246934160473981">"Ina-activate..."</string>
+ <string name="ota_hfa_activation_dialog_message" msgid="8092479227918463415">"Ina-activate ng iyong telepono ang iyong serbisyo ng data sa mobile.\n\nMaaaring magtagal ito nang hanggang 5 minuto."</string>
<string name="ota_skip_activation_dialog_title" msgid="2943366608272261306">"Laktawan ang pag-activate?"</string>
<string name="ota_skip_activation_dialog_message" msgid="2440770373498870550">"Kung lalaktawan mo ang pag-activate, hindi ka makakagawa ng mga tawag o makakakonekta sa mga mobile data network (ngunit makakakonekta ka sa mga Wi-Fi network). Hanggang sa i-activate mo ang iyong telepono, hihilingin sa iyong i-activate ito sa bawat pagkakataon na i-on mo ito."</string>
<string name="ota_skip_activation_dialog_skip_label" msgid="3458532775091563208">"Laktawan"</string>
@@ -581,8 +579,7 @@
<string name="respond_via_sms_setting_title_2" msgid="6104662227299493906">"I-edit ang mga mabilisang tugon"</string>
<string name="respond_via_sms_setting_summary" msgid="9150281183930613065"></string>
<string name="respond_via_sms_edittext_dialog_title" msgid="20379890418289778">"Mabilisang tugon"</string>
- <!-- no translation found for respond_via_sms_menu_reset_default_activity (4029277930090150223) -->
- <skip />
+ <string name="respond_via_sms_menu_reset_default_activity" msgid="4029277930090150223">"Ibalik ang mga default"</string>
<string name="respond_via_sms_confirmation_format" msgid="7229149977515784269">"Naipadala ang mensahe sa <xliff:g id="PHONE_NUMBER">%s</xliff:g>."</string>
<string name="description_image_button_one" msgid="5502718871331943463">"isa"</string>
<string name="description_image_button_two" msgid="4903738528222924522">"dalawa"</string>
diff --git a/res/values-tr/strings.xml b/res/values-tr/strings.xml
index 836ff69..86ddcb7 100644
--- a/res/values-tr/strings.xml
+++ b/res/values-tr/strings.xml
@@ -450,10 +450,8 @@
<string name="network_message" msgid="4483886461245213802">"Ağ mesajı"</string>
<string name="ota_title_activate" msgid="8616918561356194398">"Telefonunuzu aktive edin"</string>
<string name="ota_touch_activate" msgid="6553212803262586244">"Telefon hizmetinizin aktive edilmesi için özel bir çağrı yapılması gerekiyor. \n\n“Aktive Et”e bastıktan sonra, telefonunuzun aktive edilmesi için sağlanan talimatları dinleyin."</string>
- <!-- no translation found for ota_hfa_activation_title (2234246934160473981) -->
- <skip />
- <!-- no translation found for ota_hfa_activation_dialog_message (8092479227918463415) -->
- <skip />
+ <string name="ota_hfa_activation_title" msgid="2234246934160473981">"Etkinleştiriliyor..."</string>
+ <string name="ota_hfa_activation_dialog_message" msgid="8092479227918463415">"Telefon, mobil veri hizmetinizi etkinleştiriyor.\n\nBu işlem 5 dakika kadar sürebilir."</string>
<string name="ota_skip_activation_dialog_title" msgid="2943366608272261306">"Etkinleştirme atlansın mı?"</string>
<string name="ota_skip_activation_dialog_message" msgid="2440770373498870550">"Etkinleştirmeyi atlarsanız, arama yapamaz veya mobil veri ağlarına bağlanamazsınız (yine de Kablosuz ağlara bağlanabilirsiniz). Telefonunuzu etkinleştirinceye kadar, telefonu her açışınızda ürünü etkinleştirip etkinleştirmeyeceğiniz sorulur."</string>
<string name="ota_skip_activation_dialog_skip_label" msgid="3458532775091563208">"Atla"</string>
@@ -572,7 +570,7 @@
<string name="sip_system_decide" msgid="368030746310423471">"Otomatik"</string>
<string name="sip_always_send_keepalive" msgid="8192080724632877132">"Her zaman gönder"</string>
<string name="not_voice_capable" msgid="2739898841461577811">"Sesli arama desteklenmiyor"</string>
- <string name="respond_via_sms_canned_response_1" msgid="2461606462788380215">"Şimdi konuşamam. Ne oldu?"</string>
+ <string name="respond_via_sms_canned_response_1" msgid="2461606462788380215">"Şimdi konuşamam. Konu nedir?"</string>
<string name="respond_via_sms_canned_response_2" msgid="4074450431532859214">"Seni hemen geri arayacağım."</string>
<string name="respond_via_sms_canned_response_3" msgid="3496079065723960450">"Seni daha sonra ararım."</string>
<string name="respond_via_sms_canned_response_4" msgid="1698989243040062190">"Şimdi konuşamam. Daha sonra arar mısın?"</string>
@@ -581,8 +579,7 @@
<string name="respond_via_sms_setting_title_2" msgid="6104662227299493906">"Hızlı yanıtları düzenle"</string>
<string name="respond_via_sms_setting_summary" msgid="9150281183930613065"></string>
<string name="respond_via_sms_edittext_dialog_title" msgid="20379890418289778">"Hızlı yanıt"</string>
- <!-- no translation found for respond_via_sms_menu_reset_default_activity (4029277930090150223) -->
- <skip />
+ <string name="respond_via_sms_menu_reset_default_activity" msgid="4029277930090150223">"Varsayılanları geri yükle"</string>
<string name="respond_via_sms_confirmation_format" msgid="7229149977515784269">"Mesaj, <xliff:g id="PHONE_NUMBER">%s</xliff:g> numaralı telefona gönderildi."</string>
<string name="description_image_button_one" msgid="5502718871331943463">"bir"</string>
<string name="description_image_button_two" msgid="4903738528222924522">"iki"</string>
diff --git a/res/values-uk/strings.xml b/res/values-uk/strings.xml
index da58606..a299d52 100644
--- a/res/values-uk/strings.xml
+++ b/res/values-uk/strings.xml
@@ -450,10 +450,8 @@
<string name="network_message" msgid="4483886461245213802">"Повідомлення мережі"</string>
<string name="ota_title_activate" msgid="8616918561356194398">"Активуйте свій телефон"</string>
<string name="ota_touch_activate" msgid="6553212803262586244">"Щоб активувати службу вашого тел., треба зробити спеціальний дзвінок. \n\nНатиснувши \"Активувати\", прослухайте інструкції, надані для активації телефону."</string>
- <!-- no translation found for ota_hfa_activation_title (2234246934160473981) -->
- <skip />
- <!-- no translation found for ota_hfa_activation_dialog_message (8092479227918463415) -->
- <skip />
+ <string name="ota_hfa_activation_title" msgid="2234246934160473981">"Активація…"</string>
+ <string name="ota_hfa_activation_dialog_message" msgid="8092479227918463415">"Телефон активує службу мобільного передавання даних.\n\nЦе може тривати до 5 хвилин."</string>
<string name="ota_skip_activation_dialog_title" msgid="2943366608272261306">"Пропуст. активацію?"</string>
<string name="ota_skip_activation_dialog_message" msgid="2440770373498870550">"Якщо ви пропустите активацію, то не зможете розміщ. виклик чи підключ. до даних моб. мереж (хоча можете підключ. до мереж Wi-Fi). Вас проситимуть активувати тел. щоразу, коли ви його вмикаєте, поки це не викон."</string>
<string name="ota_skip_activation_dialog_skip_label" msgid="3458532775091563208">"Пропуст."</string>
@@ -581,8 +579,7 @@
<string name="respond_via_sms_setting_title_2" msgid="6104662227299493906">"Редагувати швидкі відповіді"</string>
<string name="respond_via_sms_setting_summary" msgid="9150281183930613065"></string>
<string name="respond_via_sms_edittext_dialog_title" msgid="20379890418289778">"Швидка відповідь"</string>
- <!-- no translation found for respond_via_sms_menu_reset_default_activity (4029277930090150223) -->
- <skip />
+ <string name="respond_via_sms_menu_reset_default_activity" msgid="4029277930090150223">"За умовчанням"</string>
<string name="respond_via_sms_confirmation_format" msgid="7229149977515784269">"Повідомлення надіслано на номер <xliff:g id="PHONE_NUMBER">%s</xliff:g>."</string>
<string name="description_image_button_one" msgid="5502718871331943463">"один"</string>
<string name="description_image_button_two" msgid="4903738528222924522">"два"</string>
diff --git a/res/values-vi/strings.xml b/res/values-vi/strings.xml
index a3ee0d8..7b589e9 100644
--- a/res/values-vi/strings.xml
+++ b/res/values-vi/strings.xml
@@ -450,10 +450,8 @@
<string name="network_message" msgid="4483886461245213802">"Thông báo của mạng"</string>
<string name="ota_title_activate" msgid="8616918561356194398">"Kích hoạt điện thoại của bạn"</string>
<string name="ota_touch_activate" msgid="6553212803262586244">"Bạn cần phải thực hiện cuộc gọi đặc biệt để kích hoạt dịch vụ điện thoại của mình. \n\nSau khi nhấn “Kích hoạt”, nghe hướng dẫn được cung cấp để kích hoạt điện thoại của bạn."</string>
- <!-- no translation found for ota_hfa_activation_title (2234246934160473981) -->
- <skip />
- <!-- no translation found for ota_hfa_activation_dialog_message (8092479227918463415) -->
- <skip />
+ <string name="ota_hfa_activation_title" msgid="2234246934160473981">"Đang kích hoạt..."</string>
+ <string name="ota_hfa_activation_dialog_message" msgid="8092479227918463415">"Điện thoại đang kích hoạt dịch vụ dữ liệu di động của bạn.\n\nThao tác này có thể mất tối đa 5 phút."</string>
<string name="ota_skip_activation_dialog_title" msgid="2943366608272261306">"Bỏ qua kích hoạt?"</string>
<string name="ota_skip_activation_dialog_message" msgid="2440770373498870550">"Nếu bạn bỏ qua kích hoạt, bạn không thể thực hiện cuộc gọi hoặc kết nối với mạng dữ liệu dành cho điện thoại di động (mặc dù bạn có thể kết nối với mạng Wi-Fi). Cho tới khi bạn kích hoạt điện thoại của mình, bạn được yêu cầu kích hoạt điện thoại mỗi lần bạn bật điện thoại."</string>
<string name="ota_skip_activation_dialog_skip_label" msgid="3458532775091563208">"Bỏ qua"</string>
@@ -581,8 +579,7 @@
<string name="respond_via_sms_setting_title_2" msgid="6104662227299493906">"Chỉnh sửa trả lời nhanh"</string>
<string name="respond_via_sms_setting_summary" msgid="9150281183930613065"></string>
<string name="respond_via_sms_edittext_dialog_title" msgid="20379890418289778">"Trả lời nhanh"</string>
- <!-- no translation found for respond_via_sms_menu_reset_default_activity (4029277930090150223) -->
- <skip />
+ <string name="respond_via_sms_menu_reset_default_activity" msgid="4029277930090150223">"Khôi phục mặc định"</string>
<string name="respond_via_sms_confirmation_format" msgid="7229149977515784269">"Đã gửi tin nhắn tới <xliff:g id="PHONE_NUMBER">%s</xliff:g>."</string>
<string name="description_image_button_one" msgid="5502718871331943463">"một"</string>
<string name="description_image_button_two" msgid="4903738528222924522">"hai"</string>
diff --git a/res/values-zh-rCN/strings.xml b/res/values-zh-rCN/strings.xml
index 35410a0..40625ec 100644
--- a/res/values-zh-rCN/strings.xml
+++ b/res/values-zh-rCN/strings.xml
@@ -80,21 +80,21 @@
<string name="sum_cfu_enabled_indicator" msgid="4014187342724130197">"转接所有来电"</string>
<string name="sum_cfu_enabled" msgid="2450052502198827927">"将所有来电转接到 <xliff:g id="PHONENUMBER">{0}</xliff:g>"</string>
<string name="sum_cfu_enabled_no_number" msgid="6591985777096823616">"未提供电话号码"</string>
- <string name="sum_cfu_disabled" msgid="3698472522160364904">"已停用"</string>
+ <string name="sum_cfu_disabled" msgid="3698472522160364904">"未启用"</string>
<string name="labelCFB" msgid="218938523102207587">"占线时转接"</string>
<string name="messageCFB" msgid="3711089705936187129">"占线时的转接号码"</string>
<string name="sum_cfb_enabled" msgid="5984198104833116690">"转接到 <xliff:g id="PHONENUMBER">{0}</xliff:g>"</string>
- <string name="sum_cfb_disabled" msgid="227440009979537651">"已停用"</string>
+ <string name="sum_cfb_disabled" msgid="227440009979537651">"未启用"</string>
<string name="disable_cfb_forbidden" msgid="3506984333877998061">"您的运营商不支持在手机占线时停用来电转接功能。"</string>
<string name="labelCFNRy" msgid="3646316323834351390">"无人接听时转接"</string>
<string name="messageCFNRy" msgid="672317899884380374">"无人接听时的转接号码"</string>
<string name="sum_cfnry_enabled" msgid="6955775691317662910">"转接到 <xliff:g id="PHONENUMBER">{0}</xliff:g>"</string>
- <string name="sum_cfnry_disabled" msgid="8422350929957344729">"已停用"</string>
+ <string name="sum_cfnry_disabled" msgid="8422350929957344729">"未启用"</string>
<string name="disable_cfnry_forbidden" msgid="4308233959150658058">"您的运营商不支持在手机无人接听时停用来电转接功能。"</string>
<string name="labelCFNRc" msgid="47183615370850000">"无法接通时转接"</string>
<string name="messageCFNRc" msgid="6380695421020295119">"无法接通时的转接号码"</string>
<string name="sum_cfnrc_enabled" msgid="7010898346095497421">"转接到 <xliff:g id="PHONENUMBER">{0}</xliff:g>"</string>
- <string name="sum_cfnrc_disabled" msgid="7222141261321276464">"已停用"</string>
+ <string name="sum_cfnrc_disabled" msgid="7222141261321276464">"未启用"</string>
<string name="disable_cfnrc_forbidden" msgid="5646361343094064333">"您的运营商不支持在手机无法接通时停用来电转接功能。"</string>
<string name="updating_title" msgid="6146755386174019046">"通话设置"</string>
<string name="error_updating_title" msgid="7970259216988931777">"通话设置出错"</string>
@@ -301,14 +301,14 @@
<string name="manage_fdn_list" msgid="8777755791892122369">"固定拨号列表"</string>
<string name="fdn_activation" msgid="2156479741307463576">"激活固定拨号"</string>
<string name="fdn_enabled" msgid="5238109009915521240">"已启用固定拨号"</string>
- <string name="fdn_disabled" msgid="4700049736675368279">"已停用固定拨号"</string>
+ <string name="fdn_disabled" msgid="4700049736675368279">"未启用固定拨号"</string>
<string name="enable_fdn" msgid="3740191529180493851">"启用固定拨号"</string>
- <string name="disable_fdn" msgid="7944020890722540616">"禁用固定拨号"</string>
+ <string name="disable_fdn" msgid="7944020890722540616">"停用固定拨号"</string>
<string name="change_pin2" msgid="2153563695382176676">"更改 PIN2"</string>
- <string name="enable_fdn_ok" msgid="7215588870329688132">"禁用固定拨号"</string>
+ <string name="enable_fdn_ok" msgid="7215588870329688132">"停用固定拨号"</string>
<string name="disable_fdn_ok" msgid="5727046928930740173">"启用固定拨号"</string>
<string name="sum_fdn" msgid="1959399454900272878">"管理固定拨号"</string>
- <string name="sum_fdn_change_pin" msgid="6666549734792827932">"更改为访问固定拨号设置的 PIN"</string>
+ <string name="sum_fdn_change_pin" msgid="6666549734792827932">"更改使用固定拨号所需的 PIN 码"</string>
<string name="sum_fdn_manage_list" msgid="8431088265332628316">"管理手机号码列表"</string>
<string name="voice_privacy" msgid="3776841382844614716">"语音隐私权"</string>
<string name="voice_privacy_summary" msgid="3159383389833516214">"启用增强型隐秘模式"</string>
@@ -352,7 +352,7 @@
<string name="enable_sim_pin" msgid="5803702443844458831">"启用 SIM 卡 PIN"</string>
<string name="enable_in_progress" msgid="3695303775100109650">"请稍候..."</string>
<string name="enable_pin_ok" msgid="9166061915030865848">"SIM 卡 PIN 已启用。"</string>
- <string name="disable_pin_ok" msgid="5596999379593924850">"SIM 卡 PIN 已停用。"</string>
+ <string name="disable_pin_ok" msgid="5596999379593924850">"未启用 SIM 卡 PIN 码。"</string>
<string name="pin_failed" msgid="2298841192582192277">"键入的 PIN 有误。"</string>
<string name="pin_changed" msgid="4365538014588501049">"已成功更改 SIM 卡 PIN。"</string>
<string name="puk_requested" msgid="3898394204193202803">"密码不正确,SIM 已锁定!需要 PUK2。"</string>
@@ -436,8 +436,8 @@
<string name="hac_mode_title" msgid="8740268574688743289">"助听器"</string>
<string name="hac_mode_summary" msgid="6833851160514929341">"启用助听器兼容模式"</string>
<string-array name="tty_mode_entries">
- <item msgid="512950011423868021">"TTY 已停用"</item>
- <item msgid="3971695875449640648">"TTY 已满"</item>
+ <item msgid="512950011423868021">"未启用 TTY"</item>
+ <item msgid="3971695875449640648">"TTY 完整"</item>
<item msgid="1937509904407445684">"TTY HCO"</item>
<item msgid="5644925873488772224">"TTY VCO"</item>
</string-array>
@@ -450,10 +450,8 @@
<string name="network_message" msgid="4483886461245213802">"网络讯息"</string>
<string name="ota_title_activate" msgid="8616918561356194398">"激活您的手机"</string>
<string name="ota_touch_activate" msgid="6553212803262586244">"需要拨打特别号码才能激活您的手机服务。\n\n在按下“激活”后,按照语音提示激活您的手机。"</string>
- <!-- no translation found for ota_hfa_activation_title (2234246934160473981) -->
- <skip />
- <!-- no translation found for ota_hfa_activation_dialog_message (8092479227918463415) -->
- <skip />
+ <string name="ota_hfa_activation_title" msgid="2234246934160473981">"正在激活…"</string>
+ <string name="ota_hfa_activation_dialog_message" msgid="8092479227918463415">"手机正在激活您的移动数据网络服务。\n\n此过程最多5分钟就能完成。"</string>
<string name="ota_skip_activation_dialog_title" msgid="2943366608272261306">"略过激活步骤?"</string>
<string name="ota_skip_activation_dialog_message" msgid="2440770373498870550">"如果您略过激活步骤,就无法拨打电话或连接到移动数据网络(不过您可以连接到 WLAN 网络)。如果您不激活手机,每次开机时都会收到激活提示。"</string>
<string name="ota_skip_activation_dialog_skip_label" msgid="3458532775091563208">"跳过"</string>
@@ -499,15 +497,15 @@
<string name="contactPhoto" msgid="4713193418046639466">"联系人照片"</string>
<string name="goPrivate" msgid="865837794424530980">"私聊"</string>
<string name="selectContact" msgid="781975788478987237">"选择联系人"</string>
- <string name="sip_settings" msgid="6699045718560859691">"互联网通话设置"</string>
+ <string name="sip_settings" msgid="6699045718560859691">"互联网电话设置"</string>
<string name="sip_accounts" msgid="2097054001288457163">"互联网电话 (SIP) 帐户"</string>
<string name="sip_accounts_title" msgid="1212889069281054570">"帐户"</string>
<string name="sip_receive_calls" msgid="5635685570889971559">"接听来电"</string>
<string name="sip_receive_calls_summary" msgid="8403613238633679184">"会缩短电池待机时间"</string>
<string name="sip_call_options_title" msgid="27433718808839672">"使用互联网电话"</string>
- <string name="sip_call_options_wifi_only_title" msgid="145572394529090811">"使用互联网通话(仅限 WLAN)"</string>
+ <string name="sip_call_options_wifi_only_title" msgid="145572394529090811">"使用互联网电话(仅限 WLAN)"</string>
<string name="sip_call_options_entry_1" msgid="6556668894178520760">"数据网络接通时适用于所有通话"</string>
- <string name="sip_call_options_entry_2" msgid="6789764029719494361">"仅适用于互联网通话"</string>
+ <string name="sip_call_options_entry_2" msgid="6789764029719494361">"仅适用于互联网电话"</string>
<string name="sip_call_options_entry_3" msgid="7474809001402649185">"每次呼叫时询问"</string>
<string name="sip_call_options_wifi_only_entry_1" msgid="7423523864471650069">"适用于所有通话"</string>
<string name="pick_outgoing_call_phone_type" msgid="5622916534828338675">"拨打电话"</string>
@@ -581,8 +579,7 @@
<string name="respond_via_sms_setting_title_2" msgid="6104662227299493906">"修改快速回复"</string>
<string name="respond_via_sms_setting_summary" msgid="9150281183930613065"></string>
<string name="respond_via_sms_edittext_dialog_title" msgid="20379890418289778">"快速回复"</string>
- <!-- no translation found for respond_via_sms_menu_reset_default_activity (4029277930090150223) -->
- <skip />
+ <string name="respond_via_sms_menu_reset_default_activity" msgid="4029277930090150223">"还原默认设置"</string>
<string name="respond_via_sms_confirmation_format" msgid="7229149977515784269">"讯息已发送至 <xliff:g id="PHONE_NUMBER">%s</xliff:g>。"</string>
<string name="description_image_button_one" msgid="5502718871331943463">"一"</string>
<string name="description_image_button_two" msgid="4903738528222924522">"二"</string>
diff --git a/res/values-zh-rHK/strings.xml b/res/values-zh-rHK/strings.xml
index 5fd33f7..fdeea05 100644
--- a/res/values-zh-rHK/strings.xml
+++ b/res/values-zh-rHK/strings.xml
@@ -456,10 +456,8 @@
<string name="network_message" msgid="4483886461245213802">"網絡訊息"</string>
<string name="ota_title_activate" msgid="8616918561356194398">"啟用您的手機"</string>
<string name="ota_touch_activate" msgid="6553212803262586244">"如要啟用手機服務,您必須撥打一個特別電話。\n\n按「啟用」 後,請聽取手機啟用說明。"</string>
- <!-- no translation found for ota_hfa_activation_title (2234246934160473981) -->
- <skip />
- <!-- no translation found for ota_hfa_activation_dialog_message (8092479227918463415) -->
- <skip />
+ <string name="ota_hfa_activation_title" msgid="2234246934160473981">"正在啟用…"</string>
+ <string name="ota_hfa_activation_dialog_message" msgid="8092479227918463415">"手機正在啟用流動數據服務。\n\n這個程序最多需時 5 分鐘。"</string>
<string name="ota_skip_activation_dialog_title" msgid="2943366608272261306">"是否略過啟用?"</string>
<string name="ota_skip_activation_dialog_message" msgid="2440770373498870550">"如果略過啟用程序,那麼您就無法撥打電話或是連上行動數據網絡 (雖然可連上 Wi-Fi 網絡)。除非您已啟用手機,否則每次開機時,系統都會要求您啟用手機。"</string>
<string name="ota_skip_activation_dialog_skip_label" msgid="3458532775091563208">"略過"</string>
@@ -587,8 +585,7 @@
<string name="respond_via_sms_setting_title_2" msgid="6104662227299493906">"編輯快速回應"</string>
<string name="respond_via_sms_setting_summary" msgid="9150281183930613065"></string>
<string name="respond_via_sms_edittext_dialog_title" msgid="20379890418289778">"快速回應"</string>
- <!-- no translation found for respond_via_sms_menu_reset_default_activity (4029277930090150223) -->
- <skip />
+ <string name="respond_via_sms_menu_reset_default_activity" msgid="4029277930090150223">"還原預設值"</string>
<string name="respond_via_sms_confirmation_format" msgid="7229149977515784269">"訊息已傳送至 <xliff:g id="PHONE_NUMBER">%s</xliff:g>。"</string>
<string name="description_image_button_one" msgid="5502718871331943463">"一"</string>
<string name="description_image_button_two" msgid="4903738528222924522">"二"</string>
diff --git a/res/values-zh-rTW/strings.xml b/res/values-zh-rTW/strings.xml
index d808e4a..eb70f74 100644
--- a/res/values-zh-rTW/strings.xml
+++ b/res/values-zh-rTW/strings.xml
@@ -456,10 +456,8 @@
<string name="network_message" msgid="4483886461245213802">"網路訊息"</string>
<string name="ota_title_activate" msgid="8616918561356194398">"啟用您的手機"</string>
<string name="ota_touch_activate" msgid="6553212803262586244">"如要啟用手機服務,您必須撥打一通特殊電話。\n\n按下 [啟用] 後,請聽取手機啟用說明。"</string>
- <!-- no translation found for ota_hfa_activation_title (2234246934160473981) -->
- <skip />
- <!-- no translation found for ota_hfa_activation_dialog_message (8092479227918463415) -->
- <skip />
+ <string name="ota_hfa_activation_title" msgid="2234246934160473981">"啟用中..."</string>
+ <string name="ota_hfa_activation_dialog_message" msgid="8092479227918463415">"手機正在啟用行動數據服務。\n\n最多可能需要 5 分鐘。"</string>
<string name="ota_skip_activation_dialog_title" msgid="2943366608272261306">"是否略過啟用?"</string>
<string name="ota_skip_activation_dialog_message" msgid="2440770373498870550">"如果您不啟用手機,就無法打電話或連線至行動服務資料網路 (透過這個資料網路,可連線至 Wi-Fi 網路)。每次一開機,系統就會詢問您是否要啟用手機,直到您啟用為止。"</string>
<string name="ota_skip_activation_dialog_skip_label" msgid="3458532775091563208">"略過"</string>
@@ -587,8 +585,7 @@
<string name="respond_via_sms_setting_title_2" msgid="6104662227299493906">"編輯快速回應"</string>
<string name="respond_via_sms_setting_summary" msgid="9150281183930613065"></string>
<string name="respond_via_sms_edittext_dialog_title" msgid="20379890418289778">"快速回應"</string>
- <!-- no translation found for respond_via_sms_menu_reset_default_activity (4029277930090150223) -->
- <skip />
+ <string name="respond_via_sms_menu_reset_default_activity" msgid="4029277930090150223">"還原預設值"</string>
<string name="respond_via_sms_confirmation_format" msgid="7229149977515784269">"訊息已傳送至 <xliff:g id="PHONE_NUMBER">%s</xliff:g>。"</string>
<string name="description_image_button_one" msgid="5502718871331943463">"1"</string>
<string name="description_image_button_two" msgid="4903738528222924522">"2"</string>
diff --git a/res/values-zu/strings.xml b/res/values-zu/strings.xml
index d3699cb..9feee5d 100644
--- a/res/values-zu/strings.xml
+++ b/res/values-zu/strings.xml
@@ -454,10 +454,8 @@
<string name="network_message" msgid="4483886461245213802">"Umlayezo Wenethiwekhi"</string>
<string name="ota_title_activate" msgid="8616918561356194398">"Yenza ifoni yakho isebenze"</string>
<string name="ota_touch_activate" msgid="6553212803262586244">"Ikholi ekhethekile kumele yenziwe ukuze wenze isevisi yefoni yakho isebenze.\n\nEmva kokucindezela \"Yenza kusebenze\", lalela iziqondiso ezinikeziwe ukwenza ifoni yakho isebenze."</string>
- <!-- no translation found for ota_hfa_activation_title (2234246934160473981) -->
- <skip />
- <!-- no translation found for ota_hfa_activation_dialog_message (8092479227918463415) -->
- <skip />
+ <string name="ota_hfa_activation_title" msgid="2234246934160473981">"Yenza kusebenze..."</string>
+ <string name="ota_hfa_activation_dialog_message" msgid="8092479227918463415">"Ifoni yenza isevisi yakho yedatha yeselula isebenze.\n\nLokhu kungase kuthathe amaminithi angu-5."</string>
<string name="ota_skip_activation_dialog_title" msgid="2943366608272261306">"Yeqa ukwenza kusebenze?"</string>
<string name="ota_skip_activation_dialog_message" msgid="2440770373498870550">"Uma weqa ukwenza kusebenze, awukwazi ukwenza amakholi noma xhuma kumanethiwekhi edatha yefoni (nakuba ungakwazi ukuxhuma kumanethiwekhi e-Wi-Fi). Kuze kube yilapho wenza ifoni yakho isebenze, ucelwa ukuba wenze isebenze"</string>
<string name="ota_skip_activation_dialog_skip_label" msgid="3458532775091563208">"Yeqa"</string>
@@ -585,8 +583,7 @@
<string name="respond_via_sms_setting_title_2" msgid="6104662227299493906">"Hlela izimpendulo ezisheshayo"</string>
<string name="respond_via_sms_setting_summary" msgid="9150281183930613065"></string>
<string name="respond_via_sms_edittext_dialog_title" msgid="20379890418289778">"Izimpendulo ezisheshayo"</string>
- <!-- no translation found for respond_via_sms_menu_reset_default_activity (4029277930090150223) -->
- <skip />
+ <string name="respond_via_sms_menu_reset_default_activity" msgid="4029277930090150223">"Buyisela esimeni okuzenzakalelayo"</string>
<string name="respond_via_sms_confirmation_format" msgid="7229149977515784269">"Umlayezo othunyelwe ku <xliff:g id="PHONE_NUMBER">%s</xliff:g>."</string>
<string name="description_image_button_one" msgid="5502718871331943463">"kunye"</string>
<string name="description_image_button_two" msgid="4903738528222924522">"okubili"</string>
diff --git a/res/values/array.xml b/res/values/array.xml
index 6ddea47..245c09b 100644
--- a/res/values/array.xml
+++ b/res/values/array.xml
@@ -49,53 +49,4 @@
<item>@string/sip_always_send_keepalive</item>
</string-array>
- <!-- "Target" resources for the GlowPadView widget used for incoming calls;
- see InCallTouchUi.showIncomingCallWidget() and incall_touch_ui.xml. -->
-
- <!-- For most incoming calls the GlowPadView widget provides 3 choices:
- - Answer (drag right)
- - Reject (drag left)
- - Respond via SMS (drag up) -->
- <array name="incoming_call_widget_3way_targets">
- <item>@drawable/ic_lockscreen_answer</item>
- <item>@drawable/ic_lockscreen_text</item>
- <item>@drawable/ic_lockscreen_decline</item>
- <item>@null</item>"
- </array>
- <array name="incoming_call_widget_3way_target_descriptions">
- <item>@string/description_target_answer</item>
- <item>@string/description_target_send_sms</item>
- <item>@string/description_target_decline</item>
- <item>@null</item>"
- </array>
- <array name="incoming_call_widget_3way_direction_descriptions">
- <item>@*android:string/description_direction_right</item>
- <item>@*android:string/description_direction_up</item>
- <item>@*android:string/description_direction_left</item>
- <item>@null</item>
- </array>
-
- <!-- But in some cases "Respond via SMS" isn't available, so there are
- only 2 choices:
- - Answer (drag right)
- - Reject (drag left) -->
- <array name="incoming_call_widget_2way_targets">
- <item>@drawable/ic_lockscreen_answer</item>
- <item>@null</item>
- <item>@drawable/ic_lockscreen_decline</item>
- <item>@null</item>"
- </array>
- <array name="incoming_call_widget_2way_target_descriptions">
- <item>@string/description_target_answer</item>
- <item>@null</item>
- <item>@string/description_target_decline</item>
- <item>@null</item>"
- </array>
- <array name="incoming_call_widget_2way_direction_descriptions">
- <item>@*android:string/description_direction_right</item>
- <item>@null</item>
- <item>@*android:string/description_direction_left</item>
- <item>@null</item>
- </array>
-
</resources>
diff --git a/res/values/config.xml b/res/values/config.xml
index adc54ee..5146b1f 100644
--- a/res/values/config.xml
+++ b/res/values/config.xml
@@ -120,11 +120,14 @@
<bool name="config_operator_selection_expand" translatable="false">true</bool>
<bool name="config_prefer_2g" translatable="false">true</bool>
- <!-- Package name for the default in-call UI Service [DO NOT TRANSLATE] -->
- <string name="incall_ui_default_package" translatable="false">com.android.dialer</string>
+ <!-- Package name for the default in-call UI and dialer [DO NOT TRANSLATE] -->
+ <string name="ui_default_package" translatable="false">com.android.dialer</string>
<!-- Class name for the default in-call UI Service [DO NOT TRANSLATE] -->
- <string name="incall_ui_default_class" translatable="false">com.android.incallui.CallHandlerService</string>
+ <string name="incall_default_class" translatable="false">com.android.incallui.CallHandlerService</string>
+
+ <!-- Class name for the default main Dialer activity [DO NOT TRANSLATE] -->
+ <string name="dialer_default_class" translatable="false">com.android.dialer.DialtactsActivity</string>
<!-- CDMA activation goes through HFA [DO NOT TRANSLATE] -->
<bool name="config_use_hfa_for_provisioning" translatable="false">false</bool>
diff --git a/res/values/ids.xml b/res/values/ids.xml
deleted file mode 100644
index b004051..0000000
--- a/res/values/ids.xml
+++ /dev/null
@@ -1,27 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- 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.
--->
-
-<resources>
- <!-- IDs used with events from in-call touch UI elements.
- (Note we handle these in the InCallScreen's "button click"
- handler even though the UI elements may not actually be buttons.) -->
- <item type="id" name="incomingCallAnswer" />
- <item type="id" name="incomingCallReject" />
- <item type="id" name="incomingCallRespondViaSms" />
-
- <!-- View tag ID used by AnimationUtils.Fade -->
- <item type="id" name="fadeState" />
-</resources>
diff --git a/res/values/styles.xml b/res/values/styles.xml
index c91f69b..f4f4a31 100644
--- a/res/values/styles.xml
+++ b/res/values/styles.xml
@@ -260,20 +260,6 @@
<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>
-
<style name="Theme.Transparent" parent="android:Theme">
<item name="android:windowIsTranslucent">true</item>
<item name="android:windowBackground">@android:color/transparent</item>
diff --git a/src/com/android/phone/AnimationUtils.java b/src/com/android/phone/AnimationUtils.java
deleted file mode 100644
index f7d9e2e..0000000
--- a/src/com/android/phone/AnimationUtils.java
+++ /dev/null
@@ -1,279 +0,0 @@
-/*
- * 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.animation.Animator;
-import android.animation.AnimatorListenerAdapter;
-import android.animation.ObjectAnimator;
-import android.graphics.Canvas;
-import android.graphics.drawable.BitmapDrawable;
-import android.graphics.drawable.Drawable;
-import android.graphics.drawable.LayerDrawable;
-import android.util.Log;
-import android.view.View;
-import android.view.ViewPropertyAnimator;
-import android.widget.ImageView;
-
-/**
- * Utilities for Animation.
- */
-public class AnimationUtils {
- private static final String LOG_TAG = AnimationUtils.class.getSimpleName();
- /**
- * Turn on when you're interested in fading animation. Intentionally untied from other debug
- * settings.
- */
- private static final boolean FADE_DBG = false;
-
- /**
- * Duration for animations in msec, which can be used with
- * {@link ViewPropertyAnimator#setDuration(long)} for example.
- */
- public static final int ANIMATION_DURATION = 250;
-
- private AnimationUtils() {
- }
-
- /**
- * Simple Utility class that runs fading animations on specified views.
- */
- public static class Fade {
-
- // View tag that's set during the fade-out animation; see hide() and
- // isFadingOut().
- private static final int FADE_STATE_KEY = R.id.fadeState;
- private static final String FADING_OUT = "fading_out";
-
- /**
- * Sets the visibility of the specified view to View.VISIBLE and then
- * fades it in. If the view is already visible (and not in the middle
- * of a fade-out animation), this method will return without doing
- * anything.
- *
- * @param view The view to be faded in
- */
- public static void show(final View view) {
- if (FADE_DBG) log("Fade: SHOW view " + view + "...");
- if (FADE_DBG) log("Fade: - visibility = " + view.getVisibility());
- if ((view.getVisibility() != View.VISIBLE) || isFadingOut(view)) {
- view.animate().cancel();
- // ...and clear the FADE_STATE_KEY tag in case we just
- // canceled an in-progress fade-out animation.
- view.setTag(FADE_STATE_KEY, null);
-
- view.setAlpha(0);
- view.setVisibility(View.VISIBLE);
- view.animate().setDuration(ANIMATION_DURATION);
- view.animate().alpha(1);
- if (FADE_DBG) log("Fade: ==> SHOW " + view
- + " DONE. Set visibility = " + View.VISIBLE);
- } else {
- if (FADE_DBG) log("Fade: ==> Ignoring, already visible AND not fading out.");
- }
- }
-
- /**
- * Fades out the specified view and then sets its visibility to the
- * specified value (either View.INVISIBLE or View.GONE). If the view
- * is not currently visibile, the method will return without doing
- * anything.
- *
- * Note that *during* the fade-out the view itself will still have
- * visibility View.VISIBLE, although the isFadingOut() method will
- * return true (in case the UI code needs to detect this state.)
- *
- * @param view The view to be hidden
- * @param visibility The value to which the view's visibility will be
- * set after it fades out.
- * Must be either View.INVISIBLE or View.GONE.
- */
- public static void hide(final View view, final int visibility) {
- if (FADE_DBG) log("Fade: HIDE view " + view + "...");
- if (view.getVisibility() == View.VISIBLE &&
- (visibility == View.INVISIBLE || visibility == View.GONE)) {
-
- // Use a view tag to mark this view as being in the middle
- // of a fade-out animation.
- view.setTag(FADE_STATE_KEY, FADING_OUT);
-
- view.animate().cancel();
- view.animate().setDuration(ANIMATION_DURATION);
- view.animate().alpha(0f).setListener(new AnimatorListenerAdapter() {
- @Override
- public void onAnimationEnd(Animator animation) {
- view.setAlpha(1);
- view.setVisibility(visibility);
- view.animate().setListener(null);
- // ...and we're done with the fade-out, so clear the view tag.
- view.setTag(FADE_STATE_KEY, null);
- if (FADE_DBG) log("Fade: HIDE " + view
- + " DONE. Set visibility = " + visibility);
- }
- });
- }
- }
-
- /**
- * @return true if the specified view is currently in the middle
- * of a fade-out animation. (During the fade-out, the view's
- * visibility is still VISIBLE, although in many cases the UI
- * should behave as if it's already invisible or gone. This
- * method allows the UI code to detect that state.)
- *
- * @see #hide(View, int)
- */
- public static boolean isFadingOut(final View view) {
- if (FADE_DBG) {
- log("Fade: isFadingOut view " + view + "...");
- log("Fade: - getTag() returns: " + view.getTag(FADE_STATE_KEY));
- log("Fade: - returning: " + (view.getTag(FADE_STATE_KEY) == FADING_OUT));
- }
- return (view.getTag(FADE_STATE_KEY) == FADING_OUT);
- }
-
- }
-
- /**
- * Drawable achieving cross-fade, just like TransitionDrawable. We can have
- * call-backs via animator object (see also {@link CrossFadeDrawable#getAnimator()}).
- */
- private static class CrossFadeDrawable extends LayerDrawable {
- private final ObjectAnimator mAnimator;
-
- public CrossFadeDrawable(Drawable[] layers) {
- super(layers);
- mAnimator = ObjectAnimator.ofInt(this, "crossFadeAlpha", 0xff, 0);
- }
-
- private int mCrossFadeAlpha;
-
- /**
- * This will be used from ObjectAnimator.
- * Note: this method is protected by proguard.flags so that it won't be removed
- * automatically.
- */
- @SuppressWarnings("unused")
- public void setCrossFadeAlpha(int alpha) {
- mCrossFadeAlpha = alpha;
- invalidateSelf();
- }
-
- public ObjectAnimator getAnimator() {
- return mAnimator;
- }
-
- @Override
- public void draw(Canvas canvas) {
- Drawable first = getDrawable(0);
- Drawable second = getDrawable(1);
-
- if (mCrossFadeAlpha > 0) {
- first.setAlpha(mCrossFadeAlpha);
- first.draw(canvas);
- first.setAlpha(255);
- }
-
- if (mCrossFadeAlpha < 0xff) {
- second.setAlpha(0xff - mCrossFadeAlpha);
- second.draw(canvas);
- second.setAlpha(0xff);
- }
- }
- }
-
- private static CrossFadeDrawable newCrossFadeDrawable(Drawable first, Drawable second) {
- Drawable[] layers = new Drawable[2];
- layers[0] = first;
- layers[1] = second;
- return new CrossFadeDrawable(layers);
- }
-
- /**
- * Starts cross-fade animation using TransitionDrawable. Nothing will happen if "from" and "to"
- * are the same.
- */
- public static void startCrossFade(
- final ImageView imageView, final Drawable from, final Drawable to) {
- // We skip the cross-fade when those two Drawables are equal, or they are BitmapDrawables
- // pointing to the same Bitmap.
- final boolean areSameImage = from.equals(to) ||
- ((from instanceof BitmapDrawable)
- && (to instanceof BitmapDrawable)
- && ((BitmapDrawable) from).getBitmap()
- .equals(((BitmapDrawable) to).getBitmap()));
- if (!areSameImage) {
- if (FADE_DBG) {
- log("Start cross-fade animation for " + imageView
- + "(" + Integer.toHexString(from.hashCode()) + " -> "
- + Integer.toHexString(to.hashCode()) + ")");
- }
-
- CrossFadeDrawable crossFadeDrawable = newCrossFadeDrawable(from, to);
- ObjectAnimator animator = crossFadeDrawable.getAnimator();
- imageView.setImageDrawable(crossFadeDrawable);
- animator.setDuration(ANIMATION_DURATION);
- animator.addListener(new AnimatorListenerAdapter() {
- @Override
- public void onAnimationStart(Animator animation) {
- if (FADE_DBG) {
- log("cross-fade animation start ("
- + Integer.toHexString(from.hashCode()) + " -> "
- + Integer.toHexString(to.hashCode()) + ")");
- }
- }
-
- @Override
- public void onAnimationEnd(Animator animation) {
- if (FADE_DBG) {
- log("cross-fade animation ended ("
- + Integer.toHexString(from.hashCode()) + " -> "
- + Integer.toHexString(to.hashCode()) + ")");
- }
- animation.removeAllListeners();
- // Workaround for issue 6300562; this will force the drawable to the
- // resultant one regardless of animation glitch.
- imageView.setImageDrawable(to);
- }
- });
- animator.start();
-
- /* We could use TransitionDrawable here, but it may cause some weird animation in
- * some corner cases. See issue 6300562
- * TODO: decide which to be used in the long run. TransitionDrawable is old but system
- * one. Ours uses new animation framework and thus have callback (great for testing),
- * while no framework support for the exact class.
-
- Drawable[] layers = new Drawable[2];
- layers[0] = from;
- layers[1] = to;
- TransitionDrawable transitionDrawable = new TransitionDrawable(layers);
- imageView.setImageDrawable(transitionDrawable);
- transitionDrawable.startTransition(ANIMATION_DURATION); */
- imageView.setTag(to);
- } else {
- if (FADE_DBG) {
- log("*Not* start cross-fade. " + imageView);
- }
- }
- }
-
- // Debugging / testing code
-
- private static void log(String msg) {
- Log.d(LOG_TAG, msg);
- }
-}
\ No newline at end of file
diff --git a/src/com/android/phone/AudioRouter.java b/src/com/android/phone/AudioRouter.java
index 00fc131..3c8e9d3 100644
--- a/src/com/android/phone/AudioRouter.java
+++ b/src/com/android/phone/AudioRouter.java
@@ -41,6 +41,9 @@
(PhoneGlobals.DBG_LEVEL >= 1) && (SystemProperties.getInt("ro.debuggable", 0) == 1);
private static final boolean VDBG = (PhoneGlobals.DBG_LEVEL >= 2);
+ private static final boolean ON = true;
+ private static final boolean OFF = false;
+
private final Context mContext;
private final BluetoothManager mBluetoothManager;
private final WiredHeadsetManager mWiredHeadsetManager;
@@ -108,42 +111,23 @@
*/
public void setAudioMode(int mode) {
logD("setAudioMode " + AudioMode.toString(mode));
+ boolean error = false;
- // Since they are mutually exclusive and one is ALWAYS valid, we allow a special input of
- // WIRED_OR_EARPIECE so that callers dont have to make a call to check which is supported
- // before calling setAudioMode.
- if (mode == AudioMode.WIRED_OR_EARPIECE) {
- mode = AudioMode.WIRED_OR_EARPIECE & mSupportedModes;
+ // changes WIRED_OR_EARPIECE to appropriate single entry WIRED_HEADSET or EARPIECE
+ mode = selectWiredOrEarpiece(mode);
- if (mode == 0) {
- Log.wtf(LOG_TAG, "One of wired headset or earpiece should always be valid.");
- // assume earpiece in this case.
- mode = AudioMode.EARPIECE;
- }
- }
-
+ // If mode is unsupported, do nothing.
if ((calculateSupportedModes() | mode) == 0) {
Log.wtf(LOG_TAG, "Asking to set to a mode that is unsupported: " + mode);
return;
}
if (AudioMode.SPEAKER == mode) {
-
- if (!PhoneUtils.isSpeakerOn(mContext)) {
- // Switch away from Bluetooth, if it was active.
- if (mBluetoothManager.isBluetoothAvailable() &&
- mBluetoothManager.isBluetoothAudioConnected()) {
-
- mBluetoothManager.disconnectBluetoothAudio();
- }
- PhoneUtils.turnOnSpeaker(mContext, true, true);
- }
+ turnOnOffBluetooth(OFF);
+ turnOnOffSpeaker(ON);
} else if (AudioMode.BLUETOOTH == mode) {
-
- // If already connected to BT, there's nothing to do here.
- if (mBluetoothManager.isBluetoothAvailable() &&
- !mBluetoothManager.isBluetoothAudioConnected()) {
+ if (mBluetoothManager.isBluetoothAvailable()) {
// Manually turn the speaker phone off, instead of allowing the
// Bluetooth audio routing to handle it, since there's other
// important state-updating that needs to happen in the
@@ -151,31 +135,30 @@
// (Similarly, whenever the user turns *on* the speaker, we
// manually disconnect the active bluetooth headset;
// see toggleSpeaker() and/or switchInCallAudio().)
- if (PhoneUtils.isSpeakerOn(mContext)) {
- PhoneUtils.turnOnSpeaker(mContext, false, true);
+ turnOnOffSpeaker(OFF);
+ if (!turnOnOffBluetooth(ON)) {
+ error = true;
}
- mBluetoothManager.connectBluetoothAudio();
+ } else {
+ Log.e(LOG_TAG, "Asking to turn on bluetooth when no bluetooth available. " +
+ "supportedModes: " + AudioMode.toString(calculateSupportedModes()));
+ error = true;
}
// Wired headset and earpiece work the same way
} else if (AudioMode.EARPIECE == mode || AudioMode.WIRED_HEADSET == mode) {
-
- // Switch to either the handset earpiece, or the wired headset (if connected.)
- // (Do this by simply making sure both speaker and bluetooth are off.)
- if (mBluetoothManager.isBluetoothAvailable() &&
- mBluetoothManager.isBluetoothAudioConnected()) {
- mBluetoothManager.disconnectBluetoothAudio();
- }
- if (PhoneUtils.isSpeakerOn(mContext)) {
- PhoneUtils.turnOnSpeaker(mContext, false, true);
- }
+ turnOnOffBluetooth(OFF);
+ turnOnOffSpeaker(OFF);
} else {
- Log.wtf(LOG_TAG, "Asking us to set to an unsupported mode " +
- AudioMode.toString(mode) + " (" + mode + ")");
+ error = true;
+ }
- // set it to the current audio mode
- mode = mAudioMode;
+ if (error) {
+ mode = calculateModeFromCurrentState();
+ Log.e(LOG_TAG, "There was an error in setting new audio mode. " +
+ "Resetting mode to " + AudioMode.toString(mode) + ".");
+
}
updateAudioModeTo(mode);
@@ -222,36 +205,93 @@
// speakerphone, update the "speaker" state. We ONLY want to do
// this on the wired headset connect / disconnect events for now
// though.
- PhoneConstants.State phoneState = mCallManager.getState();
+ final boolean isOffhook = (mCallManager.getState() == PhoneConstants.State.OFFHOOK);
int newMode = mAudioMode;
- // TODO: Consider using our stored states instead
+ // Change state only if we are not using bluetooth
+ if (!mBluetoothManager.isBluetoothHeadsetAudioOn()) {
- // Do not change speaker state if phone is not off hook
- if (phoneState == PhoneConstants.State.OFFHOOK &&
- !mBluetoothManager.isBluetoothHeadsetAudioOn()) {
- if (!pluggedIn) {
- // if the state is "not connected", restore the speaker state.
- PhoneUtils.restoreSpeakerMode(mContext);
+ // Do special logic with speakerphone if we have an ongoing (offhook) call.
+ if (isOffhook) {
+ if (!pluggedIn) {
+ // if the state is "not connected", restore the speaker state.
+ PhoneUtils.restoreSpeakerMode(mContext);
- if (PhoneUtils.isSpeakerOn(mContext)) {
- newMode = AudioMode.SPEAKER;
+ if (PhoneUtils.isSpeakerOn(mContext)) {
+ newMode = AudioMode.SPEAKER;
+ } else {
+ newMode = AudioMode.EARPIECE;
+ }
} else {
- newMode = AudioMode.EARPIECE;
- }
- } else {
- // if the state is "connected", force the speaker off without
- // storing the state.
- PhoneUtils.turnOnSpeaker(mContext, false, false);
+ // if the state is "connected", force the speaker off without
+ // storing the state.
+ PhoneUtils.turnOnSpeaker(mContext, false, false);
- newMode = AudioMode.WIRED_HEADSET;
+ newMode = AudioMode.WIRED_HEADSET;
+ }
+
+ // if we are outside of a phone call, the logic is simpler
+ } else {
+ newMode = pluggedIn ? AudioMode.WIRED_HEADSET : AudioMode.EARPIECE;
}
}
updateAudioModeTo(newMode);
}
+ /**
+ * Changes WIRED_OR_EARPIECE to appropriate single entry WIRED_HEADSET or EARPIECE.
+ * If mode passed it is not WIRED_OR_EARPIECE, this is a no-op and simply returns
+ * the unchanged mode parameter.
+ */
+ private int selectWiredOrEarpiece(int mode) {
+ // Since they are mutually exclusive and one is ALWAYS valid, we allow a special input of
+ // WIRED_OR_EARPIECE so that callers dont have to make a call to check which is supported
+ // before calling setAudioMode.
+ if (mode == AudioMode.WIRED_OR_EARPIECE) {
+ mode = AudioMode.WIRED_OR_EARPIECE & mSupportedModes;
+
+ if (mode == 0) {
+ Log.wtf(LOG_TAG, "One of wired headset or earpiece should always be valid.");
+ // assume earpiece in this case.
+ mode = AudioMode.EARPIECE;
+ }
+ }
+
+ return mode;
+ }
+
+ /**
+ * Turns on/off bluetooth. If bluetooth is already in the correct mode, this does
+ * nothing.
+ */
+ private boolean turnOnOffBluetooth(boolean onOff) {
+ if (mBluetoothManager.isBluetoothAvailable()) {
+ final boolean isAlreadyOn = mBluetoothManager.isBluetoothAudioConnected();
+
+ if (onOff && !isAlreadyOn) {
+ mBluetoothManager.connectBluetoothAudio();
+ } else if (!onOff && isAlreadyOn) {
+ mBluetoothManager.disconnectBluetoothAudio();
+ }
+ } else if (onOff) {
+ Log.e(LOG_TAG, "Asking to turn on bluetooth, but there is no bluetooth availabled.");
+ return false;
+ }
+
+ return true;
+ }
+
+ /**
+ * Turn on/off speaker.
+ */
+ private void turnOnOffSpeaker(boolean onOff) {
+ if (PhoneUtils.isSpeakerOn(mContext) != onOff) {
+ PhoneUtils.turnOnSpeaker(mContext, onOff, true /* storeState */);
+ }
+ }
+
private void init() {
mBluetoothManager.addBluetoothIndicatorListener(this);
mWiredHeadsetManager.addWiredHeadsetListener(this);
@@ -291,7 +331,9 @@
// that it went through. If it happens it is likely it is a race condition
// that will resolve itself when we get updates on the mode change.
if ((mSupportedModes & mode) == 0) {
- Log.e(LOG_TAG, "Setting audio mode to an unsupported mode!");
+ Log.e(LOG_TAG, "Setting audio mode to an unsupported mode: " +
+ AudioMode.toString(mode) + ", supported (" +
+ AudioMode.toString(mSupportedModes) + ")");
}
boolean doNotify = oldSupportedModes != mSupportedModes;
diff --git a/src/com/android/phone/BitmapUtils.java b/src/com/android/phone/BitmapUtils.java
deleted file mode 100644
index 94d4bf9..0000000
--- a/src/com/android/phone/BitmapUtils.java
+++ /dev/null
@@ -1,161 +0,0 @@
-/*
- * Copyright (C) 2011 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.graphics.Bitmap;
-import android.os.SystemClock;
-import android.os.SystemProperties;
-import android.util.Log;
-
-
-/**
- * Image effects used by the in-call UI.
- */
-public class BitmapUtils {
- private static final String TAG = "BitmapUtils";
- private static final boolean DBG =
- (PhoneGlobals.DBG_LEVEL >= 1) && (SystemProperties.getInt("ro.debuggable", 0) == 1);
-
- /** This class is never instantiated. */
- private BitmapUtils() {
- }
-
- //
- // Gaussian blur effect
- //
- // gaussianBlur() and related methods are borrowed from
- // BackgroundUtils.java in the Music2 code (which itself was based on
- // code from the old Cooliris android Gallery app.)
- //
- // TODO: possibly consider caching previously-generated blurred bitmaps;
- // see getAdaptedBitmap() and mAdaptedBitmapCache in the music app code.
- //
-
- private static final int RED_MASK = 0xff0000;
- private static final int RED_MASK_SHIFT = 16;
- private static final int GREEN_MASK = 0x00ff00;
- private static final int GREEN_MASK_SHIFT = 8;
- private static final int BLUE_MASK = 0x0000ff;
-
- /**
- * Creates a blurred version of the given Bitmap.
- *
- * @param bitmap the input bitmap, presumably a 96x96 pixel contact
- * thumbnail.
- */
- public static Bitmap createBlurredBitmap(Bitmap bitmap) {
- if (DBG) log("createBlurredBitmap()...");
- long startTime = SystemClock.uptimeMillis();
- if (bitmap == null) {
- Log.w(TAG, "createBlurredBitmap: null bitmap");
- return null;
- }
-
- if (DBG) log("- input bitmap: " + bitmap.getWidth() + " x " + bitmap.getHeight());
-
- // The bitmap we pass to gaussianBlur() needs to have a width
- // that's a power of 2, so scale up to 128x128.
- final int scaledSize = 128;
- bitmap = Bitmap.createScaledBitmap(bitmap,
- scaledSize, scaledSize,
- true /* filter */);
- if (DBG) log("- after resize: " + bitmap.getWidth() + " x " + bitmap.getHeight());
-
- bitmap = gaussianBlur(bitmap);
- if (DBG) log("- after blur: " + bitmap.getWidth() + " x " + bitmap.getHeight());
-
- long endTime = SystemClock.uptimeMillis();
- if (DBG) log("createBlurredBitmap() done (elapsed = " + (endTime - startTime) + " msec)");
- return bitmap;
- }
-
- /**
- * Apply a gaussian blur filter, and return a new (blurred) bitmap
- * that's the same size as the input bitmap.
- *
- * @param source input bitmap, whose width must be a power of 2
- */
- public static Bitmap gaussianBlur(Bitmap source) {
- int width = source.getWidth();
- int height = source.getHeight();
- if (DBG) log("gaussianBlur(): input: " + width + " x " + height);
-
- // Create a source and destination buffer for the image.
- int numPixels = width * height;
- int[] in = new int[numPixels];
- int[] tmp = new int[numPixels];
-
- // Get the source pixels as 32-bit ARGB.
- source.getPixels(in, 0, width, 0, 0, width, height);
-
- // Gaussian is a separable kernel, so it is decomposed into a horizontal
- // and vertical pass.
- // The filter function applies the kernel across each row and transposes
- // the output.
- // Hence we apply it twice to provide efficient horizontal and vertical
- // convolution.
- // The filter discards the alpha channel.
- gaussianBlurFilter(in, tmp, width, height);
- gaussianBlurFilter(tmp, in, width, height);
-
- // Return a bitmap scaled to the desired size.
- Bitmap filtered = Bitmap.createBitmap(in, width, height, Bitmap.Config.ARGB_8888);
- source.recycle();
- return filtered;
- }
-
- private static void gaussianBlurFilter(int[] in, int[] out, int width, int height) {
- // This function is currently hardcoded to blur with RADIUS = 4.
- // (If you change RADIUS, you'll have to change the weights[] too.)
- final int RADIUS = 4;
- final int[] weights = { 13, 23, 32, 39, 42, 39, 32, 23, 13}; // Adds up to 256
- int inPos = 0;
- int widthMask = width - 1; // width must be a power of two.
- for (int y = 0; y < height; ++y) {
- // Compute the alpha value.
- int alpha = 0xff;
- // Compute output values for the row.
- int outPos = y;
- for (int x = 0; x < width; ++x) {
- int red = 0;
- int green = 0;
- int blue = 0;
- for (int i = -RADIUS; i <= RADIUS; ++i) {
- int argb = in[inPos + (widthMask & (x + i))];
- int weight = weights[i+RADIUS];
- red += weight *((argb & RED_MASK) >> RED_MASK_SHIFT);
- green += weight *((argb & GREEN_MASK) >> GREEN_MASK_SHIFT);
- blue += weight *(argb & BLUE_MASK);
- }
- // Output the current pixel.
- out[outPos] = (alpha << 24) | ((red >> 8) << RED_MASK_SHIFT)
- | ((green >> 8) << GREEN_MASK_SHIFT)
- | (blue >> 8);
- outPos += height;
- }
- inPos += width;
- }
- }
-
- //
- // Debugging
- //
-
- private static void log(String msg) {
- Log.d(TAG, msg);
- }
-}
diff --git a/src/com/android/phone/BluetoothManager.java b/src/com/android/phone/BluetoothManager.java
index c2b4f7d..443c950 100644
--- a/src/com/android/phone/BluetoothManager.java
+++ b/src/com/android/phone/BluetoothManager.java
@@ -32,6 +32,7 @@
import android.util.Log;
import com.android.internal.telephony.CallManager;
+import com.android.internal.telephony.Connection;
import com.android.services.telephony.common.Call;
import java.util.List;
@@ -71,7 +72,6 @@
mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
init(mContext);
- // TODO(klp): Listen for changes to the call list/state.
}
/* package */ boolean isBluetoothHeadsetAudioOn() {
@@ -417,7 +417,7 @@
}
@Override
- public void onPostDialWait(int callId, String chars) {
+ public void onPostDialAction(Connection.PostDialState state, int callId, String chars, char c) {
// no-op
}
diff --git a/src/com/android/phone/CallCard.java b/src/com/android/phone/CallCard.java
deleted file mode 100644
index 22215c0..0000000
--- a/src/com/android/phone/CallCard.java
+++ /dev/null
@@ -1,1754 +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.animation.LayoutTransition;
-import android.content.ContentUris;
-import android.content.Context;
-import android.content.res.Resources;
-import android.graphics.Bitmap;
-import android.graphics.drawable.BitmapDrawable;
-import android.graphics.drawable.Drawable;
-import android.net.Uri;
-import android.os.Handler;
-import android.os.Message;
-import android.provider.ContactsContract.Contacts;
-import android.telephony.PhoneNumberUtils;
-import android.text.TextUtils;
-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;
-import android.view.accessibility.AccessibilityEvent;
-import android.widget.ImageView;
-import android.widget.LinearLayout;
-import android.widget.TextView;
-
-import com.android.internal.telephony.Call;
-import com.android.internal.telephony.CallManager;
-import com.android.internal.telephony.CallerInfo;
-import com.android.internal.telephony.CallerInfoAsyncQuery;
-import com.android.internal.telephony.Connection;
-import com.android.internal.telephony.Phone;
-import com.android.internal.telephony.PhoneConstants;
-
-import java.util.List;
-
-
-/**
- * "Call card" UI element: the in-call screen contains a tiled layout of call
- * cards, each representing the state of a current "call" (ie. an active call,
- * a call on hold, or an incoming call.)
- */
-public class CallCard extends LinearLayout
- implements CallTime.OnTickListener, CallerInfoAsyncQuery.OnQueryCompleteListener,
- ContactsAsyncHelper.OnImageLoadCompleteListener {
- private static final String LOG_TAG = "CallCard";
- 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;
-
- /**
- * Used with {@link ContactsAsyncHelper#startObtainPhotoAsync(int, Context, Uri,
- * ContactsAsyncHelper.OnImageLoadCompleteListener, Object)}
- */
- private static class AsyncLoadCookie {
- public final ImageView imageView;
- public final CallerInfo callerInfo;
- public final Call call;
- public AsyncLoadCookie(ImageView imageView, CallerInfo callerInfo, Call call) {
- this.imageView = imageView;
- this.callerInfo = callerInfo;
- this.call = call;
- }
- }
-
- /**
- * Reference to the InCallScreen activity that owns us. This may be
- * null if we haven't been initialized yet *or* after the InCallScreen
- * activity has been destroyed.
- */
- private InCallScreen mInCallScreen;
-
- // Phone app instance
- private PhoneGlobals mApplication;
-
- // Top-level subviews of the CallCard
- /** Container for info about the current call(s) */
- private ViewGroup mCallInfoContainer;
- /** Primary "call info" block (the foreground or ringing call) */
- private ViewGroup mPrimaryCallInfo;
- /** "Call banner" for the primary call */
- private ViewGroup mPrimaryCallBanner;
- /** Secondary "call info" block (the background "on hold" call) */
- private ViewStub mSecondaryCallInfo;
-
-
- // "Call state" widgets
- private TextView mCallStateLabel;
- private TextView mElapsedTime;
-
- // Text colors, used for various labels / titles
- private int mTextColorCallTypeSip;
-
- // The main block of info about the "primary" or "active" call,
- // including photo / name / phone number / etc.
- private ImageView mPhoto;
- private View mPhotoDimEffect;
-
- private TextView mName;
- private TextView mPhoneNumber;
- private TextView mLabel;
- private TextView mCallTypeLabel;
- // private TextView mSocialStatus;
-
- /**
- * Uri being used to load contact photo for mPhoto. Will be null when nothing is being loaded,
- * or a photo is already loaded.
- */
- private Uri mLoadingPersonUri;
-
- // Info about the "secondary" call, which is the "call on hold" when
- // two lines are in use.
- private TextView mSecondaryCallName;
- private ImageView mSecondaryCallPhoto;
- private View mSecondaryCallPhotoDimEffect;
-
- // Onscreen hint for the incoming call RotarySelector widget.
- private int mIncomingCallWidgetHintTextResId;
- private int mIncomingCallWidgetHintColorResId;
-
- private CallTime mCallTime;
-
- // Track the state for the photo.
- private ContactsAsyncHelper.ImageTracker mPhotoTracker;
-
- // Cached DisplayMetrics density.
- private float mDensity;
-
- /**
- * Sent when it takes too long (MESSAGE_DELAY msec) to load a contact photo for the given
- * person, at which we just start showing the default avatar picture instead of the person's
- * one. Note that we will *not* cancel the ongoing query and eventually replace the avatar
- * with the person's photo, when it is available anyway.
- */
- private static final int MESSAGE_SHOW_UNKNOWN_PHOTO = 101;
- private static final int MESSAGE_DELAY = 500; // msec
- private final Handler mHandler = new Handler() {
- @Override
- public void handleMessage(Message msg) {
- switch (msg.what) {
- case MESSAGE_SHOW_UNKNOWN_PHOTO:
- showImage(mPhoto, R.drawable.picture_unknown);
- break;
- default:
- Log.wtf(LOG_TAG, "mHandler: unexpected message: " + msg);
- break;
- }
- }
- };
-
- public CallCard(Context context, AttributeSet attrs) {
- super(context, attrs);
-
- if (DBG) log("CallCard constructor...");
- if (DBG) log("- this = " + this);
- if (DBG) log("- context " + context + ", attrs " + attrs);
-
- mApplication = PhoneGlobals.getInstance();
-
- mCallTime = new CallTime(this);
-
- // create a new object to track the state for the photo.
- mPhotoTracker = new ContactsAsyncHelper.ImageTracker();
-
- mDensity = getResources().getDisplayMetrics().density;
- if (DBG) log("- Density: " + mDensity);
- }
-
- /* package */ void setInCallScreenInstance(InCallScreen inCallScreen) {
- mInCallScreen = inCallScreen;
- }
-
- @Override
- public void onTickForCallTimeElapsed(long timeElapsed) {
- // While a call is in progress, update the elapsed time shown
- // onscreen.
- updateElapsedTimeWidget(timeElapsed);
- }
-
- /* package */ void stopTimer() {
- mCallTime.cancelTimer();
- }
-
- @Override
- protected void onFinishInflate() {
- super.onFinishInflate();
-
- if (DBG) log("CallCard onFinishInflate(this = " + this + ")...");
-
- mCallInfoContainer = (ViewGroup) findViewById(R.id.call_info_container);
- mPrimaryCallInfo = (ViewGroup) findViewById(R.id.primary_call_info);
- mPrimaryCallBanner = (ViewGroup) findViewById(R.id.primary_call_banner);
-
- mCallStateLabel = (TextView) findViewById(R.id.callStateLabel);
- mElapsedTime = (TextView) findViewById(R.id.elapsedTime);
-
- // Text colors
- mTextColorCallTypeSip = getResources().getColor(R.color.incall_callTypeSip);
-
- // "Caller info" area, including photo / name / phone numbers / etc
- mPhoto = (ImageView) findViewById(R.id.photo);
- mPhotoDimEffect = findViewById(R.id.dim_effect_for_primary_photo);
-
- mName = (TextView) findViewById(R.id.name);
- mPhoneNumber = (TextView) findViewById(R.id.phoneNumber);
- mLabel = (TextView) findViewById(R.id.label);
- mCallTypeLabel = (TextView) findViewById(R.id.callTypeLabel);
- // mSocialStatus = (TextView) findViewById(R.id.socialStatus);
-
- // Secondary info area, for the background ("on hold") call
- mSecondaryCallInfo = (ViewStub) findViewById(R.id.secondary_call_info);
- }
-
- /**
- * Updates the state of all UI elements on the CallCard, based on the
- * current state of the phone.
- */
- /* package */ void updateState(CallManager cm) {
- if (DBG) log("updateState(" + cm + ")...");
-
- // Update the onscreen UI based on the current state of the phone.
-
- PhoneConstants.State state = cm.getState(); // IDLE, RINGING, or OFFHOOK
- Call ringingCall = cm.getFirstActiveRingingCall();
- Call fgCall = cm.getActiveFgCall();
- Call bgCall = cm.getFirstActiveBgCall();
-
- // 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
- // layer rejects the ringing call while the FG call is dialing/alerting,
- // but the incoming call *does* briefly exist in the DISCONNECTING or
- // DISCONNECTED state.
- if ((ringingCall.getState() != Call.State.IDLE)
- && !fgCall.getState().isDialing()) {
- // A phone call is ringing, call waiting *or* being rejected
- // (ie. another call may also be active as well.)
- updateRingingCall(cm);
- } else if ((fgCall.getState() != Call.State.IDLE)
- || (bgCall.getState() != Call.State.IDLE)) {
- // We are here because either:
- // (1) the phone is off hook. At least one call exists that is
- // dialing, active, or holding, and no calls are ringing or waiting,
- // or:
- // (2) the phone is IDLE but a call just ended and it's still in
- // the DISCONNECTING or DISCONNECTED state. In this case, we want
- // the main CallCard to display "Hanging up" or "Call ended".
- // The normal "foreground call" code path handles both cases.
- updateForegroundCall(cm);
- } else {
- // We don't have any DISCONNECTED calls, which means that the phone
- // is *truly* idle.
- if (mApplication.inCallUiState.showAlreadyDisconnectedState) {
- // showAlreadyDisconnectedState implies the phone call is disconnected
- // and we want to show the disconnected phone call for a moment.
- //
- // This happens when a phone call ends while the screen is off,
- // which means the user had no chance to see the last status of
- // the call. We'll turn off showAlreadyDisconnectedState flag
- // and bail out of the in-call screen soon.
- updateAlreadyDisconnected(cm);
- } else {
- // It's very rare to be on the InCallScreen at all in this
- // state, but it can happen in some cases:
- // - A stray onPhoneStateChanged() event came in to the
- // InCallScreen *after* it was dismissed.
- // - We're allowed to be on the InCallScreen because
- // an MMI or USSD is running, but there's no actual "call"
- // to display.
- // - We're displaying an error dialog to the user
- // (explaining why the call failed), so we need to stay on
- // the InCallScreen so that the dialog will be visible.
- //
- // In these cases, put the callcard into a sane but "blank" state:
- updateNoCall(cm);
- }
- }
- }
-
- /**
- * Updates the overall size and positioning of mCallInfoContainer and
- * the "Call info" blocks, based on the phone state.
- */
- private void updateCallInfoLayout(PhoneConstants.State state) {
- boolean ringing = (state == PhoneConstants.State.RINGING);
- if (DBG) log("updateCallInfoLayout()... ringing = " + ringing);
-
- // Based on the current state, update the overall
- // CallCard layout:
-
- // - Update the bottom margin of mCallInfoContainer to make sure
- // the call info area won't overlap with the touchable
- // controls on the bottom part of the screen.
-
- int reservedVerticalSpace = mInCallScreen.getInCallTouchUi().getTouchUiHeight();
- ViewGroup.MarginLayoutParams callInfoLp =
- (ViewGroup.MarginLayoutParams) mCallInfoContainer.getLayoutParams();
- callInfoLp.bottomMargin = reservedVerticalSpace; // Equivalent to setting
- // android:layout_marginBottom in XML
- if (DBG) log(" ==> callInfoLp.bottomMargin: " + reservedVerticalSpace);
- mCallInfoContainer.setLayoutParams(callInfoLp);
- }
-
- /**
- * Updates the UI for the state where the phone is in use, but not ringing.
- */
- private void updateForegroundCall(CallManager cm) {
- if (DBG) log("updateForegroundCall()...");
- // if (DBG) PhoneUtils.dumpCallManager();
-
- Call fgCall = cm.getActiveFgCall();
- Call bgCall = cm.getFirstActiveBgCall();
-
- if (fgCall.getState() == Call.State.IDLE) {
- if (DBG) log("updateForegroundCall: no active call, show holding call");
- // TODO: make sure this case agrees with the latest UI spec.
-
- // Display the background call in the main info area of the
- // CallCard, since there is no foreground call. Note that
- // displayMainCallStatus() will notice if the call we passed in is on
- // hold, and display the "on hold" indication.
- fgCall = bgCall;
-
- // And be sure to not display anything in the "on hold" box.
- bgCall = null;
- }
-
- displayMainCallStatus(cm, fgCall);
-
- Phone phone = fgCall.getPhone();
-
- int phoneType = phone.getPhoneType();
- if (phoneType == PhoneConstants.PHONE_TYPE_CDMA) {
- if ((mApplication.cdmaPhoneCallState.getCurrentCallState()
- == CdmaPhoneCallState.PhoneCallState.THRWAY_ACTIVE)
- && mApplication.cdmaPhoneCallState.IsThreeWayCallOrigStateDialing()) {
- displaySecondaryCallStatus(cm, fgCall);
- } else {
- //This is required so that even if a background call is not present
- // we need to clean up the background call area.
- displaySecondaryCallStatus(cm, bgCall);
- }
- } else if ((phoneType == PhoneConstants.PHONE_TYPE_GSM)
- || (phoneType == PhoneConstants.PHONE_TYPE_SIP)) {
- displaySecondaryCallStatus(cm, bgCall);
- }
- }
-
- /**
- * Updates the UI for the state where an incoming call is ringing (or
- * call waiting), regardless of whether the phone's already offhook.
- */
- private void updateRingingCall(CallManager cm) {
- if (DBG) log("updateRingingCall()...");
-
- Call ringingCall = cm.getFirstActiveRingingCall();
-
- // Display caller-id info and photo from the incoming call:
- displayMainCallStatus(cm, ringingCall);
-
- // And even in the Call Waiting case, *don't* show any info about
- // the current ongoing call and/or the current call on hold.
- // (Since the caller-id info for the incoming call totally trumps
- // any info about the current call(s) in progress.)
- displaySecondaryCallStatus(cm, null);
- }
-
- /**
- * Updates the UI for the state where an incoming call is just disconnected while we want to
- * show the screen for a moment.
- *
- * This case happens when the whole in-call screen is in background when phone calls are hanged
- * up, which means there's no way to determine which call was the last call finished. Right now
- * this method simply shows the previous primary call status with a photo, closing the
- * secondary call status. In most cases (including conference call or misc call happening in
- * CDMA) this behaves right.
- *
- * If there were two phone calls both of which were hung up but the primary call was the
- * first, this would behave a bit odd (since the first one still appears as the
- * "last disconnected").
- */
- private void updateAlreadyDisconnected(CallManager cm) {
- // For the foreground call, we manually set up every component based on previous state.
- mPrimaryCallInfo.setVisibility(View.VISIBLE);
- mCallStateLabel.setVisibility(View.VISIBLE);
- mCallStateLabel.setText(mContext.getString(R.string.card_title_call_ended));
- mElapsedTime.setVisibility(View.VISIBLE);
- mCallTime.cancelTimer();
-
- // Just hide it.
- displaySecondaryCallStatus(cm, null);
- }
-
- /**
- * Updates the UI for the state where the phone is not in use.
- * This is analogous to updateForegroundCall() and updateRingingCall(),
- * but for the (uncommon) case where the phone is
- * totally idle. (See comments in updateState() above.)
- *
- * This puts the callcard into a sane but "blank" state.
- */
- private void updateNoCall(CallManager cm) {
- if (DBG) log("updateNoCall()...");
-
- displayMainCallStatus(cm, null);
- displaySecondaryCallStatus(cm, null);
- }
-
- /**
- * Updates the main block of caller info on the CallCard
- * (ie. the stuff in the primaryCallInfo block) based on the specified Call.
- */
- private void displayMainCallStatus(CallManager cm, Call call) {
- if (DBG) log("displayMainCallStatus(call " + call + ")...");
-
- if (call == null) {
- // There's no call to display, presumably because the phone is idle.
- mPrimaryCallInfo.setVisibility(View.GONE);
- return;
- }
- mPrimaryCallInfo.setVisibility(View.VISIBLE);
-
- Call.State state = call.getState();
- if (DBG) log(" - call.state: " + call.getState());
-
- switch (state) {
- case ACTIVE:
- case DISCONNECTING:
- // update timer field
- if (DBG) log("displayMainCallStatus: start periodicUpdateTimer");
- mCallTime.setActiveCallMode(call);
- mCallTime.reset();
- mCallTime.periodicUpdateTimer();
-
- break;
-
- case HOLDING:
- // update timer field
- mCallTime.cancelTimer();
-
- break;
-
- case DISCONNECTED:
- // Stop getting timer ticks from this call
- mCallTime.cancelTimer();
-
- break;
-
- case DIALING:
- case ALERTING:
- // Stop getting timer ticks from a previous call
- mCallTime.cancelTimer();
-
- break;
-
- case INCOMING:
- case WAITING:
- // Stop getting timer ticks from a previous call
- mCallTime.cancelTimer();
-
- break;
-
- case IDLE:
- // The "main CallCard" should never be trying to display
- // an idle call! In updateState(), if the phone is idle,
- // we call updateNoCall(), which means that we shouldn't
- // have passed a call into this method at all.
- Log.w(LOG_TAG, "displayMainCallStatus: IDLE call in the main call card!");
-
- // (It is possible, though, that we had a valid call which
- // became idle *after* the check in updateState() but
- // before we get here... So continue the best we can,
- // with whatever (stale) info we can get from the
- // passed-in Call object.)
-
- break;
-
- default:
- Log.w(LOG_TAG, "displayMainCallStatus: unexpected call state: " + state);
- break;
- }
-
- updateCallStateWidgets(call);
-
- if (PhoneUtils.isConferenceCall(call)) {
- // Update onscreen info for a conference call.
- updateDisplayForConference(call);
- } else {
- // Update onscreen info for a regular call (which presumably
- // has only one connection.)
- Connection conn = null;
- int phoneType = call.getPhone().getPhoneType();
- if (phoneType == PhoneConstants.PHONE_TYPE_CDMA) {
- conn = call.getLatestConnection();
- } else if ((phoneType == PhoneConstants.PHONE_TYPE_GSM)
- || (phoneType == PhoneConstants.PHONE_TYPE_SIP)) {
- conn = call.getEarliestConnection();
- } else {
- throw new IllegalStateException("Unexpected phone type: " + phoneType);
- }
-
- if (conn == null) {
- if (DBG) log("displayMainCallStatus: connection is null, using default values.");
- // if the connection is null, we run through the behaviour
- // we had in the past, which breaks down into trivial steps
- // with the current implementation of getCallerInfo and
- // updateDisplayForPerson.
- CallerInfo info = PhoneUtils.getCallerInfo(getContext(), null /* conn */);
- updateDisplayForPerson(info, PhoneConstants.PRESENTATION_ALLOWED, false, call,
- conn);
- } else {
- if (DBG) log(" - CONN: " + conn + ", state = " + conn.getState());
- int presentation = conn.getNumberPresentation();
-
- // make sure that we only make a new query when the current
- // callerinfo differs from what we've been requested to display.
- boolean runQuery = true;
- Object o = conn.getUserData();
- if (o instanceof PhoneUtils.CallerInfoToken) {
- runQuery = mPhotoTracker.isDifferentImageRequest(
- ((PhoneUtils.CallerInfoToken) o).currentInfo);
- } else {
- runQuery = mPhotoTracker.isDifferentImageRequest(conn);
- }
-
- // Adding a check to see if the update was caused due to a Phone number update
- // or CNAP update. If so then we need to start a new query
- if (phoneType == PhoneConstants.PHONE_TYPE_CDMA) {
- Object obj = conn.getUserData();
- String updatedNumber = conn.getAddress();
- String updatedCnapName = conn.getCnapName();
- CallerInfo info = null;
- if (obj instanceof PhoneUtils.CallerInfoToken) {
- info = ((PhoneUtils.CallerInfoToken) o).currentInfo;
- } else if (o instanceof CallerInfo) {
- info = (CallerInfo) o;
- }
-
- if (info != null) {
- if (updatedNumber != null && !updatedNumber.equals(info.phoneNumber)) {
- if (DBG) log("- displayMainCallStatus: updatedNumber = "
- + updatedNumber);
- runQuery = true;
- }
- if (updatedCnapName != null && !updatedCnapName.equals(info.cnapName)) {
- if (DBG) log("- displayMainCallStatus: updatedCnapName = "
- + updatedCnapName);
- runQuery = true;
- }
- }
- }
-
- if (runQuery) {
- if (DBG) log("- displayMainCallStatus: starting CallerInfo query...");
- PhoneUtils.CallerInfoToken info =
- PhoneUtils.startGetCallerInfo(getContext(), conn, this, call);
- updateDisplayForPerson(info.currentInfo, presentation, !info.isFinal,
- call, conn);
- } else {
- // No need to fire off a new query. We do still need
- // to update the display, though (since we might have
- // previously been in the "conference call" state.)
- if (DBG) log("- displayMainCallStatus: using data we already have...");
- if (o instanceof CallerInfo) {
- CallerInfo ci = (CallerInfo) o;
- // Update CNAP information if Phone state change occurred
- ci.cnapName = conn.getCnapName();
- ci.numberPresentation = conn.getNumberPresentation();
- ci.namePresentation = conn.getCnapNamePresentation();
- if (DBG) log("- displayMainCallStatus: CNAP data from Connection: "
- + "CNAP name=" + ci.cnapName
- + ", Number/Name Presentation=" + ci.numberPresentation);
- if (DBG) log(" ==> Got CallerInfo; updating display: ci = " + ci);
- updateDisplayForPerson(ci, presentation, false, call, conn);
- } else if (o instanceof PhoneUtils.CallerInfoToken){
- CallerInfo ci = ((PhoneUtils.CallerInfoToken) o).currentInfo;
- if (DBG) log("- displayMainCallStatus: CNAP data from Connection: "
- + "CNAP name=" + ci.cnapName
- + ", Number/Name Presentation=" + ci.numberPresentation);
- if (DBG) log(" ==> Got CallerInfoToken; updating display: ci = " + ci);
- updateDisplayForPerson(ci, presentation, true, call, conn);
- } else {
- Log.w(LOG_TAG, "displayMainCallStatus: runQuery was false, "
- + "but we didn't have a cached CallerInfo object! o = " + o);
- // TODO: any easy way to recover here (given that
- // the CallCard is probably displaying stale info
- // right now?) Maybe force the CallCard into the
- // "Unknown" state?
- }
- }
- }
- }
-
- // In some states we override the "photo" ImageView to be an
- // indication of the current state, rather than displaying the
- // regular photo as set above.
- updatePhotoForCallState(call);
-
- // One special feature of the "number" text field: For incoming
- // calls, while the user is dragging the RotarySelector widget, we
- // use mPhoneNumber to display a hint like "Rotate to answer".
- if (mIncomingCallWidgetHintTextResId != 0) {
- // Display the hint!
- mPhoneNumber.setText(mIncomingCallWidgetHintTextResId);
- mPhoneNumber.setTextColor(getResources().getColor(mIncomingCallWidgetHintColorResId));
- mPhoneNumber.setVisibility(View.VISIBLE);
- mLabel.setVisibility(View.GONE);
- }
- // If we don't have a hint to display, just don't touch
- // mPhoneNumber and mLabel. (Their text / color / visibility have
- // already been set correctly, by either updateDisplayForPerson()
- // or updateDisplayForConference().)
- }
-
- /**
- * Implemented for CallerInfoAsyncQuery.OnQueryCompleteListener interface.
- * refreshes the CallCard data when it called.
- */
- @Override
- public void onQueryComplete(int token, Object cookie, CallerInfo ci) {
- if (DBG) log("onQueryComplete: token " + token + ", cookie " + cookie + ", ci " + ci);
-
- if (cookie instanceof Call) {
- // grab the call object and update the display for an individual call,
- // as well as the successive call to update image via call state.
- // If the object is a textview instead, we update it as we need to.
- if (DBG) log("callerinfo query complete, updating ui from displayMainCallStatus()");
- Call call = (Call) cookie;
- Connection conn = null;
- int phoneType = call.getPhone().getPhoneType();
- if (phoneType == PhoneConstants.PHONE_TYPE_CDMA) {
- conn = call.getLatestConnection();
- } else if ((phoneType == PhoneConstants.PHONE_TYPE_GSM)
- || (phoneType == PhoneConstants.PHONE_TYPE_SIP)) {
- conn = call.getEarliestConnection();
- } else {
- throw new IllegalStateException("Unexpected phone type: " + phoneType);
- }
- PhoneUtils.CallerInfoToken cit =
- PhoneUtils.startGetCallerInfo(getContext(), conn, this, null);
-
- int presentation = PhoneConstants.PRESENTATION_ALLOWED;
- if (conn != null) presentation = conn.getNumberPresentation();
- if (DBG) log("- onQueryComplete: presentation=" + presentation
- + ", contactExists=" + ci.contactExists);
-
- // Depending on whether there was a contact match or not, we want to pass in different
- // CallerInfo (for CNAP). Therefore if ci.contactExists then use the ci passed in.
- // Otherwise, regenerate the CIT from the Connection and use the CallerInfo from there.
- if (ci.contactExists) {
- updateDisplayForPerson(ci, PhoneConstants.PRESENTATION_ALLOWED, false, call, conn);
- } else {
- updateDisplayForPerson(cit.currentInfo, presentation, false, call, conn);
- }
- updatePhotoForCallState(call);
-
- } else if (cookie instanceof TextView){
- if (DBG) log("callerinfo query complete, updating ui from ongoing or onhold");
- ((TextView) cookie).setText(PhoneUtils.getCompactNameFromCallerInfo(ci, mContext));
- }
- }
-
- /**
- * Implemented for ContactsAsyncHelper.OnImageLoadCompleteListener interface.
- * make sure that the call state is reflected after the image is loaded.
- */
- @Override
- public void onImageLoadComplete(int token, Drawable photo, Bitmap photoIcon, Object cookie) {
- mHandler.removeMessages(MESSAGE_SHOW_UNKNOWN_PHOTO);
- if (mLoadingPersonUri != null) {
- // Start sending view notification after the current request being done.
- // New image may possibly be available from the next phone calls.
- //
- // TODO: may be nice to update the image view again once the newer one
- // is available on contacts database.
- PhoneUtils.sendViewNotificationAsync(mApplication, mLoadingPersonUri);
- } else {
- // This should not happen while we need some verbose info if it happens..
- Log.w(LOG_TAG, "Person Uri isn't available while Image is successfully loaded.");
- }
- mLoadingPersonUri = null;
-
- AsyncLoadCookie asyncLoadCookie = (AsyncLoadCookie) cookie;
- CallerInfo callerInfo = asyncLoadCookie.callerInfo;
- ImageView imageView = asyncLoadCookie.imageView;
- Call call = asyncLoadCookie.call;
-
- callerInfo.cachedPhoto = photo;
- callerInfo.cachedPhotoIcon = photoIcon;
- callerInfo.isCachedPhotoCurrent = true;
-
- // Note: previously ContactsAsyncHelper has done this job.
- // TODO: We will need fade-in animation. See issue 5236130.
- if (photo != null) {
- showImage(imageView, photo);
- } else if (photoIcon != null) {
- showImage(imageView, photoIcon);
- } else {
- showImage(imageView, R.drawable.picture_unknown);
- }
-
- if (token == TOKEN_UPDATE_PHOTO_FOR_CALL_STATE) {
- updatePhotoForCallState(call);
- }
- }
-
- /**
- * Updates the "call state label" and the elapsed time widget based on the
- * current state of the call.
- */
- private void updateCallStateWidgets(Call call) {
- if (DBG) log("updateCallStateWidgets(call " + call + ")...");
- final Call.State state = call.getState();
- final Context context = getContext();
- final Phone phone = call.getPhone();
- final int phoneType = phone.getPhoneType();
-
- String callStateLabel = null; // Label to display as part of the call banner
- int bluetoothIconId = 0; // Icon to display alongside the call state label
-
- switch (state) {
- case IDLE:
- // "Call state" is meaningless in this state.
- break;
-
- case ACTIVE:
- // We normally don't show a "call state label" at all in
- // this state (but see below for some special cases).
- break;
-
- case HOLDING:
- callStateLabel = context.getString(R.string.card_title_on_hold);
- break;
-
- case DIALING:
- case ALERTING:
- callStateLabel = context.getString(R.string.card_title_dialing);
- break;
-
- case INCOMING:
- case WAITING:
- callStateLabel = context.getString(R.string.card_title_incoming_call);
-
- // Also, display a special icon (alongside the "Incoming call"
- // label) if there's an incoming call and audio will be routed
- // to bluetooth when you answer it.
- // TODO(klp): Add bluetooth label to new UI screen for incoming calls.
- //if (mApplication.showBluetoothIndication()) {
- // bluetoothIconId = R.drawable.ic_incoming_call_bluetooth;
- //}
- break;
-
- case DISCONNECTING:
- // While in the DISCONNECTING state we display a "Hanging up"
- // message in order to make the UI feel more responsive. (In
- // GSM it's normal to see a delay of a couple of seconds while
- // negotiating the disconnect with the network, so the "Hanging
- // up" state at least lets the user know that we're doing
- // something. This state is currently not used with CDMA.)
- callStateLabel = context.getString(R.string.card_title_hanging_up);
- break;
-
- case DISCONNECTED:
- callStateLabel = getCallFailedString(call);
- break;
-
- default:
- Log.wtf(LOG_TAG, "updateCallStateWidgets: unexpected call state: " + state);
- break;
- }
-
- // Check a couple of other special cases (these are all CDMA-specific).
-
- // TODO(klp): This code should go into the CallModeler logic instead of the UI.
- if (phoneType == PhoneConstants.PHONE_TYPE_CDMA) {
- if ((state == Call.State.ACTIVE)
- && mApplication.cdmaPhoneCallState.IsThreeWayCallOrigStateDialing()) {
- // 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 (PhoneGlobals.getInstance().notifier.getIsCdmaRedialCall()) {
- callStateLabel = context.getString(R.string.card_title_redialing);
- }
- }
- if (PhoneUtils.isPhoneInEcm(phone)) {
- // In emergency callback mode (ECM), use a special label
- // that shows your own phone number.
- callStateLabel = getECMCardTitle(context, phone);
- }
-
- final InCallUiState inCallUiState = mApplication.inCallUiState;
- if (DBG) {
- log("==> callStateLabel: '" + callStateLabel
- + "', bluetoothIconId = " + bluetoothIconId);
- }
-
- // Animation will be done by mCallerDetail's LayoutTransition, but in some cases, we don't
- // want that.
- // - DIALING: This is at the beginning of the phone call.
- // - DISCONNECTING, DISCONNECTED: Screen will disappear soon; we have no time for animation.
- final boolean skipAnimation = (state == Call.State.DIALING
- || state == Call.State.DISCONNECTING
- || state == Call.State.DISCONNECTED);
- LayoutTransition layoutTransition = null;
-
- if (!TextUtils.isEmpty(callStateLabel)) {
- mCallStateLabel.setVisibility(View.VISIBLE);
- mCallStateLabel.setText(callStateLabel);
-
- // ...and display the icon too if necessary.
- if (bluetoothIconId != 0) {
- mCallStateLabel.setCompoundDrawablesWithIntrinsicBounds(bluetoothIconId, 0, 0, 0);
- mCallStateLabel.setCompoundDrawablePadding((int) (mDensity * 5));
- } else {
- // Clear out any icons
- mCallStateLabel.setCompoundDrawablesWithIntrinsicBounds(0, 0, 0, 0);
- }
- } 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.END) {
- mCallStateLabel.setText("");
- mCallStateLabel.setGravity(Gravity.END);
- }
- }
-
- // ...and update the elapsed time widget too.
- switch (state) {
- case ACTIVE:
- case DISCONNECTING:
- // Show the time with fade-in animation.
- AnimationUtils.Fade.show(mElapsedTime);
- updateElapsedTimeWidget(call);
- break;
-
- case DISCONNECTED:
- // In the "Call ended" state, leave the mElapsedTime widget
- // visible, but don't touch it (so we continue to see the
- // elapsed time of the call that just ended.)
- // Check visibility to keep possible fade-in animation.
- if (mElapsedTime.getVisibility() != View.VISIBLE) {
- mElapsedTime.setVisibility(View.VISIBLE);
- }
- break;
-
- default:
- // Call state here is IDLE, ACTIVE, HOLDING, DIALING, ALERTING,
- // INCOMING, or WAITING.
- // In all of these states, the "elapsed time" is meaningless, so
- // don't show it.
- AnimationUtils.Fade.hide(mElapsedTime, View.INVISIBLE);
-
- // Additionally, in call states that can only occur at the start
- // of a call, reset the elapsed time to be sure we won't display
- // stale info later (like if we somehow go straight from DIALING
- // or ALERTING to DISCONNECTED, which can actually happen in
- // some failure cases like "line busy").
- if ((state == Call.State.DIALING) || (state == Call.State.ALERTING)) {
- updateElapsedTimeWidget(0);
- }
-
- break;
- }
- }
-
- /**
- * Updates mElapsedTime based on the given {@link Call} object's information.
- *
- * @see CallTime#getCallDuration(Call)
- * @see Connection#getDurationMillis()
- */
- /* package */ void updateElapsedTimeWidget(Call call) {
- long duration = CallTime.getCallDuration(call); // msec
- updateElapsedTimeWidget(duration / 1000);
- // Also see onTickForCallTimeElapsed(), which updates this
- // widget once per second while the call is active.
- }
-
- /**
- * Updates mElapsedTime based on the specified number of seconds.
- */
- private void updateElapsedTimeWidget(long timeElapsed) {
- // if (DBG) log("updateElapsedTimeWidget: " + timeElapsed);
- mElapsedTime.setText(DateUtils.formatElapsedTime(timeElapsed));
- }
-
- /**
- * Updates the "on hold" box in the "other call" info area
- * (ie. the stuff in the secondaryCallInfo block)
- * based on the specified Call.
- * Or, clear out the "on hold" box if the specified call
- * is null or idle.
- */
- private void displaySecondaryCallStatus(CallManager cm, Call call) {
- if (DBG) log("displayOnHoldCallStatus(call =" + call + ")...");
-
- if ((call == null) || (PhoneGlobals.getInstance().isOtaCallInActiveState())) {
- mSecondaryCallInfo.setVisibility(View.GONE);
- return;
- }
-
- Call.State state = call.getState();
- switch (state) {
- case HOLDING:
- // Ok, there actually is a background call on hold.
- // Display the "on hold" box.
-
- // Note this case occurs only on GSM devices. (On CDMA,
- // the "call on hold" is actually the 2nd connection of
- // that ACTIVE call; see the ACTIVE case below.)
- showSecondaryCallInfo();
-
- if (PhoneUtils.isConferenceCall(call)) {
- if (DBG) log("==> conference call.");
- mSecondaryCallName.setText(getContext().getString(R.string.confCall));
- showImage(mSecondaryCallPhoto, R.drawable.picture_conference);
- } else {
- // perform query and update the name temporarily
- // make sure we hand the textview we want updated to the
- // callback function.
- if (DBG) log("==> NOT a conf call; call startGetCallerInfo...");
- PhoneUtils.CallerInfoToken infoToken = PhoneUtils.startGetCallerInfo(
- getContext(), call, this, mSecondaryCallName);
- mSecondaryCallName.setText(
- PhoneUtils.getCompactNameFromCallerInfo(infoToken.currentInfo,
- getContext()));
-
- // Also pull the photo out of the current CallerInfo.
- // (Note we assume we already have a valid photo at
- // this point, since *presumably* the caller-id query
- // was already run at some point *before* this call
- // got put on hold. If there's no cached photo, just
- // fall back to the default "unknown" image.)
- if (infoToken.isFinal) {
- showCachedImage(mSecondaryCallPhoto, infoToken.currentInfo);
- } else {
- showImage(mSecondaryCallPhoto, R.drawable.picture_unknown);
- }
- }
-
- AnimationUtils.Fade.show(mSecondaryCallPhotoDimEffect);
- break;
-
- case ACTIVE:
- // CDMA: This is because in CDMA when the user originates the second call,
- // although the Foreground call state is still ACTIVE in reality the network
- // put the first call on hold.
- if (mApplication.phone.getPhoneType() == PhoneConstants.PHONE_TYPE_CDMA) {
- showSecondaryCallInfo();
-
- 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 PhoneGlobals that we no
- // longer know which previous caller/party had dropped out before the user
- // made this call.
- mSecondaryCallName.setText(
- getContext().getString(R.string.card_title_in_call));
- showImage(mSecondaryCallPhoto, R.drawable.picture_unknown);
- } else {
- // This means that the current Mobile Originated call IS the first 3-Way
- // and hence we display the first callers/party's info here.
- Connection conn = call.getEarliestConnection();
- PhoneUtils.CallerInfoToken infoToken = PhoneUtils.startGetCallerInfo(
- getContext(), conn, this, mSecondaryCallName);
-
- // Get the compactName to be displayed, but then check that against
- // the number presentation value for the call. If it's not an allowed
- // presentation, then display the appropriate presentation string instead.
- CallerInfo info = infoToken.currentInfo;
-
- String name = PhoneUtils.getCompactNameFromCallerInfo(info, getContext());
- boolean forceGenericPhoto = false;
- if (info != null && info.numberPresentation !=
- PhoneConstants.PRESENTATION_ALLOWED) {
- name = PhoneUtils.getPresentationString(
- getContext(), info.numberPresentation);
- forceGenericPhoto = true;
- }
- mSecondaryCallName.setText(name);
-
- // Also pull the photo out of the current CallerInfo.
- // (Note we assume we already have a valid photo at
- // this point, since *presumably* the caller-id query
- // was already run at some point *before* this call
- // got put on hold. If there's no cached photo, just
- // fall back to the default "unknown" image.)
- if (!forceGenericPhoto && infoToken.isFinal) {
- showCachedImage(mSecondaryCallPhoto, info);
- } else {
- showImage(mSecondaryCallPhoto, R.drawable.picture_unknown);
- }
- }
- } else {
- // We shouldn't ever get here at all for non-CDMA devices.
- Log.w(LOG_TAG, "displayOnHoldCallStatus: ACTIVE state on non-CDMA device");
- mSecondaryCallInfo.setVisibility(View.GONE);
- }
-
- AnimationUtils.Fade.hide(mSecondaryCallPhotoDimEffect, View.GONE);
- break;
-
- default:
- // There's actually no call on hold. (Presumably this call's
- // state is IDLE, since any other state is meaningless for the
- // background call.)
- mSecondaryCallInfo.setVisibility(View.GONE);
- break;
- }
- }
-
- private void showSecondaryCallInfo() {
- // This will call ViewStub#inflate() when needed.
- mSecondaryCallInfo.setVisibility(View.VISIBLE);
- if (mSecondaryCallName == null) {
- mSecondaryCallName = (TextView) findViewById(R.id.secondaryCallName);
- }
- if (mSecondaryCallPhoto == null) {
- mSecondaryCallPhoto = (ImageView) findViewById(R.id.secondaryCallPhoto);
- }
- if (mSecondaryCallPhotoDimEffect == null) {
- mSecondaryCallPhotoDimEffect = findViewById(R.id.dim_effect_for_secondary_photo);
- mSecondaryCallPhotoDimEffect.setOnClickListener(mInCallScreen);
- // Add a custom OnTouchListener to manually shrink the "hit target".
- mSecondaryCallPhotoDimEffect.setOnTouchListener(new SmallerHitTargetTouchListener());
- }
- mInCallScreen.updateButtonStateOutsideInCallTouchUi();
- }
-
- /**
- * Method which is expected to be called from
- * {@link InCallScreen#updateButtonStateOutsideInCallTouchUi()}.
- */
- /* package */ void setSecondaryCallClickable(boolean clickable) {
- if (mSecondaryCallPhotoDimEffect != null) {
- mSecondaryCallPhotoDimEffect.setEnabled(clickable);
- }
- }
-
- private String getCallFailedString(Call call) {
- Connection c = call.getEarliestConnection();
- int resID;
-
- if (c == null) {
- if (DBG) log("getCallFailedString: connection is null, using default values.");
- // if this connection is null, just assume that the
- // default case occurs.
- resID = R.string.card_title_call_ended;
- } else {
-
- Connection.DisconnectCause cause = c.getDisconnectCause();
-
- // TODO: The card *title* should probably be "Call ended" in all
- // cases, but if the DisconnectCause was an error condition we should
- // probably also display the specific failure reason somewhere...
-
- switch (cause) {
- case BUSY:
- resID = R.string.callFailed_userBusy;
- break;
-
- case CONGESTION:
- resID = R.string.callFailed_congestion;
- break;
-
- case TIMED_OUT:
- resID = R.string.callFailed_timedOut;
- break;
-
- case SERVER_UNREACHABLE:
- resID = R.string.callFailed_server_unreachable;
- break;
-
- case NUMBER_UNREACHABLE:
- resID = R.string.callFailed_number_unreachable;
- break;
-
- case INVALID_CREDENTIALS:
- resID = R.string.callFailed_invalid_credentials;
- break;
-
- case SERVER_ERROR:
- resID = R.string.callFailed_server_error;
- break;
-
- case OUT_OF_NETWORK:
- resID = R.string.callFailed_out_of_network;
- break;
-
- case LOST_SIGNAL:
- case CDMA_DROP:
- resID = R.string.callFailed_noSignal;
- break;
-
- case LIMIT_EXCEEDED:
- resID = R.string.callFailed_limitExceeded;
- break;
-
- case POWER_OFF:
- resID = R.string.callFailed_powerOff;
- break;
-
- case ICC_ERROR:
- resID = R.string.callFailed_simError;
- break;
-
- case OUT_OF_SERVICE:
- resID = R.string.callFailed_outOfService;
- break;
-
- case INVALID_NUMBER:
- case UNOBTAINABLE_NUMBER:
- resID = R.string.callFailed_unobtainable_number;
- break;
-
- default:
- resID = R.string.card_title_call_ended;
- break;
- }
- }
- return getContext().getString(resID);
- }
-
- /**
- * Updates the name / photo / number / label fields on the CallCard
- * based on the specified CallerInfo.
- *
- * If the current call is a conference call, use
- * updateDisplayForConference() instead.
- */
- private void updateDisplayForPerson(CallerInfo info,
- int presentation,
- boolean isTemporary,
- Call call,
- Connection conn) {
- if (DBG) log("updateDisplayForPerson(" + info + ")\npresentation:" +
- presentation + " isTemporary:" + isTemporary);
-
- // inform the state machine that we are displaying a photo.
- mPhotoTracker.setPhotoRequest(info);
- mPhotoTracker.setPhotoState(ContactsAsyncHelper.ImageTracker.DISPLAY_IMAGE);
-
- // The actual strings we're going to display onscreen:
- String displayName;
- String displayNumber = null;
- String label = null;
- Uri personUri = null;
- // String socialStatusText = null;
- // Drawable socialStatusBadge = null;
-
- // Gather missing info unless the call is generic, in which case we wouldn't use
- // the gathered information anyway.
- if (info != null && !call.isGeneric()) {
-
- // It appears that there is a small change in behaviour with the
- // PhoneUtils' startGetCallerInfo whereby if we query with an
- // empty number, we will get a valid CallerInfo object, but with
- // fields that are all null, and the isTemporary boolean input
- // parameter as true.
-
- // In the past, we would see a NULL callerinfo object, but this
- // ends up causing null pointer exceptions elsewhere down the
- // line in other cases, so we need to make this fix instead. It
- // appears that this was the ONLY call to PhoneUtils
- // .getCallerInfo() that relied on a NULL CallerInfo to indicate
- // an unknown contact.
-
- // Currently, infi.phoneNumber may actually be a SIP address, and
- // if so, it might sometimes include the "sip:" prefix. That
- // prefix isn't really useful to the user, though, so strip it off
- // if present. (For any other URI scheme, though, leave the
- // prefix alone.)
- // TODO: It would be cleaner for CallerInfo to explicitly support
- // SIP addresses instead of overloading the "phoneNumber" field.
- // Then we could remove this hack, and instead ask the CallerInfo
- // for a "user visible" form of the SIP address.
- String number = info.phoneNumber;
- if ((number != null) && number.startsWith("sip:")) {
- number = number.substring(4);
- }
-
- if (TextUtils.isEmpty(info.name)) {
- // No valid "name" in the CallerInfo, so fall back to
- // something else.
- // (Typically, we promote the phone number up to the "name" slot
- // onscreen, and possibly display a descriptive string in the
- // "number" slot.)
- if (TextUtils.isEmpty(number)) {
- // No name *or* number! Display a generic "unknown" string
- // (or potentially some other default based on the presentation.)
- displayName = PhoneUtils.getPresentationString(getContext(), presentation);
- if (DBG) log(" ==> no name *or* number! displayName = " + displayName);
- } else if (presentation != PhoneConstants.PRESENTATION_ALLOWED) {
- // This case should never happen since the network should never send a phone #
- // AND a restricted presentation. However we leave it here in case of weird
- // network behavior
- displayName = PhoneUtils.getPresentationString(getContext(), presentation);
- if (DBG) log(" ==> presentation not allowed! displayName = " + displayName);
- } else if (!TextUtils.isEmpty(info.cnapName)) {
- // No name, but we do have a valid CNAP name, so use that.
- displayName = info.cnapName;
- info.name = info.cnapName;
- displayNumber = number;
- if (DBG) log(" ==> cnapName available: displayName '"
- + displayName + "', displayNumber '" + displayNumber + "'");
- } else {
- // No name; all we have is a number. This is the typical
- // case when an incoming call doesn't match any contact,
- // or if you manually dial an outgoing number using the
- // dialpad.
-
- // Promote the phone number up to the "name" slot:
- displayName = number;
-
- // ...and use the "number" slot for a geographical description
- // string if available (but only for incoming calls.)
- if ((conn != null) && (conn.isIncoming())) {
- // TODO (CallerInfoAsyncQuery cleanup): Fix the CallerInfo
- // query to only do the geoDescription lookup in the first
- // place for incoming calls.
- displayNumber = info.geoDescription; // may be null
- }
-
- if (DBG) log(" ==> no name; falling back to number: displayName '"
- + displayName + "', displayNumber '" + displayNumber + "'");
- }
- } else {
- // We do have a valid "name" in the CallerInfo. Display that
- // in the "name" slot, and the phone number in the "number" slot.
- if (presentation != PhoneConstants.PRESENTATION_ALLOWED) {
- // This case should never happen since the network should never send a name
- // AND a restricted presentation. However we leave it here in case of weird
- // network behavior
- displayName = PhoneUtils.getPresentationString(getContext(), presentation);
- if (DBG) log(" ==> valid name, but presentation not allowed!"
- + " displayName = " + displayName);
- } else {
- displayName = info.name;
- displayNumber = number;
- label = info.phoneLabel;
- if (DBG) log(" ==> name is present in CallerInfo: displayName '"
- + displayName + "', displayNumber '" + displayNumber + "'");
- }
- }
- personUri = ContentUris.withAppendedId(Contacts.CONTENT_URI, info.person_id);
- if (DBG) log("- got personUri: '" + personUri
- + "', based on info.person_id: " + info.person_id);
- } else {
- displayName = PhoneUtils.getPresentationString(getContext(), presentation);
- }
-
- if (call.isGeneric()) {
- updateGenericInfoUi();
- } else {
- updateInfoUi(displayName, displayNumber, label);
- }
-
- // Update mPhoto
- // if the temporary flag is set, we know we'll be getting another call after
- // the CallerInfo has been correctly updated. So, we can skip the image
- // loading until then.
-
- // If the photoResource is filled in for the CallerInfo, (like with the
- // Emergency Number case), then we can just set the photo image without
- // requesting for an image load. Please refer to CallerInfoAsyncQuery.java
- // for cases where CallerInfo.photoResource may be set. We can also avoid
- // the image load step if the image data is cached.
- if (isTemporary && (info == null || !info.isCachedPhotoCurrent)) {
- mPhoto.setTag(null);
- mPhoto.setVisibility(View.INVISIBLE);
- } else if (info != null && info.photoResource != 0){
- showImage(mPhoto, info.photoResource);
- } else if (!showCachedImage(mPhoto, info)) {
- if (personUri == null) {
- Log.w(LOG_TAG, "personPri is null. Just use Unknown picture.");
- showImage(mPhoto, R.drawable.picture_unknown);
- } else if (personUri.equals(mLoadingPersonUri)) {
- if (DBG) {
- log("The requested Uri (" + personUri + ") is being loaded already."
- + " Ignoret the duplicate load request.");
- }
- } else {
- // Remember which person's photo is being loaded right now so that we won't issue
- // unnecessary load request multiple times, which will mess up animation around
- // the contact photo.
- mLoadingPersonUri = personUri;
-
- // Forget the drawable previously used.
- mPhoto.setTag(null);
- // Show empty screen for a moment.
- mPhoto.setVisibility(View.INVISIBLE);
- // Load the image with a callback to update the image state.
- // When the load is finished, onImageLoadComplete() will be called.
- ContactsAsyncHelper.startObtainPhotoAsync(TOKEN_UPDATE_PHOTO_FOR_CALL_STATE,
- getContext(), personUri, this, new AsyncLoadCookie(mPhoto, info, call));
-
- // If the image load is too slow, we show a default avatar icon afterward.
- // If it is fast enough, this message will be canceled on onImageLoadComplete().
- mHandler.removeMessages(MESSAGE_SHOW_UNKNOWN_PHOTO);
- mHandler.sendEmptyMessageDelayed(MESSAGE_SHOW_UNKNOWN_PHOTO, MESSAGE_DELAY);
- }
- }
-
- // If the phone call is on hold, show it with darker status.
- // Right now we achieve it by overlaying opaque View.
- // Note: See also layout file about why so and what is the other possibilities.
- if (call.getState() == Call.State.HOLDING) {
- AnimationUtils.Fade.show(mPhotoDimEffect);
- } else {
- AnimationUtils.Fade.hide(mPhotoDimEffect, View.GONE);
- }
-
- // Other text fields:
- updateCallTypeLabel(call);
- // updateSocialStatus(socialStatusText, socialStatusBadge, call); // Currently unused
- }
-
- /**
- * Updates the info portion of the UI to be generic. Used for CDMA 3-way calls.
- */
- private void updateGenericInfoUi() {
- mName.setText(R.string.card_title_in_call);
- mPhoneNumber.setVisibility(View.GONE);
- mLabel.setVisibility(View.GONE);
- }
-
- /**
- * Updates the info portion of the call card with passed in values.
- */
- private void updateInfoUi(String displayName, String displayNumber, String label) {
- mName.setText(displayName);
- mName.setVisibility(View.VISIBLE);
-
- if (TextUtils.isEmpty(displayNumber)) {
- mPhoneNumber.setVisibility(View.GONE);
- // We have a real phone number as "mName" so make it always LTR
- mName.setTextDirection(View.TEXT_DIRECTION_LTR);
- } else {
- mPhoneNumber.setText(displayNumber);
- mPhoneNumber.setVisibility(View.VISIBLE);
- // We have a real phone number as "mPhoneNumber" so make it always LTR
- mPhoneNumber.setTextDirection(View.TEXT_DIRECTION_LTR);
- }
-
- if (TextUtils.isEmpty(label)) {
- mLabel.setVisibility(View.GONE);
- } else {
- mLabel.setText(label);
- mLabel.setVisibility(View.VISIBLE);
- }
- }
-
- /**
- * Updates the name / photo / number / label fields
- * for the special "conference call" state.
- *
- * If the current call has only a single connection, use
- * updateDisplayForPerson() instead.
- */
- private void updateDisplayForConference(Call call) {
- if (DBG) log("updateDisplayForConference()...");
-
- int phoneType = call.getPhone().getPhoneType();
- if (phoneType == PhoneConstants.PHONE_TYPE_CDMA) {
- // This state corresponds to both 3-Way merged call and
- // Call Waiting accepted call.
- // In this case we display the UI in a "generic" state, with
- // the generic "dialing" icon and no caller information,
- // because in this state in CDMA the user does not really know
- // which caller party he is talking to.
- showImage(mPhoto, R.drawable.picture_dialing);
- mName.setText(R.string.card_title_in_call);
- } else if ((phoneType == PhoneConstants.PHONE_TYPE_GSM)
- || (phoneType == PhoneConstants.PHONE_TYPE_SIP)) {
- // Normal GSM (or possibly SIP?) conference call.
- // Display the "conference call" image as the contact photo.
- // TODO: Better visual treatment for contact photos in a
- // conference call (see bug 1313252).
- showImage(mPhoto, R.drawable.picture_conference);
- mName.setText(R.string.card_title_conf_call);
- } else {
- throw new IllegalStateException("Unexpected phone type: " + phoneType);
- }
-
- mName.setVisibility(View.VISIBLE);
-
- // TODO: For a conference call, the "phone number" slot is specced
- // to contain a summary of who's on the call, like "Bill Foldes
- // and Hazel Nutt" or "Bill Foldes and 2 others".
- // But for now, just hide it:
- mPhoneNumber.setVisibility(View.GONE);
- mLabel.setVisibility(View.GONE);
-
- // Other text fields:
- updateCallTypeLabel(call);
- // updateSocialStatus(null, null, null); // socialStatus is never visible in this state
-
- // TODO: for a GSM conference call, since we do actually know who
- // you're talking to, consider also showing names / numbers /
- // photos of some of the people on the conference here, so you can
- // see that info without having to click "Manage conference". We
- // probably have enough space to show info for 2 people, at least.
- //
- // To do this, our caller would pass us the activeConnections
- // list, and we'd call PhoneUtils.getCallerInfo() separately for
- // each connection.
- }
-
- /**
- * Updates the CallCard "photo" IFF the specified Call is in a state
- * that needs a special photo (like "busy" or "dialing".)
- *
- * If the current call does not require a special image in the "photo"
- * slot onscreen, don't do anything, since presumably the photo image
- * has already been set (to the photo of the person we're talking, or
- * the generic "picture_unknown" image, or the "conference call"
- * image.)
- */
- private void updatePhotoForCallState(Call call) {
- if (DBG) log("updatePhotoForCallState(" + call + ")...");
- int photoImageResource = 0;
-
- // Check for the (relatively few) telephony states that need a
- // special image in the "photo" slot.
- Call.State state = call.getState();
- switch (state) {
- case DISCONNECTED:
- // Display the special "busy" photo for BUSY or CONGESTION.
- // Otherwise (presumably the normal "call ended" state)
- // leave the photo alone.
- Connection c = call.getEarliestConnection();
- // if the connection is null, we assume the default case,
- // otherwise update the image resource normally.
- if (c != null) {
- Connection.DisconnectCause cause = c.getDisconnectCause();
- if ((cause == Connection.DisconnectCause.BUSY)
- || (cause == Connection.DisconnectCause.CONGESTION)) {
- photoImageResource = R.drawable.picture_busy;
- }
- } else if (DBG) {
- log("updatePhotoForCallState: connection is null, ignoring.");
- }
-
- // TODO: add special images for any other DisconnectCauses?
- break;
-
- case ALERTING:
- case DIALING:
- default:
- // Leave the photo alone in all other states.
- // If this call is an individual call, and the image is currently
- // displaying a state, (rather than a photo), we'll need to update
- // the image.
- // This is for the case where we've been displaying the state and
- // now we need to restore the photo. This can happen because we
- // only query the CallerInfo once, and limit the number of times
- // the image is loaded. (So a state image may overwrite the photo
- // and we would otherwise have no way of displaying the photo when
- // the state goes away.)
-
- // if the photoResource field is filled-in in the Connection's
- // caller info, then we can just use that instead of requesting
- // for a photo load.
-
- // look for the photoResource if it is available.
- CallerInfo ci = null;
- {
- Connection conn = null;
- int phoneType = call.getPhone().getPhoneType();
- if (phoneType == PhoneConstants.PHONE_TYPE_CDMA) {
- conn = call.getLatestConnection();
- } else if ((phoneType == PhoneConstants.PHONE_TYPE_GSM)
- || (phoneType == PhoneConstants.PHONE_TYPE_SIP)) {
- conn = call.getEarliestConnection();
- } else {
- throw new IllegalStateException("Unexpected phone type: " + phoneType);
- }
-
- if (conn != null) {
- Object o = conn.getUserData();
- if (o instanceof CallerInfo) {
- ci = (CallerInfo) o;
- } else if (o instanceof PhoneUtils.CallerInfoToken) {
- ci = ((PhoneUtils.CallerInfoToken) o).currentInfo;
- }
- }
- }
-
- if (ci != null) {
- photoImageResource = ci.photoResource;
- }
-
- // If no photoResource found, check to see if this is a conference call. If
- // it is not a conference call:
- // 1. Try to show the cached image
- // 2. If the image is not cached, check to see if a load request has been
- // made already.
- // 3. If the load request has not been made [DISPLAY_DEFAULT], start the
- // request and note that it has started by updating photo state with
- // [DISPLAY_IMAGE].
- if (photoImageResource == 0) {
- if (!PhoneUtils.isConferenceCall(call)) {
- if (!showCachedImage(mPhoto, ci) && (mPhotoTracker.getPhotoState() ==
- ContactsAsyncHelper.ImageTracker.DISPLAY_DEFAULT)) {
- Uri photoUri = mPhotoTracker.getPhotoUri();
- if (photoUri == null) {
- Log.w(LOG_TAG, "photoUri became null. Show default avatar icon");
- showImage(mPhoto, R.drawable.picture_unknown);
- } else {
- if (DBG) {
- log("start asynchronous load inside updatePhotoForCallState()");
- }
- mPhoto.setTag(null);
- // Make it invisible for a moment
- mPhoto.setVisibility(View.INVISIBLE);
- ContactsAsyncHelper.startObtainPhotoAsync(TOKEN_DO_NOTHING,
- getContext(), photoUri, this,
- new AsyncLoadCookie(mPhoto, ci, null));
- }
- mPhotoTracker.setPhotoState(
- ContactsAsyncHelper.ImageTracker.DISPLAY_IMAGE);
- }
- }
- } else {
- showImage(mPhoto, photoImageResource);
- mPhotoTracker.setPhotoState(ContactsAsyncHelper.ImageTracker.DISPLAY_IMAGE);
- return;
- }
- break;
- }
-
- if (photoImageResource != 0) {
- if (DBG) log("- overrriding photo image: " + photoImageResource);
- showImage(mPhoto, photoImageResource);
- // Track the image state.
- mPhotoTracker.setPhotoState(ContactsAsyncHelper.ImageTracker.DISPLAY_DEFAULT);
- }
- }
-
- /**
- * Try to display the cached image from the callerinfo object.
- *
- * @return true if we were able to find the image in the cache, false otherwise.
- */
- private static final boolean showCachedImage(ImageView view, CallerInfo ci) {
- if ((ci != null) && ci.isCachedPhotoCurrent) {
- if (ci.cachedPhoto != null) {
- showImage(view, ci.cachedPhoto);
- } else {
- showImage(view, R.drawable.picture_unknown);
- }
- return true;
- }
- return false;
- }
-
- /** Helper function to display the resource in the imageview AND ensure its visibility.*/
- private static final void showImage(ImageView view, int resource) {
- showImage(view, view.getContext().getResources().getDrawable(resource));
- }
-
- private static final void showImage(ImageView view, Bitmap bitmap) {
- showImage(view, new BitmapDrawable(view.getContext().getResources(), bitmap));
- }
-
- /** Helper function to display the drawable in the imageview AND ensure its visibility.*/
- private static final void showImage(ImageView view, Drawable drawable) {
- Resources res = view.getContext().getResources();
- Drawable current = (Drawable) view.getTag();
-
- if (current == null) {
- if (DBG) log("Start fade-in animation for " + view);
- view.setImageDrawable(drawable);
- AnimationUtils.Fade.show(view);
- view.setTag(drawable);
- } else {
- AnimationUtils.startCrossFade(view, current, drawable);
- view.setVisibility(View.VISIBLE);
- }
- }
-
- /**
- * Returns the special card title used in emergency callback mode (ECM),
- * which shows your own phone number.
- */
- private String getECMCardTitle(Context context, Phone phone) {
- String rawNumber = phone.getLine1Number(); // may be null or empty
- String formattedNumber;
- if (!TextUtils.isEmpty(rawNumber)) {
- formattedNumber = PhoneNumberUtils.formatNumber(rawNumber);
- } else {
- formattedNumber = context.getString(R.string.unknown);
- }
- String titleFormat = context.getString(R.string.card_title_my_phone_number);
- return String.format(titleFormat, formattedNumber);
- }
-
- /**
- * Updates the "Call type" label, based on the current foreground call.
- * This is a special label and/or branding we display for certain
- * kinds of calls.
- *
- * (So far, this is used only for SIP calls, which get an
- * "Internet call" label. TODO: But eventually, the telephony
- * layer might allow each pluggable "provider" to specify a string
- * and/or icon to be displayed here.)
- */
- private void updateCallTypeLabel(Call call) {
- int phoneType = (call != null) ? call.getPhone().getPhoneType() :
- PhoneConstants.PHONE_TYPE_NONE;
- if (phoneType == PhoneConstants.PHONE_TYPE_SIP) {
- mCallTypeLabel.setVisibility(View.VISIBLE);
- mCallTypeLabel.setText(R.string.incall_call_type_label_sip);
- mCallTypeLabel.setTextColor(mTextColorCallTypeSip);
- // If desired, we could also display a "badge" next to the label, as follows:
- // mCallTypeLabel.setCompoundDrawablesWithIntrinsicBounds(
- // callTypeSpecificBadge, null, null, null);
- // mCallTypeLabel.setCompoundDrawablePadding((int) (mDensity * 6));
- } else {
- mCallTypeLabel.setVisibility(View.GONE);
- }
- }
-
- /**
- * Updates the "social status" label with the specified text and
- * (optional) badge.
- */
- /*private void updateSocialStatus(String socialStatusText,
- Drawable socialStatusBadge,
- Call call) {
- // The socialStatus field is *only* visible while an incoming call
- // is ringing, never in any other call state.
- if ((socialStatusText != null)
- && (call != null)
- && call.isRinging()
- && !call.isGeneric()) {
- mSocialStatus.setVisibility(View.VISIBLE);
- mSocialStatus.setText(socialStatusText);
- mSocialStatus.setCompoundDrawablesWithIntrinsicBounds(
- socialStatusBadge, null, null, null);
- mSocialStatus.setCompoundDrawablePadding((int) (mDensity * 6));
- } else {
- mSocialStatus.setVisibility(View.GONE);
- }
- }*/
-
- /**
- * Hides the top-level UI elements of the call card: The "main
- * call card" element representing the current active or ringing call,
- * and also the info areas for "ongoing" or "on hold" calls in some
- * states.
- *
- * This is intended to be used in special states where the normal
- * in-call UI is totally replaced by some other UI, like OTA mode on a
- * CDMA device.
- *
- * To bring back the regular CallCard UI, just re-run the normal
- * updateState() call sequence.
- */
- public void hideCallCardElements() {
- mPrimaryCallInfo.setVisibility(View.GONE);
- mSecondaryCallInfo.setVisibility(View.GONE);
- }
-
- /*
- * Updates the hint (like "Rotate to answer") that we display while
- * the user is dragging the incoming call RotarySelector widget.
- */
- /* package */ void setIncomingCallWidgetHint(int hintTextResId, int hintColorResId) {
- mIncomingCallWidgetHintTextResId = hintTextResId;
- mIncomingCallWidgetHintColorResId = hintColorResId;
- }
-
- // Accessibility event support.
- // Since none of the CallCard elements are focusable, we need to manually
- // fill in the AccessibilityEvent here (so that the name / number / etc will
- // get pronounced by a screen reader, for example.)
- @Override
- public boolean dispatchPopulateAccessibilityEvent(AccessibilityEvent event) {
- if (event.getEventType() == AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED) {
- dispatchPopulateAccessibilityEvent(event, mName);
- dispatchPopulateAccessibilityEvent(event, mPhoneNumber);
- return true;
- }
-
- dispatchPopulateAccessibilityEvent(event, mCallStateLabel);
- dispatchPopulateAccessibilityEvent(event, mPhoto);
- dispatchPopulateAccessibilityEvent(event, mName);
- dispatchPopulateAccessibilityEvent(event, mPhoneNumber);
- dispatchPopulateAccessibilityEvent(event, mLabel);
- // dispatchPopulateAccessibilityEvent(event, mSocialStatus);
- if (mSecondaryCallName != null) {
- dispatchPopulateAccessibilityEvent(event, mSecondaryCallName);
- }
- if (mSecondaryCallPhoto != null) {
- dispatchPopulateAccessibilityEvent(event, mSecondaryCallPhoto);
- }
- return true;
- }
-
- private void dispatchPopulateAccessibilityEvent(AccessibilityEvent event, View view) {
- List<CharSequence> eventText = event.getText();
- int size = eventText.size();
- view.dispatchPopulateAccessibilityEvent(event);
- // if no text added write null to keep relative position
- if (size == eventText.size()) {
- eventText.add(null);
- }
- }
-
- public void clear() {
- // The existing phone design is to keep an instance of call card forever. Until that
- // design changes, this method is needed to clear (reset) the call card for the next call
- // so old data is not shown.
-
- // Other elements can also be cleared here. Starting with elapsed time to fix a bug.
- mElapsedTime.setVisibility(View.GONE);
- mElapsedTime.setText(null);
- }
-
-
- // Debugging / testing code
-
- private static void log(String msg) {
- Log.d(LOG_TAG, msg);
- }
-}
diff --git a/src/com/android/phone/CallCommandService.java b/src/com/android/phone/CallCommandService.java
index 90297d8..5238911 100644
--- a/src/com/android/phone/CallCommandService.java
+++ b/src/com/android/phone/CallCommandService.java
@@ -25,7 +25,7 @@
import com.android.internal.telephony.CallManager;
import com.android.internal.telephony.PhoneConstants;
import com.android.phone.CallModeler.CallResult;
-import com.android.services.telephony.common.AudioMode;
+import com.android.phone.NotificationMgr.StatusBarHelper;
import com.android.services.telephony.common.Call;
import com.android.services.telephony.common.ICallCommandService;
@@ -43,21 +43,18 @@
private final CallModeler mCallModeler;
private final DTMFTonePlayer mDtmfTonePlayer;
private final AudioRouter mAudioRouter;
- private final RejectWithTextMessageManager mRejectWithTextMessageManager;
public CallCommandService(Context context, CallManager callManager, CallModeler callModeler,
- DTMFTonePlayer dtmfTonePlayer, AudioRouter audioRouter,
- RejectWithTextMessageManager rejectWithTextMessageManager) {
+ DTMFTonePlayer dtmfTonePlayer, AudioRouter audioRouter) {
mContext = context;
mCallManager = callManager;
mCallModeler = callModeler;
mDtmfTonePlayer = dtmfTonePlayer;
mAudioRouter = audioRouter;
- mRejectWithTextMessageManager = rejectWithTextMessageManager;
}
/**
- * TODO(klp): Add a confirmation callback parameter.
+ * TODO: Add a confirmation callback parameter.
*/
@Override
public void answerCall(int callId) {
@@ -72,22 +69,28 @@
}
/**
- * TODO(klp): Add a confirmation callback parameter.
+ * TODO: Add a confirmation callback parameter.
*/
@Override
- public void rejectCall(int callId, boolean rejectWithMessage, String message) {
+ public void rejectCall(Call call, boolean rejectWithMessage, String message) {
try {
+ int callId = Call.INVALID_CALL_ID;
+ String phoneNumber = "";
+ if (call != null) {
+ callId = call.getCallId();
+ phoneNumber = call.getNumber();
+ }
CallResult result = mCallModeler.getCallWithId(callId);
+
if (result != null) {
- final String number = result.getConnection().getAddress();
+ phoneNumber = result.getConnection().getAddress();
Log.v(TAG, "Hanging up");
PhoneUtils.hangupRingingCall(result.getConnection().getCall());
+ }
- if (rejectWithMessage) {
- mRejectWithTextMessageManager.rejectCallWithMessage(
- result.getConnection().getCall(), message);
- }
+ if (rejectWithMessage && !phoneNumber.isEmpty()) {
+ RejectWithTextMessageManager.rejectCallWithMessage(phoneNumber, message);
}
} catch (Exception e) {
Log.e(TAG, "Error during rejectCall().", e);
@@ -204,7 +207,6 @@
@Override
public void speaker(boolean onOff) {
try {
- // TODO(klp): add bluetooth logic from InCallScreen.toggleSpeaker()
PhoneUtils.turnOnSpeaker(mContext, onOff, true);
} catch (Exception e) {
Log.e(TAG, "Error during speaker().", e);
@@ -253,4 +255,17 @@
result.getConnection().proceedAfterWaitChar();
}
}
+
+ @Override
+ public void setSystemBarNavigationEnabled(boolean enable) {
+ try {
+ final StatusBarHelper statusBarHelper = PhoneGlobals.getInstance().notificationMgr.
+ statusBarHelper;
+ statusBarHelper.enableSystemBarNavigation(enable);
+ statusBarHelper.enableExpandedView(enable);
+ } catch (Exception e) {
+ Log.e(TAG, "Error enabling or disabling system bar navigation", e);
+ }
+ }
+
}
diff --git a/src/com/android/phone/CallController.java b/src/com/android/phone/CallController.java
index 44de433..52dbf76 100644
--- a/src/com/android/phone/CallController.java
+++ b/src/com/android/phone/CallController.java
@@ -23,7 +23,6 @@
import com.android.phone.CallGatewayManager.RawGatewayInfo;
import com.android.phone.Constants.CallStatusCode;
import com.android.phone.ErrorDialogActivity;
-import com.android.phone.InCallUiState.InCallScreenMode;
import com.android.phone.OtaUtils.CdmaOtaScreenState;
import android.app.AlertDialog;
@@ -144,8 +143,7 @@
// Reset the mThreeWayCallOrigStateDialing state
mApp.cdmaPhoneCallState.setThreeWayCallOrigState(false);
- // Refresh the in-call UI (based on the current ongoing call)
- mApp.updateInCallScreen();
+ mApp.getCallModeler().setCdmaOutgoing3WayCall(null);
}
break;
@@ -195,8 +193,6 @@
log("placeCall()... intent = " + intent);
if (VDBG) log(" extras = " + intent.getExtras());
- final InCallUiState inCallUiState = mApp.inCallUiState;
-
// TODO: Do we need to hold a wake lock while this method runs?
// Or did we already acquire one somewhere earlier
// in this sequence (like when we first received the CALL intent?)
@@ -257,18 +253,6 @@
case SUCCESS:
case EXITED_ECM:
if (DBG) log("==> placeCall(): success from placeCallInternal(): " + status);
-
- if (status == CallStatusCode.EXITED_ECM) {
- // Call succeeded, but we also need to tell the
- // InCallScreen to show the "Exiting ECM" warning.
- inCallUiState.setPendingCallStatusCode(CallStatusCode.EXITED_ECM);
- } else {
- // Call succeeded. There's no "error condition" that
- // needs to be displayed to the user, so clear out the
- // InCallUiState's "pending call status code".
- inCallUiState.clearPendingCallStatusCode();
- }
-
break;
default:
@@ -290,20 +274,6 @@
// in-call UI. Or if there was an error, the InCallScreen will
// notice the InCallUiState pending call status code flag and display an
// error indication instead.)
-
- // TODO: double-check the behavior of mApp.displayCallScreen()
- // if the InCallScreen is already visible:
- // - make sure it forces the UI to refresh
- // - make sure it does NOT launch a new InCallScreen on top
- // of the current one (i.e. the Back button should not take
- // you back to the previous InCallScreen)
- // - it's probably OK to go thru a fresh pause/resume sequence
- // though (since that should be fast now)
- // - if necessary, though, maybe PhoneApp.displayCallScreen()
- // could notice that the InCallScreen is already in the foreground,
- // and if so simply call updateInCallScreen() instead.
-
- mApp.displayCallScreen();
}
/**
@@ -325,7 +295,6 @@
// TODO: This method is too long. Break it down into more
// manageable chunks.
- final InCallUiState inCallUiState = mApp.inCallUiState;
final Uri uri = intent.getData();
final String scheme = (uri != null) ? uri.getScheme() : null;
String number;
@@ -462,13 +431,6 @@
}
}
- // Ok, we can proceed with this outgoing call.
-
- // Reset some InCallUiState flags, just in case they're still set
- // from a prior call.
- inCallUiState.needToShowCallLostDialog = false;
- inCallUiState.clearProgressIndication();
-
// We have a valid number, so try to actually place a call:
// make sure we pass along the intent's URI which is a
// reference to the contact. We may have a provider gateway
@@ -502,40 +464,7 @@
// app.cdmaOtaInCallScreenUiState.state are redundant.
// Combine them.
- if (VDBG) log ("- inCallUiState.inCallScreenMode = "
- + inCallUiState.inCallScreenMode);
- if (inCallUiState.inCallScreenMode == InCallScreenMode.OTA_NORMAL) {
- if (VDBG) log ("==> OTA_NORMAL note: switching to OTA_STATUS_LISTENING.");
- mApp.cdmaOtaScreenState.otaScreenState =
- CdmaOtaScreenState.OtaScreenState.OTA_STATUS_LISTENING;
- }
-
boolean voicemailUriSpecified = scheme != null && scheme.equals("voicemail");
- // When voicemail is requested most likely the user wants to open
- // dialpad immediately, so we show it in the first place.
- // Otherwise we want to make sure the user can see the regular
- // in-call UI while the new call is dialing, and when it
- // first gets connected.)
- inCallUiState.showDialpad = voicemailUriSpecified;
-
- // For voicemails, we add context text to let the user know they
- // are dialing their voicemail.
- // TODO: This is only set here and becomes problematic when swapping calls
- inCallUiState.dialpadContextText = voicemailUriSpecified ?
- phone.getVoiceMailAlphaTag() : "";
-
- // Also, in case a previous call was already active (i.e. if
- // we just did "Add call"), clear out the "history" of DTMF
- // digits you typed, to make sure it doesn't persist from the
- // previous call to the new call.
- // TODO: it would be more precise to do this when the actual
- // phone state change happens (i.e. when a new foreground
- // call appears and the previous call moves to the
- // background), but the InCallScreen doesn't keep enough
- // state right now to notice that specific transition in
- // onPhoneStateChanged().
- inCallUiState.dialpadDigits = null;
-
// Check for an obscure ECM-related scenario: If the phone
// is currently in ECM (Emergency callback mode) and we
// dial a non-emergency number, that automatically
diff --git a/src/com/android/phone/CallFeaturesSetting.java b/src/com/android/phone/CallFeaturesSetting.java
index e28e3d2..5cc3aa3 100644
--- a/src/com/android/phone/CallFeaturesSetting.java
+++ b/src/com/android/phone/CallFeaturesSetting.java
@@ -1659,11 +1659,6 @@
actionBar.setDisplayShowHomeEnabled(true);
actionBar.setDisplayHomeAsUpEnabled(true);
actionBar.setDisplayShowTitleEnabled(true);
-
- final SpannableString s = new SpannableString(getString(R.string.call_settings));
- s.setSpan(new TypefaceSpan(getString(R.string.call_settings_title_font_family)), 0,
- s.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
- actionBar.setTitle(s);
}
}
diff --git a/src/com/android/phone/CallHandlerServiceProxy.java b/src/com/android/phone/CallHandlerServiceProxy.java
index 3c7b517..6670ae4 100644
--- a/src/com/android/phone/CallHandlerServiceProxy.java
+++ b/src/com/android/phone/CallHandlerServiceProxy.java
@@ -16,20 +16,28 @@
package com.android.phone;
+import android.Manifest;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.ServiceConnection;
import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
+import android.content.pm.ServiceInfo;
import android.os.Handler;
import android.os.IBinder;
import android.os.Message;
+import android.os.PowerManager;
import android.os.RemoteException;
+import android.os.SystemClock;
import android.os.SystemProperties;
+import android.text.TextUtils;
import android.util.Log;
+import com.android.internal.telephony.Connection;
+import com.android.internal.telephony.Connection.PostDialState;
import com.android.phone.AudioRouter.AudioModeListener;
+import com.android.phone.NotificationMgr.StatusBarHelper;
import com.android.services.telephony.common.AudioMode;
import com.android.services.telephony.common.Call;
import com.android.services.telephony.common.ICallHandlerService;
@@ -55,6 +63,7 @@
private CallCommandService mCallCommandService;
private CallModeler mCallModeler;
private Context mContext;
+ private boolean mFullUpdateOnConnect;
private ICallHandlerService mCallHandlerServiceGuarded; // Guarded by mServiceAndQueueLock
// Single queue to guarantee ordering
@@ -90,6 +99,8 @@
@Override
public void onDisconnect(Call call) {
+ // Wake up in case the screen was off.
+ wakeUpScreen();
synchronized (mServiceAndQueueLock) {
if (mCallHandlerServiceGuarded == null) {
if (DBG) {
@@ -103,6 +114,12 @@
processDisconnect(call);
}
+ private void wakeUpScreen() {
+ Log.d(TAG, "wakeUpScreen()");
+ final PowerManager pm = (PowerManager) mContext.getSystemService(Context.POWER_SERVICE);
+ pm.wakeUp(SystemClock.uptimeMillis());
+ }
+
private void processDisconnect(Call call) {
try {
if (DBG) {
@@ -141,7 +158,7 @@
Log.d(TAG, "onIncoming: " + call);
}
try {
- // TODO(klp): check RespondViaSmsManager.allowRespondViaSmsForCall()
+ // TODO: check RespondViaSmsManager.allowRespondViaSmsForCall()
// must refactor call method to accept proper call object.
synchronized (mServiceAndQueueLock) {
if (mCallHandlerServiceGuarded != null) {
@@ -194,7 +211,9 @@
@Override
- public void onPostDialWait(int callId, String remainingChars) {
+ public void onPostDialAction(Connection.PostDialState state, int callId, String remainingChars,
+ char currentChar) {
+ if (state != PostDialState.WAIT) return;
try {
synchronized (mServiceAndQueueLock) {
if (mCallHandlerServiceGuarded == null) {
@@ -279,18 +298,18 @@
// always have an in call ui.
unbind();
- // TODO(klp): hang up all calls.
+ reconnectOnRemainingCalls();
}
}
}
- public void bringToForeground() {
+ public void bringToForeground(boolean showDialpad) {
// only support this call if the service is already connected.
synchronized (mServiceAndQueueLock) {
if (mCallHandlerServiceGuarded != null && mCallModeler.hasLiveCall()) {
try {
- if (DBG) Log.d(TAG, "bringToForeground");
- mCallHandlerServiceGuarded.bringToForeground();
+ if (DBG) Log.d(TAG, "bringToForeground: " + showDialpad);
+ mCallHandlerServiceGuarded.bringToForeground(showDialpad);
} catch (RemoteException e) {
Log.e(TAG, "Exception handling bringToForeground", e);
}
@@ -301,8 +320,8 @@
private static Intent getInCallServiceIntent(Context context) {
final Intent serviceIntent = new Intent(ICallHandlerService.class.getName());
final ComponentName component = new ComponentName(context.getResources().getString(
- R.string.incall_ui_default_package), context.getResources().getString(
- R.string.incall_ui_default_class));
+ R.string.ui_default_package), context.getResources().getString(
+ R.string.incall_default_class));
serviceIntent.setComponent(component);
return serviceIntent;
}
@@ -327,7 +346,21 @@
final PackageManager packageManger = mContext.getPackageManager();
final List<ResolveInfo> services = packageManger.queryIntentServices(serviceIntent,
0);
- if (services.size() == 0) {
+
+ ServiceInfo serviceInfo = null;
+
+ for (int i = 0; i < services.size(); i++) {
+ final ResolveInfo info = services.get(i);
+ if (info.serviceInfo != null) {
+ if (Manifest.permission.BIND_CALL_SERVICE.equals(
+ info.serviceInfo.permission)) {
+ serviceInfo = info.serviceInfo;
+ break;
+ }
+ }
+ }
+
+ if (serviceInfo == null) {
// Service not found, retry again after some delay
// This can happen if the service is being installed by the package manager.
// Between deletes and installs, bindService could get a silent service not
@@ -346,6 +379,11 @@
return;
}
+ // Bind to the first service that has a permission
+ // TODO: Add UI to allow us to select between services
+
+ serviceIntent.setComponent(new ComponentName(serviceInfo.packageName,
+ serviceInfo.name));
if (DBG) {
Log.d(TAG, "binding to service " + serviceIntent);
}
@@ -373,6 +411,12 @@
private void unbind() {
synchronized (mServiceAndQueueLock) {
+ // On unbind, reenable the notification shade and navigation bar just in case the
+ // in-call UI crashed on an incoming call.
+ final StatusBarHelper statusBarHelper = PhoneGlobals.getInstance().notificationMgr.
+ statusBarHelper;
+ statusBarHelper.enableSystemBarNavigation(true);
+ statusBarHelper.enableExpandedView(true);
if (mCallHandlerServiceGuarded != null) {
Log.d(TAG, "Unbinding service.");
mCallHandlerServiceGuarded = null;
@@ -394,6 +438,21 @@
makeInitialServiceCalls();
processQueue();
+
+ if (mFullUpdateOnConnect) {
+ mFullUpdateOnConnect = false;
+ onUpdate(mCallModeler.getFullList());
+ }
+ }
+ }
+
+ /**
+ * Checks to see if there are any live calls left, and if so, try reconnecting the UI.
+ */
+ private void reconnectOnRemainingCalls() {
+ if (mCallModeler.hasLiveCall()) {
+ mFullUpdateOnConnect = true;
+ setupServiceConnection();
}
}
diff --git a/src/com/android/phone/CallModeler.java b/src/com/android/phone/CallModeler.java
index 79e77f6..9f4bb76 100644
--- a/src/com/android/phone/CallModeler.java
+++ b/src/com/android/phone/CallModeler.java
@@ -20,6 +20,7 @@
import android.os.Handler;
import android.os.Message;
import android.os.SystemProperties;
+import android.telephony.PhoneNumberUtils;
import android.text.TextUtils;
import android.util.Log;
@@ -28,18 +29,20 @@
import com.android.internal.telephony.Phone;
import com.android.internal.telephony.PhoneConstants;
import com.android.internal.telephony.TelephonyCapabilities;
+import com.android.internal.telephony.cdma.CdmaCallWaitingNotification;
import com.android.phone.CallGatewayManager.RawGatewayInfo;
import com.android.services.telephony.common.Call;
import com.android.services.telephony.common.Call.Capabilities;
import com.android.services.telephony.common.Call.State;
-import com.google.android.collect.Lists;
import com.google.android.collect.Maps;
import com.google.common.base.Preconditions;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableSortedSet;
+import com.google.common.collect.Lists;
import java.util.ArrayList;
+import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map.Entry;
@@ -67,7 +70,7 @@
* the telephony layer. We use Connection references as identifiers for a call;
* new reference = new call.
*
- * TODO(klp): Create a new Call class to replace the simple call Id ints
+ * TODO: Create a new Call class to replace the simple call Id ints
* being used currently.
*
* The new Call models are parcellable for transfer via the CallHandlerService
@@ -88,14 +91,13 @@
private final HashMap<Connection, Call> mConfCallMap = Maps.newHashMap();
private final AtomicInteger mNextCallId = new AtomicInteger(CALL_ID_START_VALUE);
private final ArrayList<Listener> mListeners = new ArrayList<Listener>();
- private RejectWithTextMessageManager mRejectWithTextMessageManager;
+ private Connection mCdmaIncomingConnection;
+ private Connection mCdmaOutgoingConnection;
public CallModeler(CallStateMonitor callStateMonitor, CallManager callManager,
- RejectWithTextMessageManager rejectWithTextMessageManager,
CallGatewayManager callGatewayManager) {
mCallStateMonitor = callStateMonitor;
mCallManager = callManager;
- mRejectWithTextMessageManager = rejectWithTextMessageManager;
mCallGatewayManager = callGatewayManager;
mCallStateMonitor.addListener(this);
@@ -105,11 +107,15 @@
public void handleMessage(Message msg) {
switch(msg.what) {
case CallStateMonitor.PHONE_NEW_RINGING_CONNECTION:
- onNewRingingConnection((AsyncResult) msg.obj);
+ // We let the CallNotifier handle the new ringing connection first. When the custom
+ // ringtone and send_to_voicemail settings are retrieved, CallNotifier will directly
+ // call CallModeler's onNewRingingConnection.
break;
case CallStateMonitor.PHONE_DISCONNECT:
- onDisconnect((AsyncResult) msg.obj);
+ onDisconnect((Connection) ((AsyncResult) msg.obj).result);
break;
+ case CallStateMonitor.PHONE_UNKNOWN_CONNECTION_APPEARED:
+ // fall through
case CallStateMonitor.PHONE_STATE_CHANGED:
onPhoneStateChanged((AsyncResult) msg.obj);
break;
@@ -130,9 +136,11 @@
}
public List<Call> getFullList() {
- final List<Call> retval = Lists.newArrayList();
- doUpdate(true, retval);
- return retval;
+ final List<Call> calls =
+ Lists.newArrayListWithCapacity(mCallMap.size() + mConfCallMap.size());
+ calls.addAll(mCallMap.values());
+ calls.addAll(mConfCallMap.values());
+ return calls;
}
public CallResult getCallWithId(int callId) {
@@ -145,12 +153,7 @@
for (Entry<Connection, Call> entry : mConfCallMap.entrySet()) {
if (entry.getValue().getCallId() == callId) {
- if (entry.getValue().getChildCallIds().size() == 0) {
- return null;
- }
- final CallResult child = getCallWithId(entry.getValue().getChildCallIds().first());
- return new CallResult(entry.getValue(), child.getActionableCall(),
- child.getConnection());
+ return new CallResult(entry.getValue(), entry.getKey());
}
}
return null;
@@ -161,6 +164,57 @@
hasLiveCallInternal(mConfCallMap);
}
+ public void onCdmaCallWaiting(CdmaCallWaitingNotification callWaitingInfo) {
+ // We dont get the traditional onIncomingCall notification for cdma call waiting,
+ // but the Connection does actually exist. We need to find it in the set of ringing calls
+ // and pass it through our normal incoming logic.
+ final com.android.internal.telephony.Call teleCall =
+ mCallManager.getFirstActiveRingingCall();
+
+ if (teleCall.getState() == com.android.internal.telephony.Call.State.WAITING) {
+ Connection connection = teleCall.getLatestConnection();
+
+ if (connection != null) {
+ String number = connection.getAddress();
+ if (number != null && number.equals(callWaitingInfo.number)) {
+ Call call = onNewRingingConnection(connection);
+ mCdmaIncomingConnection = connection;
+ return;
+ }
+ }
+ }
+
+ Log.e(TAG, "CDMA Call waiting notification without a matching connection.");
+ }
+
+ public void onCdmaCallWaitingReject() {
+ // Cdma call was rejected...
+ if (mCdmaIncomingConnection != null) {
+ onDisconnect(mCdmaIncomingConnection);
+ mCdmaIncomingConnection = null;
+ } else {
+ Log.e(TAG, "CDMA Call waiting rejection without an incoming call.");
+ }
+ }
+
+ /**
+ * CDMA Calls have no sense of "dialing" state. For outgoing calls 3way calls we want to
+ * mimick this state so that the the UI can notify the user that there is a "dialing"
+ * call.
+ */
+ public void setCdmaOutgoing3WayCall(Connection connection) {
+ boolean wasSet = mCdmaOutgoingConnection != null;
+
+ mCdmaOutgoingConnection = connection;
+
+ // If we reset the connection, that mean we can now tell the user that the call is actually
+ // part of the conference call and move it out of the dialing state. To do this, issue a
+ // new update completely.
+ if (wasSet && mCdmaOutgoingConnection == null) {
+ onPhoneStateChanged(null);
+ }
+ }
+
private boolean hasLiveCallInternal(HashMap<Connection, Call> map) {
for (Call call : map.values()) {
final int state = call.getState();
@@ -168,8 +222,10 @@
state == Call.State.CALL_WAITING ||
state == Call.State.CONFERENCED ||
state == Call.State.DIALING ||
+ state == Call.State.REDIALING ||
state == Call.State.INCOMING ||
- state == Call.State.ONHOLD) {
+ state == Call.State.ONHOLD ||
+ state == Call.State.DISCONNECTING) {
return true;
}
}
@@ -185,8 +241,7 @@
HashMap<Connection, Call> map) {
for (Call call : map.values()) {
final int state = call.getState();
- if (state == Call.State.ACTIVE ||
- state == Call.State.DIALING) {
+ if (state == Call.State.ACTIVE || Call.State.isDialing(state)) {
return true;
}
}
@@ -210,42 +265,46 @@
final Connection.PostDialState state = (Connection.PostDialState) r.userObj;
switch (state) {
- // TODO(klp): add other post dial related functions
case WAIT:
final Call call = getCallFromMap(mCallMap, c, false);
if (call == null) {
Log.i(TAG, "Call no longer exists. Skipping onPostDialWait().");
} else {
for (Listener mListener : mListeners) {
- mListener.onPostDialWait(call.getCallId(),
- c.getRemainingPostDialString());
+ mListener.onPostDialAction(state, call.getCallId(),
+ c.getRemainingPostDialString(), ch);
}
}
break;
-
default:
+ // This is primarily to cause the DTMFTonePlayer to play local tones.
+ // Other listeners simply perform no-ops.
+ for (Listener mListener : mListeners) {
+ mListener.onPostDialAction(state, 0, "", ch);
+ }
break;
}
}
}
- private void onNewRingingConnection(AsyncResult r) {
+ /* package */ Call onNewRingingConnection(Connection conn) {
Log.i(TAG, "onNewRingingConnection");
- final Connection conn = (Connection) r.result;
final Call call = getCallFromMap(mCallMap, conn, true);
- updateCallFromConnection(call, conn, false);
+ if (call != null) {
+ updateCallFromConnection(call, conn, false);
- for (int i = 0; i < mListeners.size(); ++i) {
- if (call != null) {
- mListeners.get(i).onIncoming(call);
+ for (int i = 0; i < mListeners.size(); ++i) {
+ mListeners.get(i).onIncoming(call);
}
}
+
+ PhoneGlobals.getInstance().updateWakeState();
+ return call;
}
- private void onDisconnect(AsyncResult r) {
+ private void onDisconnect(Connection conn) {
Log.i(TAG, "onDisconnect");
- final Connection conn = (Connection) r.result;
final Call call = getCallFromMap(mCallMap, conn, false);
if (call != null) {
@@ -266,8 +325,8 @@
mCallMap.remove(conn);
}
- // TODO(klp): Do a final check to see if there are any active calls.
- // If there are not, totally cancel all calls
+ mCallManager.clearDisconnected();
+ PhoneGlobals.getInstance().updateWakeState();
}
/**
@@ -283,6 +342,8 @@
mListeners.get(i).onUpdate(updatedCalls);
}
}
+
+ PhoneGlobals.getInstance().updateWakeState();
}
@@ -301,18 +362,32 @@
for (com.android.internal.telephony.Call telephonyCall : telephonyCalls) {
for (Connection connection : telephonyCall.getConnections()) {
+ if (DBG) Log.d(TAG, "connection: " + connection + connection.getState());
+
// We only send updates for live calls which are not incoming (ringing).
// Disconnected and incoming calls are handled by onDisconnect and
// onNewRingingConnection.
- boolean shouldUpdate = connection.getState().isAlive() &&
+ final boolean shouldUpdate =
+ connection.getState() !=
+ com.android.internal.telephony.Call.State.DISCONNECTED &&
+ connection.getState() !=
+ com.android.internal.telephony.Call.State.IDLE &&
!connection.getState().isRinging();
+ final boolean isDisconnecting = connection.getState() ==
+ com.android.internal.telephony.Call.State.DISCONNECTING;
+
+ // For disconnecting calls, we still need to send the update to the UI but we do
+ // not create a new call if the call did not exist.
+ final boolean shouldCreate = shouldUpdate && !isDisconnecting;
+
// New connections return a Call with INVALID state, which does not translate to
// a state in the internal.telephony.Call object. This ensures that staleness
// check below fails and we always add the item to the update list if it is new.
- final Call call = getCallFromMap(mCallMap, connection, shouldUpdate /* create */);
+ final Call call = getCallFromMap(mCallMap, connection, shouldCreate /* create */);
if (call == null || !shouldUpdate) {
+ if (DBG) Log.d(TAG, "update skipped");
continue;
}
@@ -345,9 +420,9 @@
*/
private boolean updateForConferenceCalls(Connection connection, List<Call> updatedCalls) {
// We consider this connection a conference connection if the call it
- // belongs to is a multiparty call AND it is the first connection.
+ // belongs to is a multiparty call AND it is the first live connection.
final boolean isConferenceCallConnection = isPartOfLiveConferenceCall(connection) &&
- connection.getCall().getEarliestConnection() == connection;
+ getEarliestLiveConnection(connection.getCall()) == connection;
boolean changed = false;
@@ -384,6 +459,23 @@
return changed;
}
+ private Connection getEarliestLiveConnection(com.android.internal.telephony.Call call) {
+ final List<Connection> connections = call.getConnections();
+ final int size = connections.size();
+ Connection earliestConn = null;
+ long earliestTime = Long.MAX_VALUE;
+ for (int i = 0; i < size; i++) {
+ final Connection connection = connections.get(i);
+ if (!connection.isAlive()) continue;
+ final long time = connection.getCreateTime();
+ if (time < earliestTime) {
+ earliestTime = time;
+ earliestConn = connection;
+ }
+ }
+ return earliestConn;
+ }
+
/**
* Sets the new call state onto the call and performs some additional logic
* associated with setting the state.
@@ -395,7 +487,7 @@
// for the call, if available, and set it.
final RawGatewayInfo info = mCallGatewayManager.getGatewayInfo(connection);
- if (newState == Call.State.DIALING) {
+ if (Call.State.isDialing(newState)) {
if (!info.isEmpty()) {
call.setGatewayNumber(info.getFormattedGatewayNumber());
call.setGatewayPackage(info.packageName);
@@ -496,7 +588,7 @@
/**
* !!! Uses values from connection and call collected above so this part must be last !!!
*/
- final int newCapabilities = getCapabilitiesFor(connection, call);
+ final int newCapabilities = getCapabilitiesFor(connection, call, isForConference);
if (call.getCapabilities() != newCapabilities) {
call.setCapabilities(newCapabilities);
changed = true;
@@ -508,23 +600,45 @@
/**
* Returns a mask of capabilities for the connection such as merge, hold, etc.
*/
- private int getCapabilitiesFor(Connection connection, Call call) {
+ private int getCapabilitiesFor(Connection connection, Call call, boolean isForConference) {
final boolean callIsActive = (call.getState() == Call.State.ACTIVE);
final Phone phone = connection.getCall().getPhone();
- final boolean canHold = TelephonyCapabilities.supportsAnswerAndHold(phone);
boolean canAddCall = false;
boolean canMergeCall = false;
boolean canSwapCall = false;
boolean canRespondViaText = false;
+ boolean canMute = false;
+
+ final boolean supportHold = PhoneUtils.okToSupportHold(mCallManager);
+ final boolean canHold = (supportHold ? PhoneUtils.okToHoldCall(mCallManager) : false);
+ final boolean genericConf = isForConference &&
+ (connection.getCall().getPhone().getPhoneType() == PhoneConstants.PHONE_TYPE_CDMA);
// only applies to active calls
if (callIsActive) {
- canAddCall = PhoneUtils.okToAddCall(mCallManager);
canMergeCall = PhoneUtils.okToMergeCalls(mCallManager);
canSwapCall = PhoneUtils.okToSwapCalls(mCallManager);
}
+ canAddCall = PhoneUtils.okToAddCall(mCallManager);
+
+ // "Mute": only enabled when the foreground call is ACTIVE.
+ // (It's meaningless while on hold, or while DIALING/ALERTING.)
+ // It's also explicitly disabled during emergency calls or if
+ // emergency callback mode (ECM) is active.
+ boolean isEmergencyCall = false;
+ if (connection != null) {
+ isEmergencyCall = PhoneNumberUtils.isLocalEmergencyNumber(connection.getAddress(),
+ phone.getContext());
+ }
+ boolean isECM = PhoneUtils.isPhoneInEcm(phone);
+ if (isEmergencyCall || isECM) { // disable "Mute" item
+ canMute = false;
+ } else {
+ canMute = callIsActive;
+ }
+
canRespondViaText = RejectWithTextMessageManager.allowRespondViaSmsForCall(call,
connection);
@@ -532,15 +646,15 @@
// CDMA always has Add
if (phone.getPhoneType() == PhoneConstants.PHONE_TYPE_CDMA) {
canAddCall = true;
- } else {
- // if neither merge nor add is on...then allow add
- canAddCall |= !(canAddCall || canMergeCall);
}
int retval = 0x0;
if (canHold) {
retval |= Capabilities.HOLD;
}
+ if (supportHold) {
+ retval |= Capabilities.SUPPORT_HOLD;
+ }
if (canAddCall) {
retval |= Capabilities.ADD_CALL;
}
@@ -550,10 +664,15 @@
if (canSwapCall) {
retval |= Capabilities.SWAP_CALLS;
}
-
if (canRespondViaText) {
retval |= Capabilities.RESPOND_VIA_TEXT;
}
+ if (canMute) {
+ retval |= Capabilities.MUTE;
+ }
+ if (genericConf) {
+ retval |= Capabilities.GENERIC_CONFERENCE;
+ }
return retval;
}
@@ -567,7 +686,10 @@
if (connection.getCall() != null && connection.getCall().isMultiparty()) {
int count = 0;
for (Connection currConn : connection.getCall().getConnections()) {
- if (currConn.isAlive()) {
+
+ // Only count connections which are alive and never cound the special
+ // "dialing" 3way call for CDMA calls.
+ if (currConn.isAlive() && currConn != mCdmaOutgoingConnection) {
count++;
if (count >= 2) {
return true;
@@ -580,8 +702,15 @@
private int translateStateFromTelephony(Connection connection, boolean isForConference) {
+ com.android.internal.telephony.Call.State connState = connection.getState();
+
+ // For the "fake" outgoing CDMA call, we need to always treat it as an outgoing call.
+ if (mCdmaOutgoingConnection == connection) {
+ connState = com.android.internal.telephony.Call.State.DIALING;
+ }
+
int retval = State.IDLE;
- switch (connection.getState()) {
+ switch (connState) {
case ACTIVE:
retval = State.ACTIVE;
break;
@@ -590,7 +719,11 @@
break;
case DIALING:
case ALERTING:
- retval = State.DIALING;
+ if (PhoneGlobals.getInstance().notifier.getIsCdmaRedialCall()) {
+ retval = State.REDIALING;
+ } else {
+ retval = State.DIALING;
+ }
break;
case WAITING:
retval = State.CALL_WAITING;
@@ -598,8 +731,10 @@
case HOLDING:
retval = State.ONHOLD;
break;
- case DISCONNECTED:
case DISCONNECTING:
+ retval = State.DISCONNECTING;
+ break;
+ case DISCONNECTED:
retval = State.DISCONNECTED;
default:
}
@@ -607,7 +742,6 @@
// If we are dealing with a potential child call (not the parent conference call),
// the check to see if we have to set the state to CONFERENCED.
if (!isForConference) {
-
// if the connection is part of a multiparty call, and it is live,
// annotate it with CONFERENCED state instead.
if (isPartOfLiveConferenceCall(connection) && connection.isAlive()) {
@@ -734,7 +868,8 @@
void onDisconnect(Call call);
void onIncoming(Call call);
void onUpdate(List<Call> calls);
- void onPostDialWait(int callId, String remainingChars);
+ void onPostDialAction(Connection.PostDialState state, int callId, String remainingChars,
+ char c);
}
/**
diff --git a/src/com/android/phone/CallNotifier.java b/src/com/android/phone/CallNotifier.java
index de5052f..c9ad397 100644
--- a/src/com/android/phone/CallNotifier.java
+++ b/src/com/android/phone/CallNotifier.java
@@ -41,7 +41,6 @@
import android.os.AsyncResult;
import android.os.Handler;
import android.os.Message;
-import android.os.RemoteException;
import android.os.SystemProperties;
import android.os.SystemVibrator;
import android.os.Vibrator;
@@ -137,10 +136,10 @@
private PhoneGlobals mApplication;
private CallManager mCM;
- private CallStateMonitor mCallStateMonitor;
private Ringer mRinger;
private BluetoothHeadset mBluetoothHeadset;
private CallLogger mCallLogger;
+ private CallModeler mCallModeler;
private boolean mSilentRingerRequested;
// ToneGenerator instance for playing SignalInfo tones
@@ -175,11 +174,11 @@
*/
/* package */ static CallNotifier init(PhoneGlobals app, Phone phone, Ringer ringer,
CallLogger callLogger, CallStateMonitor callStateMonitor,
- BluetoothManager bluetoothManager) {
+ BluetoothManager bluetoothManager, CallModeler callModeler) {
synchronized (CallNotifier.class) {
if (sInstance == null) {
sInstance = new CallNotifier(app, phone, ringer, callLogger, callStateMonitor,
- bluetoothManager);
+ bluetoothManager, callModeler);
} else {
Log.wtf(LOG_TAG, "init() called multiple times! sInstance = " + sInstance);
}
@@ -189,12 +188,13 @@
/** Private constructor; @see init() */
private CallNotifier(PhoneGlobals app, Phone phone, Ringer ringer, CallLogger callLogger,
- CallStateMonitor callStateMonitor, BluetoothManager bluetoothManager) {
+ CallStateMonitor callStateMonitor, BluetoothManager bluetoothManager,
+ CallModeler callModeler) {
mApplication = app;
mCM = app.mCM;
mCallLogger = callLogger;
- mCallStateMonitor = callStateMonitor;
mBluetoothManager = bluetoothManager;
+ mCallModeler = callModeler;
mAudioManager = (AudioManager) mApplication.getSystemService(Context.AUDIO_SERVICE);
@@ -276,7 +276,7 @@
break;
case RINGER_CUSTOM_RINGTONE_QUERY_TIMEOUT:
- onCustomRingtoneQueryTimeout((String) msg.obj);
+ onCustomRingtoneQueryTimeout((Connection) msg.obj);
break;
case PHONE_MWI_CHANGED:
@@ -303,7 +303,6 @@
if (DBG) log("Received CALLWAITING_ADDCALL_DISABLE_TIMEOUT event ...");
// Set the mAddCallMenuStateAfterCW state to true
mApplication.cdmaPhoneCallState.setAddCallMenuStateAfterCallWaiting(true);
- mApplication.updateInCallScreen();
break;
case CallStateMonitor.PHONE_STATE_DISPLAYINFO:
@@ -332,9 +331,6 @@
int toneToPlay = InCallTonePlayer.TONE_VOICE_PRIVACY;
new InCallTonePlayer(toneToPlay).start();
mVoicePrivacyState = true;
- // Update the VP icon:
- if (DBG) log("- updating notification for VP state...");
- mApplication.notificationMgr.updateInCallNotification();
}
break;
@@ -344,9 +340,6 @@
int toneToPlay = InCallTonePlayer.TONE_VOICE_PRIVACY;
new InCallTonePlayer(toneToPlay).start();
mVoicePrivacyState = false;
- // Update the VP icon:
- if (DBG) log("- updating notification for VP state...");
- mApplication.notificationMgr.updateInCallNotification();
}
break;
@@ -358,10 +351,6 @@
onResendMute();
break;
- case UPDATE_IN_CALL_NOTIFICATION:
- mApplication.notificationMgr.updateInCallNotification();
- break;
-
default:
// super.handleMessage(msg);
}
@@ -447,19 +436,9 @@
// - don't ring for call waiting connections
// - do this before showing the incoming call panel
- if (PhoneUtils.isRealIncomingCall(state)) {
- startIncomingCallQuery(c);
- } else {
- if (VDBG) log("- starting call waiting tone...");
- if (mCallWaitingTonePlayer == null) {
- mCallWaitingTonePlayer = new InCallTonePlayer(InCallTonePlayer.TONE_CALL_WAITING);
- mCallWaitingTonePlayer.start();
- }
- // in this case, just fall through like before, and call
- // showIncomingCall().
- if (DBG) log("- showing incoming call (this is a WAITING call)...");
- showIncomingCall();
- }
+ startIncomingCallQuery(c);
+
+
// Note we *don't* post a status bar notification here, since
// we're not necessarily ready to actually show the incoming call
@@ -534,7 +513,6 @@
// we should instead provide a higher-level API via OtaUtils.
if (dialogState) mApplication.dismissOtaDialogs();
mApplication.clearOtaState();
- mApplication.clearInCallScreenMode();
return false;
}
}
@@ -571,20 +549,20 @@
// query the callerinfo to try to get the ringer.
PhoneUtils.CallerInfoToken cit = PhoneUtils.startGetCallerInfo(
- mApplication, c, this, this);
+ mApplication, c, this, c);
// if this has already been queried then just ring, otherwise
// we wait for the alloted time before ringing.
if (cit.isFinal) {
if (VDBG) log("- CallerInfo already up to date, using available data");
- onQueryComplete(0, this, cit.currentInfo);
+ onQueryComplete(0, c, cit.currentInfo);
} else {
if (VDBG) log("- Starting query, posting timeout message.");
// Phone number (via getAddress()) is stored in the message to remember which
// number is actually used for the look up.
sendMessageDelayed(
- Message.obtain(this, RINGER_CUSTOM_RINGTONE_QUERY_TIMEOUT, c.getAddress()),
+ Message.obtain(this, RINGER_CUSTOM_RINGTONE_QUERY_TIMEOUT, c),
RINGTONE_QUERY_WAIT_TIME);
}
// The call to showIncomingCall() will happen after the
@@ -595,14 +573,7 @@
// and before the timeout window has closed.
EventLog.writeEvent(EventLogTags.PHONE_UI_MULTIPLE_QUERY);
- // In this case, just log the request and ring.
- if (VDBG) log("RINGING... (request to ring arrived while query is running)");
- mRinger.ring();
-
- // in this case, just fall through like before, and call
- // showIncomingCall().
- if (DBG) log("- showing incoming call (couldn't start query)...");
- showIncomingCall();
+ ringAndNotifyOfIncomingCall(c);
}
}
@@ -623,7 +594,7 @@
* (We still tell the Ringer to start, but it's going to use the
* default ringtone.)
*/
- private void onCustomRingQueryComplete() {
+ private void onCustomRingQueryComplete(Connection c) {
boolean isQueryExecutionTimeExpired = false;
synchronized (mCallerInfoQueryStateGuard) {
if (mCallerInfoQueryState == CALLERINFO_QUERYING) {
@@ -657,67 +628,42 @@
return;
}
- // Ring, either with the queried ringtone or default one.
- if (VDBG) log("RINGING... (onCustomRingQueryComplete)");
- mRinger.ring();
+ // If the ringing call still does not have any connection anymore, do not send the
+ // notification to the CallModeler.
+ final Call ringingCall = mCM.getFirstActiveRingingCall();
- // ...and display the incoming call to the user:
- if (DBG) log("- showing incoming call (custom ring query complete)...");
- showIncomingCall();
+ if (ringingCall != null && ringingCall.getLatestConnection() == c) {
+ ringAndNotifyOfIncomingCall(c);
+ }
}
private void onUnknownConnectionAppeared(AsyncResult r) {
PhoneConstants.State state = mCM.getState();
if (state == PhoneConstants.State.OFFHOOK) {
- // basically do onPhoneStateChanged + display the incoming call UI
+ if (DBG) log("unknown connection appeared...");
+
onPhoneStateChanged(r);
- if (DBG) log("- showing incoming call (unknown connection appeared)...");
- showIncomingCall();
}
}
/**
- * Informs the user about a new incoming call.
- *
- * In most cases this means "bring up the full-screen incoming call
- * UI". However, if an immersive activity is running, the system
- * NotificationManager will instead pop up a small notification window
- * on top of the activity.
- *
- * Watch out: be sure to call this method only once per incoming call,
- * or otherwise we may end up launching the InCallScreen multiple
- * times (which can lead to slow responsiveness and/or visible
- * glitches.)
- *
- * Note this method handles only the onscreen UI for incoming calls;
- * the ringer and/or vibrator are started separately (see the various
- * calls to Ringer.ring() in this class.)
- *
- * @see NotificationMgr#updateNotificationAndLaunchIncomingCallUi()
+ * Notifies the Call Modeler that there is a new ringing connection.
+ * If it is not a waiting call (there is no other active call in foreground), we will ring the
+ * ringtone. Otherwise we will play the call waiting tone instead.
+ * @param c The new ringing connection.
*/
- private void showIncomingCall() {
- log("showIncomingCall()... phone state = " + mCM.getState());
-
- // Before bringing up the "incoming call" UI, force any system
- // dialogs (like "recent tasks" or the power dialog) to close first.
- try {
- ActivityManagerNative.getDefault().closeSystemDialogs("call");
- } catch (RemoteException e) {
+ private void ringAndNotifyOfIncomingCall(Connection c) {
+ if (PhoneUtils.isRealIncomingCall(c.getState())) {
+ mRinger.ring();
+ } else {
+ if (VDBG) log("- starting call waiting tone...");
+ if (mCallWaitingTonePlayer == null) {
+ mCallWaitingTonePlayer = new InCallTonePlayer(InCallTonePlayer.TONE_CALL_WAITING);
+ mCallWaitingTonePlayer.start();
+ }
}
-
- // 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.)
- mApplication.requestWakeState(PhoneGlobals.WakeState.FULL);
-
- // Post the "incoming call" notification *and* include the
- // fullScreenIntent that'll launch the incoming-call UI.
- // (This will usually take us straight to the incoming call
- // screen, but if an immersive activity is running it'll just
- // appear as a notification.)
- if (DBG) log("- updating notification from showIncomingCall()...");
- mApplication.notificationMgr.updateNotificationAndLaunchIncomingCallUi();
+ mCallModeler.onNewRingingConnection(c);
}
/**
@@ -758,7 +704,7 @@
// There's no need to force a UI update since we update the
// in-call notification ourselves (below), and the InCallScreen
// listens for phone state changes itself.
- // TODO(klp): Have BluetoothManager listen to CallModeler instead of relying on
+ // TODO: Have BluetoothManager listen to CallModeler instead of relying on
// CallNotifier
mBluetoothManager.updateBluetoothIndication();
@@ -777,12 +723,6 @@
// make sure audio is in in-call mode now
PhoneUtils.setAudioMode(mCM);
- // if the call screen is showing, let it handle the event,
- // otherwise handle it here.
- if (!mApplication.isShowingCallScreen()) {
- mApplication.requestWakeState(PhoneGlobals.WakeState.SLEEP);
- }
-
// Since we're now in-call, the Ringer should definitely *not*
// be ringing any more. (This is just a sanity-check; we
// already stopped the ringer explicitly back in
@@ -791,26 +731,6 @@
// remove it!
if (DBG) log("stopRing()... (OFFHOOK state)");
mRinger.stopRing();
-
- // Post a request to update the "in-call" status bar icon.
- //
- // We don't call NotificationMgr.updateInCallNotification()
- // directly here, for two reasons:
- // (1) a single phone state change might actually trigger multiple
- // onPhoneStateChanged() callbacks, so this prevents redundant
- // updates of the notification.
- // (2) we suppress the status bar icon while the in-call UI is
- // visible (see updateInCallNotification()). But when launching
- // an outgoing call the phone actually goes OFFHOOK slightly
- // *before* the InCallScreen comes up, so the delay here avoids a
- // brief flicker of the icon at that point.
-
- if (DBG) log("- posting UPDATE_IN_CALL_NOTIFICATION request...");
- // Remove any previous requests in the queue
- removeMessages(UPDATE_IN_CALL_NOTIFICATION);
- final int IN_CALL_NOTIFICATION_UPDATE_DELAY = 1000; // msec
- sendEmptyMessageDelayed(UPDATE_IN_CALL_NOTIFICATION,
- IN_CALL_NOTIFICATION_UPDATE_DELAY);
}
if (fgPhone.getPhoneType() == PhoneConstants.PHONE_TYPE_CDMA) {
@@ -884,7 +804,8 @@
mApplication.notificationMgr.notifyMissedCall(ci.name, ci.phoneNumber,
ci.phoneLabel, ci.cachedPhoto, ci.cachedPhotoIcon,
((Long) cookie).longValue());
- } else if (cookie instanceof CallNotifier) {
+ } else if (cookie instanceof Connection) {
+ final Connection c = (Connection) cookie;
if (VDBG) log("CallerInfo query complete (for CallNotifier), "
+ "updating state for incoming call..");
@@ -904,18 +825,21 @@
// send directly to voicemail.
if (ci.shouldSendToVoicemail) {
if (DBG) log("send to voicemail flag detected. hanging up.");
- PhoneUtils.hangupRingingCall(mCM.getFirstActiveRingingCall());
- return;
+ final Call ringingCall = mCM.getFirstActiveRingingCall();
+ if (ringingCall != null && ringingCall.getLatestConnection() == c) {
+ PhoneUtils.hangupRingingCall(ringingCall);
+ return;
+ }
}
// set the ringtone uri to prepare for the ring.
if (ci.contactRingtoneUri != null) {
if (DBG) log("custom ringtone found, setting up ringer.");
- Ringer r = ((CallNotifier) cookie).mRinger;
+ Ringer r = mRinger;
r.setCustomRingtoneUri(ci.contactRingtoneUri);
}
// ring, and other post-ring actions.
- onCustomRingQueryComplete();
+ onCustomRingQueryComplete(c);
}
}
}
@@ -931,7 +855,7 @@
* @param number The phone number used for the async query. This method will take care of
* formatting or normalization of the number.
*/
- private void onCustomRingtoneQueryTimeout(String number) {
+ private void onCustomRingtoneQueryTimeout(Connection c) {
// First of all, this case itself should be rare enough, though we cannot avoid it in
// some situations (e.g. IPC is slow due to system overload, database is in sync, etc.)
Log.w(LOG_TAG, "CallerInfo query took too long; look up local fallback cache.");
@@ -939,29 +863,34 @@
// This method is intentionally verbose for now to detect possible bad side-effect for it.
// TODO: Remove the verbose log when it looks stable and reliable enough.
- final CallerInfoCache.CacheEntry entry =
- mApplication.callerInfoCache.getCacheEntry(number);
- if (entry != null) {
- if (entry.sendToVoicemail) {
- log("send to voicemail flag detected (in fallback cache). hanging up.");
- PhoneUtils.hangupRingingCall(mCM.getFirstActiveRingingCall());
- return;
- }
- if (entry.customRingtone != null) {
- log("custom ringtone found (in fallback cache), setting up ringer: "
- + entry.customRingtone);
- this.mRinger.setCustomRingtoneUri(Uri.parse(entry.customRingtone));
+ if (c != null) {
+ final CallerInfoCache.CacheEntry entry =
+ mApplication.callerInfoCache.getCacheEntry(c.getAddress());
+ if (entry != null) {
+ if (entry.sendToVoicemail) {
+ log("send to voicemail flag detected (in fallback cache). hanging up.");
+ if (mCM.getFirstActiveRingingCall().getLatestConnection() == c) {
+ PhoneUtils.hangupRingingCall(mCM.getFirstActiveRingingCall());
+ return;
+ }
+ }
+
+ if (entry.customRingtone != null) {
+ log("custom ringtone found (in fallback cache), setting up ringer: "
+ + entry.customRingtone);
+ this.mRinger.setCustomRingtoneUri(Uri.parse(entry.customRingtone));
+ }
+ } else {
+ // In this case we call onCustomRingQueryComplete(), just
+ // like if the query had completed normally. (But we're
+ // going to get the default ringtone, since we never got
+ // the chance to call Ringer.setCustomRingtoneUri()).
+ log("Failed to find fallback cache. Use default ringer tone.");
}
- } else {
- // In this case we call onCustomRingQueryComplete(), just
- // like if the query had completed normally. (But we're
- // going to get the default ringtone, since we never got
- // the chance to call Ringer.setCustomRingtoneUri()).
- log("Failed to find fallback cache. Use default ringer tone.");
}
- onCustomRingQueryComplete();
+ onCustomRingQueryComplete(c);
}
private void onDisconnect(AsyncResult r) {
@@ -1165,8 +1094,11 @@
if (autoretrySetting == InCallScreen.AUTO_RETRY_ON) {
// TODO: (Moto): The contact reference data may need to be stored and use
// here when redialing a call. For now, pass in NULL as the URI parameter.
- PhoneUtils.placeCall(mApplication, phone, number, null, false);
- mIsCdmaRedialCall = true;
+ final int status =
+ PhoneUtils.placeCall(mApplication, phone, number, null, false);
+ if (status != PhoneUtils.CALL_STATUS_FAILED) {
+ mIsCdmaRedialCall = true;
+ }
} else {
mIsCdmaRedialCall = false;
}
@@ -1644,13 +1576,6 @@
mApplication.cdmaPhoneCallState.setCurrentCallState(
CdmaPhoneCallState.PhoneCallState.SINGLE_ACTIVE);
- // Display the incoming call to the user if the InCallScreen isn't
- // already in the foreground.
- if (!mApplication.isShowingCallScreen()) {
- if (DBG) log("- showing incoming call (CDMA call waiting)...");
- showIncomingCall();
- }
-
// Start timer for CW display
mCallWaitingTimeOut = false;
sendEmptyMessageDelayed(CALLWAITING_CALLERINFO_DISPLAY_DONE,
@@ -1680,6 +1605,8 @@
//Create the SignalInfo tone player and pass the ToneID
new SignalInfoTonePlayer(toneID).start();
}
+
+ mCallModeler.onCdmaCallWaiting(infoCW);
}
/**
@@ -1733,6 +1660,10 @@
//Reset the mCallWaitingTimeOut boolean
mCallWaitingTimeOut = false;
}
+
+ // Call modeler needs to know about this event regardless of the
+ // state conditionals in the previous code.
+ mCallModeler.onCdmaCallWaitingReject();
}
/**
diff --git a/src/com/android/phone/DTMFTonePlayer.java b/src/com/android/phone/DTMFTonePlayer.java
index 0acd114..b8adaf1 100644
--- a/src/com/android/phone/DTMFTonePlayer.java
+++ b/src/com/android/phone/DTMFTonePlayer.java
@@ -27,6 +27,7 @@
import android.util.Log;
import com.android.internal.telephony.CallManager;
+import com.android.internal.telephony.Connection.PostDialState;
import com.android.internal.telephony.Phone;
import com.android.internal.telephony.PhoneConstants;
import com.android.services.telephony.common.Call;
@@ -124,8 +125,25 @@
}
@Override
- public void onPostDialWait(int callId, String chars) {
- // no-op
+ public void onPostDialAction(PostDialState state, int callId, String remainingChars,
+ char currentChar) {
+ switch (state) {
+ case STARTED:
+ stopLocalToneIfNeeded();
+ if (!mToneMap.containsKey(currentChar)) {
+ return;
+ }
+ startLocalToneIfNeeded(currentChar);
+ break;
+ case PAUSE:
+ case WAIT:
+ case WILD:
+ case COMPLETE:
+ stopLocalToneIfNeeded();
+ break;
+ default:
+ break;
+ }
}
/**
@@ -387,5 +405,4 @@
Log.d(LOG_TAG, msg);
}
}
-
}
diff --git a/src/com/android/phone/DTMFTwelveKeyDialer.java b/src/com/android/phone/DTMFTwelveKeyDialer.java
deleted file mode 100644
index 4dd4a88..0000000
--- a/src/com/android/phone/DTMFTwelveKeyDialer.java
+++ /dev/null
@@ -1,1116 +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.content.Context;
-import android.media.AudioManager;
-import android.media.ToneGenerator;
-import android.os.Handler;
-import android.os.Message;
-import android.provider.Settings;
-import android.telephony.PhoneNumberUtils;
-import android.text.Editable;
-import android.text.SpannableString;
-import android.text.method.DialerKeyListener;
-import android.text.style.RelativeSizeSpan;
-import android.util.Log;
-import android.view.KeyEvent;
-import android.view.MotionEvent;
-import android.view.View;
-import android.view.accessibility.AccessibilityManager;
-import android.view.ViewStub;
-import android.widget.EditText;
-
-import com.android.internal.telephony.CallManager;
-import com.android.internal.telephony.Phone;
-import com.android.internal.telephony.PhoneConstants;
-
-import java.util.HashMap;
-import java.util.LinkedList;
-import java.util.Queue;
-
-
-/**
- * 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,
- View.OnHoverListener, View.OnClickListener {
- private static final String LOG_TAG = "DTMFTwelveKeyDialer";
- 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;
- private static final int DTMF_STOP = 102;
-
- /** 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();
-
- // indicate if we want to enable the local tone playback.
- private boolean mLocalToneEnabled;
-
- // indicates that we are using automatically shortened DTMF tones
- boolean mShortTone;
-
- // indicate if the confirmation from TelephonyFW is pending.
- private boolean mDTMFBurstCnfPending = false;
-
- // Queue to queue the short dtmf characters.
- private Queue<Character> mDTMFQueue = new LinkedList<Character>();
-
- // Short Dtmf tone duration
- private static final int DTMF_DURATION_MS = 120;
-
-
- /** Hash Map to map a character to a tone*/
- private static final HashMap<Character, Integer> mToneMap =
- new HashMap<Character, Integer>();
- /** Hash Map to map a view id to a character*/
- private static final HashMap<Integer, Character> mDisplayMap =
- new HashMap<Integer, Character>();
- /** Set up the static maps*/
- static {
- // Map the key characters to tones
- mToneMap.put('1', ToneGenerator.TONE_DTMF_1);
- mToneMap.put('2', ToneGenerator.TONE_DTMF_2);
- mToneMap.put('3', ToneGenerator.TONE_DTMF_3);
- mToneMap.put('4', ToneGenerator.TONE_DTMF_4);
- mToneMap.put('5', ToneGenerator.TONE_DTMF_5);
- mToneMap.put('6', ToneGenerator.TONE_DTMF_6);
- mToneMap.put('7', ToneGenerator.TONE_DTMF_7);
- mToneMap.put('8', ToneGenerator.TONE_DTMF_8);
- mToneMap.put('9', ToneGenerator.TONE_DTMF_9);
- mToneMap.put('0', ToneGenerator.TONE_DTMF_0);
- mToneMap.put('#', ToneGenerator.TONE_DTMF_P);
- mToneMap.put('*', ToneGenerator.TONE_DTMF_S);
-
- // Map the buttons to the display characters
- mDisplayMap.put(R.id.one, '1');
- mDisplayMap.put(R.id.two, '2');
- mDisplayMap.put(R.id.three, '3');
- mDisplayMap.put(R.id.four, '4');
- mDisplayMap.put(R.id.five, '5');
- mDisplayMap.put(R.id.six, '6');
- mDisplayMap.put(R.id.seven, '7');
- mDisplayMap.put(R.id.eight, '8');
- mDisplayMap.put(R.id.nine, '9');
- mDisplayMap.put(R.id.zero, '0');
- mDisplayMap.put(R.id.pound, '#');
- mDisplayMap.put(R.id.star, '*');
- }
-
- /** EditText field used to display the DTMF digits sent so far.
- Note this is null in some modes (like during the CDMA OTA call,
- where there's no onscreen "digits" display.) */
- private EditText mDialpadDigits;
-
- // InCallScreen reference.
- private InCallScreen mInCallScreen;
-
- /**
- * The DTMFTwelveKeyDialerView we use to display the dialpad.
- *
- * Only one of mDialerView or mDialerStub will have a legitimate object; the other one will be
- * null at that moment. Either of following scenarios will occur:
- *
- * - If the constructor with {@link DTMFTwelveKeyDialerView} is called, mDialerView will
- * obtain that object, and mDialerStub will be null. mDialerStub won't be used in this case.
- *
- * - If the constructor with {@link ViewStub} is called, mDialerView will be null at that
- * moment, and mDialerStub will obtain the ViewStub object.
- * When the dialer is required by the user (i.e. until {@link #openDialer(boolean)} being
- * called), mDialerStub will inflate the dialer, and make mDialerStub itself null.
- * mDialerStub won't be used afterward.
- */
- private DTMFTwelveKeyDialerView mDialerView;
-
- /**
- * {@link ViewStub} holding {@link DTMFTwelveKeyDialerView}. See the comments for mDialerView.
- */
- private ViewStub mDialerStub;
-
- // KeyListener used with the "dialpad digits" EditText widget.
- private DTMFKeyListener mDialerKeyListener;
-
- /**
- * Our own key listener, specialized for dealing with DTMF codes.
- * 1. Ignore the backspace since it is irrelevant.
- * 2. Allow ONLY valid DTMF characters to generate a tone and be
- * sent as a DTMF code.
- * 3. All other remaining characters are handled by the superclass.
- *
- * This code is purely here to handle events from the hardware keyboard
- * while the DTMF dialpad is up.
- */
- private class DTMFKeyListener extends DialerKeyListener {
-
- private DTMFKeyListener() {
- super();
- }
-
- /**
- * Overriden to return correct DTMF-dialable characters.
- */
- @Override
- protected char[] getAcceptedChars(){
- return DTMF_CHARACTERS;
- }
-
- /** special key listener ignores backspace. */
- @Override
- public boolean backspace(View view, Editable content, int keyCode,
- KeyEvent event) {
- return false;
- }
-
- /**
- * Return true if the keyCode is an accepted modifier key for the
- * dialer (ALT or SHIFT).
- */
- private boolean isAcceptableModifierKey(int keyCode) {
- switch (keyCode) {
- case KeyEvent.KEYCODE_ALT_LEFT:
- case KeyEvent.KEYCODE_ALT_RIGHT:
- case KeyEvent.KEYCODE_SHIFT_LEFT:
- case KeyEvent.KEYCODE_SHIFT_RIGHT:
- return true;
- default:
- return false;
- }
- }
-
- /**
- * Overriden so that with each valid button press, we start sending
- * a dtmf code and play a local dtmf tone.
- */
- @Override
- public boolean onKeyDown(View view, Editable content,
- int keyCode, KeyEvent event) {
- // if (DBG) log("DTMFKeyListener.onKeyDown, keyCode " + keyCode + ", view " + view);
-
- // find the character
- char c = (char) lookup(event, content);
-
- // if not a long press, and parent onKeyDown accepts the input
- if (event.getRepeatCount() == 0 && super.onKeyDown(view, content, keyCode, event)) {
-
- boolean keyOK = ok(getAcceptedChars(), c);
-
- // if the character is a valid dtmf code, start playing the tone and send the
- // code.
- if (keyOK) {
- if (DBG) log("DTMFKeyListener reading '" + c + "' from input.");
- processDtmf(c);
- } else if (DBG) {
- log("DTMFKeyListener rejecting '" + c + "' from input.");
- }
- return true;
- }
- return false;
- }
-
- /**
- * Overriden so that with each valid button up, we stop sending
- * a dtmf code and the dtmf tone.
- */
- @Override
- public boolean onKeyUp(View view, Editable content,
- int keyCode, KeyEvent event) {
- // if (DBG) log("DTMFKeyListener.onKeyUp, keyCode " + keyCode + ", view " + view);
-
- super.onKeyUp(view, content, keyCode, event);
-
- // find the character
- char c = (char) lookup(event, content);
-
- boolean keyOK = ok(getAcceptedChars(), c);
-
- if (keyOK) {
- if (DBG) log("Stopping the tone for '" + c + "'");
- stopTone();
- return true;
- }
-
- return false;
- }
-
- /**
- * Handle individual keydown events when we DO NOT have an Editable handy.
- */
- public boolean onKeyDown(KeyEvent event) {
- char c = lookup(event);
- if (DBG) log("DTMFKeyListener.onKeyDown: event '" + c + "'");
-
- // if not a long press, and parent onKeyDown accepts the input
- if (event.getRepeatCount() == 0 && c != 0) {
- // if the character is a valid dtmf code, start playing the tone and send the
- // code.
- if (ok(getAcceptedChars(), c)) {
- if (DBG) log("DTMFKeyListener reading '" + c + "' from input.");
- processDtmf(c);
- return true;
- } else if (DBG) {
- log("DTMFKeyListener rejecting '" + c + "' from input.");
- }
- }
- return false;
- }
-
- /**
- * Handle individual keyup events.
- *
- * @param event is the event we are trying to stop. If this is null,
- * then we just force-stop the last tone without checking if the event
- * is an acceptable dialer event.
- */
- public boolean onKeyUp(KeyEvent event) {
- if (event == null) {
- //the below piece of code sends stopDTMF event unnecessarily even when a null event
- //is received, hence commenting it.
- /*if (DBG) log("Stopping the last played tone.");
- stopTone();*/
- return true;
- }
-
- char c = lookup(event);
- if (DBG) log("DTMFKeyListener.onKeyUp: event '" + c + "'");
-
- // TODO: stopTone does not take in character input, we may want to
- // consider checking for this ourselves.
- if (ok(getAcceptedChars(), c)) {
- if (DBG) log("Stopping the tone for '" + c + "'");
- stopTone();
- return true;
- }
-
- return false;
- }
-
- /**
- * Find the Dialer Key mapped to this event.
- *
- * @return The char value of the input event, otherwise
- * 0 if no matching character was found.
- */
- private char lookup(KeyEvent event) {
- // This code is similar to {@link DialerKeyListener#lookup(KeyEvent, Spannable) lookup}
- int meta = event.getMetaState();
- int number = event.getNumber();
-
- if (!((meta & (KeyEvent.META_ALT_ON | KeyEvent.META_SHIFT_ON)) == 0) || (number == 0)) {
- int match = event.getMatch(getAcceptedChars(), meta);
- number = (match != 0) ? match : number;
- }
-
- return (char) number;
- }
-
- /**
- * Check to see if the keyEvent is dialable.
- */
- boolean isKeyEventAcceptable (KeyEvent event) {
- return (ok(getAcceptedChars(), lookup(event)));
- }
-
- /**
- * Overrides the characters used in {@link DialerKeyListener#CHARACTERS}
- * These are the valid dtmf characters.
- */
- public final char[] DTMF_CHARACTERS = new char[] {
- '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '#', '*'
- };
- }
-
- /**
- * Our own handler to take care of the messages from the phone state changes
- */
- private final Handler mHandler = new Handler() {
- @Override
- public void handleMessage(Message msg) {
- switch (msg.what) {
- // disconnect action
- // make sure to close the dialer on ALL disconnect actions.
- case PHONE_DISCONNECT:
- if (DBG) log("disconnect message recieved, shutting down.");
- // unregister since we are closing.
- mCM.unregisterForDisconnect(this);
- closeDialer(false);
- break;
- case DTMF_SEND_CNF:
- if (DBG) log("dtmf confirmation received from FW.");
- // handle burst dtmf confirmation
- handleBurstDtmfConfirmation();
- break;
- case DTMF_STOP:
- if (DBG) log("dtmf stop received");
- stopTone();
- break;
- }
- }
- };
-
-
- /**
- * DTMFTwelveKeyDialer constructor with {@link DTMFTwelveKeyDialerView}
- *
- * @param parent the InCallScreen instance that owns us.
- * @param dialerView the DTMFTwelveKeyDialerView we should use to display the dialpad.
- */
- public DTMFTwelveKeyDialer(InCallScreen parent,
- DTMFTwelveKeyDialerView dialerView) {
- this(parent);
-
- // The passed-in DTMFTwelveKeyDialerView *should* always be
- // non-null, now that the in-call UI uses only portrait mode.
- if (dialerView == null) {
- Log.e(LOG_TAG, "DTMFTwelveKeyDialer: null dialerView!", new IllegalStateException());
- // ...continue as best we can, although things will
- // be pretty broken without the mDialerView UI elements!
- }
- mDialerView = dialerView;
- if (DBG) log("- Got passed-in mDialerView: " + mDialerView);
-
- if (mDialerView != null) {
- setupDialerView();
- }
- }
-
- /**
- * DTMFTwelveKeyDialer constructor with {@link ViewStub}.
- *
- * When the dialer is required for the first time (e.g. when {@link #openDialer(boolean)} is
- * called), the object will inflate the ViewStub by itself, assuming the ViewStub will return
- * {@link DTMFTwelveKeyDialerView} on {@link ViewStub#inflate()}.
- *
- * @param parent the InCallScreen instance that owns us.
- * @param dialerStub ViewStub which will return {@link DTMFTwelveKeyDialerView} on
- * {@link ViewStub#inflate()}.
- */
- public DTMFTwelveKeyDialer(InCallScreen parent, ViewStub dialerStub) {
- this(parent);
-
- mDialerStub = dialerStub;
- if (DBG) log("- Got passed-in mDialerStub: " + mDialerStub);
-
- // At this moment mDialerView is still null. We delay calling setupDialerView().
- }
-
- /**
- * 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() {
- if (DBG) log("setupDialerView()");
- mDialerView.setDialer(this);
-
- // In the normal in-call DTMF dialpad, mDialpadDigits is an
- // EditText used to display the digits the user has typed so
- // far. But some other modes (like the OTA call) have no
- // "digits" display at all, in which case mDialpadDigits will
- // be null.
- mDialpadDigits = (EditText) mDialerView.findViewById(R.id.dtmfDialerField);
- if (mDialpadDigits != null) {
- mDialerKeyListener = new DTMFKeyListener();
- mDialpadDigits.setKeyListener(mDialerKeyListener);
-
- // remove the long-press context menus that support
- // the edit (copy / paste / select) functions.
- mDialpadDigits.setLongClickable(false);
- }
-
- // Hook up touch / key listeners for the buttons in the onscreen
- // keypad.
- setupKeypad(mDialerView);
- }
-
- /**
- * Null out our reference to the InCallScreen activity.
- * This indicates that the InCallScreen activity has been destroyed.
- * At the same time, get rid of listeners since we're not going to
- * be valid anymore.
- */
- /* package */ void clearInCallScreenReference() {
- if (DBG) log("clearInCallScreenReference()...");
- mInCallScreen = null;
- mDialerKeyListener = null;
- mHandler.removeMessages(DTMF_SEND_CNF);
- synchronized (mDTMFQueue) {
- mDTMFBurstCnfPending = false;
- mDTMFQueue.clear();
- }
- closeDialer(false);
- }
-
- /**
- * Dialer code that runs when the dialer is brought up.
- * This includes layout changes, etc, and just prepares the dialer model for use.
- */
- private void onDialerOpen(boolean animate) {
- if (DBG) log("onDialerOpen()...");
-
- // Any time the dialer is open, listen for "disconnect" events (so
- // we can close ourself.)
- mCM.registerForDisconnect(mHandler, PHONE_DISCONNECT, null);
-
- // On some devices the screen timeout is set to a special value
- // while the dialpad is up.
- PhoneGlobals.getInstance().updateWakeState();
-
- // Give the InCallScreen a chance to do any necessary UI updates.
- if (mInCallScreen != null) {
- mInCallScreen.onDialerOpen(animate);
- } else {
- Log.e(LOG_TAG, "InCallScreen object was null during onDialerOpen()");
- }
- }
-
- /**
- * Allocates some resources we keep around during a "dialer session".
- *
- * (Currently, a "dialer session" just means any situation where we
- * might need to play local DTMF tones, which means that we need to
- * keep a ToneGenerator instance around. A ToneGenerator instance
- * keeps an AudioTrack resource busy in AudioFlinger, so we don't want
- * to keep it around forever.)
- *
- * Call {@link stopDialerSession} to release the dialer session
- * resources.
- */
- public void startDialerSession() {
- if (DBG) log("startDialerSession()... this = " + this);
-
- // see if we need to play local 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 {
- mLocalToneEnabled = false;
- }
- if (DBG) log("- startDialerSession: mLocalToneEnabled = " + mLocalToneEnabled);
-
- // create the tone generator
- // if the mToneGenerator creation fails, just continue without it. It is
- // a local audio signal, and is not as important as the dtmf tone itself.
- if (mLocalToneEnabled) {
- synchronized (mToneGeneratorLock) {
- if (mToneGenerator == null) {
- try {
- mToneGenerator = new ToneGenerator(AudioManager.STREAM_DTMF, 80);
- } catch (RuntimeException e) {
- if (DBG) log("Exception caught while creating local tone generator: " + e);
- mToneGenerator = null;
- }
- }
- }
- }
- }
-
- /**
- * Dialer code that runs when the dialer is closed.
- * This releases resources acquired when we start the dialer.
- */
- private void onDialerClose(boolean animate) {
- if (DBG) log("onDialerClose()...");
-
- // reset back to a short delay for the poke lock.
- PhoneGlobals app = PhoneGlobals.getInstance();
- app.updateWakeState();
-
- mCM.unregisterForDisconnect(mHandler);
-
- // Give the InCallScreen a chance to do any necessary UI updates.
- if (mInCallScreen != null) {
- mInCallScreen.onDialerClose(animate);
- } else {
- Log.e(LOG_TAG, "InCallScreen object was null during onDialerClose()");
- }
- }
-
- /**
- * Releases resources we keep around during a "dialer session"
- * (see {@link startDialerSession}).
- *
- * It's safe to call this even without a corresponding
- * startDialerSession call.
- */
- public void stopDialerSession() {
- // release the tone generator.
- synchronized (mToneGeneratorLock) {
- if (mToneGenerator != null) {
- mToneGenerator.release();
- mToneGenerator = null;
- }
- }
- }
-
- /**
- * Called externally (from InCallScreen) to play a DTMF Tone.
- */
- public boolean onDialerKeyDown(KeyEvent event) {
- if (DBG) log("Notifying dtmf key down.");
- if (mDialerKeyListener != null) {
- return mDialerKeyListener.onKeyDown(event);
- } else {
- return false;
- }
- }
-
- /**
- * Called externally (from InCallScreen) to cancel the last DTMF Tone played.
- */
- public boolean onDialerKeyUp(KeyEvent event) {
- if (DBG) log("Notifying dtmf key up.");
- if (mDialerKeyListener != null) {
- return mDialerKeyListener.onKeyUp(event);
- } else {
- return false;
- }
- }
-
- /**
- * setup the keys on the dialer activity, using the keymaps.
- */
- private void setupKeypad(DTMFTwelveKeyDialerView dialerView) {
- // for each view id listed in the displaymap
- View button;
- for (int viewId : mDisplayMap.keySet()) {
- // locate the view
- button = dialerView.findViewById(viewId);
- // Setup the listeners for the buttons
- button.setOnTouchListener(this);
- button.setClickable(true);
- button.setOnKeyListener(this);
- button.setOnHoverListener(this);
- button.setOnClickListener(this);
- }
- }
-
- /**
- * catch the back and call buttons to return to the in call activity.
- */
- public boolean onKeyDown(int keyCode, KeyEvent event) {
- // if (DBG) log("onKeyDown: keyCode " + keyCode);
- switch (keyCode) {
- // finish for these events
- case KeyEvent.KEYCODE_BACK:
- case KeyEvent.KEYCODE_CALL:
- if (DBG) log("exit requested");
- closeDialer(true); // do the "closing" animation
- return true;
- }
- return mInCallScreen.onKeyDown(keyCode, event);
- }
-
- /**
- * catch the back and call buttons to return to the in call activity.
- */
- public boolean onKeyUp(int keyCode, KeyEvent event) {
- // if (DBG) log("onKeyUp: keyCode " + keyCode);
- return mInCallScreen.onKeyUp(keyCode, event);
- }
-
- /**
- * 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 /* timedShortTone */);
- }
- }
- }
-
- /**
- * Implemented for the TouchListener, process the touch events.
- */
- @Override
- public boolean onTouch(View v, MotionEvent event) {
- int viewId = v.getId();
-
- // if the button is recognized
- if (mDisplayMap.containsKey(viewId)) {
- switch (event.getAction()) {
- case MotionEvent.ACTION_DOWN:
- // Append the character mapped to this button, to the display.
- // start the tone
- processDtmf(mDisplayMap.get(viewId));
- break;
- case MotionEvent.ACTION_UP:
- case MotionEvent.ACTION_CANCEL:
- // stop the tone on ANY other event, except for MOVE.
- stopTone();
- break;
- }
- // do not return true [handled] here, since we want the
- // press / click animation to be handled by the framework.
- }
- return false;
- }
-
- /**
- * Implements View.OnKeyListener for the DTMF buttons. Enables dialing with trackball/dpad.
- */
- @Override
- public boolean onKey(View v, int keyCode, KeyEvent event) {
- // if (DBG) log("onKey: keyCode " + keyCode + ", view " + v);
-
- if (keyCode == KeyEvent.KEYCODE_DPAD_CENTER) {
- int viewId = v.getId();
- if (mDisplayMap.containsKey(viewId)) {
- switch (event.getAction()) {
- case KeyEvent.ACTION_DOWN:
- if (event.getRepeatCount() == 0) {
- processDtmf(mDisplayMap.get(viewId));
- }
- break;
- case KeyEvent.ACTION_UP:
- stopTone();
- break;
- }
- // do not return true [handled] here, since we want the
- // press / click animation to be handled by the framework.
- }
- }
- return false;
- }
-
- /**
- * Returns true if the dialer is in "open" state, meaning it is already visible *and* it
- * isn't fading out. Note that during fade-out animation the View will return VISIBLE but
- * will become GONE soon later, so you would want to use this method instead of
- * {@link View#getVisibility()}.
- *
- * Fade-in animation, on the other hand, will set the View's visibility VISIBLE soon after
- * the request, so we don't need to take care much of it. In other words,
- * {@link #openDialer(boolean)} soon makes the visibility VISIBLE and thus this method will
- * return true just after the method call.
- *
- * Note: during the very early stage of "open" state, users may not see the dialpad yet because
- * of its fading-in animation, while they will see it shortly anyway. Similarly, during the
- * early stage of "closed" state (opposite of "open" state), users may still see the dialpad
- * due to fading-out animation, but it will vanish shortly and thus we can treat it as "closed",
- * or "not open". To make the transition clearer, we call the state "open", not "shown" nor
- * "visible".
- */
- public boolean isOpened() {
- // Return whether or not the dialer view is visible.
- // (Note that if we're in the middle of a fade-out animation, that
- // also counts as "not visible" even though mDialerView itself is
- // technically still VISIBLE.)
- return (mDialerView != null
- &&(mDialerView.getVisibility() == View.VISIBLE)
- && !AnimationUtils.Fade.isFadingOut(mDialerView));
- }
-
- /**
- * Forces the dialer into the "open" state.
- * Does nothing if the dialer is already open.
- *
- * The "open" state includes the state the dialer is fading in.
- * {@link InCallScreen#onDialerOpen(boolean)} will change visibility state and do
- * actual animation.
- *
- * @param animate if true, open the dialer with an animation.
- *
- * @see #isOpened
- */
- public void openDialer(boolean animate) {
- if (DBG) log("openDialer()...");
-
- if (mDialerView == null && mDialerStub != null) {
- if (DBG) log("Dialer isn't ready. Inflate it from ViewStub.");
- mDialerView = (DTMFTwelveKeyDialerView) mDialerStub.inflate();
- setupDialerView();
- mDialerStub = null;
- }
-
- if (!isOpened()) {
- // Make the dialer view visible.
- if (animate) {
- AnimationUtils.Fade.show(mDialerView);
- } else {
- mDialerView.setVisibility(View.VISIBLE);
- }
- onDialerOpen(animate);
- }
- }
-
- /**
- * Forces the dialer into the "closed" state.
- * Does nothing if the dialer is already closed.
- *
- * {@link InCallScreen#onDialerOpen(boolean)} will change visibility state and do
- * actual animation.
- *
- * @param animate if true, close the dialer with an animation.
- *
- * @see #isOpened
- */
- public void closeDialer(boolean animate) {
- if (DBG) log("closeDialer()...");
-
- if (isOpened()) {
- // Hide the dialer view.
- if (animate) {
- AnimationUtils.Fade.hide(mDialerView, View.GONE);
- } else {
- mDialerView.setVisibility(View.GONE);
- }
- onDialerClose(animate);
- }
- }
-
- /**
- * 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 timedShortTone) {
- // 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 + "'");
-
- // Append this key to the "digits" widget.
- if (mDialpadDigits != null) {
- // TODO: maybe *don't* manually append this digit if
- // mDialpadDigits is focused and this key came from the HW
- // keyboard, since in that case the EditText field will
- // get the key event directly and automatically appends
- // whetever the user types.
- // (Or, a cleaner fix would be to just make mDialpadDigits
- // *not* handle HW key presses. That seems to be more
- // complicated than just setting focusable="false" on it,
- // though.)
- mDialpadDigits.getText().append(c);
- }
-
- // Play the tone if it exists.
- if (mToneMap.containsKey(c)) {
- // begin tone playback.
- startTone(c, timedShortTone);
- }
- } else if (DBG) {
- log("ignoring dtmf request for '" + c + "'");
- }
-
- // Any DTMF keypress counts as explicit "user activity".
- PhoneGlobals.getInstance().pokeUserActivity();
- }
-
- /**
- * Clears out the display of "DTMF digits typed so far" that's kept in
- * mDialpadDigits.
- *
- * The InCallScreen is responsible for calling this method any time a
- * new call becomes active (or, more simply, any time a call ends).
- * This is how we make sure that the "history" of DTMF digits you type
- * doesn't persist from one call to the next.
- *
- * TODO: it might be more elegent if the dialpad itself could remember
- * the call that we're associated with, and clear the digits if the
- * "current call" has changed since last time. (This would require
- * some unique identifier that's different for each call. We can't
- * just use the foreground Call object, since that's a singleton that
- * lasts the whole life of the phone process. Instead, maybe look at
- * the Connection object that comes back from getEarliestConnection()?
- * Or getEarliestConnectTime()?)
- *
- * Or to be even fancier, we could keep a mapping of *multiple*
- * "active calls" to DTMF strings. That way you could have two lines
- * in use and swap calls multiple times, and we'd still remember the
- * digits for each call. (But that's such an obscure use case that
- * it's probably not worth the extra complexity.)
- */
- public void clearDigits() {
- if (DBG) log("clearDigits()...");
-
- if (mDialpadDigits != null) {
- mDialpadDigits.setText("");
- }
-
- setDialpadContext("");
- }
-
- /**
- * Set the context text (hint) to show in the dialpad Digits EditText.
- *
- * This is currently only used for displaying a value for "Voice Mail"
- * calls since they default to the dialpad and we want to give users better
- * context when they dial voicemail.
- *
- * TODO: Is there value in extending this functionality for all contacts
- * and not just Voice Mail calls?
- * TODO: This should include setting the digits as well as the context
- * once we start saving the digits properly...and properly in this case
- * ideally means moving some of processDtmf() out of this class.
- */
- public void setDialpadContext(String contextValue) {
- if (mDialpadDigits != null) {
- if (contextValue == null) {
- contextValue = "";
- }
- final SpannableString hint = new SpannableString(contextValue);
- hint.setSpan(new RelativeSizeSpan(0.8f), 0, hint.length(), 0);
- mDialpadDigits.setHint(hint);
- }
- }
-
- /**
- * Plays the local tone based the phone type.
- */
- public void startTone(char c, boolean timedShortTone) {
- // Only play the tone if it exists.
- if (!mToneMap.containsKey(c)) {
- return;
- }
-
- if (!mInCallScreen.okToDialDTMFTones()) {
- return;
- }
-
- // Read the settings as it may be changed by the user during the call
- Phone phone = mCM.getFgPhone();
- mShortTone = useShortDtmfTones(phone, phone.getContext());
-
- // Before we go ahead and start a tone, we need to make sure that any pending
- // stop-tone message is processed.
- if (mHandler.hasMessages(DTMF_STOP)) {
- mHandler.removeMessages(DTMF_STOP);
- stopTone();
- }
-
- if (DBG) log("startDtmfTone()...");
-
- // For Short DTMF we need to play the local tone for fixed duration
- if (mShortTone) {
- sendShortDtmfToNetwork(c);
- } else {
- // Pass as a char to be sent to network
- if (DBG) log("send long dtmf for " + c);
- mCM.startDtmf(c);
-
- // If it is a timed tone, queue up the stop command in DTMF_DURATION_MS.
- if (timedShortTone) {
- mHandler.sendMessageDelayed(mHandler.obtainMessage(DTMF_STOP), DTMF_DURATION_MS);
- }
- }
- startLocalToneIfNeeded(c);
- }
-
-
- /**
- * Plays the local tone based the phone type, optionally forcing a short
- * tone.
- */
- public void startLocalToneIfNeeded(char c) {
- // if local tone playback is enabled, start it.
- // Only play the tone if it exists.
- if (!mToneMap.containsKey(c)) {
- return;
- }
- if (mLocalToneEnabled) {
- synchronized (mToneGeneratorLock) {
- if (mToneGenerator == null) {
- if (DBG) log("startDtmfTone: mToneGenerator == null, tone: " + c);
- } else {
- if (DBG) log("starting local tone " + c);
- int toneDuration = -1;
- if (mShortTone) {
- toneDuration = DTMF_DURATION_MS;
- }
- mToneGenerator.startTone(mToneMap.get(c), toneDuration);
- }
- }
- }
- }
-
- /**
- * Check to see if the keyEvent is dialable.
- */
- boolean isKeyEventAcceptable (KeyEvent event) {
- return (mDialerKeyListener != null && mDialerKeyListener.isKeyEventAcceptable(event));
- }
-
- /**
- * static logging method
- */
- private static void log(String msg) {
- Log.d(LOG_TAG, msg);
- }
-
- /**
- * Stops the local tone based on the phone type.
- */
- public void stopTone() {
- // We do not rely on InCallScreen#okToDialDTMFTones() here since it is ok to stop tones
- // without starting them.
-
- if (!mShortTone) {
- if (DBG) log("stopping remote tone.");
- mCM.stopDtmf();
- stopLocalToneIfNeeded();
- }
- }
-
- /**
- * Stops the local tone based on the phone type.
- */
- public void stopLocalToneIfNeeded() {
- if (!mShortTone) {
- // if local tone playback is enabled, stop it.
- if (DBG) log("trying to stop local tone...");
- if (mLocalToneEnabled) {
- synchronized (mToneGeneratorLock) {
- if (mToneGenerator == null) {
- if (DBG) log("stopLocalTone: mToneGenerator == null");
- } else {
- if (DBG) log("stopping local tone.");
- mToneGenerator.stopTone();
- }
- }
- }
- }
- }
-
- /**
- * Sends the dtmf character over the network for short DTMF settings
- * When the characters are entered in quick succession,
- * the characters are queued before sending over the network.
- */
- private void sendShortDtmfToNetwork(char dtmfDigit) {
- synchronized (mDTMFQueue) {
- if (mDTMFBurstCnfPending == true) {
- // Insert the dtmf char to the queue
- mDTMFQueue.add(new Character(dtmfDigit));
- } else {
- String dtmfStr = Character.toString(dtmfDigit);
- mCM.sendBurstDtmf(dtmfStr, 0, 0, mHandler.obtainMessage(DTMF_SEND_CNF));
- // Set flag to indicate wait for Telephony confirmation.
- mDTMFBurstCnfPending = true;
- }
- }
- }
-
- /**
- * Handles Burst Dtmf Confirmation from the Framework.
- */
- void handleBurstDtmfConfirmation() {
- Character dtmfChar = null;
- synchronized (mDTMFQueue) {
- mDTMFBurstCnfPending = false;
- if (!mDTMFQueue.isEmpty()) {
- dtmfChar = mDTMFQueue.remove();
- Log.i(LOG_TAG, "The dtmf character removed from queue" + dtmfChar);
- }
- }
- if (dtmfChar != null) {
- sendShortDtmfToNetwork(dtmfChar);
- }
- }
-
- /**
- * On GSM devices, we never use short tones.
- * On CDMA devices, it depends upon the settings.
- */
- private static boolean useShortDtmfTones(Phone phone, Context context) {
- int phoneType = phone.getPhoneType();
- if (phoneType == PhoneConstants.PHONE_TYPE_GSM) {
- return false;
- } else if (phoneType == PhoneConstants.PHONE_TYPE_CDMA) {
- int toneType = android.provider.Settings.System.getInt(
- context.getContentResolver(),
- Settings.System.DTMF_TONE_TYPE_WHEN_DIALING,
- Constants.DTMF_TONE_TYPE_NORMAL);
- if (toneType == Constants.DTMF_TONE_TYPE_NORMAL) {
- return true;
- } else {
- return false;
- }
- } else if (phoneType == PhoneConstants.PHONE_TYPE_SIP) {
- return false;
- } else {
- throw new IllegalStateException("Unexpected phone type: " + phoneType);
- }
- }
-
-}
diff --git a/src/com/android/phone/DTMFTwelveKeyDialerView.java b/src/com/android/phone/DTMFTwelveKeyDialerView.java
deleted file mode 100644
index e0502b7..0000000
--- a/src/com/android/phone/DTMFTwelveKeyDialerView.java
+++ /dev/null
@@ -1,87 +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.content.Context;
-import android.graphics.Rect;
-import android.graphics.drawable.Drawable;
-import android.util.AttributeSet;
-import android.util.Log;
-import android.view.FocusFinder;
-import android.view.KeyEvent;
-import android.view.MotionEvent;
-import android.view.View;
-import android.view.ViewConfiguration;
-import android.view.ViewGroup;
-import android.widget.LinearLayout;
-
-import java.util.ArrayList;
-
-/**
- * DTMFTwelveKeyDialerView is the view logic that the DTMFDialer uses.
- * This is really a thin wrapper around Linear Layout that intercepts
- * some user interactions to provide the correct UI behaviour for the
- * dialer.
- *
- * See dtmf_twelve_key_dialer_view.xml.
- */
-class DTMFTwelveKeyDialerView extends LinearLayout {
-
- private static final String LOG_TAG = "PHONE/DTMFTwelveKeyDialerView";
- private static final boolean DBG = false;
-
- private DTMFTwelveKeyDialer mDialer;
-
-
- public DTMFTwelveKeyDialerView (Context context) {
- super(context);
- }
-
- public DTMFTwelveKeyDialerView(Context context, AttributeSet attrs) {
- super(context, attrs);
- }
-
- void setDialer (DTMFTwelveKeyDialer dialer) {
- mDialer = dialer;
- }
-
- /**
- * Normally we ignore everything except for the BACK and CALL keys.
- * For those, we pass them to the model (and then the InCallScreen).
- */
- @Override
- public boolean dispatchKeyEvent(KeyEvent event) {
- if (DBG) log("dispatchKeyEvent(" + event + ")...");
-
- int keyCode = event.getKeyCode();
- if (mDialer != null) {
- switch (keyCode) {
- case KeyEvent.KEYCODE_BACK:
- case KeyEvent.KEYCODE_CALL:
- return event.isDown() ? mDialer.onKeyDown(keyCode, event) :
- mDialer.onKeyUp(keyCode, event);
- }
- }
-
- if (DBG) log("==> dispatchKeyEvent: forwarding event to the DTMFDialer");
- return super.dispatchKeyEvent(event);
- }
-
- private void log(String msg) {
- Log.d(LOG_TAG, msg);
- }
-}
diff --git a/src/com/android/phone/EmergencyCallHelper.java b/src/com/android/phone/EmergencyCallHelper.java
index a23e3e0..866f2be 100644
--- a/src/com/android/phone/EmergencyCallHelper.java
+++ b/src/com/android/phone/EmergencyCallHelper.java
@@ -21,7 +21,6 @@
import com.android.internal.telephony.Phone;
import com.android.internal.telephony.PhoneConstants;
import com.android.phone.Constants.CallStatusCode;
-import com.android.phone.InCallUiState.ProgressIndicationType;
import android.content.Context;
import android.content.Intent;
@@ -183,10 +182,6 @@
// for some reason.
startRetryTimer();
- // And finally, let the in-call UI know that we need to
- // display the "Turning on radio..." progress indication.
- mApp.inCallUiState.setProgressIndication(ProgressIndicationType.TURNING_ON_RADIO);
-
// (Our caller is responsible for calling mApp.displayCallScreen().)
}
@@ -220,14 +215,7 @@
// Deregister for the service state change events.
unregisterForServiceStateChanged();
- // Take down the "Turning on radio..." indication.
- mApp.inCallUiState.clearProgressIndication();
-
placeEmergencyCall();
-
- // The in-call UI is probably still up at this point,
- // but make sure of that:
- mApp.displayCallScreen();
} else {
// The service state changed, but we're still not ready to call yet.
// (This probably was the transition from STATE_POWER_OFF to
@@ -307,9 +295,6 @@
// these any more now that the radio is powered-on.
unregisterForServiceStateChanged();
- // Take down the "Turning on radio..." indication.
- mApp.inCallUiState.clearProgressIndication();
-
placeEmergencyCall(); // If the call fails, placeEmergencyCall()
// will schedule a retry.
} else {
@@ -324,10 +309,6 @@
// totally if we've had too many failures.)
scheduleRetryOrBailOut();
}
-
- // Finally, the in-call UI is probably still up at this point,
- // but make sure of that:
- mApp.displayCallScreen();
}
/**
@@ -441,13 +422,9 @@
if (mNumRetriesSoFar > MAX_NUM_RETRIES) {
Log.w(TAG, "scheduleRetryOrBailOut: hit MAX_NUM_RETRIES; giving up...");
cleanup();
- // ...and have the InCallScreen display a generic failure
- // message.
- mApp.inCallUiState.setPendingCallStatusCode(CallStatusCode.CALL_FAILED);
} else {
if (DBG) log("- Scheduling another retry...");
startRetryTimer();
- mApp.inCallUiState.setProgressIndication(ProgressIndicationType.RETRYING);
}
}
@@ -475,9 +452,6 @@
private void cleanup() {
if (DBG) log("cleanup()...");
- // Take down the "Turning on radio..." indication.
- mApp.inCallUiState.clearProgressIndication();
-
unregisterForServiceStateChanged();
unregisterForDisconnect();
cancelRetryTimer();
@@ -490,10 +464,6 @@
}
mPartialWakeLock = null;
}
-
- // And finally, ask the in-call UI to refresh itself (to clean up the
- // progress indication if necessary), if it's currently visible.
- mApp.updateInCallScreen();
}
private void startRetryTimer() {
diff --git a/src/com/android/phone/EmergencyDialer.java b/src/com/android/phone/EmergencyDialer.java
index 42c73ae..26bfc73 100644
--- a/src/com/android/phone/EmergencyDialer.java
+++ b/src/com/android/phone/EmergencyDialer.java
@@ -166,7 +166,7 @@
lp.flags |= WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED;
// When no proximity sensor is available, use a shorter timeout.
- // TODO(klp): Do we enable this for non proximity devices any more?
+ // TODO: Do we enable this for non proximity devices any more?
// lp.userActivityTimeout = USER_ACTIVITY_TIMEOUT_WHEN_NO_PROX_SENSOR;
getWindow().setAttributes(lp);
diff --git a/src/com/android/phone/HfaActivity.java b/src/com/android/phone/HfaActivity.java
index 3bc047d..bcd3652 100644
--- a/src/com/android/phone/HfaActivity.java
+++ b/src/com/android/phone/HfaActivity.java
@@ -19,82 +19,47 @@
import android.app.Activity;
import android.app.AlertDialog;
import android.app.PendingIntent;
-import android.app.PendingIntent.CanceledException;
-import android.content.BroadcastReceiver;
-import android.content.Context;
import android.content.DialogInterface;
-import android.content.Intent;
-import android.content.IntentFilter;
-import android.os.AsyncResult;
import android.os.Bundle;
-import android.os.Handler;
-import android.os.Message;
-import android.telephony.ServiceState;
import android.util.Log;
-import com.android.internal.telephony.CallManager;
-import com.android.internal.telephony.Phone;
-import com.google.common.base.Objects;
-import com.google.common.base.Objects.ToStringHelper;
-
/**
* Starts and displays status for Hands Free Activation (HFA).
*
- * This class operates with Hands Free Activation apps.
- * It starts by broadcasting the intent com.android.action.START_HFA.
- * An HFA app will pick that up and start the HFA process.
- * If it fails it return ERROR_HFA Intent and upon success returns COMPLETE_HFA.
- *
- * If successful, we bounce the radio so that the service picks up the new number. This is also
- * necessary for the setup wizard to pick up the successful activation so that it can continue
- * past the welcome screen. Once the radio is back on we send back the pendingIntent to setup
- * wizard and destroy the activity.
- *
- * If there is an error, we do not bounce the radio but still send the pending intent back to
- * the wizard (with a failure code).
- *
- * The user has an option to skip activation. If that happens, we go back to the setup
- * wizard.
- *
- * TODO(klp): We need system-only permissions for the HFA intents.
- * TODO(klp): Should be full screen activity instead of dialogs.
- * TODO(klp): Currently display the error code instead of the error string resource.
- * TODO(klp): Need to check the system to ensure someone is listening for the intent
- * before we send it. Should there be a timeout? 5 minutes?
+ * This class operates with Hands Free Activation apps. It comes up during activation
+ * requests that occur outside of setup wizard and so provides its own UI.
+ * It uses {@link HfaLogic} to perform the actual activation and during the process
+ * displays a "performing activation..." dialog. This will remain up until the user
+ * chooses to skip the activation (still happens in the background) or the activation
+ * is successful. Upon failure, the dialog also goes away but a subsequent dialog will
+ * ask the user if they would like to try again or cancel.
*/
public class HfaActivity extends Activity {
private static final String TAG = HfaActivity.class.getSimpleName();
- private static final boolean VERBOSE = Log.isLoggable(TAG, Log.VERBOSE);
-
- private static final String ACTION_START = "com.android.action.START_HFA";
- private static final String ACTION_ERROR = "com.android.action.ERROR_HFA";
- private static final String ACTION_CANCEL = "com.android.action.CANCEL_HFA";
- private static final String ACTION_COMPLETE = "com.android.action.COMPLETE_HFA";
-
- private static final int SERVICE_STATE_CHANGED = 1;
-
- public static final int OTASP_UNKNOWN = 0;
- public static final int OTASP_USER_SKIPPED = 1;
- public static final int OTASP_SUCCESS = 2;
- public static final int OTASP_FAILURE = 3;
-
- public static final int NOT_WAITING = 0;
- public static final int WAITING_FOR_RADIO_OFF = 1;
- public static final int WAITING_FOR_RADIO_ON = 2;
-
- private int mPhoneMonitorState = NOT_WAITING;
- private boolean mCanSkip;
private AlertDialog mDialog;
- private BroadcastReceiver mReceiver;
+ private HfaLogic mHfaLogic;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
+ Log.i(TAG, "onCreate");
- if (VERBOSE) Log.v(TAG, "onCreate");
+ final PendingIntent otaResponseIntent = getIntent().getParcelableExtra(
+ OtaUtils.EXTRA_OTASP_RESULT_CODE_PENDING_INTENT);
- startHfaIntentReceiver();
+ mHfaLogic = new HfaLogic(this.getApplicationContext(), new HfaLogic.HfaLogicCallback() {
+ @Override
+ public void onSuccess() {
+ onHfaSuccess();
+ }
+
+ @Override
+ public void onError(String error) {
+ onHfaError(error);
+ }
+ }, otaResponseIntent);
+
startProvisioning();
}
@@ -102,28 +67,20 @@
protected void onDestroy() {
super.onDestroy();
- if (VERBOSE) Log.v(TAG, "onDestroy");
+ Log.i(TAG, "onDestroy");
if (mDialog != null && mDialog.isShowing()) {
mDialog.dismiss();
mDialog = null;
}
-
- if (mReceiver != null) {
- unregisterReceiver(mReceiver);
- mReceiver = null;
- }
}
private void startProvisioning() {
buildAndShowDialog();
-
- sendHfaCommand(ACTION_START);
+ mHfaLogic.start();
}
private void buildAndShowDialog() {
- mCanSkip = true;
-
mDialog = new AlertDialog.Builder(this)
.setTitle(R.string.ota_hfa_activation_title)
.setMessage(R.string.ota_hfa_activation_dialog_message)
@@ -131,25 +88,21 @@
new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface di, int which) {
- if (mCanSkip) {
- sendHfaCommand(ACTION_CANCEL);
- sendResponseToSetupWizard(OTASP_USER_SKIPPED);
- }
+ onUserSkip();
}})
/*.setOnCancelListener(new DialogInterface.OnCancelListener() {
@Override
public void onCancel(DialogInterface di) {
- sendResponseToSetupWizard(OTASP_USER_SKIPPED);
+ sendFinalResponse(OTASP_USER_SKIPPED);
}})*/
.create();
- if (VERBOSE) Log.v(TAG, "showing dialog");
- mDialog.show();
- }
+ // Do not allow user to dismiss dialog unless they are clicking "skip"
+ mDialog.setCanceledOnTouchOutside(false);
+ mDialog.setCancelable(false);
- private void sendHfaCommand(String action) {
- if (VERBOSE) Log.v(TAG, "Sending command: " + action);
- sendBroadcast(new Intent(action));
+ Log.i(TAG, "showing dialog");
+ mDialog.show();
}
private void onHfaError(String errorMsg) {
@@ -162,7 +115,7 @@
@Override
public void onClick(DialogInterface di, int which) {
di.dismiss();
- sendResponseToSetupWizard(OTASP_USER_SKIPPED);
+ onUserSkip();
}
})
.setNegativeButton(R.string.ota_try_again,
@@ -179,97 +132,11 @@
}
private void onHfaSuccess() {
- // User can no longer skip after success.
- mCanSkip = false;
-
- // We need to restart the modem upon successful activation
- // so that it can acquire a number and ensure setupwizard will
- // know about this success through phone state changes.
-
- bounceRadio();
- }
-
- private void bounceRadio() {
- final Phone phone = PhoneGlobals.getInstance().getPhone();
- phone.registerForServiceStateChanged(mHandler, SERVICE_STATE_CHANGED, null);
-
- mPhoneMonitorState = WAITING_FOR_RADIO_OFF;
- phone.setRadioPower(false);
- onServiceStateChange(phone.getServiceState());
- }
-
- private void onServiceStateChange(ServiceState state) {
- final boolean radioIsOff = state.getVoiceRegState() == ServiceState.STATE_POWER_OFF;
- final Phone phone = PhoneGlobals.getInstance().getPhone();
-
- if (VERBOSE) Log.v(TAG, "Radio is off: " + radioIsOff);
-
- if (mPhoneMonitorState == WAITING_FOR_RADIO_OFF) {
- if (radioIsOff) {
- mPhoneMonitorState = WAITING_FOR_RADIO_ON;
- phone.setRadioPower(true);
- }
- } else if (mPhoneMonitorState == WAITING_FOR_RADIO_ON) {
- if (!radioIsOff) {
- mPhoneMonitorState = NOT_WAITING;
- phone.unregisterForServiceStateChanged(mHandler);
-
- // We have successfully bounced the radio.
- // Time to go back to the setup wizard.
- sendResponseToSetupWizard(OTASP_SUCCESS);
- }
- }
- }
-
- private void sendResponseToSetupWizard(int responseCode) {
- final PendingIntent otaResponseIntent = getIntent().getParcelableExtra(
- OtaUtils.EXTRA_OTASP_RESULT_CODE_PENDING_INTENT);
-
- final Intent extraStuff = new Intent();
- extraStuff.putExtra(OtaUtils.EXTRA_OTASP_RESULT_CODE, responseCode);
-
- try {
- if (VERBOSE) Log.v(TAG, "Sending OTASP confirmation with result code: " + responseCode);
- otaResponseIntent.send(this, 0 /* resultCode (not used) */, extraStuff);
- } catch (CanceledException e) {
- Log.e(TAG, "Pending Intent canceled");
- }
-
finish();
}
- public void startHfaIntentReceiver() {
- final IntentFilter filter = new IntentFilter(ACTION_COMPLETE);
- filter.addAction(ACTION_ERROR);
-
- mReceiver = new BroadcastReceiver() {
- @Override
- public void onReceive(Context context, Intent intent) {
- final String action = intent.getAction();
- if (action.equals(ACTION_ERROR)) {
- onHfaError(intent.getStringExtra("errorCode"));
- } else if (action.equals(ACTION_COMPLETE)) {
- if (VERBOSE) Log.v(TAG, "Hfa Successful");
- onHfaSuccess();
- }
- }
- };
-
- registerReceiver(mReceiver, filter);
+ private void onUserSkip() {
+ finish();
}
- private Handler mHandler = new Handler() {
- @Override
- public void handleMessage(Message msg) {
- switch (msg.what) {
- case SERVICE_STATE_CHANGED:
- ServiceState state = (ServiceState) ((AsyncResult) msg.obj).result;
- onServiceStateChange(state);
- break;
- default:
- break;
- }
- }
- };
-
}
diff --git a/src/com/android/phone/HfaLogic.java b/src/com/android/phone/HfaLogic.java
new file mode 100644
index 0000000..e4a3205
--- /dev/null
+++ b/src/com/android/phone/HfaLogic.java
@@ -0,0 +1,224 @@
+/*
+ * Copyright (C) 2013 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.phone;
+
+import android.app.PendingIntent;
+import android.app.PendingIntent.CanceledException;
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.os.AsyncResult;
+import android.os.Handler;
+import android.os.Message;
+import android.telephony.ServiceState;
+import android.util.Log;
+
+import com.android.internal.telephony.Phone;
+import com.google.common.base.Preconditions;
+
+/**
+ * Starts and displays status for Hands Free Activation (HFA).
+ *
+ * This class operates with Hands Free Activation apps.
+ * It starts by broadcasting the intent com.android.action.START_HFA.
+ * An HFA app will pick that up and start the HFA process.
+ * If it fails it return ERROR_HFA Intent and upon success returns COMPLETE_HFA.
+ *
+ * If successful, we bounce the radio so that the service picks up the new number.
+ * Once the radio is back on we callback the requestor.
+ *
+ * If there is an error, we do not bounce the radio but still callback with a failure.
+ *
+ * TODO(klp): We need system-only permissions for the HFA intents.
+ */
+public class HfaLogic {
+ private static final String TAG = HfaLogic.class.getSimpleName();
+
+ private static final String ACTION_START = "com.android.action.START_HFA";
+ private static final String ACTION_ERROR = "com.android.action.ERROR_HFA";
+ private static final String ACTION_CANCEL = "com.android.action.CANCEL_HFA";
+ private static final String ACTION_COMPLETE = "com.android.action.COMPLETE_HFA";
+
+ private static final int SERVICE_STATE_CHANGED = 1;
+
+ public static final int NOT_WAITING = 0;
+ public static final int WAITING_FOR_RADIO_OFF = 1;
+ public static final int WAITING_FOR_RADIO_ON = 2;
+
+ public static final int OTASP_UNKNOWN = 0;
+ public static final int OTASP_USER_SKIPPED = 1;
+ public static final int OTASP_SUCCESS = 2;
+ public static final int OTASP_FAILURE = 3;
+
+ private int mPhoneMonitorState = NOT_WAITING;
+ private BroadcastReceiver mReceiver;
+ private HfaLogicCallback mCallback;
+ private PendingIntent mResponseIntent;
+ private Context mContext;
+
+ private static final int DEFAULT_RETRY_COUNT = 1;
+ private int mRetryCount;
+
+ public interface HfaLogicCallback {
+ public void onSuccess();
+ public void onError(String errorMsg);
+ }
+
+ public HfaLogic(Context context, HfaLogicCallback callback, PendingIntent intent) {
+ mCallback = Preconditions.checkNotNull(callback);
+ mContext = Preconditions.checkNotNull(context);
+ mResponseIntent = intent;
+ }
+
+ public void start() {
+ Log.i(TAG, "start:");
+ mRetryCount = DEFAULT_RETRY_COUNT;
+ startHfaIntentReceiver();
+ startProvisioning();
+ }
+
+ private void startProvisioning() {
+ Log.i(TAG, "startProvisioning:");
+ sendHfaCommand(ACTION_START);
+ }
+
+ private void sendHfaCommand(String action) {
+ Log.i(TAG, "sendHfaCommand: command=" + action);
+ mContext.sendBroadcast(new Intent(action));
+ }
+
+ private void onHfaError(String errorMsg) {
+ Log.i(TAG, "onHfaError: call mCallBack.onError errorMsg=" + errorMsg
+ + " mRetryCount=" + mRetryCount);
+ mRetryCount -= 1;
+ if (mRetryCount >= 0) {
+ Log.i(TAG, "onHfaError: retry");
+ startProvisioning();
+ } else {
+ Log.i(TAG, "onHfaError: Declare OTASP_FAILURE");
+ mRetryCount = 0;
+ stopHfaIntentReceiver();
+ sendFinalResponse(OTASP_FAILURE, errorMsg);
+ mCallback.onError(errorMsg);
+ }
+ }
+
+ private void onHfaSuccess() {
+ Log.i(TAG, "onHfaSuccess: NOT bouncing radio call onTotalSuccess");
+ stopHfaIntentReceiver();
+ // bounceRadio();
+ onTotalSuccess();
+ }
+
+ private void onTotalSuccess() {
+ Log.i(TAG, "onTotalSuccess: call mCallBack.onSuccess");
+ sendFinalResponse(OTASP_SUCCESS, null);
+ mCallback.onSuccess();
+ }
+
+ private void bounceRadio() {
+ final Phone phone = PhoneGlobals.getInstance().getPhone();
+ phone.registerForServiceStateChanged(mHandler, SERVICE_STATE_CHANGED, null);
+
+ mPhoneMonitorState = WAITING_FOR_RADIO_OFF;
+ phone.setRadioPower(false);
+ onServiceStateChange(phone.getServiceState());
+ }
+
+ private void onServiceStateChange(ServiceState state) {
+ final boolean radioIsOff = state.getVoiceRegState() == ServiceState.STATE_POWER_OFF;
+ final Phone phone = PhoneGlobals.getInstance().getPhone();
+
+ Log.i(TAG, "Radio is on: " + !radioIsOff);
+
+ if (mPhoneMonitorState == WAITING_FOR_RADIO_OFF) {
+ if (radioIsOff) {
+ mPhoneMonitorState = WAITING_FOR_RADIO_ON;
+ phone.setRadioPower(true);
+ }
+ } else if (mPhoneMonitorState == WAITING_FOR_RADIO_ON) {
+ if (!radioIsOff) {
+ mPhoneMonitorState = NOT_WAITING;
+ phone.unregisterForServiceStateChanged(mHandler);
+
+ onTotalSuccess();
+ }
+ }
+ }
+
+ private void startHfaIntentReceiver() {
+ final IntentFilter filter = new IntentFilter(ACTION_COMPLETE);
+ filter.addAction(ACTION_ERROR);
+
+ mReceiver = new BroadcastReceiver() {
+ @Override
+ public void onReceive(Context context, Intent intent) {
+ final String action = intent.getAction();
+ if (action.equals(ACTION_ERROR)) {
+ onHfaError(intent.getStringExtra("errorCode"));
+ } else if (action.equals(ACTION_COMPLETE)) {
+ Log.i(TAG, "Hfa Successful");
+ onHfaSuccess();
+ }
+ }
+ };
+
+ mContext.registerReceiver(mReceiver, filter);
+ }
+
+ private void stopHfaIntentReceiver() {
+ if (mReceiver != null) {
+ mContext.unregisterReceiver(mReceiver);
+ mReceiver = null;
+ }
+ }
+
+ private void sendFinalResponse(int responseCode, String errorCode) {
+ if (mResponseIntent != null) {
+ final Intent extraStuff = new Intent();
+ extraStuff.putExtra(OtaUtils.EXTRA_OTASP_RESULT_CODE, responseCode);
+
+ if (responseCode == OTASP_FAILURE && errorCode != null) {
+ extraStuff.putExtra(OtaUtils.EXTRA_OTASP_ERROR_CODE, errorCode);
+ }
+
+ try {
+ Log.i(TAG, "Sending OTASP confirmation with result code: "
+ + responseCode);
+ mResponseIntent.send(mContext, 0 /* resultCode (not used) */, extraStuff);
+ } catch (CanceledException e) {
+ Log.e(TAG, "Pending Intent canceled");
+ }
+ }
+ }
+
+ private Handler mHandler = new Handler() {
+ @Override
+ public void handleMessage(Message msg) {
+ switch (msg.what) {
+ case SERVICE_STATE_CHANGED:
+ ServiceState state = (ServiceState) ((AsyncResult) msg.obj).result;
+ onServiceStateChange(state);
+ break;
+ default:
+ break;
+ }
+ }
+ };
+
+}
diff --git a/src/com/android/phone/HfaService.java b/src/com/android/phone/HfaService.java
new file mode 100644
index 0000000..d5c92b8
--- /dev/null
+++ b/src/com/android/phone/HfaService.java
@@ -0,0 +1,71 @@
+/*
+ * Copyright (C) 2013 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.phone;
+
+import android.app.PendingIntent;
+import android.app.Service;
+import android.content.Intent;
+import android.os.IBinder;
+import android.util.Log;
+
+/**
+ * Service for performing HfaActivation without any UI.
+ */
+public class HfaService extends Service {
+ private static final String TAG = HfaService.class.getSimpleName();
+
+ private HfaLogic mHfaLogic;
+
+ @Override
+ public void onCreate() {
+ Log.i(TAG, "service started");
+ }
+
+ @Override
+ public int onStartCommand(Intent intent, int flags, int startId) {
+ final PendingIntent otaResponseIntent = intent.getParcelableExtra(
+ OtaUtils.EXTRA_OTASP_RESULT_CODE_PENDING_INTENT);
+
+ mHfaLogic = new HfaLogic(this, new HfaLogic.HfaLogicCallback() {
+ @Override
+ public void onSuccess() {
+ Log.i(TAG, "onSuccess");
+ onComplete();
+ }
+
+ @Override
+ public void onError(String msg) {
+ Log.i(TAG, "onError: " + msg);
+ // We do not respond from this service. On success or failure
+ // we do the same thing...finish.
+ onComplete();
+ }
+ }, otaResponseIntent);
+ mHfaLogic.start();
+
+ return START_STICKY;
+ }
+
+ @Override
+ public IBinder onBind(Intent intent) {
+ return null;
+ }
+
+ private void onComplete() {
+ stopSelf();
+ }
+}
diff --git a/src/com/android/phone/InCallControlState.java b/src/com/android/phone/InCallControlState.java
deleted file mode 100644
index 38eaf5c..0000000
--- a/src/com/android/phone/InCallControlState.java
+++ /dev/null
@@ -1,235 +0,0 @@
-/*
- * Copyright (C) 2009 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.telephony.PhoneNumberUtils;
-import android.util.Log;
-
-import com.android.internal.telephony.Call;
-import com.android.internal.telephony.Connection;
-import com.android.internal.telephony.CallManager;
-import com.android.internal.telephony.PhoneConstants;
-import com.android.internal.telephony.TelephonyCapabilities;
-
-/**
- * Helper class to keep track of enabledness, visibility, and "on/off"
- * or "checked" state of the various controls available in the in-call
- * UI, based on the current telephony state.
- *
- * This class is independent of the exact UI controls used on any given
- * device. To avoid cluttering up the "view" code (i.e. InCallTouchUi)
- * with logic about which functions are available right now, we instead
- * have that logic here, and provide simple boolean flags to indicate the
- * state and/or enabledness of all possible in-call user operations.
- *
- * (In other words, this is the "model" that corresponds to the "view"
- * implemented by InCallTouchUi.)
- */
-public class InCallControlState {
- private static final String LOG_TAG = "InCallControlState";
- private static final boolean DBG = (PhoneGlobals.DBG_LEVEL >= 2);
-
- private final BluetoothManager mBluetoothManager;
- private InCallScreen mInCallScreen;
- private CallManager mCM;
-
- //
- // Our "public API": Boolean flags to indicate the state and/or
- // enabledness of all possible in-call user operations:
- //
-
- public boolean manageConferenceVisible;
- public boolean manageConferenceEnabled;
- //
- public boolean canAddCall;
- //
- public boolean canEndCall;
- //
- public boolean canSwap;
- public boolean canMerge;
- //
- public boolean bluetoothEnabled;
- public boolean bluetoothIndicatorOn;
- //
- public boolean speakerEnabled;
- public boolean speakerOn;
- //
- public boolean canMute;
- public boolean muteIndicatorOn;
- //
- public boolean dialpadEnabled;
- public boolean dialpadVisible;
- //
- /** True if the "Hold" function is *ever* available on this device */
- public boolean supportsHold;
- /** True if the call is currently on hold */
- public boolean onHold;
- /** True if the "Hold" or "Unhold" function should be available right now */
- // TODO: this name is misleading. Let's break this apart into
- // separate canHold and canUnhold flags, and have the caller look at
- // "canHold || canUnhold" to decide whether the hold/unhold UI element
- // should be visible.
- public boolean canHold;
-
-
- public InCallControlState(InCallScreen inCallScreen, CallManager cm,
- BluetoothManager bluetoothManager) {
- if (DBG) log("InCallControlState constructor...");
- mInCallScreen = inCallScreen;
- mCM = cm;
- mBluetoothManager = bluetoothManager;
- }
-
- /**
- * Updates all our public boolean flags based on the current state of
- * the Phone.
- */
- public void update() {
- final PhoneConstants.State state = mCM.getState(); // coarse-grained voice call state
- final Call fgCall = mCM.getActiveFgCall();
- final Call.State fgCallState = fgCall.getState();
- final boolean hasActiveForegroundCall = (fgCallState == Call.State.ACTIVE);
- final boolean hasHoldingCall = mCM.hasActiveBgCall();
-
- // Manage conference:
- if (TelephonyCapabilities.supportsConferenceCallManagement(fgCall.getPhone())) {
- // This item is visible only if the foreground call is a
- // conference call, and it's enabled unless the "Manage
- // conference" UI is already up.
- manageConferenceVisible = PhoneUtils.isConferenceCall(fgCall);
- manageConferenceEnabled =
- manageConferenceVisible && !mInCallScreen.isManageConferenceMode();
- } else {
- // This device has no concept of managing a conference call.
- manageConferenceVisible = false;
- manageConferenceEnabled = false;
- }
-
- // "Add call":
- canAddCall = PhoneUtils.okToAddCall(mCM);
-
- // "End call": always enabled unless the phone is totally idle.
- // Note that while the phone is ringing, the InCallTouchUi widget isn't
- // visible at all, so the state of the End button doesn't matter. However
- // we *do* still set canEndCall to true in this case, purely to prevent a
- // UI glitch when the InCallTouchUi widget first appears, immediately after
- // answering an incoming call.
- canEndCall = (mCM.hasActiveFgCall() || mCM.hasActiveRingingCall() || mCM.hasActiveBgCall());
-
- // Swap / merge calls
- canSwap = PhoneUtils.okToSwapCalls(mCM);
- canMerge = PhoneUtils.okToMergeCalls(mCM);
-
- // "Bluetooth":
- if (mBluetoothManager.isBluetoothAvailable()) {
- bluetoothEnabled = true;
- bluetoothIndicatorOn = mBluetoothManager.isBluetoothAudioConnectedOrPending();
- } else {
- bluetoothEnabled = false;
- bluetoothIndicatorOn = false;
- }
-
- // "Speaker": always enabled unless the phone is totally idle.
- // The current speaker state comes from the AudioManager.
- speakerEnabled = (state != PhoneConstants.State.IDLE);
- speakerOn = PhoneUtils.isSpeakerOn(mInCallScreen);
-
- // "Mute": only enabled when the foreground call is ACTIVE.
- // (It's meaningless while on hold, or while DIALING/ALERTING.)
- // It's also explicitly disabled during emergency calls or if
- // emergency callback mode (ECM) is active.
- Connection c = fgCall.getLatestConnection();
- boolean isEmergencyCall = false;
- if (c != null) isEmergencyCall =
- PhoneNumberUtils.isLocalEmergencyNumber(c.getAddress(),
- fgCall.getPhone().getContext());
- boolean isECM = PhoneUtils.isPhoneInEcm(fgCall.getPhone());
- if (isEmergencyCall || isECM) { // disable "Mute" item
- canMute = false;
- muteIndicatorOn = false;
- } else {
- canMute = hasActiveForegroundCall;
- muteIndicatorOn = PhoneUtils.getMute();
- }
-
- // "Dialpad": Enabled only when it's OK to use the dialpad in the
- // first place.
- dialpadEnabled = mInCallScreen.okToShowDialpad();
-
- // Also keep track of whether the dialpad is currently "opened"
- // (i.e. visible).
- dialpadVisible = mInCallScreen.isDialerOpened();
-
- // "Hold:
- if (TelephonyCapabilities.supportsHoldAndUnhold(fgCall.getPhone())) {
- // This phone has the concept of explicit "Hold" and "Unhold" actions.
- supportsHold = true;
- // "On hold" means that there's a holding call and
- // *no* foreground call. (If there *is* a foreground call,
- // that's "two lines in use".)
- onHold = hasHoldingCall && (fgCallState == Call.State.IDLE);
- // The "Hold" control is disabled entirely if there's
- // no way to either hold or unhold in the current state.
- boolean okToHold = hasActiveForegroundCall && !hasHoldingCall;
- boolean okToUnhold = onHold;
- canHold = okToHold || okToUnhold;
- } else if (hasHoldingCall && (fgCallState == Call.State.IDLE)) {
- // Even when foreground phone device doesn't support hold/unhold, phone devices
- // for background holding calls may do.
- //
- // If the foreground call is ACTIVE, we should turn on "swap" button instead.
- final Call bgCall = mCM.getFirstActiveBgCall();
- if (bgCall != null &&
- TelephonyCapabilities.supportsHoldAndUnhold(bgCall.getPhone())) {
- supportsHold = true;
- onHold = true;
- canHold = true;
- }
- } else {
- // This device has no concept of "putting a call on hold."
- supportsHold = false;
- onHold = false;
- canHold = false;
- }
-
- if (DBG) dumpState();
- }
-
- public void dumpState() {
- log("InCallControlState:");
- log(" manageConferenceVisible: " + manageConferenceVisible);
- log(" manageConferenceEnabled: " + manageConferenceEnabled);
- log(" canAddCall: " + canAddCall);
- log(" canEndCall: " + canEndCall);
- log(" canSwap: " + canSwap);
- log(" canMerge: " + canMerge);
- log(" bluetoothEnabled: " + bluetoothEnabled);
- log(" bluetoothIndicatorOn: " + bluetoothIndicatorOn);
- log(" speakerEnabled: " + speakerEnabled);
- log(" speakerOn: " + speakerOn);
- log(" canMute: " + canMute);
- log(" muteIndicatorOn: " + muteIndicatorOn);
- log(" dialpadEnabled: " + dialpadEnabled);
- log(" dialpadVisible: " + dialpadVisible);
- log(" onHold: " + onHold);
- log(" canHold: " + canHold);
- }
-
- private void log(String msg) {
- Log.d(LOG_TAG, msg);
- }
-}
diff --git a/src/com/android/phone/InCallScreen.java b/src/com/android/phone/InCallScreen.java
index 8b67b77..b18cc43 100644
--- a/src/com/android/phone/InCallScreen.java
+++ b/src/com/android/phone/InCallScreen.java
@@ -16,101 +16,7 @@
package com.android.phone;
-import android.app.Activity;
-import android.app.ActivityOptions;
-import android.app.AlertDialog;
-import android.app.Dialog;
-import android.app.ProgressDialog;
-import android.bluetooth.BluetoothAdapter;
-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;
-import android.content.DialogInterface;
-import android.content.DialogInterface.OnCancelListener;
-import android.content.Intent;
-import android.content.IntentFilter;
-import android.content.res.Configuration;
-import android.content.res.Resources;
-import android.graphics.Typeface;
-import android.media.AudioManager;
-import android.os.AsyncResult;
-import android.os.Bundle;
-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;
-import android.text.TextUtils;
-import android.text.method.DialerKeyListener;
-import android.util.EventLog;
-import android.util.Log;
-import android.view.KeyEvent;
-import android.view.View;
-import android.view.ViewGroup;
-import android.view.ViewStub;
-import android.view.Window;
-import android.view.WindowManager;
-import android.view.accessibility.AccessibilityEvent;
-import android.widget.EditText;
-import android.widget.ImageView;
-import android.widget.LinearLayout;
-import android.widget.TextView;
-import android.widget.Toast;
-
-import com.android.internal.telephony.Call;
-import com.android.internal.telephony.CallManager;
-import com.android.internal.telephony.Connection;
-import com.android.internal.telephony.MmiCode;
-import com.android.internal.telephony.Phone;
-import com.android.internal.telephony.PhoneConstants;
-import com.android.internal.telephony.TelephonyCapabilities;
-import com.android.phone.Constants.CallStatusCode;
-import com.android.phone.InCallUiState.InCallScreenMode;
-import com.android.phone.OtaUtils.CdmaOtaScreenState;
-
-import java.util.List;
-
-
-/**
- * Phone app "in call" screen.
- */
-public class InCallScreen extends Activity
- implements View.OnClickListener {
- private static final String LOG_TAG = "InCallScreen";
-
- private static final boolean DBG =
- (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
- * initially visible when bringing up the InCallScreen. (If this
- * extra is present, the dialpad will be initially shown if the extra
- * has the boolean value true, and initially hidden otherwise.)
- */
- // TODO: Should be EXTRA_SHOW_DIALPAD for consistency.
- static final String SHOW_DIALPAD_EXTRA = "com.android.phone.ShowDialpad";
-
- // Amount of time (in msec) that we display the "Call ended" state.
- // The "short" value is for calls ended by the local user, and the
- // "long" value is for calls ended by the remote caller.
- private static final int CALL_ENDED_SHORT_DELAY = 200; // msec
- private static final int CALL_ENDED_LONG_DELAY = 2000; // msec
- private static final int CALL_ENDED_EXTRA_LONG_DELAY = 5000; // msec
-
- // Amount of time that we display the PAUSE alert Dialog showing the
- // post dial string yet to be send out to the n/w
- private static final int PAUSE_PROMPT_DIALOG_TIMEOUT = 2000; //msec
-
- // Amount of time that we display the provider info if applicable.
- private static final int PROVIDER_INFO_TIMEOUT = 5000; // msec
-
+public class InCallScreen {
// These are values for the settings of the auto retry mode:
// 0 = disabled
// 1 = enabled
@@ -118,4093 +24,4 @@
// they should be moved to Settings where the value is being looked up in the first place
static final int AUTO_RETRY_OFF = 0;
static final int AUTO_RETRY_ON = 1;
-
- // Message codes; see mHandler below.
- // Note message codes < 100 are reserved for the PhoneApp.
- private static final int PHONE_STATE_CHANGED = 101;
- private static final int PHONE_DISCONNECT = 102;
- private static final int EVENT_HEADSET_PLUG_STATE_CHANGED = 103;
- private static final int POST_ON_DIAL_CHARS = 104;
- private static final int WILD_PROMPT_CHAR_ENTERED = 105;
- private static final int ADD_VOICEMAIL_NUMBER = 106;
- 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 PHONE_CDMA_CALL_WAITING = 115;
- private static final int REQUEST_CLOSE_SPC_ERROR_NOTICE = 118;
- private static final int REQUEST_CLOSE_OTA_FAILURE_NOTICE = 119;
- private static final int EVENT_PAUSE_DIALOG_COMPLETE = 120;
- private static final int EVENT_HIDE_PROVIDER_INFO = 121; // Time to remove the info.
- private static final int REQUEST_UPDATE_SCREEN = 122;
- private static final int PHONE_INCOMING_RING = 123;
- private static final int PHONE_NEW_RINGING_CONNECTION = 124;
-
- // When InCallScreenMode is UNDEFINED set the default action
- // to ACTION_UNDEFINED so if we are resumed the activity will
- // know its undefined. In particular checkIsOtaCall will return
- // false.
- public static final String ACTION_UNDEFINED = "com.android.phone.InCallScreen.UNDEFINED";
-
- /** Status codes returned from syncWithPhoneState(). */
- private enum SyncWithPhoneStateStatus {
- /**
- * Successfully updated our internal state based on the telephony state.
- */
- SUCCESS,
-
- /**
- * There was no phone state to sync with (i.e. the phone was
- * completely idle). In most cases this means that the
- * in-call UI shouldn't be visible in the first place, unless
- * we need to remain in the foreground while displaying an
- * error message.
- */
- PHONE_NOT_IN_USE
- }
-
- private boolean mRegisteredForPhoneStates;
-
- private PhoneGlobals mApp;
- private CallManager mCM;
-
- // TODO: need to clean up all remaining uses of mPhone.
- // (There may be more than one Phone instance on the device, so it's wrong
- // to just keep a single mPhone field. Instead, any time we need a Phone
- // reference we should get it dynamically from the CallManager, probably
- // based on the current foreground Call.)
- private Phone mPhone;
-
- /** Main in-call UI elements. */
- private CallCard mCallCard;
-
- // UI controls:
- private InCallControlState mInCallControlState;
- private InCallTouchUi mInCallTouchUi;
- private RespondViaSmsManager mRespondViaSmsManager; // see internalRespondViaSms()
- private ManageConferenceUtils mManageConferenceUtils;
-
- // DTMF Dialer controller and its view:
- private DTMFTwelveKeyDialer mDialer;
-
- private EditText mWildPromptText;
-
- // Various dialogs we bring up (see dismissAllDialogs()).
- // TODO: convert these all to use the "managed dialogs" framework.
- //
- // The MMI started dialog can actually be one of 2 items:
- // 1. An alert dialog if the MMI code is a normal MMI
- // 2. A progress dialog if the user requested a USSD
- private Dialog mMmiStartedDialog;
- private AlertDialog mMissingVoicemailDialog;
- private AlertDialog mGenericErrorDialog;
- private AlertDialog mSuppServiceFailureDialog;
- private AlertDialog mWaitPromptDialog;
- private AlertDialog mWildPromptDialog;
- private AlertDialog mCallLostDialog;
- private AlertDialog mPausePromptDialog;
- private AlertDialog mExitingECMDialog;
- // NOTE: if you add a new dialog here, be sure to add it to dismissAllDialogs() also.
-
- // ProgressDialog created by showProgressIndication()
- private ProgressDialog mProgressDialog;
-
- // TODO: If the Activity class ever provides an easy way to get the
- // current "activity lifecycle" state, we can remove these flags.
- private boolean mIsDestroyed = false;
- private boolean mIsForegroundActivity = false;
- private PowerManager mPowerManager;
-
- // For use with Pause/Wait dialogs
- private String mPostDialStrAfterPause;
- private boolean mPauseInProgress = false;
-
- // Info about the most-recently-disconnected Connection, which is used
- // to determine what should happen when exiting the InCallScreen after a
- // call. (This info is set by onDisconnect(), and used by
- // delayedCleanupAfterDisconnect().)
- private Connection.DisconnectCause mLastDisconnectCause;
-
- /** In-call audio routing options; see switchInCallAudio(). */
- public enum InCallAudioMode {
- SPEAKER, // Speakerphone
- BLUETOOTH, // Bluetooth headset (if available)
- EARPIECE, // Handset earpiece (or wired headset, if connected)
- }
-
-
- private Handler mHandler = new Handler() {
- @Override
- public void handleMessage(Message msg) {
- if (mIsDestroyed) {
- if (DBG) log("Handler: ignoring message " + msg + "; we're destroyed!");
- return;
- }
- if (!mIsForegroundActivity) {
- if (DBG) log("Handler: handling message " + msg + " while not in foreground");
- // Continue anyway; some of the messages below *want* to
- // be handled even if we're not the foreground activity
- // (like DELAYED_CLEANUP_AFTER_DISCONNECT), and they all
- // should at least be safe to handle if we're not in the
- // foreground...
- }
-
- switch (msg.what) {
- case SUPP_SERVICE_FAILED:
- onSuppServiceFailed((AsyncResult) msg.obj);
- break;
-
- case PHONE_STATE_CHANGED:
- onPhoneStateChanged((AsyncResult) msg.obj);
- break;
-
- case PHONE_DISCONNECT:
- onDisconnect((AsyncResult) msg.obj);
- break;
-
- case EVENT_HEADSET_PLUG_STATE_CHANGED:
- // Update the in-call UI, since some UI elements (such
- // as the "Speaker" button) may change state depending on
- // whether a headset is plugged in.
- // TODO: A full updateScreen() is overkill here, since
- // the value of PhoneApp.isHeadsetPlugged() only affects a
- // single onscreen UI element. (But even a full updateScreen()
- // is still pretty cheap, so let's keep this simple
- // for now.)
- updateScreen();
-
- // Also, force the "audio mode" popup to refresh itself if
- // it's visible, since one of its items is either "Wired
- // headset" or "Handset earpiece" depending on whether the
- // headset is plugged in or not.
- mInCallTouchUi.refreshAudioModePopup(); // safe even if the popup's not active
-
- break;
-
- // TODO: sort out MMI code (probably we should remove this method entirely).
- // See also MMI handling code in onResume()
- // case PhoneApp.MMI_INITIATE:
- // onMMIInitiate((AsyncResult) msg.obj);
- // break;
-
- case PhoneGlobals.MMI_CANCEL:
- onMMICancel();
- break;
-
- // handle the mmi complete message.
- // 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 PhoneGlobals.MMI_COMPLETE:
- onMMIComplete((MmiCode) ((AsyncResult) msg.obj).result);
- break;
-
- case POST_ON_DIAL_CHARS:
- handlePostOnDialChars((AsyncResult) msg.obj, (char) msg.arg1);
- break;
-
- case ADD_VOICEMAIL_NUMBER:
- addVoiceMailNumberPanel();
- break;
-
- case DONT_ADD_VOICEMAIL_NUMBER:
- dontAddVoiceMailNumber();
- break;
-
- case DELAYED_CLEANUP_AFTER_DISCONNECT:
- delayedCleanupAfterDisconnect();
- break;
-
- case PHONE_CDMA_CALL_WAITING:
- if (DBG) log("Received PHONE_CDMA_CALL_WAITING event ...");
- Connection cn = mCM.getFirstActiveRingingCall().getLatestConnection();
-
- // Only proceed if we get a valid connection object
- if (cn != null) {
- // Finally update screen with Call waiting info and request
- // screen to wake up
- updateScreen();
- mApp.updateWakeState();
- }
- break;
-
- case REQUEST_CLOSE_SPC_ERROR_NOTICE:
- if (mApp.otaUtils != null) {
- mApp.otaUtils.onOtaCloseSpcNotice();
- }
- break;
-
- case REQUEST_CLOSE_OTA_FAILURE_NOTICE:
- if (mApp.otaUtils != null) {
- mApp.otaUtils.onOtaCloseFailureNotice();
- }
- break;
-
- case EVENT_PAUSE_DIALOG_COMPLETE:
- if (mPausePromptDialog != null) {
- if (DBG) log("- DISMISSING mPausePromptDialog.");
- mPausePromptDialog.dismiss(); // safe even if already dismissed
- mPausePromptDialog = null;
- }
- break;
-
- case EVENT_HIDE_PROVIDER_INFO:
- if (mCallCard != null) {
- mCallCard.updateState(mCM);
- }
- break;
- case REQUEST_UPDATE_SCREEN:
- updateScreen();
- break;
-
- case PHONE_INCOMING_RING:
- onIncomingRing();
- break;
-
- case PHONE_NEW_RINGING_CONNECTION:
- onNewRingingConnection();
- break;
-
- default:
- Log.wtf(LOG_TAG, "mHandler: unexpected message: " + msg);
- break;
- }
- }
- };
-
- private final BroadcastReceiver mReceiver = new BroadcastReceiver() {
- @Override
- public void onReceive(Context context, Intent intent) {
- String action = intent.getAction();
- if (action.equals(Intent.ACTION_HEADSET_PLUG)) {
- // Listen for ACTION_HEADSET_PLUG broadcasts so that we
- // can update the onscreen UI when the headset state changes.
- // if (DBG) log("mReceiver: ACTION_HEADSET_PLUG");
- // if (DBG) log("==> intent: " + intent);
- // if (DBG) log(" state: " + intent.getIntExtra("state", 0));
- // if (DBG) log(" name: " + intent.getStringExtra("name"));
- // send the event and add the state as an argument.
- Message message = Message.obtain(mHandler, EVENT_HEADSET_PLUG_STATE_CHANGED,
- intent.getIntExtra("state", 0), 0);
- mHandler.sendMessage(message);
- }
- }
- };
-
-
- @Override
- protected void onCreate(Bundle icicle) {
- Log.i(LOG_TAG, "onCreate()... this = " + this);
- Profiler.callScreenOnCreate();
- super.onCreate(icicle);
-
- // Make sure this is a voice-capable device.
- 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
- // like the CALL intent and ITelephony.showCallScreen().
- // So the fact that we got here indicates a phone app bug.
- Log.wtf(LOG_TAG, "onCreate() reached on non-voice-capable device");
- finish();
- return;
- }
-
- 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
- | 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
- // 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.
- flags |= WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD;
- }
-
- WindowManager.LayoutParams lp = getWindow().getAttributes();
- lp.flags |= flags;
-
- setPhone(mApp.phone); // Sets mPhone
-
- mCM = mApp.mCM;
- log("- onCreate: phone state = " + mCM.getState());
-
- requestWindowFeature(Window.FEATURE_NO_TITLE);
-
- // 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();
-
- // No need to change wake state here; that happens in onResume() when we
- // are actually displayed.
-
- // Handle the Intent we were launched with, but only if this is the
- // the very first time we're being launched (ie. NOT if we're being
- // re-initialized after previously being shut down.)
- // Once we're up and running, any future Intents we need
- // to handle will come in via the onNewIntent() method.
- if (icicle == null) {
- if (DBG) log("onCreate(): this is our very first launch, checking intent...");
- internalResolveIntent(getIntent());
- }
-
- Profiler.callScreenCreated();
- if (DBG) log("onCreate(): exit");
- }
-
- /**
- * Sets the Phone object used internally by the InCallScreen.
- *
- * In normal operation this is called from onCreate(), and the
- * passed-in Phone object comes from the PhoneApp.
- * For testing, test classes can use this method to
- * inject a test Phone instance.
- */
- /* package */ void setPhone(Phone phone) {
- mPhone = phone;
- }
-
- @Override
- protected void onResume() {
- if (DBG) log("onResume()...");
- super.onResume();
-
- mIsForegroundActivity = true;
-
- // The flag shouldn't be turned on when there are actual phone calls.
- if (mCM.hasActiveFgCall() || mCM.hasActiveBgCall() || mCM.hasActiveRingingCall()) {
- mApp.inCallUiState.showAlreadyDisconnectedState = false;
- }
-
- final InCallUiState inCallUiState = mApp.inCallUiState;
- if (VDBG) inCallUiState.dumpState();
-
- updateExpandedViewState();
-
- // ...and update the in-call notification too, since the status bar
- // icon needs to be hidden while we're the foreground activity:
- mApp.notificationMgr.updateInCallNotification();
-
- // Listen for broadcast intents that might affect the onscreen UI.
- registerReceiver(mReceiver, new IntentFilter(Intent.ACTION_HEADSET_PLUG));
-
- // Keep a "dialer session" active when we're in the foreground.
- // (This is needed to play DTMF tones.)
- mDialer.startDialerSession();
-
- // Restore various other state from the InCallUiState object:
-
- // Update the onscreen dialpad state to match the InCallUiState.
- if (inCallUiState.showDialpad) {
- openDialpadInternal(false); // no "opening" animation
- } else {
- closeDialpadInternal(false); // no "closing" animation
- }
-
- // Reset the dialpad context
- // TODO: Dialpad digits should be set here as well (once they are saved)
- mDialer.setDialpadContext(inCallUiState.dialpadContextText);
-
- // If there's a "Respond via SMS" popup still around since the
- // last time we were the foreground activity, make sure it's not
- // still active!
- // (The popup should *never* be visible initially when we first
- // come to the foreground; it only ever comes up in response to
- // the user selecting the "SMS" option from the incoming call
- // widget.)
- mRespondViaSmsManager.dismissPopup(); // safe even if already dismissed
-
- // Display an error / diagnostic indication if necessary.
- //
- // When the InCallScreen comes to the foreground, we normally we
- // display the in-call UI in whatever state is appropriate based on
- // the state of the telephony framework (e.g. an outgoing call in
- // DIALING state, an incoming call, etc.)
- //
- // But if the InCallUiState has a "pending call status code" set,
- // that means we need to display some kind of status or error
- // indication to the user instead of the regular in-call UI. (The
- // most common example of this is when there's some kind of
- // failure while initiating an outgoing call; see
- // CallController.placeCall().)
- boolean handledStartupError = false;
- if (inCallUiState.hasPendingCallStatusCode()) {
- if (DBG) log("- onResume: need to show status indication!");
- showStatusIndication(inCallUiState.getPendingCallStatusCode());
-
- // Set handledStartupError to ensure that we won't bail out below.
- // (We need to stay here in the InCallScreen so that the user
- // is able to see the error dialog!)
- handledStartupError = true;
- }
-
- // Set the volume control handler while we are in the foreground.
- final boolean bluetoothConnected = false; //isBluetoothAudioConnected();
-
- // TODO(klp): Move this volume button control code to the UI
- if (bluetoothConnected) {
- setVolumeControlStream(AudioManager.STREAM_BLUETOOTH_SCO);
- } else {
- setVolumeControlStream(AudioManager.STREAM_VOICE_CALL);
- }
-
- takeKeyEvents(true);
-
- // If an OTASP call is in progress, use the special OTASP-specific UI.
- boolean inOtaCall = false;
- if (TelephonyCapabilities.supportsOtasp(mPhone)) {
- inOtaCall = checkOtaspStateOnResume();
- }
- if (!inOtaCall) {
- // Always start off in NORMAL mode
- setInCallScreenMode(InCallScreenMode.NORMAL);
- }
-
- // Before checking the state of the CallManager, clean up any
- // connections in the DISCONNECTED state.
- // (The DISCONNECTED state is used only to drive the "call ended"
- // UI; it's totally useless when *entering* the InCallScreen.)
- mCM.clearDisconnected();
-
- // Update the onscreen UI to reflect the current telephony state.
- SyncWithPhoneStateStatus status = syncWithPhoneState();
-
- // Note there's no need to call updateScreen() here;
- // syncWithPhoneState() already did that if necessary.
-
- if (status != SyncWithPhoneStateStatus.SUCCESS) {
- if (DBG) log("- onResume: syncWithPhoneState failed! status = " + status);
- // Couldn't update the UI, presumably because the phone is totally
- // idle.
-
- // Even though the phone is idle, though, we do still need to
- // stay here on the InCallScreen if we're displaying an
- // error dialog (see "showStatusIndication()" above).
-
- if (handledStartupError) {
- // Stay here for now. We'll eventually leave the
- // InCallScreen when the user presses the dialog's OK
- // button (see bailOutAfterErrorDialog()), or when the
- // progress indicator goes away.
- Log.i(LOG_TAG, " ==> syncWithPhoneState failed, but staying here anyway.");
- } else {
- // The phone is idle, and we did NOT handle a
- // startup error during this pass thru onResume.
- //
- // This basically means that we're being resumed because of
- // some action *other* than a new intent. (For example,
- // the user pressing POWER to wake up the device, causing
- // the InCallScreen to come back to the foreground.)
- //
- // In this scenario we do NOT want to stay here on the
- // InCallScreen: we're not showing any useful info to the
- // user (like a dialog), and the in-call UI itself is
- // useless if there's no active call. So bail out.
-
- Log.i(LOG_TAG, " ==> syncWithPhoneState failed; bailing out!");
- dismissAllDialogs();
-
- // Force the InCallScreen to truly finish(), rather than just
- // moving it to the back of the activity stack (which is what
- // our finish() method usually does.)
- // This is necessary to avoid an obscure scenario where the
- // InCallScreen can get stuck in an inconsistent state, somehow
- // causing a *subsequent* outgoing call to fail (bug 4172599).
- endInCallScreenSession(true /* force a real finish() call */);
- return;
- }
- } else if (TelephonyCapabilities.supportsOtasp(mPhone)) {
- if (inCallUiState.inCallScreenMode == InCallScreenMode.OTA_NORMAL ||
- inCallUiState.inCallScreenMode == InCallScreenMode.OTA_ENDED) {
- if (mCallCard != null) mCallCard.setVisibility(View.GONE);
- updateScreen();
- return;
- }
- }
-
- // InCallScreen is now active.
- EventLog.writeEvent(EventLogTags.PHONE_UI_ENTER);
-
- // 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();
-
- // Restore the mute state if the last mute state change was NOT
- // done by the user.
- if (mApp.getRestoreMuteOnInCallResume()) {
- // Mute state is based on the foreground call
- PhoneUtils.restoreMuteState();
- mApp.setRestoreMuteOnInCallResume(false);
- }
-
- Profiler.profileViewCreate(getWindow(), InCallScreen.class.getName());
-
- // If there's a pending MMI code, we'll show a dialog here.
- //
- // Note: previously we had shown the dialog when MMI_INITIATE event's coming
- // from telephony layer, while right now we don't because the event comes
- // too early (before in-call screen is prepared).
- // Now we instead check pending MMI code and show the dialog here.
- //
- // This *may* cause some problem, e.g. when the user really quickly starts
- // MMI sequence and calls an actual phone number before the MMI request
- // being completed, which is rather rare.
- //
- // TODO: streamline this logic and have a UX in a better manner.
- // Right now syncWithPhoneState() above will return SUCCESS based on
- // mPhone.getPendingMmiCodes().isEmpty(), while we check it again here.
- // Also we show pre-populated in-call UI under the dialog, which looks
- // not great. (issue 5210375, 5545506)
- // After cleaning them, remove commented-out MMI handling code elsewhere.
- if (!mPhone.getPendingMmiCodes().isEmpty()) {
- if (mMmiStartedDialog == null) {
- MmiCode mmiCode = mPhone.getPendingMmiCodes().get(0);
- 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,
- // which will dismiss the entire screen.
- }
- }
-
- // This means the screen is shown even though there's no connection, which only happens
- // when the phone call has hung up while the screen is turned off at that moment.
- // We want to show "disconnected" state with photos with appropriate elapsed time for
- // the finished phone call.
- if (mApp.inCallUiState.showAlreadyDisconnectedState) {
- // if (DBG) {
- log("onResume(): detected \"show already disconnected state\" situation."
- + " set up DELAYED_CLEANUP_AFTER_DISCONNECT message with "
- + CALL_ENDED_LONG_DELAY + " msec delay.");
- //}
- mHandler.removeMessages(DELAYED_CLEANUP_AFTER_DISCONNECT);
- mHandler.sendEmptyMessageDelayed(DELAYED_CLEANUP_AFTER_DISCONNECT,
- CALL_ENDED_LONG_DELAY);
- }
-
- if (VDBG) log("onResume() done.");
- }
-
- // onPause is guaranteed to be called when the InCallScreen goes
- // in the background.
- @Override
- protected void onPause() {
- if (DBG) log("onPause()...");
- super.onPause();
-
- mIsForegroundActivity = false;
-
- // "show-already-disconnected-state" should be effective just during the first wake-up.
- // We should never allow it to stay true after that.
- mApp.inCallUiState.showAlreadyDisconnectedState = false;
-
- // Make sure the "Manage conference" chronometer is stopped when
- // we move away from the foreground.
- mManageConferenceUtils.stopConferenceTime();
-
- // as a catch-all, make sure that any dtmf tones are stopped
- // when the UI is no longer in the foreground.
- mDialer.onDialerKeyUp(null);
-
- // Release any "dialer session" resources, now that we're no
- // longer in the foreground.
- mDialer.stopDialerSession();
-
- // If the device is put to sleep as the phone call is ending,
- // we may see cases where the DELAYED_CLEANUP_AFTER_DISCONNECT
- // event gets handled AFTER the device goes to sleep and wakes
- // up again.
-
- // This is because it is possible for a sleep command
- // (executed with the End Call key) to come during the 2
- // seconds that the "Call Ended" screen is up. Sleep then
- // pauses the device (including the cleanup event) and
- // resumes the event when it wakes up.
-
- // To fix this, we introduce a bit of code that pushes the UI
- // to the background if we pause and see a request to
- // DELAYED_CLEANUP_AFTER_DISCONNECT.
-
- // Note: We can try to finish directly, by:
- // 1. Removing the DELAYED_CLEANUP_AFTER_DISCONNECT messages
- // 2. Calling delayedCleanupAfterDisconnect directly
-
- // However, doing so can cause problems between the phone
- // app and the keyguard - the keyguard is trying to sleep at
- // the same time that the phone state is changing. This can
- // end up causing the sleep request to be ignored.
- if (mHandler.hasMessages(DELAYED_CLEANUP_AFTER_DISCONNECT)
- && mCM.getState() != PhoneConstants.State.RINGING) {
- if (DBG) log("DELAYED_CLEANUP_AFTER_DISCONNECT detected, moving UI to background.");
- endInCallScreenSession();
- }
-
- EventLog.writeEvent(EventLogTags.PHONE_UI_EXIT);
-
- // Dismiss any dialogs we may have brought up, just to be 100%
- // sure they won't still be around when we get back here.
- dismissAllDialogs();
-
- updateExpandedViewState();
-
- // ...and the in-call notification too:
- mApp.notificationMgr.updateInCallNotification();
- // ...and *always* reset the system bar back to its normal state
- // when leaving the in-call UI.
- // (While we're the foreground activity, we disable navigation in
- // some call states; see InCallTouchUi.updateState().)
- mApp.notificationMgr.statusBarHelper.enableSystemBarNavigation(true);
-
- // Unregister for broadcast intents. (These affect the visible UI
- // of the InCallScreen, so we only care about them while we're in the
- // foreground.)
- unregisterReceiver(mReceiver);
-
- // Make sure we revert the poke lock and wake lock when we move to
- // the background.
- mApp.updateWakeState();
-
- // clear the dismiss keyguard flag so we are back to the default state
- // when we next resume
- updateKeyguardPolicy(false);
-
- // See also PhoneApp#updatePhoneState(), which takes care of all the other release() calls.
- if (mApp.getUpdateLock().isHeld() && mApp.getPhoneState() == PhoneConstants.State.IDLE) {
- if (DBG) {
- log("Release UpdateLock on onPause() because there's no active phone call.");
- }
- mApp.getUpdateLock().release();
- }
- }
-
- @Override
- protected void onStop() {
- if (DBG) log("onStop()...");
- super.onStop();
-
- stopTimer();
-
- PhoneConstants.State state = mCM.getState();
- if (DBG) log("onStop: state = " + state);
-
- if (state == PhoneConstants.State.IDLE) {
- if (mRespondViaSmsManager.isShowingPopup()) {
- // This means that the user has been opening the "Respond via SMS" dialog even
- // after the incoming call hanging up, and the screen finally went background.
- // In that case we just close the dialog and exit the whole in-call screen.
- mRespondViaSmsManager.dismissPopup();
- }
-
- // when OTA Activation, OTA Success/Failure dialog or OTA SPC
- // failure dialog is running, do not destroy inCallScreen. Because call
- // is already ended and dialog will not get redrawn on slider event.
- if ((mApp.cdmaOtaProvisionData != null) && (mApp.cdmaOtaScreenState != null)
- && ((mApp.cdmaOtaScreenState.otaScreenState !=
- CdmaOtaScreenState.OtaScreenState.OTA_STATUS_ACTIVATION)
- && (mApp.cdmaOtaScreenState.otaScreenState !=
- CdmaOtaScreenState.OtaScreenState.OTA_STATUS_SUCCESS_FAILURE_DLG)
- && (!mApp.cdmaOtaProvisionData.inOtaSpcState))) {
- // we don't want the call screen to remain in the activity history
- // if there are not active or ringing calls.
- if (DBG) log("- onStop: calling finish() to clear activity history...");
- moveTaskToBack(true);
- if (mApp.otaUtils != null) {
- mApp.otaUtils.cleanOtaScreen(true);
- }
- }
- }
- }
-
- @Override
- protected void onDestroy() {
- Log.i(LOG_TAG, "onDestroy()... this = " + this);
- super.onDestroy();
-
- // Set the magic flag that tells us NOT to handle any handler
- // messages that come in asynchronously after we get destroyed.
- mIsDestroyed = true;
-
- mApp.setInCallScreenInstance(null);
-
- // Clear out the InCallScreen references in various helper objects
- // (to let them know we've been destroyed).
- if (mCallCard != null) {
- mCallCard.setInCallScreenInstance(null);
- }
- if (mInCallTouchUi != null) {
- mInCallTouchUi.setInCallScreenInstance(null);
- }
- mRespondViaSmsManager.setInCallScreenInstance(null);
-
- mDialer.clearInCallScreenReference();
- mDialer = null;
-
- unregisterForPhoneStates();
- // No need to change wake state here; that happens in onPause() when we
- // are moving out of the foreground.
-
- // Dismiss all dialogs, to be absolutely sure we won't leak any of
- // them while changing orientation.
- dismissAllDialogs();
-
- // If there's an OtaUtils instance around, clear out its
- // references to our internal widgets.
- if (mApp.otaUtils != null) {
- mApp.otaUtils.clearUiWidgets();
- }
- }
-
- /**
- * Dismisses the in-call screen.
- *
- * We never *really* finish() the InCallScreen, since we don't want to
- * get destroyed and then have to be re-created from scratch for the
- * next call. Instead, we just move ourselves to the back of the
- * activity stack.
- *
- * This also means that we'll no longer be reachable via the BACK
- * button (since moveTaskToBack() puts us behind the Home app, but the
- * home app doesn't allow the BACK key to move you any farther down in
- * the history stack.)
- *
- * (Since the Phone app itself is never killed, this basically means
- * that we'll keep a single InCallScreen instance around for the
- * entire uptime of the device. This noticeably improves the UI
- * responsiveness for incoming calls.)
- */
- @Override
- public void finish() {
- if (DBG) log("finish()...");
- moveTaskToBack(true);
- }
-
- /**
- * End the current in call screen session.
- *
- * This must be called when an InCallScreen session has
- * complete so that the next invocation via an onResume will
- * not be in an old state.
- */
- public void endInCallScreenSession() {
- if (DBG) log("endInCallScreenSession()... phone state = " + mCM.getState());
- endInCallScreenSession(false);
- }
-
- /**
- * Internal version of endInCallScreenSession().
- *
- * @param forceFinish If true, force the InCallScreen to
- * truly finish() rather than just calling moveTaskToBack().
- * @see finish()
- */
- private void endInCallScreenSession(boolean forceFinish) {
- if (DBG) {
- log("endInCallScreenSession(" + forceFinish + ")... phone state = " + mCM.getState());
- }
- if (forceFinish) {
- Log.i(LOG_TAG, "endInCallScreenSession(): FORCING a call to super.finish()!");
- super.finish(); // Call super.finish() rather than our own finish() method,
- // which actually just calls moveTaskToBack().
- } else {
- moveTaskToBack(true);
- }
- setInCallScreenMode(InCallScreenMode.UNDEFINED);
-
- // Call update screen so that the in-call screen goes back to a normal state.
- // This avoids bugs where a previous state will filcker the next time phone is
- // opened.
- updateScreen();
-
- if (mCallCard != null) {
- mCallCard.clear();
- }
- }
-
- /**
- * True when this Activity is in foreground (between onResume() and onPause()).
- */
- /* package */ boolean isForegroundActivity() {
- return mIsForegroundActivity;
- }
-
- /* package */ void updateKeyguardPolicy(boolean dismissKeyguard) {
- if (dismissKeyguard) {
- getWindow().addFlags(WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD);
- } else {
- getWindow().clearFlags(WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD);
- }
- }
-
- private void registerForPhoneStates() {
- if (!mRegisteredForPhoneStates) {
- mCM.registerForPreciseCallStateChanged(mHandler, PHONE_STATE_CHANGED, null);
- mCM.registerForDisconnect(mHandler, PHONE_DISCONNECT, null);
- // TODO: sort out MMI code (probably we should remove this method entirely).
- // See also MMI handling code in onResume()
- // mCM.registerForMmiInitiate(mHandler, PhoneApp.MMI_INITIATE, null);
-
- // register for the MMI complete message. Upon completion,
- // PhoneUtils will bring up a system dialog instead of the
- // 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, 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);
- mCM.registerForIncomingRing(mHandler, PHONE_INCOMING_RING, null);
- mCM.registerForNewRingingConnection(mHandler, PHONE_NEW_RINGING_CONNECTION, null);
- mRegisteredForPhoneStates = true;
- }
- }
-
- private void unregisterForPhoneStates() {
- mCM.unregisterForPreciseCallStateChanged(mHandler);
- mCM.unregisterForDisconnect(mHandler);
- mCM.unregisterForMmiInitiate(mHandler);
- mCM.unregisterForMmiComplete(mHandler);
- mCM.unregisterForCallWaiting(mHandler);
- mCM.unregisterForPostDialCharacter(mHandler);
- mCM.unregisterForSuppServiceFailed(mHandler);
- mCM.unregisterForIncomingRing(mHandler);
- mCM.unregisterForNewRingingConnection(mHandler);
- mRegisteredForPhoneStates = false;
- }
-
- /* package */ void updateAfterRadioTechnologyChange() {
- if (DBG) Log.d(LOG_TAG, "updateAfterRadioTechnologyChange()...");
-
- // Reset the call screen since the calls cannot be transferred
- // across radio technologies.
- resetInCallScreenMode();
-
- // Unregister for all events from the old obsolete phone
- unregisterForPhoneStates();
-
- // (Re)register for all events relevant to the new active phone
- registerForPhoneStates();
-
- // And finally, refresh the onscreen UI. (Note that it's safe
- // to call requestUpdateScreen() even if the radio change ended up
- // causing us to exit the InCallScreen.)
- requestUpdateScreen();
- }
-
- @Override
- protected void onNewIntent(Intent intent) {
- log("onNewIntent: intent = " + intent + ", phone state = " + mCM.getState());
-
- // We're being re-launched with a new Intent. Since it's possible for a
- // single InCallScreen instance to persist indefinitely (even if we
- // finish() ourselves), this sequence can potentially happen any time
- // the InCallScreen needs to be displayed.
-
- // Stash away the new intent so that we can get it in the future
- // by calling getIntent(). (Otherwise getIntent() will return the
- // original Intent from when we first got created!)
- setIntent(intent);
-
- // Activities are always paused before receiving a new intent, so
- // we can count on our onResume() method being called next.
-
- // Just like in onCreate(), handle the intent.
- internalResolveIntent(intent);
- }
-
- private void internalResolveIntent(Intent intent) {
- if (intent == null || intent.getAction() == null) {
- return;
- }
- String action = intent.getAction();
- if (DBG) log("internalResolveIntent: action=" + action);
-
- // In gingerbread and earlier releases, the InCallScreen used to
- // directly handle certain intent actions that could initiate phone
- // calls, namely ACTION_CALL and ACTION_CALL_EMERGENCY, and also
- // OtaUtils.ACTION_PERFORM_CDMA_PROVISIONING.
- //
- // But it doesn't make sense to tie those actions to the InCallScreen
- // (or especially to the *activity lifecycle* of the InCallScreen).
- // Instead, the InCallScreen should only be concerned with running the
- // onscreen UI while in a call. So we've now offloaded the call-control
- // functionality to a new module called CallController, and OTASP calls
- // are now launched from the OtaUtils startInteractiveOtasp() or
- // startNonInteractiveOtasp() methods.
- //
- // So now, the InCallScreen is only ever launched using the ACTION_MAIN
- // action, and (upon launch) performs no functionality other than
- // displaying the UI in a state that matches the current telephony
- // state.
-
- if (action.equals(intent.ACTION_MAIN)) {
- // This action is the normal way to bring up the in-call UI.
- //
- // Most of the interesting work of updating the onscreen UI (to
- // match the current telephony state) happens in the
- // syncWithPhoneState() => updateScreen() sequence that happens in
- // onResume().
- //
- // But we do check here for one extra that can come along with the
- // ACTION_MAIN intent:
-
- if (intent.hasExtra(SHOW_DIALPAD_EXTRA)) {
- // SHOW_DIALPAD_EXTRA can be used here to specify whether the DTMF
- // dialpad should be initially visible. If the extra isn't
- // present at all, we just leave the dialpad in its previous state.
-
- boolean showDialpad = intent.getBooleanExtra(SHOW_DIALPAD_EXTRA, false);
- if (VDBG) log("- internalResolveIntent: SHOW_DIALPAD_EXTRA: " + showDialpad);
-
- // If SHOW_DIALPAD_EXTRA is specified, that overrides whatever
- // the previous state of inCallUiState.showDialpad was.
- mApp.inCallUiState.showDialpad = showDialpad;
-
- final boolean hasActiveCall = mCM.hasActiveFgCall();
- final boolean hasHoldingCall = mCM.hasActiveBgCall();
-
- // There's only one line in use, AND it's on hold, at which we're sure the user
- // wants to use the dialpad toward the exact line, so un-hold the holding line.
- if (showDialpad && !hasActiveCall && hasHoldingCall) {
- PhoneUtils.switchHoldingAndActive(mCM.getFirstActiveBgCall());
- }
- }
- // ...and in onResume() we'll update the onscreen dialpad state to
- // match the InCallUiState.
-
- return;
- }
-
- if (action.equals(OtaUtils.ACTION_DISPLAY_ACTIVATION_SCREEN)) {
- // Bring up the in-call UI in the OTASP-specific "activate" state;
- // see OtaUtils.startInteractiveOtasp(). Note that at this point
- // the OTASP call has not been started yet; we won't actually make
- // the call until the user presses the "Activate" button.
-
- if (!TelephonyCapabilities.supportsOtasp(mPhone)) {
- throw new IllegalStateException(
- "Received ACTION_DISPLAY_ACTIVATION_SCREEN intent on non-OTASP-capable device: "
- + intent);
- }
-
- setInCallScreenMode(InCallScreenMode.OTA_NORMAL);
- if ((mApp.cdmaOtaProvisionData != null)
- && (!mApp.cdmaOtaProvisionData.isOtaCallIntentProcessed)) {
- mApp.cdmaOtaProvisionData.isOtaCallIntentProcessed = true;
- mApp.cdmaOtaScreenState.otaScreenState =
- CdmaOtaScreenState.OtaScreenState.OTA_STATUS_ACTIVATION;
- }
- return;
- }
-
- // Various intent actions that should no longer come here directly:
- if (action.equals(OtaUtils.ACTION_PERFORM_CDMA_PROVISIONING)) {
- // This intent is now handled by the InCallScreenShowActivation
- // activity, which translates it into a call to
- // OtaUtils.startInteractiveOtasp().
- throw new IllegalStateException(
- "Unexpected ACTION_PERFORM_CDMA_PROVISIONING received by InCallScreen: "
- + intent);
- } else if (action.equals(Intent.ACTION_CALL)
- || action.equals(Intent.ACTION_CALL_EMERGENCY)) {
- // ACTION_CALL* intents go to the OutgoingCallBroadcaster, which now
- // translates them into CallController.placeCall() calls rather than
- // launching the InCallScreen directly.
- throw new IllegalStateException("Unexpected CALL action received by InCallScreen: "
- + intent);
- } else if (action.equals(ACTION_UNDEFINED)) {
- // This action is only used for internal bookkeeping; we should
- // never actually get launched with it.
- Log.wtf(LOG_TAG, "internalResolveIntent: got launched with ACTION_UNDEFINED");
- return;
- } else {
- Log.wtf(LOG_TAG, "internalResolveIntent: unexpected intent action: " + action);
- // But continue the best we can (basically treating this case
- // like ACTION_MAIN...)
- return;
- }
- }
-
- private void stopTimer() {
- if (mCallCard != null) mCallCard.stopTimer();
- }
-
- private void initInCallScreen() {
- if (VDBG) log("initInCallScreen()...");
-
- // Have the WindowManager filter out touch events that are "too fat".
- getWindow().addFlags(WindowManager.LayoutParams.FLAG_IGNORE_CHEEK_PRESSES);
-
- // Initialize the CallCard.
- mCallCard = (CallCard) findViewById(R.id.callCard);
- if (VDBG) log(" - mCallCard = " + mCallCard);
- mCallCard.setInCallScreenInstance(this);
-
- // Initialize the onscreen UI elements.
- initInCallTouchUi();
-
- // Helper class to keep track of enabledness/state of UI controls
- mInCallControlState = new InCallControlState(this, mCM, mApp.getBluetoothManager());
-
- // Helper class to run the "Manage conference" UI
- mManageConferenceUtils = new ManageConferenceUtils(this, mCM);
-
- // The DTMF Dialpad.
- ViewStub stub = (ViewStub) findViewById(R.id.dtmf_twelve_key_dialer_stub);
- mDialer = new DTMFTwelveKeyDialer(this, stub);
- mPowerManager = (PowerManager) getSystemService(Context.POWER_SERVICE);
- }
-
- /**
- * Returns true if the phone is "in use", meaning that at least one line
- * is active (ie. off hook or ringing or dialing). Conversely, a return
- * value of false means there's currently no phone activity at all.
- */
- private boolean phoneIsInUse() {
- return mCM.getState() != PhoneConstants.State.IDLE;
- }
-
- private boolean handleDialerKeyDown(int keyCode, KeyEvent event) {
- if (VDBG) log("handleDialerKeyDown: keyCode " + keyCode + ", event " + event + "...");
-
- // As soon as the user starts typing valid dialable keys on the
- // keyboard (presumably to type DTMF tones) we start passing the
- // key events to the DTMFDialer's onDialerKeyDown. We do so
- // only if the okToDialDTMFTones() conditions pass.
- if (okToDialDTMFTones()) {
- return mDialer.onDialerKeyDown(event);
-
- // TODO: If the dialpad isn't currently visible, maybe
- // consider automatically bringing it up right now?
- // (Just to make sure the user sees the digits widget...)
- // But this probably isn't too critical since it's awkward to
- // use the hard keyboard while in-call in the first place,
- // especially now that the in-call UI is portrait-only...
- }
-
- return false;
- }
-
- @Override
- public void onBackPressed() {
- if (DBG) log("onBackPressed()...");
-
- // To consume this BACK press, the code here should just do
- // something and return. Otherwise, call super.onBackPressed() to
- // get the default implementation (which simply finishes the
- // current activity.)
-
- if (mCM.hasActiveRingingCall()) {
- // The Back key, just like the Home key, is always disabled
- // while an incoming call is ringing. (The user *must* either
- // answer or reject the call before leaving the incoming-call
- // screen.)
- if (DBG) log("BACK key while ringing: ignored");
-
- // And consume this event; *don't* call super.onBackPressed().
- return;
- }
-
- // BACK is also used to exit out of any "special modes" of the
- // in-call UI:
-
- if (mDialer.isOpened()) {
- closeDialpadInternal(true); // do the "closing" animation
- return;
- }
-
- if (mApp.inCallUiState.inCallScreenMode == InCallScreenMode.MANAGE_CONFERENCE) {
- // Hide the Manage Conference panel, return to NORMAL mode.
- setInCallScreenMode(InCallScreenMode.NORMAL);
- requestUpdateScreen();
- return;
- }
-
- // Nothing special to do. Fall back to the default behavior.
- super.onBackPressed();
- }
-
- /**
- * Handles the green CALL key while in-call.
- * @return true if we consumed the event.
- */
- private boolean handleCallKey() {
- // The green CALL button means either "Answer", "Unhold", or
- // "Swap calls", or can be a no-op, depending on the current state
- // of the Phone.
-
- final boolean hasRingingCall = mCM.hasActiveRingingCall();
- final boolean hasActiveCall = mCM.hasActiveFgCall();
- final boolean hasHoldingCall = mCM.hasActiveBgCall();
-
- int phoneType = mPhone.getPhoneType();
- if (phoneType == PhoneConstants.PHONE_TYPE_CDMA) {
- // The green CALL button means either "Answer", "Swap calls/On Hold", or
- // "Add to 3WC", depending on the current state of the Phone.
-
- CdmaPhoneCallState.PhoneCallState currCallState =
- mApp.cdmaPhoneCallState.getCurrentCallState();
- if (hasRingingCall) {
- //Scenario 1: Accepting the First Incoming and Call Waiting call
- if (DBG) log("answerCall: First Incoming and Call Waiting scenario");
- internalAnswerCall(); // Automatically holds the current active call,
- // if there is one
- } else if ((currCallState == CdmaPhoneCallState.PhoneCallState.THRWAY_ACTIVE)
- && (hasActiveCall)) {
- //Scenario 2: Merging 3Way calls
- if (DBG) log("answerCall: Merge 3-way call scenario");
- // Merge calls
- PhoneUtils.mergeCalls(mCM);
- } else if (currCallState == CdmaPhoneCallState.PhoneCallState.CONF_CALL) {
- //Scenario 3: Switching between two Call waiting calls or drop the latest
- // connection if in a 3Way merge scenario
- if (DBG) log("answerCall: Switch btwn 2 calls scenario");
- internalSwapCalls();
- }
- } else if ((phoneType == PhoneConstants.PHONE_TYPE_GSM)
- || (phoneType == PhoneConstants.PHONE_TYPE_SIP)) {
- if (hasRingingCall) {
- // If an incoming call is ringing, the CALL button is actually
- // handled by the PhoneWindowManager. (We do this to make
- // sure that we'll respond to the key even if the InCallScreen
- // hasn't come to the foreground yet.)
- //
- // We'd only ever get here in the extremely rare case that the
- // incoming call started ringing *after*
- // PhoneWindowManager.interceptKeyTq() but before the event
- // got here, or else if the PhoneWindowManager had some
- // problem connecting to the ITelephony service.
- Log.w(LOG_TAG, "handleCallKey: incoming call is ringing!"
- + " (PhoneWindowManager should have handled this key.)");
- // But go ahead and handle the key as normal, since the
- // PhoneWindowManager presumably did NOT handle it:
-
- // There's an incoming ringing call: CALL means "Answer".
- internalAnswerCall();
- } else if (hasActiveCall && hasHoldingCall) {
- // Two lines are in use: CALL means "Swap calls".
- if (DBG) log("handleCallKey: both lines in use ==> swap calls.");
- internalSwapCalls();
- } else if (hasHoldingCall) {
- // There's only one line in use, AND it's on hold.
- // In this case CALL is a shortcut for "unhold".
- if (DBG) log("handleCallKey: call on hold ==> unhold.");
- PhoneUtils.switchHoldingAndActive(
- mCM.getFirstActiveBgCall()); // Really means "unhold" in this state
- } else {
- // The most common case: there's only one line in use, and
- // it's an active call (i.e. it's not on hold.)
- // In this case CALL is a no-op.
- // (This used to be a shortcut for "add call", but that was a
- // bad idea because "Add call" is so infrequently-used, and
- // because the user experience is pretty confusing if you
- // inadvertently trigger it.)
- if (VDBG) log("handleCallKey: call in foregound ==> ignoring.");
- // But note we still consume this key event; see below.
- }
- } else {
- throw new IllegalStateException("Unexpected phone type: " + phoneType);
- }
-
- // We *always* consume the CALL key, since the system-wide default
- // action ("go to the in-call screen") is useless here.
- return true;
- }
-
- boolean isKeyEventAcceptableDTMF (KeyEvent event) {
- return (mDialer != null && mDialer.isKeyEventAcceptable(event));
- }
-
- /**
- * Overriden to track relevant focus changes.
- *
- * If a key is down and some time later the focus changes, we may
- * NOT recieve the keyup event; logically the keyup event has not
- * occured in this window. This issue is fixed by treating a focus
- * changed event as an interruption to the keydown, making sure
- * that any code that needs to be run in onKeyUp is ALSO run here.
- */
- @Override
- public void onWindowFocusChanged(boolean hasFocus) {
- // the dtmf tones should no longer be played
- if (VDBG) log("onWindowFocusChanged(" + hasFocus + ")...");
- if (!hasFocus && mDialer != null) {
- if (VDBG) log("- onWindowFocusChanged: faking onDialerKeyUp()...");
- mDialer.onDialerKeyUp(null);
- }
- }
-
- @Override
- public boolean onKeyUp(int keyCode, KeyEvent event) {
- // if (DBG) log("onKeyUp(keycode " + keyCode + ")...");
-
- // push input to the dialer.
- if ((mDialer != null) && (mDialer.onDialerKeyUp(event))){
- return true;
- } else if (keyCode == KeyEvent.KEYCODE_CALL) {
- // Always consume CALL to be sure the PhoneWindow won't do anything with it
- return true;
- }
- return super.onKeyUp(keyCode, event);
- }
-
- @Override
- public boolean onKeyDown(int keyCode, KeyEvent event) {
- // if (DBG) log("onKeyDown(keycode " + keyCode + ")...");
-
- switch (keyCode) {
- case KeyEvent.KEYCODE_CALL:
- boolean handled = handleCallKey();
- if (!handled) {
- Log.w(LOG_TAG, "InCallScreen should always handle KEYCODE_CALL in onKeyDown");
- }
- // Always consume CALL to be sure the PhoneWindow won't do anything with it
- return true;
-
- // Note there's no KeyEvent.KEYCODE_ENDCALL case here.
- // The standard system-wide handling of the ENDCALL key
- // (see PhoneWindowManager's handling of KEYCODE_ENDCALL)
- // already implements exactly what the UI spec wants,
- // namely (1) "hang up" if there's a current active call,
- // or (2) "don't answer" if there's a current ringing call.
-
- case KeyEvent.KEYCODE_CAMERA:
- // Disable the CAMERA button while in-call since it's too
- // easy to press accidentally.
- return true;
-
- case KeyEvent.KEYCODE_VOLUME_UP:
- case KeyEvent.KEYCODE_VOLUME_DOWN:
- case KeyEvent.KEYCODE_VOLUME_MUTE:
- if (mCM.getState() == PhoneConstants.State.RINGING) {
- // If an incoming call is ringing, the VOLUME buttons are
- // actually handled by the PhoneWindowManager. (We do
- // this to make sure that we'll respond to them even if
- // the InCallScreen hasn't come to the foreground yet.)
- //
- // We'd only ever get here in the extremely rare case that the
- // incoming call started ringing *after*
- // PhoneWindowManager.interceptKeyTq() but before the event
- // got here, or else if the PhoneWindowManager had some
- // problem connecting to the ITelephony service.
- Log.w(LOG_TAG, "VOLUME key: incoming call is ringing!"
- + " (PhoneWindowManager should have handled this key.)");
- // But go ahead and handle the key as normal, since the
- // PhoneWindowManager presumably did NOT handle it:
- internalSilenceRinger();
-
- // As long as an incoming call is ringing, we always
- // consume the VOLUME keys.
- return true;
- }
- break;
-
- case KeyEvent.KEYCODE_MUTE:
- onMuteClick();
- return true;
-
- // Various testing/debugging features, enabled ONLY when VDBG == true.
- case KeyEvent.KEYCODE_SLASH:
- if (VDBG) {
- log("----------- InCallScreen View dump --------------");
- // Dump starting from the top-level view of the entire activity:
- Window w = this.getWindow();
- View decorView = w.getDecorView();
- decorView.debug();
- return true;
- }
- break;
- case KeyEvent.KEYCODE_EQUALS:
- if (VDBG) {
- log("----------- InCallScreen call state dump --------------");
- PhoneUtils.dumpCallState(mPhone);
- PhoneUtils.dumpCallManager();
- return true;
- }
- break;
- case KeyEvent.KEYCODE_GRAVE:
- if (VDBG) {
- // Placeholder for other misc temp testing
- log("------------ Temp testing -----------------");
- return true;
- }
- break;
- }
-
- if (event.getRepeatCount() == 0 && handleDialerKeyDown(keyCode, event)) {
- return true;
- }
-
- return super.onKeyDown(keyCode, event);
- }
-
- /**
- * Handle a failure notification for a supplementary service
- * (i.e. conference, switch, separate, transfer, etc.).
- */
- void onSuppServiceFailed(AsyncResult r) {
- Phone.SuppService service = (Phone.SuppService) r.result;
- if (DBG) log("onSuppServiceFailed: " + service);
-
- int errorMessageResId;
- switch (service) {
- case SWITCH:
- // Attempt to switch foreground and background/incoming calls failed
- // ("Failed to switch calls")
- errorMessageResId = R.string.incall_error_supp_service_switch;
- break;
-
- case SEPARATE:
- // Attempt to separate a call from a conference call
- // failed ("Failed to separate out call")
- errorMessageResId = R.string.incall_error_supp_service_separate;
- break;
-
- case TRANSFER:
- // Attempt to connect foreground and background calls to
- // each other (and hanging up user's line) failed ("Call
- // transfer failed")
- errorMessageResId = R.string.incall_error_supp_service_transfer;
- break;
-
- case CONFERENCE:
- // Attempt to add a call to conference call failed
- // ("Conference call failed")
- errorMessageResId = R.string.incall_error_supp_service_conference;
- break;
-
- case REJECT:
- // Attempt to reject an incoming call failed
- // ("Call rejection failed")
- errorMessageResId = R.string.incall_error_supp_service_reject;
- break;
-
- case HANGUP:
- // Attempt to release a call failed ("Failed to release call(s)")
- errorMessageResId = R.string.incall_error_supp_service_hangup;
- break;
-
- case UNKNOWN:
- default:
- // Attempt to use a service we don't recognize or support
- // ("Unsupported service" or "Selected service failed")
- errorMessageResId = R.string.incall_error_supp_service_unknown;
- break;
- }
-
- // mSuppServiceFailureDialog is a generic dialog used for any
- // supp service failure, and there's only ever have one
- // instance at a time. So just in case a previous dialog is
- // still around, dismiss it.
- if (mSuppServiceFailureDialog != null) {
- if (DBG) log("- DISMISSING mSuppServiceFailureDialog.");
- mSuppServiceFailureDialog.dismiss(); // It's safe to dismiss() a dialog
- // that's already dismissed.
- mSuppServiceFailureDialog = null;
- }
-
- mSuppServiceFailureDialog = new AlertDialog.Builder(this)
- .setMessage(errorMessageResId)
- .setPositiveButton(R.string.ok, null)
- .create();
- mSuppServiceFailureDialog.getWindow().addFlags(
- WindowManager.LayoutParams.FLAG_BLUR_BEHIND);
- mSuppServiceFailureDialog.show();
- }
-
- /**
- * Something has changed in the phone's state. Update the UI.
- */
- private void onPhoneStateChanged(AsyncResult r) {
- PhoneConstants.State state = mCM.getState();
- if (DBG) log("onPhoneStateChanged: current state = " + state);
-
- // There's nothing to do here if we're not the foreground activity.
- // (When we *do* eventually come to the foreground, we'll do a
- // full update then.)
- if (!mIsForegroundActivity) {
- if (DBG) log("onPhoneStateChanged: Activity not in foreground! Bailing out...");
- return;
- }
-
- updateExpandedViewState();
-
- // Update the onscreen UI.
- // We use requestUpdateScreen() here (which posts a handler message)
- // instead of calling updateScreen() directly, which allows us to avoid
- // unnecessary work if multiple onPhoneStateChanged() events come in all
- // at the same time.
-
- requestUpdateScreen();
-
- // Make sure we update the poke lock and wake lock when certain
- // phone state changes occur.
- mApp.updateWakeState();
- }
-
- /**
- * Updates the UI after a phone connection is disconnected, as follows:
- *
- * - If this was a missed or rejected incoming call, and no other
- * calls are active, dismiss the in-call UI immediately. (The
- * CallNotifier will still create a "missed call" notification if
- * necessary.)
- *
- * - With any other disconnect cause, if the phone is now totally
- * idle, display the "Call ended" state for a couple of seconds.
- *
- * - Or, if the phone is still in use, stay on the in-call screen
- * (and update the UI to reflect the current state of the Phone.)
- *
- * @param r r.result contains the connection that just ended
- */
- private void onDisconnect(AsyncResult r) {
- Connection c = (Connection) r.result;
- Connection.DisconnectCause cause = c.getDisconnectCause();
- if (DBG) log("onDisconnect: connection '" + c + "', cause = " + cause
- + ", showing screen: " + mApp.isShowingCallScreen());
-
- boolean currentlyIdle = !phoneIsInUse();
- int autoretrySetting = AUTO_RETRY_OFF;
- boolean phoneIsCdma = (mPhone.getPhoneType() == PhoneConstants.PHONE_TYPE_CDMA);
- if (phoneIsCdma) {
- // 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.Global.getInt(mPhone.getContext().
- getContentResolver(), android.provider.Settings.Global.CALL_AUTO_RETRY, 0);
- }
- }
-
- // for OTA Call, only if in OTA NORMAL mode, handle OTA END scenario
- if ((mApp.inCallUiState.inCallScreenMode == InCallScreenMode.OTA_NORMAL)
- && ((mApp.cdmaOtaProvisionData != null)
- && (!mApp.cdmaOtaProvisionData.inOtaSpcState))) {
- setInCallScreenMode(InCallScreenMode.OTA_ENDED);
- updateScreen();
- return;
- } else if ((mApp.inCallUiState.inCallScreenMode == InCallScreenMode.OTA_ENDED)
- || ((mApp.cdmaOtaProvisionData != null)
- && mApp.cdmaOtaProvisionData.inOtaSpcState)) {
- if (DBG) log("onDisconnect: OTA Call end already handled");
- return;
- }
-
- // Any time a call disconnects, clear out the "history" of DTMF
- // digits you typed (to make sure it doesn't persist from one call
- // to the next.)
- mDialer.clearDigits();
-
- // Under certain call disconnected states, we want to alert the user
- // with a dialog instead of going through the normal disconnect
- // routine.
- if (cause == Connection.DisconnectCause.CALL_BARRED) {
- showGenericErrorDialog(R.string.callFailed_cb_enabled, false);
- return;
- } else if (cause == Connection.DisconnectCause.FDN_BLOCKED) {
- showGenericErrorDialog(R.string.callFailed_fdn_only, false);
- return;
- } else if (cause == Connection.DisconnectCause.CS_RESTRICTED) {
- showGenericErrorDialog(R.string.callFailed_dsac_restricted, false);
- return;
- } else if (cause == Connection.DisconnectCause.CS_RESTRICTED_EMERGENCY) {
- showGenericErrorDialog(R.string.callFailed_dsac_restricted_emergency, false);
- return;
- } else if (cause == Connection.DisconnectCause.CS_RESTRICTED_NORMAL) {
- showGenericErrorDialog(R.string.callFailed_dsac_restricted_normal, false);
- return;
- }
-
- if (phoneIsCdma) {
- Call.State callState = mApp.notifier.getPreviousCdmaCallState();
- if ((callState == Call.State.ACTIVE)
- && (cause != Connection.DisconnectCause.INCOMING_MISSED)
- && (cause != Connection.DisconnectCause.NORMAL)
- && (cause != Connection.DisconnectCause.LOCAL)
- && (cause != Connection.DisconnectCause.INCOMING_REJECTED)) {
- showCallLostDialog();
- } else if ((callState == Call.State.DIALING || callState == Call.State.ALERTING)
- && (cause != Connection.DisconnectCause.INCOMING_MISSED)
- && (cause != Connection.DisconnectCause.NORMAL)
- && (cause != Connection.DisconnectCause.LOCAL)
- && (cause != Connection.DisconnectCause.INCOMING_REJECTED)) {
-
- if (mApp.inCallUiState.needToShowCallLostDialog) {
- // Show the dialog now since the call that just failed was a retry.
- showCallLostDialog();
- mApp.inCallUiState.needToShowCallLostDialog = false;
- } else {
- if (autoretrySetting == AUTO_RETRY_OFF) {
- // Show the dialog for failed call if Auto Retry is OFF in Settings.
- showCallLostDialog();
- mApp.inCallUiState.needToShowCallLostDialog = false;
- } else {
- // Set the needToShowCallLostDialog flag now, so we'll know to show
- // the dialog if *this* call fails.
- mApp.inCallUiState.needToShowCallLostDialog = true;
- }
- }
- }
- }
-
- // Explicitly clean up up any DISCONNECTED connections
- // in a conference call.
- // [Background: Even after a connection gets disconnected, its
- // Connection object still stays around for a few seconds, in the
- // DISCONNECTED state. With regular calls, this state drives the
- // "call ended" UI. But when a single person disconnects from a
- // conference call there's no "call ended" state at all; in that
- // case we blow away any DISCONNECTED connections right now to make sure
- // the UI updates instantly to reflect the current state.]
- final Call call = c.getCall();
- if (call != null) {
- // We only care about situation of a single caller
- // disconnecting from a conference call. In that case, the
- // call will have more than one Connection (including the one
- // that just disconnected, which will be in the DISCONNECTED
- // state) *and* at least one ACTIVE connection. (If the Call
- // has *no* ACTIVE connections, that means that the entire
- // conference call just ended, so we *do* want to show the
- // "Call ended" state.)
- List<Connection> connections = call.getConnections();
- if (connections != null && connections.size() > 1) {
- for (Connection conn : connections) {
- if (conn.getState() == Call.State.ACTIVE) {
- // This call still has at least one ACTIVE connection!
- // So blow away any DISCONNECTED connections
- // (including, presumably, the one that just
- // disconnected from this conference call.)
-
- // We also force the wake state to refresh, just in
- // case the disconnected connections are removed
- // before the phone state change.
- if (VDBG) log("- Still-active conf call; clearing DISCONNECTED...");
- mApp.updateWakeState();
- mCM.clearDisconnected(); // This happens synchronously.
- break;
- }
- }
- }
- }
-
- // Note: see CallNotifier.onDisconnect() for some other behavior
- // that might be triggered by a disconnect event, like playing the
- // busy/congestion tone.
-
- // Stash away some info about the call that just disconnected.
- // (This might affect what happens after we exit the InCallScreen; see
- // delayedCleanupAfterDisconnect().)
- // TODO: rather than stashing this away now and then reading it in
- // delayedCleanupAfterDisconnect(), it would be cleaner to just pass
- // this as an argument to delayedCleanupAfterDisconnect() (if we call
- // it directly) or else pass it as a Message argument when we post the
- // DELAYED_CLEANUP_AFTER_DISCONNECT message.
- mLastDisconnectCause = cause;
-
- // We bail out immediately (and *don't* display the "call ended"
- // state at all) if this was an incoming call.
- boolean bailOutImmediately =
- ((cause == Connection.DisconnectCause.INCOMING_MISSED)
- || (cause == Connection.DisconnectCause.INCOMING_REJECTED))
- && currentlyIdle;
-
- boolean showingQuickResponseDialog =
- mRespondViaSmsManager != null && mRespondViaSmsManager.isShowingPopup();
-
- // Note: we also do some special handling for the case when a call
- // disconnects with cause==OUT_OF_SERVICE while making an
- // emergency call from airplane mode. That's handled by
- // EmergencyCallHelper.onDisconnect().
-
- if (bailOutImmediately && showingQuickResponseDialog) {
- if (DBG) log("- onDisconnect: Respond-via-SMS dialog is still being displayed...");
-
- // Do *not* exit the in-call UI yet!
- // If the call was an incoming call that was missed *and* the user is using
- // quick response screen, we keep showing the screen for a moment, assuming the
- // user wants to reply the call anyway.
- //
- // For this case, we will exit the screen when:
- // - the message is sent (RespondViaSmsManager)
- // - the message is canceled (RespondViaSmsManager), or
- // - when the whole in-call UI becomes background (onPause())
- } else if (bailOutImmediately) {
- if (DBG) log("- onDisconnect: bailOutImmediately...");
-
- // Exit the in-call UI!
- // (This is basically the same "delayed cleanup" we do below,
- // just with zero delay. Since the Phone is currently idle,
- // this call is guaranteed to immediately finish this activity.)
- delayedCleanupAfterDisconnect();
- } else {
- if (DBG) log("- onDisconnect: delayed bailout...");
- // Stay on the in-call screen for now. (Either the phone is
- // still in use, or the phone is idle but we want to display
- // the "call ended" state for a couple of seconds.)
-
- // Switch to the special "Call ended" state when the phone is idle
- // but there's still a call in the DISCONNECTED state:
- if (currentlyIdle
- && (mCM.hasDisconnectedFgCall() || mCM.hasDisconnectedBgCall())) {
- if (DBG) log("- onDisconnect: switching to 'Call ended' state...");
- setInCallScreenMode(InCallScreenMode.CALL_ENDED);
- }
-
- // Force a UI update in case we need to display anything
- // special based on this connection's DisconnectCause
- // (see CallCard.getCallFailedString()).
- updateScreen();
-
- // Some other misc cleanup that we do if the call that just
- // disconnected was the foreground call.
- final boolean hasActiveCall = mCM.hasActiveFgCall();
- if (!hasActiveCall) {
- if (DBG) log("- onDisconnect: cleaning up after FG call disconnect...");
-
- // Dismiss any dialogs which are only meaningful for an
- // active call *and* which become moot if the call ends.
- if (mWaitPromptDialog != null) {
- if (VDBG) log("- DISMISSING mWaitPromptDialog.");
- mWaitPromptDialog.dismiss(); // safe even if already dismissed
- mWaitPromptDialog = null;
- }
- if (mWildPromptDialog != null) {
- if (VDBG) log("- DISMISSING mWildPromptDialog.");
- mWildPromptDialog.dismiss(); // safe even if already dismissed
- mWildPromptDialog = null;
- }
- if (mPausePromptDialog != null) {
- if (DBG) log("- DISMISSING mPausePromptDialog.");
- mPausePromptDialog.dismiss(); // safe even if already dismissed
- mPausePromptDialog = null;
- }
- }
-
- // Updating the screen wake state is done in onPhoneStateChanged().
-
-
- // CDMA: We only clean up if the Phone state is IDLE as we might receive an
- // onDisconnect for a Call Collision case (rare but possible).
- // For Call collision cases i.e. when the user makes an out going call
- // and at the same time receives an Incoming Call, the Incoming Call is given
- // higher preference. At this time framework sends a disconnect for the Out going
- // call connection hence we should *not* bring down the InCallScreen as the Phone
- // State would be RINGING
- if (mPhone.getPhoneType() == PhoneConstants.PHONE_TYPE_CDMA) {
- if (!currentlyIdle) {
- // Clean up any connections in the DISCONNECTED state.
- // This is necessary cause in CallCollision the foreground call might have
- // connections in DISCONNECTED state which needs to be cleared.
- mCM.clearDisconnected();
-
- // The phone is still in use. Stay here in this activity.
- // But we don't need to keep the screen on.
- if (DBG) log("onDisconnect: Call Collision case - staying on InCallScreen.");
- if (DBG) PhoneUtils.dumpCallState(mPhone);
- return;
- }
- }
-
- // This is onDisconnect() request from the last phone call; no available call anymore.
- //
- // When the in-call UI is in background *because* the screen is turned off (unlike the
- // other case where the other activity is being shown), we wake up the screen and
- // show "DISCONNECTED" state once, with appropriate elapsed time. After showing that
- // we *must* bail out of the screen again, showing screen lock if needed.
- //
- //
- // TODO: Consider moving this to CallNotifier. This code assumes the InCallScreen
- // never gets destroyed. For this exact case, it works (since InCallScreen won't be
- // destroyed), while technically this isn't right; Activity may be destroyed when
- // in background.
- if (currentlyIdle && !isForegroundActivity()) {
- log("Force waking up the screen to let users see \"disconnected\" state");
- if (call != null) {
- mCallCard.updateElapsedTimeWidget(call);
- }
- // This variable will be kept true until the next InCallScreen#onPause(), which
- // forcibly turns it off regardless of the situation (for avoiding unnecessary
- // confusion around this special case).
- mApp.inCallUiState.showAlreadyDisconnectedState = true;
-
- // Finally request wake-up..
- mApp.wakeUpScreen();
-
- // InCallScreen#onResume() will set DELAYED_CLEANUP_AFTER_DISCONNECT message,
- // so skip the following section.
- return;
- }
-
- // Finally, arrange for delayedCleanupAfterDisconnect() to get
- // called after a short interval (during which we display the
- // "call ended" state.) At that point, if the
- // Phone is idle, we'll finish out of this activity.
- final int callEndedDisplayDelay;
- switch (cause) {
- // When the local user hanged up the ongoing call, it is ok to dismiss the screen
- // soon. In other cases, we show the "hung up" screen longer.
- //
- // - For expected reasons we will use CALL_ENDED_LONG_DELAY.
- // -- when the peer hanged up the call
- // -- when the local user rejects the incoming call during the other ongoing call
- // (TODO: there may be other cases which should be in this category)
- //
- // - For other unexpected reasons, we will use CALL_ENDED_EXTRA_LONG_DELAY,
- // assuming the local user wants to confirm the disconnect reason.
- case LOCAL:
- callEndedDisplayDelay = CALL_ENDED_SHORT_DELAY;
- break;
- case NORMAL:
- case INCOMING_REJECTED:
- callEndedDisplayDelay = CALL_ENDED_LONG_DELAY;
- break;
- default:
- callEndedDisplayDelay = CALL_ENDED_EXTRA_LONG_DELAY;
- break;
- }
- mHandler.removeMessages(DELAYED_CLEANUP_AFTER_DISCONNECT);
- mHandler.sendEmptyMessageDelayed(DELAYED_CLEANUP_AFTER_DISCONNECT,
- callEndedDisplayDelay);
- }
-
- // Remove 3way timer (only meaningful for CDMA)
- // TODO: this call needs to happen in the CallController, not here.
- // (It should probably be triggered by the CallNotifier's onDisconnect method.)
- // mHandler.removeMessages(THREEWAY_CALLERINFO_DISPLAY_DONE);
- }
-
- /**
- * Brings up the "MMI Started" dialog.
- */
- /* TODO: sort out MMI code (probably we should remove this method entirely). See also
- MMI handling code in onResume()
- private void onMMIInitiate(AsyncResult r) {
- if (VDBG) log("onMMIInitiate()... AsyncResult r = " + r);
-
- // Watch out: don't do this if we're not the foreground activity,
- // mainly since in the Dialog.show() might fail if we don't have a
- // valid window token any more...
- // (Note that this exact sequence can happen if you try to start
- // an MMI code while the radio is off or out of service.)
- if (!mIsForegroundActivity) {
- if (VDBG) log("Activity not in foreground! Bailing out...");
- return;
- }
-
- // Also, if any other dialog is up right now (presumably the
- // generic error dialog displaying the "Starting MMI..." message)
- // take it down before bringing up the real "MMI Started" dialog
- // in its place.
- dismissAllDialogs();
-
- MmiCode mmiCode = (MmiCode) r.result;
- if (VDBG) log(" - MmiCode: " + mmiCode);
-
- Message message = Message.obtain(mHandler, PhoneApp.MMI_CANCEL);
- mMmiStartedDialog = PhoneUtils.displayMMIInitiate(this, mmiCode,
- message, mMmiStartedDialog);
- }*/
-
- /**
- * Handles an MMI_CANCEL event, which is triggered by the button
- * (labeled either "OK" or "Cancel") on the "MMI Started" dialog.
- * @see PhoneUtils#cancelMmiCode(Phone)
- */
- private void onMMICancel() {
- if (VDBG) log("onMMICancel()...");
-
- // First of all, cancel the outstanding MMI code (if possible.)
- PhoneUtils.cancelMmiCode(mPhone);
-
- // Regardless of whether the current MMI code was cancelable, the
- // PhoneApp will get an MMI_COMPLETE event very soon, which will
- // take us to the MMI Complete dialog (see
- // PhoneUtils.displayMMIComplete().)
- //
- // But until that event comes in, we *don't* want to stay here on
- // the in-call screen, since we'll be visible in a
- // partially-constructed state as soon as the "MMI Started" dialog
- // gets dismissed. So let's forcibly bail out right now.
- if (DBG) log("onMMICancel: finishing InCallScreen...");
- dismissAllDialogs();
- endInCallScreenSession();
- }
-
- /**
- * Handles an MMI_COMPLETE event, which is triggered by telephony,
- * implying MMI
- */
- private void onMMIComplete(MmiCode mmiCode) {
- // Check the code to see if the request is ready to
- // finish, this includes any MMI state that is not
- // PENDING.
-
- // if phone is a CDMA phone display feature code completed message
- int phoneType = mPhone.getPhoneType();
- if (phoneType == PhoneConstants.PHONE_TYPE_CDMA) {
- PhoneUtils.displayMMIComplete(mPhone, mApp, mmiCode, null, null);
- } else if (phoneType == PhoneConstants.PHONE_TYPE_GSM) {
- if (mmiCode.getState() != MmiCode.State.PENDING) {
- if (DBG) log("Got MMI_COMPLETE, finishing InCallScreen...");
- dismissAllDialogs();
- endInCallScreenSession();
- }
- }
- }
-
- /**
- * Handles the POST_ON_DIAL_CHARS message from the Phone
- * (see our call to mPhone.setOnPostDialCharacter() above.)
- *
- * TODO: NEED TO TEST THIS SEQUENCE now that we no longer handle
- * "dialable" key events here in the InCallScreen: we do directly to the
- * Dialer UI instead. Similarly, we may now need to go directly to the
- * Dialer to handle POST_ON_DIAL_CHARS too.
- */
- private void handlePostOnDialChars(AsyncResult r, char ch) {
- Connection c = (Connection) r.result;
-
- if (c != null) {
- Connection.PostDialState state =
- (Connection.PostDialState) r.userObj;
-
- if (VDBG) log("handlePostOnDialChar: state = " +
- state + ", ch = " + ch);
-
- switch (state) {
- case STARTED:
- mDialer.stopLocalToneIfNeeded();
- if (mPauseInProgress) {
- /**
- * Note that on some devices, this will never happen,
- * because we will not ever enter the PAUSE state.
- */
- showPausePromptDialog(c, mPostDialStrAfterPause);
- }
- mPauseInProgress = false;
- mDialer.startLocalToneIfNeeded(ch);
-
- // TODO: is this needed, now that you can't actually
- // type DTMF chars or dial directly from here?
- // If so, we'd need to yank you out of the in-call screen
- // here too (and take you to the 12-key dialer in "in-call" mode.)
- // displayPostDialedChar(ch);
- break;
-
- case WAIT:
- // wait shows a prompt.
- if (DBG) log("handlePostOnDialChars: show WAIT prompt...");
- mDialer.stopLocalToneIfNeeded();
- String postDialStr = c.getRemainingPostDialString();
- showWaitPromptDialog(c, postDialStr);
- break;
-
- case WILD:
- if (DBG) log("handlePostOnDialChars: show WILD prompt");
- mDialer.stopLocalToneIfNeeded();
- showWildPromptDialog(c);
- break;
-
- case COMPLETE:
- mDialer.stopLocalToneIfNeeded();
- break;
-
- case PAUSE:
- // pauses for a brief period of time then continue dialing.
- mDialer.stopLocalToneIfNeeded();
- mPostDialStrAfterPause = c.getRemainingPostDialString();
- mPauseInProgress = true;
- break;
-
- default:
- break;
- }
- }
- }
-
- /**
- * Pop up an alert dialog with OK and Cancel buttons to allow user to
- * Accept or Reject the WAIT inserted as part of the Dial string.
- */
- private void showWaitPromptDialog(final Connection c, String postDialStr) {
- if (DBG) log("showWaitPromptDialogChoice: '" + postDialStr + "'...");
-
- Resources r = getResources();
- StringBuilder buf = new StringBuilder();
- buf.append(r.getText(R.string.wait_prompt_str));
- buf.append(postDialStr);
-
- // if (DBG) log("- mWaitPromptDialog = " + mWaitPromptDialog);
- if (mWaitPromptDialog != null) {
- if (DBG) log("- DISMISSING mWaitPromptDialog.");
- mWaitPromptDialog.dismiss(); // safe even if already dismissed
- mWaitPromptDialog = null;
- }
-
- mWaitPromptDialog = new AlertDialog.Builder(this)
- .setMessage(buf.toString())
- .setPositiveButton(R.string.pause_prompt_yes,
- new DialogInterface.OnClickListener() {
- @Override
- public void onClick(DialogInterface dialog, int whichButton) {
- if (DBG) log("handle WAIT_PROMPT_CONFIRMED, proceed...");
- c.proceedAfterWaitChar();
- }
- })
- .setNegativeButton(R.string.pause_prompt_no,
- new DialogInterface.OnClickListener() {
- @Override
- public void onClick(DialogInterface dialog, int whichButton) {
- if (DBG) log("handle POST_DIAL_CANCELED!");
- c.cancelPostDial();
- }
- })
- .create();
- mWaitPromptDialog.getWindow().addFlags(
- WindowManager.LayoutParams.FLAG_BLUR_BEHIND);
-
- mWaitPromptDialog.show();
- }
-
- /**
- * Pop up an alert dialog which waits for 2 seconds for each P (Pause) Character entered
- * as part of the Dial String.
- */
- private void showPausePromptDialog(final Connection c, String postDialStrAfterPause) {
- Resources r = getResources();
- StringBuilder buf = new StringBuilder();
- buf.append(r.getText(R.string.pause_prompt_str));
- buf.append(postDialStrAfterPause);
-
- if (mPausePromptDialog != null) {
- if (DBG) log("- DISMISSING mPausePromptDialog.");
- mPausePromptDialog.dismiss(); // safe even if already dismissed
- mPausePromptDialog = null;
- }
-
- mPausePromptDialog = new AlertDialog.Builder(this)
- .setMessage(buf.toString())
- .create();
- mPausePromptDialog.show();
- // 2 second timer
- Message msg = Message.obtain(mHandler, EVENT_PAUSE_DIALOG_COMPLETE);
- mHandler.sendMessageDelayed(msg, PAUSE_PROMPT_DIALOG_TIMEOUT);
- }
-
- private View createWildPromptView() {
- LinearLayout result = new LinearLayout(this);
- result.setOrientation(LinearLayout.VERTICAL);
- result.setPadding(5, 5, 5, 5);
-
- LinearLayout.LayoutParams lp = new LinearLayout.LayoutParams(
- ViewGroup.LayoutParams.MATCH_PARENT,
- ViewGroup.LayoutParams.WRAP_CONTENT);
-
- TextView promptMsg = new TextView(this);
- promptMsg.setTextSize(14);
- promptMsg.setTypeface(Typeface.DEFAULT_BOLD);
- promptMsg.setText(getResources().getText(R.string.wild_prompt_str));
-
- result.addView(promptMsg, lp);
-
- mWildPromptText = new EditText(this);
- mWildPromptText.setKeyListener(DialerKeyListener.getInstance());
- mWildPromptText.setMovementMethod(null);
- mWildPromptText.setTextSize(14);
- mWildPromptText.setMaxLines(1);
- mWildPromptText.setHorizontallyScrolling(true);
- mWildPromptText.setBackgroundResource(android.R.drawable.editbox_background);
-
- LinearLayout.LayoutParams lp2 = new LinearLayout.LayoutParams(
- ViewGroup.LayoutParams.MATCH_PARENT,
- ViewGroup.LayoutParams.WRAP_CONTENT);
- lp2.setMargins(0, 3, 0, 0);
-
- result.addView(mWildPromptText, lp2);
-
- return result;
- }
-
- private void showWildPromptDialog(final Connection c) {
- View v = createWildPromptView();
-
- if (mWildPromptDialog != null) {
- if (VDBG) log("- DISMISSING mWildPromptDialog.");
- mWildPromptDialog.dismiss(); // safe even if already dismissed
- mWildPromptDialog = null;
- }
-
- mWildPromptDialog = new AlertDialog.Builder(this)
- .setView(v)
- .setPositiveButton(
- R.string.send_button,
- new DialogInterface.OnClickListener() {
- @Override
- public void onClick(DialogInterface dialog, int whichButton) {
- if (VDBG) log("handle WILD_PROMPT_CHAR_ENTERED, proceed...");
- String replacement = null;
- if (mWildPromptText != null) {
- replacement = mWildPromptText.getText().toString();
- mWildPromptText = null;
- }
- c.proceedAfterWildChar(replacement);
- mApp.pokeUserActivity();
- }
- })
- .setOnCancelListener(
- new DialogInterface.OnCancelListener() {
- @Override
- public void onCancel(DialogInterface dialog) {
- if (VDBG) log("handle POST_DIAL_CANCELED!");
- c.cancelPostDial();
- mApp.pokeUserActivity();
- }
- })
- .create();
- mWildPromptDialog.getWindow().addFlags(
- WindowManager.LayoutParams.FLAG_BLUR_BEHIND);
- mWildPromptDialog.show();
-
- mWildPromptText.requestFocus();
- }
-
- /**
- * Updates the state of the in-call UI based on the current state of
- * the Phone. This call has no effect if we're not currently the
- * foreground activity.
- *
- * This method is only allowed to be called from the UI thread (since it
- * manipulates our View hierarchy). If you need to update the screen from
- * some other thread, or if you just want to "post a request" for the screen
- * to be updated (rather than doing it synchronously), call
- * requestUpdateScreen() instead.
- *
- * Right now this method will update UI visibility immediately, with no animation.
- * TODO: have animate flag here and use it anywhere possible.
- */
- private void updateScreen() {
- if (DBG) log("updateScreen()...");
- final InCallScreenMode inCallScreenMode = mApp.inCallUiState.inCallScreenMode;
- if (VDBG) {
- PhoneConstants.State state = mCM.getState();
- log(" - phone state = " + state);
- log(" - inCallScreenMode = " + inCallScreenMode);
- }
-
- // Don't update anything if we're not in the foreground (there's
- // no point updating our UI widgets since we're not visible!)
- // Also note this check also ensures we won't update while we're
- // in the middle of pausing, which could cause a visible glitch in
- // the "activity ending" transition.
- if (!mIsForegroundActivity) {
- if (DBG) log("- updateScreen: not the foreground Activity! Bailing out...");
- return;
- }
-
- if (inCallScreenMode == InCallScreenMode.OTA_NORMAL) {
- if (DBG) log("- updateScreen: OTA call state NORMAL (NOT updating in-call UI)...");
- mCallCard.setVisibility(View.GONE);
- if (mApp.otaUtils != null) {
- mApp.otaUtils.otaShowProperScreen();
- } else {
- Log.w(LOG_TAG, "OtaUtils object is null, not showing any screen for that.");
- }
- return; // Return without updating in-call UI.
- } else if (inCallScreenMode == InCallScreenMode.OTA_ENDED) {
- if (DBG) log("- updateScreen: OTA call ended state (NOT updating in-call UI)...");
- mCallCard.setVisibility(View.GONE);
- // Wake up the screen when we get notification, good or bad.
- mApp.wakeUpScreen();
- if (mApp.cdmaOtaScreenState.otaScreenState
- == CdmaOtaScreenState.OtaScreenState.OTA_STATUS_ACTIVATION) {
- if (DBG) log("- updateScreen: OTA_STATUS_ACTIVATION");
- if (mApp.otaUtils != null) {
- if (DBG) log("- updateScreen: mApp.otaUtils is not null, "
- + "call otaShowActivationScreen");
- mApp.otaUtils.otaShowActivateScreen();
- }
- } else {
- if (DBG) log("- updateScreen: OTA Call end state for Dialogs");
- if (mApp.otaUtils != null) {
- if (DBG) log("- updateScreen: Show OTA Success Failure dialog");
- mApp.otaUtils.otaShowSuccessFailure();
- }
- }
- return; // Return without updating in-call UI.
- } else if (inCallScreenMode == InCallScreenMode.MANAGE_CONFERENCE) {
- if (DBG) log("- updateScreen: manage conference mode (NOT updating in-call UI)...");
- mCallCard.setVisibility(View.GONE);
- updateManageConferencePanelIfNecessary();
- return; // Return without updating in-call UI.
- } else if (inCallScreenMode == InCallScreenMode.CALL_ENDED) {
- if (DBG) log("- updateScreen: call ended state...");
- // Continue with the rest of updateScreen() as usual, since we do
- // need to update the background (to the special "call ended" color)
- // and the CallCard (to show the "Call ended" label.)
- }
-
- if (DBG) log("- updateScreen: updating the in-call UI...");
- // Note we update the InCallTouchUi widget before the CallCard,
- // since the CallCard adjusts its size based on how much vertical
- // space the InCallTouchUi widget needs.
- updateInCallTouchUi();
- mCallCard.updateState(mCM);
-
- // If an incoming call is ringing, make sure the dialpad is
- // closed. (We do this to make sure we're not covering up the
- // "incoming call" UI.)
- if (mCM.getState() == PhoneConstants.State.RINGING) {
- if (mDialer.isOpened()) {
- Log.i(LOG_TAG, "During RINGING state we force hiding dialpad.");
- closeDialpadInternal(false); // don't do the "closing" animation
- }
-
- // At this point, we are guranteed that the dialer is closed.
- // This means that it is safe to clear out the "history" of DTMF digits
- // you may have typed into the previous call (so you don't see the
- // previous call's digits if you answer this call and then bring up the
- // dialpad.)
- //
- // TODO: it would be more precise to do this when you *answer* the
- // incoming call, rather than as soon as it starts ringing, but
- // the InCallScreen doesn't keep enough state right now to notice
- // that specific transition in onPhoneStateChanged().
- // TODO: This clears out the dialpad context as well so when a second
- // call comes in while a voicemail call is happening, the voicemail
- // dialpad will no longer have the "Voice Mail" context. It's a small
- // case so not terribly bad, but we need to maintain a better
- // call-to-callstate mapping before we can fix this.
- mDialer.clearDigits();
- }
-
-
- // Now that we're sure DTMF dialpad is in an appropriate state, reflect
- // the dialpad state into CallCard
- updateCallCardVisibilityPerDialerState(false);
-
- updateProgressIndication();
-
- // Forcibly take down all dialog if an incoming call is ringing.
- if (mCM.hasActiveRingingCall()) {
- dismissAllDialogs();
- } else {
- // Wait prompt dialog is not currently up. But it *should* be
- // up if the FG call has a connection in the WAIT state and
- // the phone isn't ringing.
- String postDialStr = null;
- List<Connection> fgConnections = mCM.getFgCallConnections();
- int phoneType = mCM.getFgPhone().getPhoneType();
- if (phoneType == PhoneConstants.PHONE_TYPE_CDMA) {
- Connection fgLatestConnection = mCM.getFgCallLatestConnection();
- if (mApp.cdmaPhoneCallState.getCurrentCallState() ==
- CdmaPhoneCallState.PhoneCallState.CONF_CALL) {
- for (Connection cn : fgConnections) {
- if ((cn != null) && (cn.getPostDialState() ==
- Connection.PostDialState.WAIT)) {
- cn.cancelPostDial();
- }
- }
- } else if ((fgLatestConnection != null)
- && (fgLatestConnection.getPostDialState() == Connection.PostDialState.WAIT)) {
- if(DBG) log("show the Wait dialog for CDMA");
- postDialStr = fgLatestConnection.getRemainingPostDialString();
- showWaitPromptDialog(fgLatestConnection, postDialStr);
- }
- } else if ((phoneType == PhoneConstants.PHONE_TYPE_GSM)
- || (phoneType == PhoneConstants.PHONE_TYPE_SIP)) {
- for (Connection cn : fgConnections) {
- if ((cn != null) && (cn.getPostDialState() == Connection.PostDialState.WAIT)) {
- postDialStr = cn.getRemainingPostDialString();
- showWaitPromptDialog(cn, postDialStr);
- }
- }
- } else {
- throw new IllegalStateException("Unexpected phone type: " + phoneType);
- }
- }
- }
-
- /**
- * (Re)synchronizes the onscreen UI with the current state of the
- * telephony framework.
- *
- * @return SyncWithPhoneStateStatus.SUCCESS if we successfully updated the UI, or
- * SyncWithPhoneStateStatus.PHONE_NOT_IN_USE if there was no phone state to sync
- * with (ie. the phone was completely idle). In the latter case, we
- * shouldn't even be in the in-call UI in the first place, and it's
- * the caller's responsibility to bail out of this activity by
- * calling endInCallScreenSession if appropriate.
- *
- * This method directly calls updateScreen() in the normal "phone is
- * in use" case, so there's no need for the caller to do so.
- */
- private SyncWithPhoneStateStatus syncWithPhoneState() {
- boolean updateSuccessful = false;
- if (DBG) log("syncWithPhoneState()...");
- if (DBG) PhoneUtils.dumpCallState(mPhone);
-
- // Make sure the Phone is "in use". (If not, we shouldn't be on
- // this screen in the first place.)
-
- // An active or just-ended OTA call counts as "in use".
- if (TelephonyCapabilities.supportsOtasp(mCM.getFgPhone())
- && ((mApp.inCallUiState.inCallScreenMode == InCallScreenMode.OTA_NORMAL)
- || (mApp.inCallUiState.inCallScreenMode == InCallScreenMode.OTA_ENDED))) {
- // Even when OTA Call ends, need to show OTA End UI,
- // so return Success to allow UI update.
- return SyncWithPhoneStateStatus.SUCCESS;
- }
-
- // If an MMI code is running that also counts as "in use".
- //
- // TODO: We currently only call getPendingMmiCodes() for GSM
- // phones. (The code's been that way all along.) But CDMAPhone
- // does in fact implement getPendingMmiCodes(), so should we
- // check that here regardless of the phone type?
- boolean hasPendingMmiCodes =
- (mPhone.getPhoneType() == PhoneConstants.PHONE_TYPE_GSM)
- && !mPhone.getPendingMmiCodes().isEmpty();
-
- // Finally, it's also OK to stay here on the InCallScreen if we
- // need to display a progress indicator while something's
- // happening in the background.
- boolean showProgressIndication = mApp.inCallUiState.isProgressIndicationActive();
-
- boolean showScreenEvenAfterDisconnect = mApp.inCallUiState.showAlreadyDisconnectedState;
-
- if (mCM.hasActiveFgCall() || mCM.hasActiveBgCall() || mCM.hasActiveRingingCall()
- || hasPendingMmiCodes || showProgressIndication || showScreenEvenAfterDisconnect) {
- if (VDBG) log("syncWithPhoneState: it's ok to be here; update the screen...");
- updateScreen();
- return SyncWithPhoneStateStatus.SUCCESS;
- }
-
- Log.i(LOG_TAG, "syncWithPhoneState: phone is idle (shouldn't be here)");
- return SyncWithPhoneStateStatus.PHONE_NOT_IN_USE;
- }
-
-
-
- private void handleMissingVoiceMailNumber() {
- if (DBG) log("handleMissingVoiceMailNumber");
-
- final Message msg = Message.obtain(mHandler);
- msg.what = DONT_ADD_VOICEMAIL_NUMBER;
-
- final Message msg2 = Message.obtain(mHandler);
- msg2.what = ADD_VOICEMAIL_NUMBER;
-
- mMissingVoicemailDialog = new AlertDialog.Builder(this)
- .setTitle(R.string.no_vm_number)
- .setMessage(R.string.no_vm_number_msg)
- .setPositiveButton(R.string.ok, new DialogInterface.OnClickListener() {
- public void onClick(DialogInterface dialog, int which) {
- if (VDBG) log("Missing voicemail AlertDialog: POSITIVE click...");
- msg.sendToTarget(); // see dontAddVoiceMailNumber()
- mApp.pokeUserActivity();
- }})
- .setNegativeButton(R.string.add_vm_number_str,
- new DialogInterface.OnClickListener() {
- public void onClick(DialogInterface dialog, int which) {
- if (VDBG) log("Missing voicemail AlertDialog: NEGATIVE click...");
- msg2.sendToTarget(); // see addVoiceMailNumber()
- mApp.pokeUserActivity();
- }})
- .setOnCancelListener(new OnCancelListener() {
- public void onCancel(DialogInterface dialog) {
- if (VDBG) log("Missing voicemail AlertDialog: CANCEL handler...");
- msg.sendToTarget(); // see dontAddVoiceMailNumber()
- mApp.pokeUserActivity();
- }})
- .create();
-
- // When the dialog is up, completely hide the in-call UI
- // underneath (which is in a partially-constructed state).
- mMissingVoicemailDialog.getWindow().addFlags(
- WindowManager.LayoutParams.FLAG_DIM_BEHIND);
-
- mMissingVoicemailDialog.show();
- }
-
- private void addVoiceMailNumberPanel() {
- if (mMissingVoicemailDialog != null) {
- mMissingVoicemailDialog.dismiss();
- mMissingVoicemailDialog = null;
- }
- if (DBG) log("addVoiceMailNumberPanel: finishing InCallScreen...");
- endInCallScreenSession();
-
- if (DBG) log("show vm setting");
-
- // navigate to the Voicemail setting in the Call Settings activity.
- Intent intent = new Intent(CallFeaturesSetting.ACTION_ADD_VOICEMAIL);
- intent.setClass(this, CallFeaturesSetting.class);
- startActivity(intent);
- }
-
- private void dontAddVoiceMailNumber() {
- if (mMissingVoicemailDialog != null) {
- mMissingVoicemailDialog.dismiss();
- mMissingVoicemailDialog = null;
- }
- if (DBG) log("dontAddVoiceMailNumber: finishing InCallScreen...");
- endInCallScreenSession();
- }
-
- /**
- * Do some delayed cleanup after a Phone call gets disconnected.
- *
- * This method gets called a couple of seconds after any DISCONNECT
- * event from the Phone; it's triggered by the
- * DELAYED_CLEANUP_AFTER_DISCONNECT message we send in onDisconnect().
- *
- * If the Phone is totally idle right now, that means we've already
- * shown the "call ended" state for a couple of seconds, and it's now
- * time to endInCallScreenSession this activity.
- *
- * If the Phone is *not* idle right now, that probably means that one
- * call ended but the other line is still in use. In that case, do
- * nothing, and instead stay here on the InCallScreen.
- */
- private void delayedCleanupAfterDisconnect() {
- if (VDBG) log("delayedCleanupAfterDisconnect()... Phone state = " + mCM.getState());
-
- // Clean up any connections in the DISCONNECTED state.
- //
- // [Background: Even after a connection gets disconnected, its
- // Connection object still stays around, in the special
- // DISCONNECTED state. This is necessary because we we need the
- // caller-id information from that Connection to properly draw the
- // "Call ended" state of the CallCard.
- // But at this point we truly don't need that connection any
- // more, so tell the Phone that it's now OK to to clean up any
- // connections still in that state.]
- mCM.clearDisconnected();
-
- // There are two cases where we should *not* exit the InCallScreen:
- // (1) Phone is still in use
- // or
- // (2) There's an active progress indication (i.e. the "Retrying..."
- // progress dialog) that we need to continue to display.
-
- boolean stayHere = phoneIsInUse() || mApp.inCallUiState.isProgressIndicationActive();
-
- if (stayHere) {
- if (DBG) log("- delayedCleanupAfterDisconnect: staying on the InCallScreen...");
- } else {
- // Phone is idle! We should exit the in-call UI now.
- if (DBG) log("- delayedCleanupAfterDisconnect: phone is idle...");
-
- // And (finally!) exit from the in-call screen
- // (but not if we're already in the process of pausing...)
- if (mIsForegroundActivity) {
- if (DBG) log("- delayedCleanupAfterDisconnect: finishing InCallScreen...");
-
- // In some cases we finish the call by taking the user to the
- // Call Log. Otherwise, we simply call endInCallScreenSession,
- // which will take us back to wherever we came from.
- //
- // UI note: In eclair and earlier, we went to the Call Log
- // after outgoing calls initiated on the device, but never for
- // incoming calls. Now we do it for incoming calls too, as
- // long as the call was answered by the user. (We always go
- // back where you came from after a rejected or missed incoming
- // call.)
- //
- // And in any case, *never* go to the call log if we're in
- // emergency mode (i.e. if the screen is locked and a lock
- // pattern or PIN/password is set), or if we somehow got here
- // on a non-voice-capable device.
-
- if (VDBG) log("- Post-call behavior:");
- if (VDBG) log(" - mLastDisconnectCause = " + mLastDisconnectCause);
- if (VDBG) log(" - isPhoneStateRestricted() = " + isPhoneStateRestricted());
-
- // DisconnectCause values in the most common scenarios:
- // - INCOMING_MISSED: incoming ringing call times out, or the
- // other end hangs up while still ringing
- // - INCOMING_REJECTED: user rejects the call while ringing
- // - LOCAL: user hung up while a call was active (after
- // answering an incoming call, or after making an
- // outgoing call)
- // - NORMAL: the other end hung up (after answering an incoming
- // call, or after making an outgoing call)
-
- if ((mLastDisconnectCause != Connection.DisconnectCause.INCOMING_MISSED)
- && (mLastDisconnectCause != Connection.DisconnectCause.INCOMING_REJECTED)
- && !isPhoneStateRestricted()
- && PhoneGlobals.sVoiceCapable) {
- final Intent intent = mApp.createPhoneEndIntentUsingCallOrigin();
- ActivityOptions opts = ActivityOptions.makeCustomAnimation(this,
- R.anim.activity_close_enter, R.anim.activity_close_exit);
- if (VDBG) {
- log("- Show Call Log (or Dialtacts) after disconnect. Current intent: "
- + intent);
- }
- try {
- startActivity(intent, opts.toBundle());
- } catch (ActivityNotFoundException e) {
- // Don't crash if there's somehow no "Call log" at
- // all on this device.
- // (This should never happen, though, since we already
- // checked PhoneApp.sVoiceCapable above, and any
- // voice-capable device surely *should* have a call
- // log activity....)
- Log.w(LOG_TAG, "delayedCleanupAfterDisconnect: "
- + "transition to call log failed; intent = " + intent);
- // ...so just return back where we came from....
- }
- // Even if we did go to the call log, note that we still
- // call endInCallScreenSession (below) to make sure we don't
- // stay in the activity history.
- }
-
- }
- endInCallScreenSession();
-
- // Reset the call origin when the session ends and this in-call UI is being finished.
- mApp.setLatestActiveCallOrigin(null);
- }
- }
-
-
- /**
- * View.OnClickListener implementation.
- *
- * This method handles clicks from UI elements that use the
- * InCallScreen itself as their OnClickListener.
- *
- * Note: Currently this method is used only for a few special buttons:
- * - the mButtonManageConferenceDone "Back to call" button
- * - the "dim" effect for the secondary call photo in CallCard as the second "swap" button
- * - other OTASP-specific buttons managed by OtaUtils.java.
- *
- * *Most* in-call controls are handled by the handleOnscreenButtonClick() method, via the
- * InCallTouchUi widget.
- */
- @Override
- public void onClick(View view) {
- int id = view.getId();
- if (VDBG) log("onClick(View " + view + ", id " + id + ")...");
-
- switch (id) {
- case R.id.manage_done: // mButtonManageConferenceDone
- if (VDBG) log("onClick: mButtonManageConferenceDone...");
- // Hide the Manage Conference panel, return to NORMAL mode.
- setInCallScreenMode(InCallScreenMode.NORMAL);
- requestUpdateScreen();
- break;
-
- case R.id.dim_effect_for_secondary_photo:
- if (mInCallControlState.canSwap) {
- internalSwapCalls();
- }
- break;
-
- default:
- // Presumably one of the OTASP-specific buttons managed by
- // OtaUtils.java.
- // (TODO: It would be cleaner for the OtaUtils instance itself to
- // be the OnClickListener for its own buttons.)
-
- if ((mApp.inCallUiState.inCallScreenMode == InCallScreenMode.OTA_NORMAL
- || mApp.inCallUiState.inCallScreenMode == InCallScreenMode.OTA_ENDED)
- && mApp.otaUtils != null) {
- mApp.otaUtils.onClickHandler(id);
- } else {
- // Uh oh: we *should* only receive clicks here from the
- // buttons managed by OtaUtils.java, but if we're not in one
- // of the special OTASP modes, those buttons shouldn't have
- // been visible in the first place.
- Log.w(LOG_TAG,
- "onClick: unexpected click from ID " + id + " (View = " + view + ")");
- }
- break;
- }
-
- EventLog.writeEvent(EventLogTags.PHONE_UI_BUTTON_CLICK,
- (view instanceof TextView) ? ((TextView) view).getText() : "");
-
- // Clicking any onscreen UI element counts as explicit "user activity".
- mApp.pokeUserActivity();
- }
-
- private void onHoldClick() {
- final boolean hasActiveCall = mCM.hasActiveFgCall();
- final boolean hasHoldingCall = mCM.hasActiveBgCall();
- log("onHoldClick: hasActiveCall = " + hasActiveCall
- + ", hasHoldingCall = " + hasHoldingCall);
- boolean newHoldState;
- boolean holdButtonEnabled;
- if (hasActiveCall && !hasHoldingCall) {
- // There's only one line in use, and that line is active.
- PhoneUtils.switchHoldingAndActive(
- mCM.getFirstActiveBgCall()); // Really means "hold" in this state
- newHoldState = true;
- holdButtonEnabled = true;
- } else if (!hasActiveCall && hasHoldingCall) {
- // There's only one line in use, and that line is on hold.
- PhoneUtils.switchHoldingAndActive(
- mCM.getFirstActiveBgCall()); // Really means "unhold" in this state
- newHoldState = false;
- holdButtonEnabled = true;
- } else {
- // Either zero or 2 lines are in use; "hold/unhold" is meaningless.
- newHoldState = false;
- holdButtonEnabled = false;
- }
- // No need to forcibly update the onscreen UI; just wait for the
- // onPhoneStateChanged() callback. (This seems to be responsive
- // enough.)
-
- // Also, any time we hold or unhold, force the DTMF dialpad to close.
- closeDialpadInternal(true); // do the "closing" animation
- }
-
- /**
- * Toggles in-call audio between speaker and the built-in earpiece (or
- * wired headset.)
- */
- public void toggleSpeaker() {
- // TODO: Turning on the speaker seems to enable the mic
- // whether or not the "mute" feature is active!
- // Not sure if this is an feature of the telephony API
- // that I need to handle specially, or just a bug.
- boolean newSpeakerState = !PhoneUtils.isSpeakerOn(this);
- log("toggleSpeaker(): newSpeakerState = " + newSpeakerState);
-
- // TODO(klp): Add bluetooth query back in for AudioRouter.
- /*
- if (newSpeakerState && isBluetoothAvailable() && isBluetoothAudioConnected()) {
- disconnectBluetoothAudio();
- }
- */
- PhoneUtils.turnOnSpeaker(this, newSpeakerState, true);
-
- // And update the InCallTouchUi widget (since the "audio mode"
- // button might need to change its appearance based on the new
- // audio state.)
- updateInCallTouchUi();
- }
-
- /*
- * onMuteClick is called only when there is a foreground call
- */
- private void onMuteClick() {
- boolean newMuteState = !PhoneUtils.getMute();
- log("onMuteClick(): newMuteState = " + newMuteState);
- PhoneUtils.setMute(newMuteState);
- }
-
- public void toggleBluetooth() {
- // TODO(klp) this still here to avoid compile errors until remove
- // the UI from services/Telephony completely.
- }
-
- public void switchInCallAudio(InCallAudioMode newMode) {
- // TODO(klp) this still here to avoid compile errors until remove
- // the UI from services/Telephony completely.
- }
-
- /**
- * Handle a click on the "Open/Close dialpad" button.
- *
- * @see DTMFTwelveKeyDialer#openDialer(boolean)
- * @see DTMFTwelveKeyDialer#closeDialer(boolean)
- */
- private void onOpenCloseDialpad() {
- if (VDBG) log("onOpenCloseDialpad()...");
- if (mDialer.isOpened()) {
- closeDialpadInternal(true); // do the "closing" animation
- } else {
- openDialpadInternal(true); // do the "opening" animation
- }
- }
-
- /** Internal wrapper around {@link DTMFTwelveKeyDialer#openDialer(boolean)} */
- private void openDialpadInternal(boolean animate) {
- mDialer.openDialer(animate);
- // And update the InCallUiState (so that we'll restore the dialpad
- // to the correct state if we get paused/resumed).
- mApp.inCallUiState.showDialpad = true;
- }
-
- // Internal wrapper around DTMFTwelveKeyDialer.closeDialer()
- private void closeDialpadInternal(boolean animate) {
- mDialer.closeDialer(animate);
- // And update the InCallUiState (so that we'll restore the dialpad
- // to the correct state if we get paused/resumed).
- mApp.inCallUiState.showDialpad = false;
- }
-
- /**
- * Handles button clicks from the InCallTouchUi widget.
- */
- /* package */ void handleOnscreenButtonClick(int id) {
- if (DBG) log("handleOnscreenButtonClick(id " + id + ")...");
-
- switch (id) {
- // Actions while an incoming call is ringing:
- case R.id.incomingCallAnswer:
- internalAnswerCall();
- break;
- case R.id.incomingCallReject:
- hangupRingingCall();
- break;
- case R.id.incomingCallRespondViaSms:
- internalRespondViaSms();
- break;
-
- // The other regular (single-tap) buttons used while in-call:
- case R.id.holdButton:
- onHoldClick();
- break;
- case R.id.swapButton:
- internalSwapCalls();
- break;
- case R.id.endButton:
- internalHangup();
- break;
- case R.id.dialpadButton:
- onOpenCloseDialpad();
- break;
- case R.id.muteButton:
- onMuteClick();
- break;
- case R.id.addButton:
- PhoneUtils.startNewCall(mCM); // Fires off an ACTION_DIAL intent
- break;
- case R.id.mergeButton:
- case R.id.cdmaMergeButton:
- PhoneUtils.mergeCalls(mCM);
- break;
- case R.id.manageConferenceButton:
- // Show the Manage Conference panel.
- setInCallScreenMode(InCallScreenMode.MANAGE_CONFERENCE);
- requestUpdateScreen();
- break;
-
- default:
- Log.w(LOG_TAG, "handleOnscreenButtonClick: unexpected ID " + id);
- break;
- }
-
- // Clicking any onscreen UI element counts as explicit "user activity".
- mApp.pokeUserActivity();
-
- // Just in case the user clicked a "stateful" UI element (like one
- // of the toggle buttons), we force the in-call buttons to update,
- // to make sure the user sees the *new* current state.
- //
- // Note that some in-call buttons will *not* immediately change the
- // state of the UI, namely those that send a request to the telephony
- // layer (like "Hold" or "End call".) For those buttons, the
- // updateInCallTouchUi() call here won't have any visible effect.
- // Instead, the UI will be updated eventually when the next
- // onPhoneStateChanged() event comes in and triggers an updateScreen()
- // call.
- //
- // TODO: updateInCallTouchUi() is overkill here; it would be
- // more efficient to update *only* the affected button(s).
- // (But this isn't a big deal since updateInCallTouchUi() is pretty
- // cheap anyway...)
- updateInCallTouchUi();
- }
-
- /**
- * Display a status or error indication to the user according to the
- * specified InCallUiState.CallStatusCode value.
- */
- private void showStatusIndication(CallStatusCode status) {
- switch (status) {
- case SUCCESS:
- // The InCallScreen does not need to display any kind of error indication,
- // so we shouldn't have gotten here in the first place.
- Log.wtf(LOG_TAG, "showStatusIndication: nothing to display");
- break;
-
- case POWER_OFF:
- // Radio is explictly powered off, presumably because the
- // device is in airplane mode.
- //
- // TODO: For now this UI is ultra-simple: we simply display
- // a message telling the user to turn off airplane mode.
- // But it might be nicer for the dialog to offer the option
- // to turn the radio on right there (and automatically retry
- // the call once network registration is complete.)
- showGenericErrorDialog(R.string.incall_error_power_off,
- true /* isStartupError */);
- break;
-
- case EMERGENCY_ONLY:
- // Only emergency numbers are allowed, but we tried to dial
- // a non-emergency number.
- // (This state is currently unused; see comments above.)
- showGenericErrorDialog(R.string.incall_error_emergency_only,
- true /* isStartupError */);
- break;
-
- case OUT_OF_SERVICE:
- // No network connection.
- showGenericErrorDialog(R.string.incall_error_out_of_service,
- true /* isStartupError */);
- break;
-
- case NO_PHONE_NUMBER_SUPPLIED:
- // The supplied Intent didn't contain a valid phone number.
- // (This is rare and should only ever happen with broken
- // 3rd-party apps.) For now just show a generic error.
- showGenericErrorDialog(R.string.incall_error_no_phone_number_supplied,
- true /* isStartupError */);
- break;
-
- case DIALED_MMI:
- // Our initial phone number was actually an MMI sequence.
- // There's no real "error" here, but we do bring up the
- // a Toast (as requested of the New UI paradigm).
- //
- // In-call MMIs do not trigger the normal MMI Initiate
- // Notifications, so we should notify the user here.
- // Otherwise, the code in PhoneUtils.java should handle
- // user notifications in the form of Toasts or Dialogs.
- if (mCM.getState() == PhoneConstants.State.OFFHOOK) {
- Toast.makeText(mApp, R.string.incall_status_dialed_mmi, Toast.LENGTH_SHORT)
- .show();
- }
- break;
-
- case CALL_FAILED:
- // We couldn't successfully place the call; there was some
- // failure in the telephony layer.
- // TODO: Need UI spec for this failure case; for now just
- // show a generic error.
- showGenericErrorDialog(R.string.incall_error_call_failed,
- true /* isStartupError */);
- break;
-
- case VOICEMAIL_NUMBER_MISSING:
- // We tried to call a voicemail: URI but the device has no
- // voicemail number configured.
- handleMissingVoiceMailNumber();
- break;
-
- case CDMA_CALL_LOST:
- // This status indicates that InCallScreen should display the
- // CDMA-specific "call lost" dialog. (If an outgoing call fails,
- // and the CDMA "auto-retry" feature is enabled, *and* the retried
- // call fails too, we display this specific dialog.)
- //
- // TODO: currently unused; see InCallUiState.needToShowCallLostDialog
- break;
-
- case EXITED_ECM:
- // This status indicates that InCallScreen needs to display a
- // warning that we're exiting ECM (emergency callback mode).
- showExitingECMDialog();
- break;
-
- default:
- throw new IllegalStateException(
- "showStatusIndication: unexpected status code: " + status);
- }
-
- // TODO: still need to make sure that pressing OK or BACK from
- // *any* of the dialogs we launch here ends up calling
- // inCallUiState.clearPendingCallStatusCode()
- // *and*
- // make sure the Dialog handles both OK *and* cancel by calling
- // endInCallScreenSession. (See showGenericErrorDialog() for an
- // example.)
- //
- // (showGenericErrorDialog() currently does this correctly,
- // but handleMissingVoiceMailNumber() probably needs to be fixed too.)
- //
- // Also need to make sure that bailing out of any of these dialogs by
- // pressing Home clears out the pending status code too. (If you do
- // that, neither the dialog's clickListener *or* cancelListener seems
- // to run...)
- }
-
- /**
- * Utility function to bring up a generic "error" dialog, and then bail
- * out of the in-call UI when the user hits OK (or the BACK button.)
- */
- private void showGenericErrorDialog(int resid, boolean isStartupError) {
- CharSequence msg = getResources().getText(resid);
- if (DBG) log("showGenericErrorDialog('" + msg + "')...");
-
- // create the clicklistener and cancel listener as needed.
- DialogInterface.OnClickListener clickListener;
- OnCancelListener cancelListener;
- if (isStartupError) {
- clickListener = new DialogInterface.OnClickListener() {
- public void onClick(DialogInterface dialog, int which) {
- bailOutAfterErrorDialog();
- }};
- cancelListener = new OnCancelListener() {
- public void onCancel(DialogInterface dialog) {
- bailOutAfterErrorDialog();
- }};
- } else {
- clickListener = new DialogInterface.OnClickListener() {
- public void onClick(DialogInterface dialog, int which) {
- delayedCleanupAfterDisconnect();
- }};
- cancelListener = new OnCancelListener() {
- public void onCancel(DialogInterface dialog) {
- delayedCleanupAfterDisconnect();
- }};
- }
-
- // TODO: Consider adding a setTitle() call here (with some generic
- // "failure" title?)
- mGenericErrorDialog = new AlertDialog.Builder(this)
- .setMessage(msg)
- .setPositiveButton(R.string.ok, clickListener)
- .setOnCancelListener(cancelListener)
- .create();
-
- // When the dialog is up, completely hide the in-call UI
- // underneath (which is in a partially-constructed state).
- mGenericErrorDialog.getWindow().addFlags(
- WindowManager.LayoutParams.FLAG_DIM_BEHIND);
-
- mGenericErrorDialog.show();
- }
-
- private void showCallLostDialog() {
- if (DBG) log("showCallLostDialog()...");
-
- // Don't need to show the dialog if InCallScreen isn't in the forgeround
- if (!mIsForegroundActivity) {
- if (DBG) log("showCallLostDialog: not the foreground Activity! Bailing out...");
- return;
- }
-
- // Don't need to show the dialog again, if there is one already.
- if (mCallLostDialog != null) {
- if (DBG) log("showCallLostDialog: There is a mCallLostDialog already.");
- return;
- }
-
- mCallLostDialog = new AlertDialog.Builder(this)
- .setMessage(R.string.call_lost)
- .setIconAttribute(android.R.attr.alertDialogIcon)
- .create();
- mCallLostDialog.show();
- }
-
- /**
- * Displays the "Exiting ECM" warning dialog.
- *
- * Background: If the phone is currently in ECM (Emergency callback
- * mode) and we dial a non-emergency number, that automatically
- * *cancels* ECM. (That behavior comes from CdmaCallTracker.dial().)
- * When that happens, we need to warn the user that they're no longer
- * in ECM (bug 4207607.)
- *
- * So bring up a dialog explaining what's happening. There's nothing
- * for the user to do, by the way; we're simply providing an
- * indication that they're exiting ECM. We *could* use a Toast for
- * this, but toasts are pretty easy to miss, so instead use a dialog
- * with a single "OK" button.
- *
- * TODO: it's ugly that the code here has to make assumptions about
- * the behavior of the telephony layer (namely that dialing a
- * non-emergency number while in ECM causes us to exit ECM.)
- *
- * Instead, this warning dialog should really be triggered by our
- * handler for the
- * TelephonyIntents.ACTION_EMERGENCY_CALLBACK_MODE_CHANGED intent in
- * PhoneApp.java. But that won't work until that intent also
- * includes a *reason* why we're exiting ECM, since we need to
- * display this dialog when exiting ECM because of an outgoing call,
- * but NOT if we're exiting ECM because the user manually turned it
- * off via the EmergencyCallbackModeExitDialog.
- *
- * Or, it might be simpler to just have outgoing non-emergency calls
- * *not* cancel ECM. That way the UI wouldn't have to do anything
- * special here.
- */
- private void showExitingECMDialog() {
- Log.i(LOG_TAG, "showExitingECMDialog()...");
-
- if (mExitingECMDialog != null) {
- if (DBG) log("- DISMISSING mExitingECMDialog.");
- mExitingECMDialog.dismiss(); // safe even if already dismissed
- mExitingECMDialog = null;
- }
-
- // When the user dismisses the "Exiting ECM" dialog, we clear out
- // the pending call status code field (since we're done with this
- // dialog), but do *not* bail out of the InCallScreen.
-
- final InCallUiState inCallUiState = mApp.inCallUiState;
- DialogInterface.OnClickListener clickListener = new DialogInterface.OnClickListener() {
- public void onClick(DialogInterface dialog, int which) {
- inCallUiState.clearPendingCallStatusCode();
- }};
- OnCancelListener cancelListener = new OnCancelListener() {
- public void onCancel(DialogInterface dialog) {
- inCallUiState.clearPendingCallStatusCode();
- }};
-
- // Ultra-simple AlertDialog with only an OK button:
- mExitingECMDialog = new AlertDialog.Builder(this)
- .setMessage(R.string.progress_dialog_exiting_ecm)
- .setPositiveButton(R.string.ok, clickListener)
- .setOnCancelListener(cancelListener)
- .create();
- mExitingECMDialog.getWindow().addFlags(
- WindowManager.LayoutParams.FLAG_BLUR_BEHIND);
- mExitingECMDialog.show();
- }
-
- private void bailOutAfterErrorDialog() {
- if (mGenericErrorDialog != null) {
- if (DBG) log("bailOutAfterErrorDialog: DISMISSING mGenericErrorDialog.");
- mGenericErrorDialog.dismiss();
- mGenericErrorDialog = null;
- }
- if (DBG) log("bailOutAfterErrorDialog(): end InCallScreen session...");
-
- // Now that the user has dismissed the error dialog (presumably by
- // either hitting the OK button or pressing Back, we can now reset
- // the pending call status code field.
- //
- // (Note that the pending call status is NOT cleared simply
- // by the InCallScreen being paused or finished, since the resulting
- // dialog is supposed to persist across orientation changes or if the
- // screen turns off.)
- //
- // See the "Error / diagnostic indications" section of
- // InCallUiState.java for more detailed info about the
- // pending call status code field.
- final InCallUiState inCallUiState = mApp.inCallUiState;
- inCallUiState.clearPendingCallStatusCode();
-
- // Force the InCallScreen to truly finish(), rather than just
- // moving it to the back of the activity stack (which is what
- // our finish() method usually does.)
- // This is necessary to avoid an obscure scenario where the
- // InCallScreen can get stuck in an inconsistent state, somehow
- // causing a *subsequent* outgoing call to fail (bug 4172599).
- endInCallScreenSession(true /* force a real finish() call */);
- }
-
- /**
- * Dismisses (and nulls out) all persistent Dialogs managed
- * by the InCallScreen. Useful if (a) we're about to bring up
- * a dialog and want to pre-empt any currently visible dialogs,
- * or (b) as a cleanup step when the Activity is going away.
- */
- private void dismissAllDialogs() {
- if (DBG) log("dismissAllDialogs()...");
-
- // Note it's safe to dismiss() a dialog that's already dismissed.
- // (Even if the AlertDialog object(s) below are still around, it's
- // possible that the actual dialog(s) may have already been
- // dismissed by the user.)
-
- if (mMissingVoicemailDialog != null) {
- if (VDBG) log("- DISMISSING mMissingVoicemailDialog.");
- mMissingVoicemailDialog.dismiss();
- mMissingVoicemailDialog = null;
- }
- if (mMmiStartedDialog != null) {
- if (VDBG) log("- DISMISSING mMmiStartedDialog.");
- mMmiStartedDialog.dismiss();
- mMmiStartedDialog = null;
- }
- if (mGenericErrorDialog != null) {
- if (VDBG) log("- DISMISSING mGenericErrorDialog.");
- mGenericErrorDialog.dismiss();
- mGenericErrorDialog = null;
- }
- if (mSuppServiceFailureDialog != null) {
- if (VDBG) log("- DISMISSING mSuppServiceFailureDialog.");
- mSuppServiceFailureDialog.dismiss();
- mSuppServiceFailureDialog = null;
- }
- if (mWaitPromptDialog != null) {
- if (VDBG) log("- DISMISSING mWaitPromptDialog.");
- mWaitPromptDialog.dismiss();
- mWaitPromptDialog = null;
- }
- if (mWildPromptDialog != null) {
- if (VDBG) log("- DISMISSING mWildPromptDialog.");
- mWildPromptDialog.dismiss();
- mWildPromptDialog = null;
- }
- if (mCallLostDialog != null) {
- if (VDBG) log("- DISMISSING mCallLostDialog.");
- mCallLostDialog.dismiss();
- mCallLostDialog = null;
- }
- if ((mApp.inCallUiState.inCallScreenMode == InCallScreenMode.OTA_NORMAL
- || mApp.inCallUiState.inCallScreenMode == InCallScreenMode.OTA_ENDED)
- && mApp.otaUtils != null) {
- mApp.otaUtils.dismissAllOtaDialogs();
- }
- if (mPausePromptDialog != null) {
- if (DBG) log("- DISMISSING mPausePromptDialog.");
- mPausePromptDialog.dismiss();
- mPausePromptDialog = null;
- }
- if (mExitingECMDialog != null) {
- if (DBG) log("- DISMISSING mExitingECMDialog.");
- mExitingECMDialog.dismiss();
- mExitingECMDialog = null;
- }
- }
-
- /**
- * Updates the state of the onscreen "progress indication" used in
- * some (relatively rare) scenarios where we need to wait for
- * something to happen before enabling the in-call UI.
- *
- * If necessary, this method will cause a ProgressDialog (i.e. a
- * spinning wait cursor) to be drawn *on top of* whatever the current
- * state of the in-call UI is.
- *
- * @see InCallUiState.ProgressIndicationType
- */
- private void updateProgressIndication() {
- // If an incoming call is ringing, that takes priority over any
- // possible value of inCallUiState.progressIndication.
- if (mCM.hasActiveRingingCall()) {
- dismissProgressIndication();
- return;
- }
-
- // Otherwise, put up a progress indication if indicated by the
- // inCallUiState.progressIndication field.
- final InCallUiState inCallUiState = mApp.inCallUiState;
- switch (inCallUiState.getProgressIndication()) {
- case NONE:
- // No progress indication necessary, so make sure it's dismissed.
- dismissProgressIndication();
- break;
-
- case TURNING_ON_RADIO:
- showProgressIndication(
- R.string.emergency_enable_radio_dialog_title,
- R.string.emergency_enable_radio_dialog_message);
- break;
-
- case RETRYING:
- showProgressIndication(
- R.string.emergency_enable_radio_dialog_title,
- R.string.emergency_enable_radio_dialog_retry);
- break;
-
- default:
- Log.wtf(LOG_TAG, "updateProgressIndication: unexpected value: "
- + inCallUiState.getProgressIndication());
- dismissProgressIndication();
- break;
- }
- }
-
- /**
- * Show an onscreen "progress indication" with the specified title and message.
- */
- private void showProgressIndication(int titleResId, int messageResId) {
- if (DBG) log("showProgressIndication(message " + messageResId + ")...");
-
- // TODO: make this be a no-op if the progress indication is
- // already visible with the exact same title and message.
-
- dismissProgressIndication(); // Clean up any prior progress indication
- mProgressDialog = new ProgressDialog(this);
- mProgressDialog.setTitle(getText(titleResId));
- mProgressDialog.setMessage(getText(messageResId));
- mProgressDialog.setIndeterminate(true);
- mProgressDialog.setCancelable(false);
- mProgressDialog.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_DIALOG);
- mProgressDialog.getWindow().addFlags(WindowManager.LayoutParams.FLAG_BLUR_BEHIND);
- mProgressDialog.show();
- }
-
- /**
- * Dismiss the onscreen "progress indication" (if present).
- */
- private void dismissProgressIndication() {
- if (DBG) log("dismissProgressIndication()...");
- if (mProgressDialog != null) {
- mProgressDialog.dismiss(); // safe even if already dismissed
- mProgressDialog = null;
- }
- }
-
-
- //
- // Helper functions for answering incoming calls.
- //
-
- /**
- * Answer a ringing call. This method does nothing if there's no
- * ringing or waiting call.
- */
- private void internalAnswerCall() {
- if (DBG) log("internalAnswerCall()...");
- // if (DBG) PhoneUtils.dumpCallState(mPhone);
-
- final boolean hasRingingCall = mCM.hasActiveRingingCall();
-
- if (hasRingingCall) {
- Phone phone = mCM.getRingingPhone();
- Call ringing = mCM.getFirstActiveRingingCall();
- int phoneType = phone.getPhoneType();
- if (phoneType == PhoneConstants.PHONE_TYPE_CDMA) {
- if (DBG) log("internalAnswerCall: answering (CDMA)...");
- if (mCM.hasActiveFgCall()
- && mCM.getFgPhone().getPhoneType() == PhoneConstants.PHONE_TYPE_SIP) {
- // The incoming call is CDMA call and the ongoing
- // call is a SIP call. The CDMA network does not
- // support holding an active call, so there's no
- // way to swap between a CDMA call and a SIP call.
- // So for now, we just don't allow a CDMA call and
- // a SIP call to be active at the same time.We'll
- // "answer incoming, end ongoing" in this case.
- if (DBG) log("internalAnswerCall: answer "
- + "CDMA incoming and end SIP ongoing");
- PhoneUtils.answerAndEndActive(mCM, ringing);
- } else {
- PhoneUtils.answerCall(ringing);
- }
- } else if (phoneType == PhoneConstants.PHONE_TYPE_SIP) {
- if (DBG) log("internalAnswerCall: answering (SIP)...");
- if (mCM.hasActiveFgCall()
- && mCM.getFgPhone().getPhoneType() == PhoneConstants.PHONE_TYPE_CDMA) {
- // Similar to the PHONE_TYPE_CDMA handling.
- // The incoming call is SIP call and the ongoing
- // call is a CDMA call. The CDMA network does not
- // support holding an active call, so there's no
- // way to swap between a CDMA call and a SIP call.
- // So for now, we just don't allow a CDMA call and
- // a SIP call to be active at the same time.We'll
- // "answer incoming, end ongoing" in this case.
- if (DBG) log("internalAnswerCall: answer "
- + "SIP incoming and end CDMA ongoing");
- PhoneUtils.answerAndEndActive(mCM, ringing);
- } else {
- PhoneUtils.answerCall(ringing);
- }
- } else if (phoneType == PhoneConstants.PHONE_TYPE_GSM) {
- if (DBG) log("internalAnswerCall: answering (GSM)...");
- // GSM: this is usually just a wrapper around
- // PhoneUtils.answerCall(), *but* we also need to do
- // something special for the "both lines in use" case.
-
- final boolean hasActiveCall = mCM.hasActiveFgCall();
- final boolean hasHoldingCall = mCM.hasActiveBgCall();
-
- if (hasActiveCall && hasHoldingCall) {
- if (DBG) log("internalAnswerCall: answering (both lines in use!)...");
- // The relatively rare case where both lines are
- // already in use. We "answer incoming, end ongoing"
- // in this case, according to the current UI spec.
- PhoneUtils.answerAndEndActive(mCM, ringing);
-
- // Alternatively, we could use
- // PhoneUtils.answerAndEndHolding(mPhone);
- // here to end the on-hold call instead.
- } else {
- if (DBG) log("internalAnswerCall: answering...");
- PhoneUtils.answerCall(ringing); // Automatically holds the current active call,
- // if there is one
- }
- } else {
- throw new IllegalStateException("Unexpected phone type: " + phoneType);
- }
-
- // Call origin is valid only with outgoing calls. Disable it on incoming calls.
- mApp.setLatestActiveCallOrigin(null);
- }
- }
-
- /**
- * Hang up the ringing call (aka "Don't answer").
- */
- /* package */ void hangupRingingCall() {
- if (DBG) log("hangupRingingCall()...");
- if (VDBG) PhoneUtils.dumpCallManager();
- // In the rare case when multiple calls are ringing, the UI policy
- // it to always act on the first ringing call.
- PhoneUtils.hangupRingingCall(mCM.getFirstActiveRingingCall());
- }
-
- /**
- * Silence the ringer (if an incoming call is ringing.)
- */
- private void internalSilenceRinger() {
- if (DBG) log("internalSilenceRinger()...");
- final CallNotifier notifier = mApp.notifier;
- if (notifier.isRinging()) {
- // ringer is actually playing, so silence it.
- notifier.silenceRinger();
- }
- }
-
- /**
- * Respond via SMS to the ringing call.
- * @see RespondViaSmsManager
- */
- private void internalRespondViaSms() {
- log("internalRespondViaSms()...");
- if (VDBG) PhoneUtils.dumpCallManager();
-
- // In the rare case when multiple calls are ringing, the UI policy
- // it to always act on the first ringing call.
- Call ringingCall = mCM.getFirstActiveRingingCall();
-
- // Silence the ringer, since it would be distracting while you're trying
- // to pick a response. (Note that we'll restart the ringer if you bail
- // out of the popup, though; see RespondViaSmsCancelListener.)
- internalSilenceRinger();
- }
-
- /**
- * Hang up the current active call.
- */
- private void internalHangup() {
- PhoneConstants.State state = mCM.getState();
- log("internalHangup()... phone state = " + state);
-
- // Regardless of the phone state, issue a hangup request.
- // (If the phone is already idle, this call will presumably have no
- // effect (but also see the note below.))
- PhoneUtils.hangup(mCM);
-
- // If the user just hung up the only active call, we'll eventually exit
- // the in-call UI after the following sequence:
- // - When the hangup() succeeds, we'll get a DISCONNECT event from
- // the telephony layer (see onDisconnect()).
- // - We immediately switch to the "Call ended" state (see the "delayed
- // bailout" code path in onDisconnect()) and also post a delayed
- // DELAYED_CLEANUP_AFTER_DISCONNECT message.
- // - When the DELAYED_CLEANUP_AFTER_DISCONNECT message comes in (see
- // delayedCleanupAfterDisconnect()) we do some final cleanup, and exit
- // this activity unless the phone is still in use (i.e. if there's
- // another call, or something else going on like an active MMI
- // sequence.)
-
- if (state == PhoneConstants.State.IDLE) {
- // The user asked us to hang up, but the phone was (already) idle!
- Log.w(LOG_TAG, "internalHangup(): phone is already IDLE!");
-
- // This is rare, but can happen in a few cases:
- // (a) If the user quickly double-taps the "End" button. In this case
- // we'll see that 2nd press event during the brief "Call ended"
- // state (where the phone is IDLE), or possibly even before the
- // radio has been able to respond to the initial hangup request.
- // (b) More rarely, this can happen if the user presses "End" at the
- // exact moment that the call ends on its own (like because of the
- // other person hanging up.)
- // (c) Finally, this could also happen if we somehow get stuck here on
- // the InCallScreen with the phone truly idle, perhaps due to a
- // bug where we somehow *didn't* exit when the phone became idle
- // in the first place.
-
- // TODO: as a "safety valve" for case (c), consider immediately
- // bailing out of the in-call UI right here. (The user can always
- // bail out by pressing Home, of course, but they'll probably try
- // pressing End first.)
- //
- // Log.i(LOG_TAG, "internalHangup(): phone is already IDLE! Bailing out...");
- // endInCallScreenSession();
- }
- }
-
- /**
- * InCallScreen-specific wrapper around PhoneUtils.switchHoldingAndActive().
- */
- private void internalSwapCalls() {
- if (DBG) log("internalSwapCalls()...");
-
- // Any time we swap calls, force the DTMF dialpad to close.
- // (We want the regular in-call UI to be visible right now, so the
- // user can clearly see which call is now in the foreground.)
- closeDialpadInternal(true); // do the "closing" animation
-
- // Also, clear out the "history" of DTMF digits you typed, to make
- // sure you don't see digits from call #1 while call #2 is active.
- // (Yes, this does mean that swapping calls twice will cause you
- // to lose any previous digits from the current call; see the TODO
- // comment on DTMFTwelvKeyDialer.clearDigits() for more info.)
- mDialer.clearDigits();
- }
-
- /**
- * Sets the current high-level "mode" of the in-call UI.
- *
- * NOTE: if newMode is CALL_ENDED, the caller is responsible for
- * posting a delayed DELAYED_CLEANUP_AFTER_DISCONNECT message, to make
- * sure the "call ended" state goes away after a couple of seconds.
- *
- * Note this method does NOT refresh of the onscreen UI; the caller is
- * responsible for calling updateScreen() or requestUpdateScreen() if
- * necessary.
- */
- private void setInCallScreenMode(InCallScreenMode newMode) {
- if (DBG) log("setInCallScreenMode: " + newMode);
- mApp.inCallUiState.inCallScreenMode = newMode;
-
- switch (newMode) {
- case MANAGE_CONFERENCE:
- if (!PhoneUtils.isConferenceCall(mCM.getActiveFgCall())) {
- Log.w(LOG_TAG, "MANAGE_CONFERENCE: no active conference call!");
- // Hide the Manage Conference panel, return to NORMAL mode.
- setInCallScreenMode(InCallScreenMode.NORMAL);
- return;
- }
- List<Connection> connections = mCM.getFgCallConnections();
- // There almost certainly will be > 1 connection,
- // since isConferenceCall() just returned true.
- if ((connections == null) || (connections.size() <= 1)) {
- Log.w(LOG_TAG,
- "MANAGE_CONFERENCE: Bogus TRUE from isConferenceCall(); connections = "
- + connections);
- // Hide the Manage Conference panel, return to NORMAL mode.
- setInCallScreenMode(InCallScreenMode.NORMAL);
- return;
- }
-
- // TODO: Don't do this here. The call to
- // initManageConferencePanel() should instead happen
- // automagically in ManageConferenceUtils the very first
- // time you call updateManageConferencePanel() or
- // setPanelVisible(true).
- mManageConferenceUtils.initManageConferencePanel(); // if necessary
-
- mManageConferenceUtils.updateManageConferencePanel(connections);
-
- // The "Manage conference" UI takes up the full main frame,
- // replacing the CallCard PopupWindow.
- mManageConferenceUtils.setPanelVisible(true);
-
- // Start the chronometer.
- // TODO: Similarly, we shouldn't expose startConferenceTime()
- // and stopConferenceTime(); the ManageConferenceUtils
- // class ought to manage the conferenceTime widget itself
- // based on setPanelVisible() calls.
-
- // Note: there is active Fg call since we are in conference call
- long callDuration =
- mCM.getActiveFgCall().getEarliestConnection().getDurationMillis();
- mManageConferenceUtils.startConferenceTime(
- SystemClock.elapsedRealtime() - callDuration);
-
- // No need to close the dialer here, since the Manage
- // Conference UI will just cover it up anyway.
-
- break;
-
- case CALL_ENDED:
- case NORMAL:
- mManageConferenceUtils.setPanelVisible(false);
- mManageConferenceUtils.stopConferenceTime();
- break;
-
- case OTA_NORMAL:
- mApp.otaUtils.setCdmaOtaInCallScreenUiState(
- OtaUtils.CdmaOtaInCallScreenUiState.State.NORMAL);
- break;
-
- case OTA_ENDED:
- mApp.otaUtils.setCdmaOtaInCallScreenUiState(
- OtaUtils.CdmaOtaInCallScreenUiState.State.ENDED);
- break;
-
- case UNDEFINED:
- // Set our Activities intent to ACTION_UNDEFINED so
- // that if we get resumed after we've completed a call
- // the next call will not cause checkIsOtaCall to
- // return true.
- //
- // TODO(OTASP): update these comments
- //
- // With the framework as of October 2009 the sequence below
- // causes the framework to call onResume, onPause, onNewIntent,
- // onResume. If we don't call setIntent below then when the
- // first onResume calls checkIsOtaCall via checkOtaspStateOnResume it will
- // return true and the Activity will be confused.
- //
- // 1) Power up Phone A
- // 2) Place *22899 call and activate Phone A
- // 3) Press the power key on Phone A to turn off the display
- // 4) Call Phone A from Phone B answering Phone A
- // 5) The screen will be blank (Should be normal InCallScreen)
- // 6) Hang up the Phone B
- // 7) Phone A displays the activation screen.
- //
- // Step 3 is the critical step to cause the onResume, onPause
- // onNewIntent, onResume sequence. If step 3 is skipped the
- // sequence will be onNewIntent, onResume and all will be well.
- setIntent(new Intent(ACTION_UNDEFINED));
-
- // Cleanup Ota Screen if necessary and set the panel
- // to VISIBLE.
- if (mCM.getState() != PhoneConstants.State.OFFHOOK) {
- if (mApp.otaUtils != null) {
- mApp.otaUtils.cleanOtaScreen(true);
- }
- } else {
- log("WARNING: Setting mode to UNDEFINED but phone is OFFHOOK,"
- + " skip cleanOtaScreen.");
- }
- break;
- }
- }
-
- /**
- * @return true if the "Manage conference" UI is currently visible.
- */
- /* package */ boolean isManageConferenceMode() {
- return (mApp.inCallUiState.inCallScreenMode == InCallScreenMode.MANAGE_CONFERENCE);
- }
-
- /**
- * Checks if the "Manage conference" UI needs to be updated.
- * If the state of the current conference call has changed
- * since our previous call to updateManageConferencePanel()),
- * do a fresh update. Also, if the current call is no longer a
- * conference call at all, bail out of the "Manage conference" UI and
- * return to InCallScreenMode.NORMAL mode.
- */
- private void updateManageConferencePanelIfNecessary() {
- if (VDBG) log("updateManageConferencePanelIfNecessary: " + mCM.getActiveFgCall() + "...");
-
- List<Connection> connections = mCM.getFgCallConnections();
- if (connections == null) {
- if (VDBG) log("==> no connections on foreground call!");
- // Hide the Manage Conference panel, return to NORMAL mode.
- setInCallScreenMode(InCallScreenMode.NORMAL);
- SyncWithPhoneStateStatus status = syncWithPhoneState();
- if (status != SyncWithPhoneStateStatus.SUCCESS) {
- Log.w(LOG_TAG, "- syncWithPhoneState failed! status = " + status);
- // We shouldn't even be in the in-call UI in the first
- // place, so bail out:
- if (DBG) log("updateManageConferencePanelIfNecessary: endInCallScreenSession... 1");
- endInCallScreenSession();
- return;
- }
- return;
- }
-
- int numConnections = connections.size();
- if (numConnections <= 1) {
- if (VDBG) log("==> foreground call no longer a conference!");
- // Hide the Manage Conference panel, return to NORMAL mode.
- setInCallScreenMode(InCallScreenMode.NORMAL);
- SyncWithPhoneStateStatus status = syncWithPhoneState();
- if (status != SyncWithPhoneStateStatus.SUCCESS) {
- Log.w(LOG_TAG, "- syncWithPhoneState failed! status = " + status);
- // We shouldn't even be in the in-call UI in the first
- // place, so bail out:
- if (DBG) log("updateManageConferencePanelIfNecessary: endInCallScreenSession... 2");
- endInCallScreenSession();
- return;
- }
- return;
- }
-
- // TODO: the test to see if numConnections has changed can go in
- // updateManageConferencePanel(), rather than here.
- if (numConnections != mManageConferenceUtils.getNumCallersInConference()) {
- if (VDBG) log("==> Conference size has changed; need to rebuild UI!");
- mManageConferenceUtils.updateManageConferencePanel(connections);
- }
- }
-
- /**
- * Updates {@link #mCallCard}'s visibility state per DTMF dialpad visibility. They
- * cannot be shown simultaneously and thus we should reflect DTMF dialpad visibility into
- * another.
- *
- * Note: During OTA calls or users' managing conference calls, we should *not* call this method
- * but manually manage both visibility.
- *
- * @see #updateScreen()
- */
- private void updateCallCardVisibilityPerDialerState(boolean animate) {
- // We need to hide the CallCard while the dialpad is visible.
- if (isDialerOpened()) {
- if (VDBG) {
- log("- updateCallCardVisibilityPerDialerState(animate="
- + animate + "): dialpad open, hide mCallCard...");
- }
- if (animate) {
- AnimationUtils.Fade.hide(mCallCard, View.GONE);
- } else {
- mCallCard.setVisibility(View.GONE);
- }
- } else {
- // Dialpad is dismissed; bring back the CallCard if it's supposed to be visible.
- if ((mApp.inCallUiState.inCallScreenMode == InCallScreenMode.NORMAL)
- || (mApp.inCallUiState.inCallScreenMode == InCallScreenMode.CALL_ENDED)) {
- if (VDBG) {
- log("- updateCallCardVisibilityPerDialerState(animate="
- + animate + "): dialpad dismissed, show mCallCard...");
- }
- if (animate) {
- AnimationUtils.Fade.show(mCallCard);
- } else {
- mCallCard.setVisibility(View.VISIBLE);
- }
- }
- }
- }
-
- /**
- * @see DTMFTwelveKeyDialer#isOpened()
- */
- /* package */ boolean isDialerOpened() {
- return (mDialer != null && mDialer.isOpened());
- }
-
- /**
- * Called any time the DTMF dialpad is opened.
- * @see DTMFTwelveKeyDialer#openDialer(boolean)
- */
- /* package */ void onDialerOpen(boolean animate) {
- if (DBG) log("onDialerOpen()...");
-
- // Update the in-call touch UI.
- updateInCallTouchUi();
-
- // Update CallCard UI, which depends on the dialpad.
- updateCallCardVisibilityPerDialerState(animate);
-
- // This counts as explicit "user activity".
- mApp.pokeUserActivity();
-
- //If on OTA Call, hide OTA Screen
- // TODO: This may not be necessary, now that the dialpad is
- // always visible in OTA mode.
- if ((mApp.inCallUiState.inCallScreenMode == InCallScreenMode.OTA_NORMAL
- || mApp.inCallUiState.inCallScreenMode == InCallScreenMode.OTA_ENDED)
- && mApp.otaUtils != null) {
- mApp.otaUtils.hideOtaScreen();
- }
- }
-
- /**
- * Called any time the DTMF dialpad is closed.
- * @see DTMFTwelveKeyDialer#closeDialer(boolean)
- */
- /* package */ void onDialerClose(boolean animate) {
- if (DBG) log("onDialerClose()...");
-
- // OTA-specific cleanup upon closing the dialpad.
- if ((mApp.inCallUiState.inCallScreenMode == InCallScreenMode.OTA_NORMAL)
- || (mApp.inCallUiState.inCallScreenMode == InCallScreenMode.OTA_ENDED)
- || ((mApp.cdmaOtaScreenState != null)
- && (mApp.cdmaOtaScreenState.otaScreenState ==
- CdmaOtaScreenState.OtaScreenState.OTA_STATUS_ACTIVATION))) {
- if (mApp.otaUtils != null) {
- mApp.otaUtils.otaShowProperScreen();
- }
- }
-
- // Update the in-call touch UI.
- updateInCallTouchUi();
-
- // Update CallCard UI, which depends on the dialpad.
- updateCallCardVisibilityPerDialerState(animate);
-
- // This counts as explicit "user activity".
- mApp.pokeUserActivity();
- }
-
- /**
- * Determines when we can dial DTMF tones.
- */
- /* package */ boolean okToDialDTMFTones() {
- final boolean hasRingingCall = mCM.hasActiveRingingCall();
- final Call.State fgCallState = mCM.getActiveFgCallState();
-
- // We're allowed to send DTMF tones when there's an ACTIVE
- // foreground call, and not when an incoming call is ringing
- // (since DTMF tones are useless in that state), or if the
- // Manage Conference UI is visible (since the tab interferes
- // with the "Back to call" button.)
-
- // We can also dial while in ALERTING state because there are
- // some connections that never update to an ACTIVE state (no
- // indication from the network).
- boolean canDial =
- (fgCallState == Call.State.ACTIVE || fgCallState == Call.State.ALERTING)
- && !hasRingingCall
- && (mApp.inCallUiState.inCallScreenMode != InCallScreenMode.MANAGE_CONFERENCE);
-
- if (VDBG) log ("[okToDialDTMFTones] foreground state: " + fgCallState +
- ", ringing state: " + hasRingingCall +
- ", call screen mode: " + mApp.inCallUiState.inCallScreenMode +
- ", result: " + canDial);
-
- return canDial;
- }
-
- /**
- * @return true if the in-call DTMF dialpad should be available to the
- * user, given the current state of the phone and the in-call UI.
- * (This is used to control the enabledness of the "Show
- * dialpad" onscreen button; see InCallControlState.dialpadEnabled.)
- */
- /* package */ boolean okToShowDialpad() {
- // Very similar to okToDialDTMFTones(), but allow DIALING here.
- final Call.State fgCallState = mCM.getActiveFgCallState();
- return okToDialDTMFTones() || (fgCallState == Call.State.DIALING);
- }
-
- /**
- * Initializes the in-call touch UI on devices that need it.
- */
- private void initInCallTouchUi() {
- if (DBG) log("initInCallTouchUi()...");
- // TODO: we currently use the InCallTouchUi widget in at least
- // some states on ALL platforms. But if some devices ultimately
- // end up not using *any* onscreen touch UI, we should make sure
- // to not even inflate the InCallTouchUi widget on those devices.
- mInCallTouchUi = (InCallTouchUi) findViewById(R.id.inCallTouchUi);
- mInCallTouchUi.setInCallScreenInstance(this);
-
- // RespondViaSmsManager implements the "Respond via SMS"
- // feature that's triggered from the incoming call widget.
- mRespondViaSmsManager = new RespondViaSmsManager();
- mRespondViaSmsManager.setInCallScreenInstance(this);
- }
-
- /**
- * Updates the state of the in-call touch UI.
- */
- private void updateInCallTouchUi() {
- if (mInCallTouchUi != null) {
- mInCallTouchUi.updateState(mCM);
- }
- }
-
- /**
- * @return the InCallTouchUi widget
- */
- /* package */ InCallTouchUi getInCallTouchUi() {
- return mInCallTouchUi;
- }
-
- /**
- * Posts a handler message telling the InCallScreen to refresh the
- * onscreen in-call UI.
- *
- * This is just a wrapper around updateScreen(), for use by the
- * rest of the phone app or from a thread other than the UI thread.
- *
- * updateScreen() is a no-op if the InCallScreen is not the foreground
- * activity, so it's safe to call this whether or not the InCallScreen
- * is currently visible.
- */
- /* package */ void requestUpdateScreen() {
- if (DBG) log("requestUpdateScreen()...");
- mHandler.removeMessages(REQUEST_UPDATE_SCREEN);
- mHandler.sendEmptyMessage(REQUEST_UPDATE_SCREEN);
- }
-
- /**
- * @return true if we're in restricted / emergency dialing only mode.
- */
- public boolean isPhoneStateRestricted() {
- // TODO: This needs to work IN TANDEM with the KeyGuardViewMediator Code.
- // Right now, it looks like the mInputRestricted flag is INTERNAL to the
- // KeyGuardViewMediator and SPECIFICALLY set to be FALSE while the emergency
- // phone call is being made, to allow for input into the InCallScreen.
- // Having the InCallScreen judge the state of the device from this flag
- // becomes meaningless since it is always false for us. The mediator should
- // have an additional API to let this app know that it should be restricted.
- int serviceState = mCM.getServiceState();
- return ((serviceState == ServiceState.STATE_EMERGENCY_ONLY) ||
- (serviceState == ServiceState.STATE_OUT_OF_SERVICE) ||
- (mApp.getKeyguardManager().inKeyguardRestrictedInputMode()));
- }
-
- /**
- * Posts a handler message telling the InCallScreen to close
- * the OTA failure notice after the specified delay.
- * @see OtaUtils.otaShowProgramFailureNotice
- */
- /* package */ void requestCloseOtaFailureNotice(long timeout) {
- if (DBG) log("requestCloseOtaFailureNotice() with timeout: " + timeout);
- mHandler.sendEmptyMessageDelayed(REQUEST_CLOSE_OTA_FAILURE_NOTICE, timeout);
-
- // TODO: we probably ought to call removeMessages() for this
- // message code in either onPause or onResume, just to be 100%
- // sure that the message we just posted has no way to affect a
- // *different* call if the user quickly backs out and restarts.
- // (This is also true for requestCloseSpcErrorNotice() below, and
- // probably anywhere else we use mHandler.sendEmptyMessageDelayed().)
- }
-
- /**
- * Posts a handler message telling the InCallScreen to close
- * the SPC error notice after the specified delay.
- * @see OtaUtils.otaShowSpcErrorNotice
- */
- /* package */ void requestCloseSpcErrorNotice(long timeout) {
- if (DBG) log("requestCloseSpcErrorNotice() with timeout: " + timeout);
- mHandler.sendEmptyMessageDelayed(REQUEST_CLOSE_SPC_ERROR_NOTICE, timeout);
- }
-
- public boolean isOtaCallInActiveState() {
- if ((mApp.inCallUiState.inCallScreenMode == InCallScreenMode.OTA_NORMAL)
- || ((mApp.cdmaOtaScreenState != null)
- && (mApp.cdmaOtaScreenState.otaScreenState ==
- CdmaOtaScreenState.OtaScreenState.OTA_STATUS_ACTIVATION))) {
- return true;
- } else {
- return false;
- }
- }
-
- /**
- * Handle OTA Call End scenario when display becomes dark during OTA Call
- * and InCallScreen is in pause mode. CallNotifier will listen for call
- * end indication and call this api to handle OTA Call end scenario
- */
- public void handleOtaCallEnd() {
- if (DBG) log("handleOtaCallEnd entering");
- if (((mApp.inCallUiState.inCallScreenMode == InCallScreenMode.OTA_NORMAL)
- || ((mApp.cdmaOtaScreenState != null)
- && (mApp.cdmaOtaScreenState.otaScreenState !=
- CdmaOtaScreenState.OtaScreenState.OTA_STATUS_UNDEFINED)))
- && ((mApp.cdmaOtaProvisionData != null)
- && (!mApp.cdmaOtaProvisionData.inOtaSpcState))) {
- if (DBG) log("handleOtaCallEnd - Set OTA Call End stater");
- setInCallScreenMode(InCallScreenMode.OTA_ENDED);
- updateScreen();
- }
- }
-
- public boolean isOtaCallInEndState() {
- return (mApp.inCallUiState.inCallScreenMode == InCallScreenMode.OTA_ENDED);
- }
-
-
- /**
- * Upon resuming the in-call UI, check to see if an OTASP call is in
- * progress, and if so enable the special OTASP-specific UI.
- *
- * TODO: have a simple single flag in InCallUiState for this rather than
- * needing to know about all those mApp.cdma*State objects.
- *
- * @return true if any OTASP-related UI is active
- */
- private boolean checkOtaspStateOnResume() {
- // If there's no OtaUtils instance, that means we haven't even tried
- // to start an OTASP call (yet), so there's definitely nothing to do here.
- if (mApp.otaUtils == null) {
- if (DBG) log("checkOtaspStateOnResume: no OtaUtils instance; nothing to do.");
- return false;
- }
-
- if ((mApp.cdmaOtaScreenState == null) || (mApp.cdmaOtaProvisionData == null)) {
- // Uh oh -- something wrong with our internal OTASP state.
- // (Since this is an OTASP-capable device, these objects
- // *should* have already been created by PhoneApp.onCreate().)
- throw new IllegalStateException("checkOtaspStateOnResume: "
- + "app.cdmaOta* objects(s) not initialized");
- }
-
- // The PhoneApp.cdmaOtaInCallScreenUiState instance is the
- // authoritative source saying whether or not the in-call UI should
- // show its OTASP-related UI.
-
- OtaUtils.CdmaOtaInCallScreenUiState.State cdmaOtaInCallScreenState =
- mApp.otaUtils.getCdmaOtaInCallScreenUiState();
- // These states are:
- // - UNDEFINED: no OTASP-related UI is visible
- // - NORMAL: OTASP call in progress, so show in-progress OTASP UI
- // - ENDED: OTASP call just ended, so show success/failure indication
-
- boolean otaspUiActive =
- (cdmaOtaInCallScreenState == OtaUtils.CdmaOtaInCallScreenUiState.State.NORMAL)
- || (cdmaOtaInCallScreenState == OtaUtils.CdmaOtaInCallScreenUiState.State.ENDED);
-
- if (otaspUiActive) {
- // Make sure the OtaUtils instance knows about the InCallScreen's
- // OTASP-related UI widgets.
- //
- // (This call has no effect if the UI widgets have already been set up.
- // It only really matters the very first time that the InCallScreen instance
- // is onResume()d after starting an OTASP call.)
- mApp.otaUtils.updateUiWidgets(this, mInCallTouchUi, mCallCard);
-
- // Also update the InCallScreenMode based on the cdmaOtaInCallScreenState.
-
- if (cdmaOtaInCallScreenState == OtaUtils.CdmaOtaInCallScreenUiState.State.NORMAL) {
- if (DBG) log("checkOtaspStateOnResume - in OTA Normal mode");
- setInCallScreenMode(InCallScreenMode.OTA_NORMAL);
- } else if (cdmaOtaInCallScreenState ==
- OtaUtils.CdmaOtaInCallScreenUiState.State.ENDED) {
- if (DBG) log("checkOtaspStateOnResume - in OTA END mode");
- setInCallScreenMode(InCallScreenMode.OTA_ENDED);
- }
-
- // TODO(OTASP): we might also need to go into OTA_ENDED mode
- // in one extra case:
- //
- // else if (mApp.cdmaOtaScreenState.otaScreenState ==
- // CdmaOtaScreenState.OtaScreenState.OTA_STATUS_SUCCESS_FAILURE_DLG) {
- // if (DBG) log("checkOtaspStateOnResume - set OTA END Mode");
- // setInCallScreenMode(InCallScreenMode.OTA_ENDED);
- // }
-
- } else {
- // OTASP is not active; reset to regular in-call UI.
-
- if (DBG) log("checkOtaspStateOnResume - Set OTA NORMAL Mode");
- setInCallScreenMode(InCallScreenMode.OTA_NORMAL);
-
- if (mApp.otaUtils != null) {
- mApp.otaUtils.cleanOtaScreen(false);
- }
- }
-
- // TODO(OTASP):
- // The original check from checkIsOtaCall() when handling ACTION_MAIN was this:
- //
- // [ . . . ]
- // else if (action.equals(intent.ACTION_MAIN)) {
- // if (DBG) log("checkIsOtaCall action ACTION_MAIN");
- // boolean isRingingCall = mCM.hasActiveRingingCall();
- // if (isRingingCall) {
- // if (DBG) log("checkIsOtaCall isRingingCall: " + isRingingCall);
- // return false;
- // } else if ((mApp.cdmaOtaInCallScreenUiState.state
- // == CdmaOtaInCallScreenUiState.State.NORMAL)
- // || (mApp.cdmaOtaInCallScreenUiState.state
- // == CdmaOtaInCallScreenUiState.State.ENDED)) {
- // if (DBG) log("action ACTION_MAIN, OTA call already in progress");
- // isOtaCall = true;
- // } else {
- // if (mApp.cdmaOtaScreenState.otaScreenState !=
- // CdmaOtaScreenState.OtaScreenState.OTA_STATUS_UNDEFINED) {
- // if (DBG) log("checkIsOtaCall action ACTION_MAIN, "
- // + "OTA call in progress with UNDEFINED");
- // isOtaCall = true;
- // }
- // }
- // }
- //
- // Also, in internalResolveIntent() we used to do this:
- //
- // if ((mApp.inCallUiState.inCallScreenMode == InCallScreenMode.OTA_NORMAL)
- // || (mApp.inCallUiState.inCallScreenMode == InCallScreenMode.OTA_ENDED)) {
- // // If in OTA Call, update the OTA UI
- // updateScreen();
- // return;
- // }
- //
- // We still need more cleanup to simplify the mApp.cdma*State objects.
-
- return otaspUiActive;
- }
-
- /**
- * Updates and returns the InCallControlState instance.
- */
- public InCallControlState getUpdatedInCallControlState() {
- if (VDBG) log("getUpdatedInCallControlState()...");
- mInCallControlState.update();
- return mInCallControlState;
- }
-
- public void resetInCallScreenMode() {
- if (DBG) log("resetInCallScreenMode: setting mode to UNDEFINED...");
- setInCallScreenMode(InCallScreenMode.UNDEFINED);
- }
-
- /**
- * Updates the onscreen hint displayed while the user is dragging one
- * of the handles of the RotarySelector widget used for incoming
- * calls.
- *
- * @param hintTextResId resource ID of the hint text to display,
- * or 0 if no hint should be visible.
- * @param hintColorResId resource ID for the color of the hint text
- */
- /* package */ void updateIncomingCallWidgetHint(int hintTextResId, int hintColorResId) {
- if (VDBG) log("updateIncomingCallWidgetHint(" + hintTextResId + ")...");
- if (mCallCard != null) {
- mCallCard.setIncomingCallWidgetHint(hintTextResId, hintColorResId);
- mCallCard.updateState(mCM);
- // TODO: if hintTextResId == 0, consider NOT clearing the onscreen
- // hint right away, but instead post a delayed handler message to
- // keep it onscreen for an extra second or two. (This might make
- // the hint more helpful if the user quickly taps one of the
- // handles without dragging at all...)
- // (Or, maybe this should happen completely within the RotarySelector
- // widget, since the widget itself probably wants to keep the colored
- // arrow visible for some extra time also...)
- }
- }
-
-
- /**
- * Used when we need to update buttons outside InCallTouchUi's updateInCallControls() along
- * with that method being called. CallCard may call this too because it doesn't have
- * enough information to update buttons inside itself (more specifically, the class cannot
- * obtain mInCallControllState without some side effect. See also
- * {@link #getUpdatedInCallControlState()}. We probably don't want a method like
- * getRawCallControlState() which returns raw intance with no side effect just for this
- * corner case scenario)
- *
- * TODO: need better design for buttons outside InCallTouchUi.
- */
- /* package */ void updateButtonStateOutsideInCallTouchUi() {
- if (mCallCard != null) {
- mCallCard.setSecondaryCallClickable(mInCallControlState.canSwap);
- }
- }
-
- @Override
- public boolean dispatchPopulateAccessibilityEvent(AccessibilityEvent event) {
- super.dispatchPopulateAccessibilityEvent(event);
- mCallCard.dispatchPopulateAccessibilityEvent(event);
- return true;
- }
-
- /**
- * Manually handle configuration changes.
- *
- * 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) {
- if (DBG) log("onConfigurationChanged: newConfig = " + newConfig);
-
- // Note: At the time this function is called, our Resources object
- // will have already been updated to return resource values matching
- // the new configuration.
-
- // Watch out: we *can* still get destroyed and recreated if a
- // configuration change occurs that is *not* listed in the
- // android:configChanges attribute. TODO: Any others we need to list?
-
- super.onConfigurationChanged(newConfig);
-
- // Nothing else to do here, since (currently) the InCallScreen looks
- // exactly the same regardless of configuration.
- // (Specifically, we'll never be in landscape mode because we set
- // android:screenOrientation="portrait" in our manifest, and we don't
- // change our UI at all based on newConfig.keyboardHidden or
- // newConfig.uiMode.)
-
- // TODO: we do eventually want to handle at least some config changes, such as:
- boolean isKeyboardOpen = (newConfig.keyboardHidden == Configuration.KEYBOARDHIDDEN_NO);
- if (DBG) log(" - isKeyboardOpen = " + isKeyboardOpen);
- boolean isLandscape = (newConfig.orientation == Configuration.ORIENTATION_LANDSCAPE);
- if (DBG) log(" - isLandscape = " + isLandscape);
- if (DBG) log(" - uiMode = " + newConfig.uiMode);
- // See bug 2089513.
- }
-
- /**
- * Handles an incoming RING event from the telephony layer.
- */
- private void onIncomingRing() {
- if (DBG) log("onIncomingRing()...");
- // IFF we're visible, forward this event to the InCallTouchUi
- // instance (which uses this event to drive the animation of the
- // incoming-call UI.)
- if (mIsForegroundActivity && (mInCallTouchUi != null)) {
- mInCallTouchUi.onIncomingRing();
- }
- }
-
- /**
- * Handles a "new ringing connection" event from the telephony layer.
- *
- * This event comes in right at the start of the incoming-call sequence,
- * exactly once per incoming call.
- *
- * Watch out: this won't be called if InCallScreen isn't ready yet,
- * which typically happens for the first incoming phone call (even before
- * the possible first outgoing call).
- */
- private void onNewRingingConnection() {
- if (DBG) log("onNewRingingConnection()...");
-
- // We use this event to reset any incoming-call-related UI elements
- // that might have been left in an inconsistent state after a prior
- // incoming call.
- // (Note we do this whether or not we're the foreground activity,
- // since this event comes in *before* we actually get launched to
- // display the incoming-call UI.)
-
- // If there's a "Respond via SMS" popup still around since the
- // last time we were the foreground activity, make sure it's not
- // still active(!) since that would interfere with *this* incoming
- // call.
- // (Note that we also do this same check in onResume(). But we
- // need it here too, to make sure the popup gets reset in the case
- // where a call-waiting call comes in while the InCallScreen is
- // already in the foreground.)
- mRespondViaSmsManager.dismissPopup(); // safe even if already dismissed
- }
-
- /**
- * Enables or disables the status bar "window shade" based on the current situation.
- */
- private void updateExpandedViewState() {
- if (mIsForegroundActivity) {
- // We should not enable notification's expanded view on RINGING state.
- mApp.notificationMgr.statusBarHelper.enableExpandedView(
- mCM.getState() != PhoneConstants.State.RINGING);
- } else {
- mApp.notificationMgr.statusBarHelper.enableExpandedView(true);
- }
- }
-
- private void log(String msg) {
- Log.d(LOG_TAG, msg);
- }
-
- /**
- * Requests to remove provider info frame after having
- * {@link #PROVIDER_INFO_TIMEOUT}) msec delay.
- */
- /* package */ void requestRemoveProviderInfoWithDelay() {
- // Remove any zombie messages and then send a message to
- // self to remove the provider info after some time.
- mHandler.removeMessages(EVENT_HIDE_PROVIDER_INFO);
- Message msg = Message.obtain(mHandler, EVENT_HIDE_PROVIDER_INFO);
- mHandler.sendMessageDelayed(msg, PROVIDER_INFO_TIMEOUT);
- if (DBG) {
- 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 15abb11..fd202db 100644
--- a/src/com/android/phone/InCallScreenShowActivation.java
+++ b/src/com/android/phone/InCallScreenShowActivation.java
@@ -18,9 +18,13 @@
import android.app.Activity;
import android.app.PendingIntent;
+import android.content.Context;
import android.content.Intent;
+import android.content.pm.PackageManager;
+import android.content.pm.ResolveInfo;
import android.os.Bundle;
import android.os.SystemProperties;
+import android.provider.Settings;
import android.util.Log;
import com.android.internal.telephony.Phone;
@@ -78,7 +82,7 @@
// On voice-capable devices, we perform CDMA provisioning in
// "interactive" mode by directly launching the InCallScreen.
// boolean interactiveMode = PhoneGlobals.sVoiceCapable;
- // TODO(klp): Renable interactive mode for device provisioning.
+ // TODO: Renable interactive mode for device provisioning.
boolean interactiveMode = false;
Log.d(LOG_TAG, "ACTION_PERFORM_CDMA_PROVISIONING (interactiveMode = "
+ interactiveMode + ")...");
@@ -146,20 +150,58 @@
finish();
}
+ /**
+ * On devices that provide a phone initialization wizard (such as Google Setup Wizard),
+ * the wizard displays it's own activation UI. The Hfa activation started by this class
+ * will show a UI or not depending on the status of the setup wizard. If the setup wizard
+ * is running, do not show a UI, otherwise show our own UI since setup wizard will not.
+ *
+ * The method checks two properties:
+ * 1. Does the device require a setup wizard (ro.setupwizard.mode == (REQUIRED|OPTIONAL))
+ * 2. Is device_provisioned set to non-zero--a property that setup wizard sets at completion.
+ * @return true if wizard is running, false otherwise.
+ */
+ private boolean isWizardRunning(Context context) {
+ Intent intent = new Intent("android.intent.action.DEVICE_INITIALIZATION_WIZARD");
+ ResolveInfo resolveInfo = context.getPackageManager().resolveActivity(intent,
+ PackageManager.MATCH_DEFAULT_ONLY);
+ 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) {
+ Log.v(LOG_TAG, "resolvInfo = " + resolveInfo + ", provisioned = " + provisioned
+ + ", runningSetupWizard = " + runningSetupWizard);
+ }
+ return resolveInfo != null && !provisioned && runningSetupWizard;
+ }
/**
* Starts the HFA provisioning process by bringing up the HFA Activity.
*/
private void startHfa() {
- final Intent intent = new Intent(this, HfaActivity.class);
+ final Intent intent = new Intent();
final PendingIntent otaResponseIntent = getIntent().getParcelableExtra(
OtaUtils.EXTRA_OTASP_RESULT_CODE_PENDING_INTENT);
- intent.putExtra(OtaUtils.EXTRA_OTASP_RESULT_CODE_PENDING_INTENT, otaResponseIntent);
- intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
+ final boolean showUi = !isWizardRunning(this);
+
+ intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+
+ if (otaResponseIntent != null) {
+ intent.putExtra(OtaUtils.EXTRA_OTASP_RESULT_CODE_PENDING_INTENT, otaResponseIntent);
+ }
Log.v(LOG_TAG, "Starting hfa activation activity");
- startActivity(intent);
+ if (showUi) {
+ intent.setClassName(this, HfaActivity.class.getName());
+ startActivity(intent);
+ } else {
+ intent.setClassName(this, HfaService.class.getName());
+ startService(intent);
+ }
+
+ setResult(RESULT_OK);
}
}
diff --git a/src/com/android/phone/InCallTouchUi.java b/src/com/android/phone/InCallTouchUi.java
deleted file mode 100644
index 1d08671..0000000
--- a/src/com/android/phone/InCallTouchUi.java
+++ /dev/null
@@ -1,1338 +0,0 @@
-/*
- * Copyright (C) 2009 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.phone;
-
-import android.animation.Animator;
-import android.animation.AnimatorListenerAdapter;
-import android.content.Context;
-import android.graphics.drawable.LayerDrawable;
-import android.os.Handler;
-import android.os.Message;
-import android.os.SystemClock;
-import android.text.TextUtils;
-import android.util.AttributeSet;
-import android.util.Log;
-import android.view.Gravity;
-import android.view.Menu;
-import android.view.MenuItem;
-import android.view.View;
-import android.view.ViewGroup;
-import android.view.ViewPropertyAnimator;
-import android.view.ViewStub;
-import android.widget.CompoundButton;
-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;
-import com.android.internal.telephony.CallManager;
-import com.android.internal.telephony.PhoneConstants;
-import com.android.internal.widget.multiwaveview.GlowPadView;
-import com.android.internal.widget.multiwaveview.GlowPadView.OnTriggerListener;
-import com.android.phone.InCallUiState.InCallScreenMode;
-
-/**
- * In-call onscreen touch UI elements, used on some platforms.
- *
- * This widget is a fullscreen overlay, drawn on top of the
- * non-touch-sensitive parts of the in-call UI (i.e. the call card).
- */
-public class InCallTouchUi extends FrameLayout
- implements View.OnClickListener, View.OnLongClickListener, OnTriggerListener,
- PopupMenu.OnMenuItemClickListener, PopupMenu.OnDismissListener {
- private static final String LOG_TAG = "InCallTouchUi";
- private static final boolean DBG = (PhoneGlobals.DBG_LEVEL >= 2);
-
- // Incoming call widget targets
- private static final int ANSWER_CALL_ID = 0; // drag right
- private static final int SEND_SMS_ID = 1; // drag up
- private static final int DECLINE_CALL_ID = 2; // drag left
-
- /**
- * Reference to the InCallScreen activity that owns us. This may be
- * null if we haven't been initialized yet *or* after the InCallScreen
- * activity has been destroyed.
- */
- private InCallScreen mInCallScreen;
-
- // Phone app instance
- private PhoneGlobals mApp;
-
- // UI containers / elements
- private GlowPadView mIncomingCallWidget; // UI used for an incoming call
- private boolean mIncomingCallWidgetIsFadingOut;
- private boolean mIncomingCallWidgetShouldBeReset = true;
-
- /** UI elements while on a regular call (bottom buttons, DTMF dialpad) */
- private View mInCallControls;
- private boolean mShowInCallControlsDuringHidingAnimation;
-
- //
- private ImageButton mAddButton;
- private ImageButton mMergeButton;
- private ImageButton mEndButton;
- private CompoundButton mDialpadButton;
- private CompoundButton mMuteButton;
- private CompoundButton mAudioButton;
- private CompoundButton mHoldButton;
- private ImageButton mSwapButton;
- private View mHoldSwapSpacer;
- private View mVideoSpacer;
- private ImageButton mVideoButton;
-
- // "Extra button row"
- private ViewStub mExtraButtonRow;
- private ViewGroup mCdmaMergeButton;
- private ViewGroup mManageConferenceButton;
- private ImageButton mManageConferenceButtonImage;
-
- // "Audio mode" PopupMenu
- private PopupMenu mAudioModePopup;
- private boolean mAudioModePopupVisible = false;
-
- // Time of the most recent "answer" or "reject" action (see updateState())
- private long mLastIncomingCallActionTime; // in SystemClock.uptimeMillis() time base
-
- // Parameters for the GlowPadView "ping" animation; see triggerPing().
- private static final boolean ENABLE_PING_ON_RING_EVENTS = false;
- private static final boolean ENABLE_PING_AUTO_REPEAT = true;
- private static final long PING_AUTO_REPEAT_DELAY_MSEC = 1200;
-
- private static final int INCOMING_CALL_WIDGET_PING = 101;
- private Handler mHandler = new Handler() {
- @Override
- public void handleMessage(Message msg) {
- // If the InCallScreen activity isn't around any more,
- // there's no point doing anything here.
- if (mInCallScreen == null) return;
-
- switch (msg.what) {
- case INCOMING_CALL_WIDGET_PING:
- if (DBG) log("INCOMING_CALL_WIDGET_PING...");
- triggerPing();
- break;
- default:
- Log.wtf(LOG_TAG, "mHandler: unexpected message: " + msg);
- break;
- }
- }
- };
-
- public InCallTouchUi(Context context, AttributeSet attrs) {
- super(context, attrs);
-
- if (DBG) log("InCallTouchUi constructor...");
- if (DBG) log("- this = " + this);
- if (DBG) log("- context " + context + ", attrs " + attrs);
- mApp = PhoneGlobals.getInstance();
- }
-
- void setInCallScreenInstance(InCallScreen inCallScreen) {
- mInCallScreen = inCallScreen;
- }
-
- @Override
- protected void onFinishInflate() {
- super.onFinishInflate();
- if (DBG) log("InCallTouchUi onFinishInflate(this = " + this + ")...");
-
- // Look up the various UI elements.
-
- // "Drag-to-answer" widget for incoming calls.
- mIncomingCallWidget = (GlowPadView) findViewById(R.id.incomingCallWidget);
- mIncomingCallWidget.setOnTriggerListener(this);
-
- // Container for the UI elements shown while on a regular call.
- mInCallControls = findViewById(R.id.inCallControls);
-
- // Regular (single-tap) buttons, where we listen for click events:
- // Main cluster of buttons:
- mAddButton = (ImageButton) mInCallControls.findViewById(R.id.addButton);
- mAddButton.setOnClickListener(this);
- mAddButton.setOnLongClickListener(this);
- mMergeButton = (ImageButton) mInCallControls.findViewById(R.id.mergeButton);
- mMergeButton.setOnClickListener(this);
- mMergeButton.setOnLongClickListener(this);
- mEndButton = (ImageButton) mInCallControls.findViewById(R.id.endButton);
- mEndButton.setOnClickListener(this);
- mDialpadButton = (CompoundButton) mInCallControls.findViewById(R.id.dialpadButton);
- mDialpadButton.setOnClickListener(this);
- mDialpadButton.setOnLongClickListener(this);
- mMuteButton = (CompoundButton) mInCallControls.findViewById(R.id.muteButton);
- mMuteButton.setOnClickListener(this);
- mMuteButton.setOnLongClickListener(this);
- mAudioButton = (CompoundButton) mInCallControls.findViewById(R.id.audioButton);
- mAudioButton.setOnClickListener(this);
- mAudioButton.setOnLongClickListener(this);
- mHoldButton = (CompoundButton) mInCallControls.findViewById(R.id.holdButton);
- mHoldButton.setOnClickListener(this);
- mHoldButton.setOnLongClickListener(this);
- mSwapButton = (ImageButton) mInCallControls.findViewById(R.id.swapButton);
- mSwapButton.setOnClickListener(this);
- mSwapButton.setOnLongClickListener(this);
- mHoldSwapSpacer = mInCallControls.findViewById(R.id.holdSwapSpacer);
- mVideoButton = (ImageButton) mInCallControls.findViewById(R.id.videoCallButton);
- mVideoButton.setOnClickListener(this);
- mVideoButton.setOnLongClickListener(this);
- mVideoSpacer = mInCallControls.findViewById(R.id.videoCallSpacer);
-
- // TODO: Back when these buttons had text labels, we changed
- // the label of mSwapButton for CDMA as follows:
- //
- // if (PhoneApp.getPhone().getPhoneType() == PhoneConstants.PHONE_TYPE_CDMA) {
- // // In CDMA we use a generalized text - "Manage call", as behavior on selecting
- // // this option depends entirely on what the current call state is.
- // mSwapButtonLabel.setText(R.string.onscreenManageCallsText);
- // } else {
- // mSwapButtonLabel.setText(R.string.onscreenSwapCallsText);
- // }
- //
- // If this is still needed, consider having a special icon for this
- // button in CDMA.
-
- // Buttons shown on the "extra button row", only visible in certain (rare) states.
- mExtraButtonRow = (ViewStub) mInCallControls.findViewById(R.id.extraButtonRow);
-
- // 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) {
- log("- updateState: mInCallScreen has been destroyed; bailing out...");
- return;
- }
-
- PhoneConstants.State state = cm.getState(); // IDLE, RINGING, or OFFHOOK
- if (DBG) log("updateState: current state = " + state);
-
- boolean showIncomingCallControls = false;
- boolean showInCallControls = false;
-
- final Call ringingCall = cm.getFirstActiveRingingCall();
- final Call.State fgCallState = cm.getActiveFgCallState();
-
- // If the FG call is dialing/alerting, we should display for that call
- // and ignore the ringing call. This case happens when the telephony
- // layer rejects the ringing call while the FG call is dialing/alerting,
- // but the incoming call *does* briefly exist in the DISCONNECTING or
- // DISCONNECTED state.
- if ((ringingCall.getState() != Call.State.IDLE) && !fgCallState.isDialing()) {
- // A phone call is ringing *or* call waiting.
-
- // Watch out: even if the phone state is RINGING, it's
- // possible for the ringing call to be in the DISCONNECTING
- // state. (This typically happens immediately after the user
- // rejects an incoming call, and in that case we *don't* show
- // the incoming call controls.)
- if (ringingCall.getState().isAlive()) {
- if (DBG) log("- updateState: RINGING! Showing incoming call controls...");
- showIncomingCallControls = true;
- }
-
- // Ugly hack to cover up slow response from the radio:
- // if we get an updateState() call immediately after answering/rejecting a call
- // (via onTrigger()), *don't* show the incoming call
- // UI even if the phone is still in the RINGING state.
- // This covers up a slow response from the radio for some actions.
- // To detect that situation, we are using "500 msec" heuristics.
- //
- // Watch out: we should *not* rely on this behavior when "instant text response" action
- // has been chosen. See also onTrigger() for why.
- long now = SystemClock.uptimeMillis();
- if (now < mLastIncomingCallActionTime + 500) {
- 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()) {
- showInCallControls = true;
- } else {
- if (DBG) log("- updateState: NOT OK to show touch UI; disabling...");
- }
- }
-
- // In usual cases we don't allow showing both incoming call controls and in-call controls.
- //
- // There's one exception: if this call is during fading-out animation for the incoming
- // call controls, we need to show both for smoother transition.
- if (showIncomingCallControls && showInCallControls) {
- throw new IllegalStateException(
- "'Incoming' and 'in-call' touch controls visible at the same time!");
- }
- if (mShowInCallControlsDuringHidingAnimation) {
- if (DBG) {
- log("- updateState: FORCE showing in-call controls during incoming call widget"
- + " being hidden with animation");
- }
- showInCallControls = true;
- }
-
- // Update visibility and state of the incoming call controls or
- // the normal in-call controls.
-
- if (showInCallControls) {
- if (DBG) log("- updateState: showing in-call controls...");
- updateInCallControls(cm);
- mInCallControls.setVisibility(View.VISIBLE);
- } else {
- if (DBG) log("- updateState: HIDING in-call controls...");
- mInCallControls.setVisibility(View.GONE);
- }
-
- if (showIncomingCallControls) {
- if (DBG) log("- updateState: showing incoming call widget...");
- showIncomingCallWidget(ringingCall);
-
- // On devices with a system bar (soft buttons at the bottom of
- // the screen), disable navigation while the incoming-call UI
- // is up.
- // This prevents false touches (e.g. on the "Recents" button)
- // from interfering with the incoming call UI, like if you
- // accidentally touch the system bar while pulling the phone
- // out of your pocket.
- mApp.notificationMgr.statusBarHelper.enableSystemBarNavigation(false);
- } else {
- if (DBG) log("- updateState: HIDING incoming call widget...");
- hideIncomingCallWidget();
-
- // The system bar is allowed to work normally in regular
- // in-call states.
- mApp.notificationMgr.statusBarHelper.enableSystemBarNavigation(true);
- }
-
- // Dismiss the "Audio mode" PopupMenu if necessary.
- //
- // The "Audio mode" popup is only relevant in call states that support
- // in-call audio, namely when the phone is OFFHOOK (not RINGING), *and*
- // the foreground call is either ALERTING (where you can hear the other
- // end ringing) or ACTIVE (when the call is actually connected.) In any
- // state *other* than these, the popup should not be visible.
-
- if ((state == PhoneConstants.State.OFFHOOK)
- && (fgCallState == Call.State.ALERTING || fgCallState == Call.State.ACTIVE)) {
- // The audio mode popup is allowed to be visible in this state.
- // So if it's up, leave it alone.
- } else {
- // The Audio mode popup isn't relevant in this state, so make sure
- // it's not visible.
- dismissAudioModePopup(); // safe even if not active
- }
- }
-
- private boolean okToShowInCallControls() {
- // Note that this method is concerned only with the internal state
- // of the InCallScreen. (The InCallTouchUi widget has separate
- // logic to make sure it's OK to display the touch UI given the
- // current telephony state, and that it's allowed on the current
- // device in the first place.)
-
- // The touch UI is available in the following InCallScreenModes:
- // - NORMAL (obviously)
- // - CALL_ENDED (which is intended to look mostly the same as
- // a normal in-call state, even though the in-call
- // buttons are mostly disabled)
- // and is hidden in any of the other modes, like MANAGE_CONFERENCE
- // or one of the OTA modes (which use totally different UIs.)
-
- return ((mApp.inCallUiState.inCallScreenMode == InCallScreenMode.NORMAL)
- || (mApp.inCallUiState.inCallScreenMode == InCallScreenMode.CALL_ENDED));
- }
-
- @Override
- public void onClick(View view) {
- int id = view.getId();
- if (DBG) log("onClick(View " + view + ", id " + id + ")...");
-
- switch (id) {
- case R.id.addButton:
- case R.id.mergeButton:
- case R.id.endButton:
- case R.id.dialpadButton:
- case R.id.muteButton:
- case R.id.holdButton:
- case R.id.swapButton:
- case R.id.cdmaMergeButton:
- case R.id.manageConferenceButton:
- case R.id.videoCallButton:
- // Clicks on the regular onscreen buttons get forwarded
- // straight to the InCallScreen.
- mInCallScreen.handleOnscreenButtonClick(id);
- break;
-
- case R.id.audioButton:
- handleAudioButtonClick();
- break;
-
- default:
- Log.w(LOG_TAG, "onClick: unexpected click: View " + view + ", id " + id);
- break;
- }
- }
-
- @Override
- public boolean onLongClick(View view) {
- final int id = view.getId();
- if (DBG) log("onLongClick(View " + view + ", id " + id + ")...");
-
- switch (id) {
- case R.id.addButton:
- case R.id.mergeButton:
- case R.id.dialpadButton:
- case R.id.muteButton:
- case R.id.holdButton:
- case R.id.swapButton:
- case R.id.audioButton:
- case R.id.videoCallButton: {
- final CharSequence description = view.getContentDescription();
- if (!TextUtils.isEmpty(description)) {
- // Show description as ActionBar's menu buttons do.
- // See also ActionMenuItemView#onLongClick() for the original implementation.
- final Toast cheatSheet =
- Toast.makeText(view.getContext(), description, Toast.LENGTH_SHORT);
- cheatSheet.setGravity(
- Gravity.BOTTOM | Gravity.CENTER_HORIZONTAL, 0, view.getHeight());
- cheatSheet.show();
- }
- return true;
- }
- default:
- Log.w(LOG_TAG, "onLongClick() with unexpected View " + view + ". Ignoring it.");
- break;
- }
- return false;
- }
-
- /**
- * Updates the enabledness and "checked" state of the buttons on the
- * "inCallControls" panel, based on the current telephony state.
- */
- private void updateInCallControls(CallManager cm) {
- int phoneType = cm.getActiveFgCall().getPhone().getPhoneType();
-
- // Note we do NOT need to worry here about cases where the entire
- // in-call touch UI is disabled, like during an OTA call or if the
- // dtmf dialpad is up. (That's handled by updateState(), which
- // calls okToShowInCallControls().)
- //
- // If we get here, it *is* OK to show the in-call touch UI, so we
- // now need to update the enabledness and/or "checked" state of
- // each individual button.
- //
-
- // The InCallControlState object tells us the enabledness and/or
- // state of the various onscreen buttons:
- InCallControlState inCallControlState = mInCallScreen.getUpdatedInCallControlState();
-
- if (DBG) {
- log("updateInCallControls()...");
- inCallControlState.dumpState();
- }
-
- // "Add" / "Merge":
- // These two buttons occupy the same space onscreen, so at any
- // given point exactly one of them must be VISIBLE and the other
- // must be GONE.
- if (inCallControlState.canAddCall) {
- mAddButton.setVisibility(View.VISIBLE);
- mAddButton.setEnabled(true);
- mMergeButton.setVisibility(View.GONE);
- } else if (inCallControlState.canMerge) {
- if (phoneType == PhoneConstants.PHONE_TYPE_CDMA) {
- // In CDMA "Add" option is always given to the user and the
- // "Merge" option is provided as a button on the top left corner of the screen,
- // we always set the mMergeButton to GONE
- mMergeButton.setVisibility(View.GONE);
- } else if ((phoneType == PhoneConstants.PHONE_TYPE_GSM)
- || (phoneType == PhoneConstants.PHONE_TYPE_SIP)) {
- mMergeButton.setVisibility(View.VISIBLE);
- mMergeButton.setEnabled(true);
- mAddButton.setVisibility(View.GONE);
- } else {
- throw new IllegalStateException("Unexpected phone type: " + phoneType);
- }
- } else {
- // Neither "Add" nor "Merge" is available. (This happens in
- // some transient states, like while dialing an outgoing call,
- // and in other rare cases like if you have both lines in use
- // *and* there are already 5 people on the conference call.)
- // Since the common case here is "while dialing", we show the
- // "Add" button in a disabled state so that there won't be any
- // jarring change in the UI when the call finally connects.
- mAddButton.setVisibility(View.VISIBLE);
- mAddButton.setEnabled(false);
- mMergeButton.setVisibility(View.GONE);
- }
- if (inCallControlState.canAddCall && inCallControlState.canMerge) {
- if ((phoneType == PhoneConstants.PHONE_TYPE_GSM)
- || (phoneType == PhoneConstants.PHONE_TYPE_SIP)) {
- // Uh oh, the InCallControlState thinks that "Add" *and* "Merge"
- // should both be available right now. This *should* never
- // happen with GSM, but if it's possible on any
- // future devices we may need to re-layout Add and Merge so
- // they can both be visible at the same time...
- Log.w(LOG_TAG, "updateInCallControls: Add *and* Merge enabled," +
- " but can't show both!");
- } else if (phoneType == PhoneConstants.PHONE_TYPE_CDMA) {
- // In CDMA "Add" option is always given to the user and the hence
- // in this case both "Add" and "Merge" options would be available to user
- if (DBG) log("updateInCallControls: CDMA: Add and Merge both enabled");
- } else {
- throw new IllegalStateException("Unexpected phone type: " + phoneType);
- }
- }
-
- // "End call"
- mEndButton.setEnabled(inCallControlState.canEndCall);
-
- // "Dialpad": Enabled only when it's OK to use the dialpad in the
- // first place.
- mDialpadButton.setEnabled(inCallControlState.dialpadEnabled);
- mDialpadButton.setChecked(inCallControlState.dialpadVisible);
-
- // "Mute"
- mMuteButton.setEnabled(inCallControlState.canMute);
- mMuteButton.setChecked(inCallControlState.muteIndicatorOn);
-
- // "Audio"
- updateAudioButton(inCallControlState);
-
- // "Hold" / "Swap":
- // These two buttons occupy the same space onscreen, so at any
- // given point exactly one of them must be VISIBLE and the other
- // must be GONE.
- if (inCallControlState.canHold) {
- mHoldButton.setVisibility(View.VISIBLE);
- 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:
- // (1) this is a transient state on a device that *can*
- // normally hold or swap, or
- // (2) this device just doesn't have the concept of hold/swap.
- //
- // In case (1), show the "Hold" button in a disabled state. In case
- // (2), remove the button entirely. (This means that the button row
- // will only have 4 buttons on some devices.)
-
- if (inCallControlState.supportsHold) {
- mHoldButton.setVisibility(View.VISIBLE);
- mHoldButton.setEnabled(false);
- mHoldButton.setChecked(false);
- mSwapButton.setVisibility(View.GONE);
- mHoldSwapSpacer.setVisibility(View.VISIBLE);
- } else {
- mHoldButton.setVisibility(View.GONE);
- mSwapButton.setVisibility(View.GONE);
- mHoldSwapSpacer.setVisibility(View.GONE);
- }
- }
- mInCallScreen.updateButtonStateOutsideInCallTouchUi();
- if (inCallControlState.canSwap && inCallControlState.canHold) {
- // Uh oh, the InCallControlState thinks that Swap *and* Hold
- // should both be available. This *should* never happen with
- // either GSM or CDMA, but if it's possible on any future
- // devices we may need to re-layout Hold and Swap so they can
- // both be visible at the same time...
- Log.w(LOG_TAG, "updateInCallControls: Hold *and* Swap enabled, but can't show both!");
- }
-
- if (phoneType == PhoneConstants.PHONE_TYPE_CDMA) {
- if (inCallControlState.canSwap && inCallControlState.canMerge) {
- // Uh oh, the InCallControlState thinks that Swap *and* Merge
- // should both be available. This *should* never happen with
- // CDMA, but if it's possible on any future
- // devices we may need to re-layout Merge and Swap so they can
- // both be visible at the same time...
- Log.w(LOG_TAG, "updateInCallControls: Merge *and* Swap" +
- "enabled, but can't show both!");
- }
- }
-
- // Finally, update the "extra button row": It's displayed above the
- // "End" button, but only if necessary. Also, it's never displayed
- // while the dialpad is visible (since it would overlap.)
- //
- // The row contains two buttons:
- //
- // - "Manage conference" (used only on GSM devices)
- // - "Merge" button (used only on CDMA devices)
- //
- // Note that mExtraButtonRow is ViewStub, which will be inflated for the first time when
- // any of its buttons becomes visible.
- final boolean showCdmaMerge =
- (phoneType == PhoneConstants.PHONE_TYPE_CDMA) && inCallControlState.canMerge;
- final boolean showExtraButtonRow =
- showCdmaMerge || inCallControlState.manageConferenceVisible;
- if (showExtraButtonRow && !inCallControlState.dialpadVisible) {
- // This will require the ViewStub inflate itself.
- mExtraButtonRow.setVisibility(View.VISIBLE);
-
- // Need to set up mCdmaMergeButton and mManageConferenceButton if this is the first
- // time they're visible.
- if (mCdmaMergeButton == null) {
- setupExtraButtons();
- }
- mCdmaMergeButton.setVisibility(showCdmaMerge ? View.VISIBLE : View.GONE);
- if (inCallControlState.manageConferenceVisible) {
- mManageConferenceButton.setVisibility(View.VISIBLE);
- mManageConferenceButtonImage.setEnabled(inCallControlState.manageConferenceEnabled);
- } else {
- mManageConferenceButton.setVisibility(View.GONE);
- }
- } else {
- mExtraButtonRow.setVisibility(View.GONE);
- }
-
- setupVideoCallButton();
-
- if (DBG) {
- log("At the end of updateInCallControls().");
- dumpBottomButtonState();
- }
- }
-
- /**
- * Set up the video call button. Checks the system for any video call providers before
- * displaying the video chat button.
- */
- private void setupVideoCallButton() {
- // TODO: Check system to see if there are video chat providers and if not, disable the
- // button.
- }
-
-
- /**
- * Set up the buttons that are part of the "extra button row"
- */
- private void setupExtraButtons() {
- // The two "buttons" here (mCdmaMergeButton and mManageConferenceButton)
- // are actually layouts containing an icon and a text label side-by-side.
- mCdmaMergeButton = (ViewGroup) mInCallControls.findViewById(R.id.cdmaMergeButton);
- if (mCdmaMergeButton == null) {
- Log.wtf(LOG_TAG, "CDMA Merge button is null even after ViewStub being inflated.");
- return;
- }
- mCdmaMergeButton.setOnClickListener(this);
-
- mManageConferenceButton =
- (ViewGroup) mInCallControls.findViewById(R.id.manageConferenceButton);
- mManageConferenceButton.setOnClickListener(this);
- mManageConferenceButtonImage =
- (ImageButton) mInCallControls.findViewById(R.id.manageConferenceButtonImage);
- }
-
- private void dumpBottomButtonState() {
- log(" - dialpad: " + getButtonState(mDialpadButton));
- log(" - speaker: " + getButtonState(mAudioButton));
- log(" - mute: " + getButtonState(mMuteButton));
- log(" - hold: " + getButtonState(mHoldButton));
- log(" - swap: " + getButtonState(mSwapButton));
- log(" - add: " + getButtonState(mAddButton));
- log(" - merge: " + getButtonState(mMergeButton));
- log(" - cdmaMerge: " + getButtonState(mCdmaMergeButton));
- log(" - swap: " + getButtonState(mSwapButton));
- log(" - manageConferenceButton: " + getButtonState(mManageConferenceButton));
- }
-
- private static String getButtonState(View view) {
- if (view == null) {
- return "(null)";
- }
- StringBuilder builder = new StringBuilder();
- builder.append("visibility: " + (view.getVisibility() == View.VISIBLE ? "VISIBLE"
- : view.getVisibility() == View.INVISIBLE ? "INVISIBLE" : "GONE"));
- if (view instanceof ImageButton) {
- builder.append(", enabled: " + ((ImageButton) view).isEnabled());
- } else if (view instanceof CompoundButton) {
- builder.append(", enabled: " + ((CompoundButton) view).isEnabled());
- builder.append(", checked: " + ((CompoundButton) view).isChecked());
- }
- return builder.toString();
- }
-
- /**
- * Updates the onscreen "Audio mode" button based on the current state.
- *
- * - If bluetooth is available, this button's function is to bring up the
- * "Audio mode" popup (which provides a 3-way choice between earpiece /
- * speaker / bluetooth). So it should look like a regular action button,
- * but should also have the small "more_indicator" triangle that indicates
- * that a menu will pop up.
- *
- * - If speaker (but not bluetooth) is available, this button should look like
- * a regular toggle button (and indicate the current speaker state.)
- *
- * - If even speaker isn't available, disable the button entirely.
- */
- private void updateAudioButton(InCallControlState inCallControlState) {
- if (DBG) log("updateAudioButton()...");
-
- // The various layers of artwork for this button come from
- // btn_compound_audio.xml. Keep track of which layers we want to be
- // visible:
- //
- // - This selector shows the blue bar below the button icon when
- // this button is a toggle *and* it's currently "checked".
- boolean showToggleStateIndication = false;
- //
- // - This is visible if the popup menu is enabled:
- boolean showMoreIndicator = false;
- //
- // - Foreground icons for the button. Exactly one of these is enabled:
- boolean showSpeakerOnIcon = false;
- boolean showSpeakerOffIcon = false;
- boolean showHandsetIcon = false;
- boolean showBluetoothIcon = false;
-
- if (inCallControlState.bluetoothEnabled) {
- if (DBG) log("- updateAudioButton: 'popup menu action button' mode...");
-
- mAudioButton.setEnabled(true);
-
- // The audio button is NOT a toggle in this state. (And its
- // setChecked() state is irrelevant since we completely hide the
- // btn_compound_background layer anyway.)
-
- // Update desired layers:
- showMoreIndicator = true;
- if (inCallControlState.bluetoothIndicatorOn) {
- showBluetoothIcon = true;
- } else if (inCallControlState.speakerOn) {
- showSpeakerOnIcon = true;
- } else {
- showHandsetIcon = true;
- // TODO: if a wired headset is plugged in, that takes precedence
- // over the handset earpiece. If so, maybe we should show some
- // sort of "wired headset" icon here instead of the "handset
- // earpiece" icon. (Still need an asset for that, though.)
- }
- } else if (inCallControlState.speakerEnabled) {
- if (DBG) log("- updateAudioButton: 'speaker toggle' mode...");
-
- mAudioButton.setEnabled(true);
-
- // The audio button *is* a toggle in this state, and indicates the
- // current state of the speakerphone.
- mAudioButton.setChecked(inCallControlState.speakerOn);
-
- // Update desired layers:
- showToggleStateIndication = true;
-
- showSpeakerOnIcon = inCallControlState.speakerOn;
- showSpeakerOffIcon = !inCallControlState.speakerOn;
- } else {
- if (DBG) log("- updateAudioButton: disabled...");
-
- // The audio button is a toggle in this state, but that's mostly
- // irrelevant since it's always disabled and unchecked.
- mAudioButton.setEnabled(false);
- mAudioButton.setChecked(false);
-
- // Update desired layers:
- showToggleStateIndication = true;
- showSpeakerOffIcon = true;
- }
-
- // Finally, update the drawable layers (see btn_compound_audio.xml).
-
- // Constants used below with Drawable.setAlpha():
- final int HIDDEN = 0;
- final int VISIBLE = 255;
-
- LayerDrawable layers = (LayerDrawable) mAudioButton.getBackground();
- if (DBG) log("- 'layers' drawable: " + layers);
-
- layers.findDrawableByLayerId(R.id.compoundBackgroundItem)
- .setAlpha(showToggleStateIndication ? VISIBLE : HIDDEN);
-
- layers.findDrawableByLayerId(R.id.moreIndicatorItem)
- .setAlpha(showMoreIndicator ? VISIBLE : HIDDEN);
-
- layers.findDrawableByLayerId(R.id.bluetoothItem)
- .setAlpha(showBluetoothIcon ? VISIBLE : HIDDEN);
-
- layers.findDrawableByLayerId(R.id.handsetItem)
- .setAlpha(showHandsetIcon ? VISIBLE : HIDDEN);
-
- layers.findDrawableByLayerId(R.id.speakerphoneOnItem)
- .setAlpha(showSpeakerOnIcon ? VISIBLE : HIDDEN);
-
- layers.findDrawableByLayerId(R.id.speakerphoneOffItem)
- .setAlpha(showSpeakerOffIcon ? VISIBLE : HIDDEN);
- }
-
- /**
- * Handles a click on the "Audio mode" button.
- * - If bluetooth is available, bring up the "Audio mode" popup
- * (which provides a 3-way choice between earpiece / speaker / bluetooth).
- * - If bluetooth is *not* available, just toggle between earpiece and
- * speaker, with no popup at all.
- */
- private void handleAudioButtonClick() {
- InCallControlState inCallControlState = mInCallScreen.getUpdatedInCallControlState();
- if (inCallControlState.bluetoothEnabled) {
- if (DBG) log("- handleAudioButtonClick: 'popup menu' mode...");
- showAudioModePopup();
- } else {
- if (DBG) log("- handleAudioButtonClick: 'speaker toggle' mode...");
- mInCallScreen.toggleSpeaker();
- }
- }
-
- /**
- * Brings up the "Audio mode" popup.
- */
- private void showAudioModePopup() {
- if (DBG) log("showAudioModePopup()...");
-
- mAudioModePopup = new PopupMenu(mInCallScreen /* context */,
- mAudioButton /* anchorView */);
- mAudioModePopup.getMenuInflater().inflate(R.menu.incall_audio_mode_menu,
- mAudioModePopup.getMenu());
- mAudioModePopup.setOnMenuItemClickListener(this);
- mAudioModePopup.setOnDismissListener(this);
-
- // Update the enabled/disabledness of menu items based on the
- // current call state.
- InCallControlState inCallControlState = mInCallScreen.getUpdatedInCallControlState();
-
- Menu menu = mAudioModePopup.getMenu();
-
- // TODO: Still need to have the "currently active" audio mode come
- // up pre-selected (or focused?) with a blue highlight. Still
- // need exact visual design, and possibly framework support for this.
- // See comments below for the exact logic.
-
- MenuItem speakerItem = menu.findItem(R.id.audio_mode_speaker);
- speakerItem.setEnabled(inCallControlState.speakerEnabled);
- // TODO: Show speakerItem as initially "selected" if
- // inCallControlState.speakerOn is true.
-
- // We display *either* "earpiece" or "wired headset", never both,
- // depending on whether a wired headset is physically plugged in.
- MenuItem earpieceItem = menu.findItem(R.id.audio_mode_earpiece);
- MenuItem wiredHeadsetItem = menu.findItem(R.id.audio_mode_wired_headset);
-
- // TODO(klp): This is a compile stop-gap. This will all be deleted
- final boolean usingHeadset = false; //mApp.isHeadsetPlugged();
-
- earpieceItem.setVisible(!usingHeadset);
- earpieceItem.setEnabled(!usingHeadset);
- wiredHeadsetItem.setVisible(usingHeadset);
- wiredHeadsetItem.setEnabled(usingHeadset);
- // TODO: Show the above item (either earpieceItem or wiredHeadsetItem)
- // as initially "selected" if inCallControlState.speakerOn and
- // inCallControlState.bluetoothIndicatorOn are both false.
-
- MenuItem bluetoothItem = menu.findItem(R.id.audio_mode_bluetooth);
- bluetoothItem.setEnabled(inCallControlState.bluetoothEnabled);
- // TODO: Show bluetoothItem as initially "selected" if
- // inCallControlState.bluetoothIndicatorOn is true.
-
- mAudioModePopup.show();
-
- // Unfortunately we need to manually keep track of the popup menu's
- // visiblity, since PopupMenu doesn't have an isShowing() method like
- // Dialogs do.
- mAudioModePopupVisible = true;
- }
-
- /**
- * Dismisses the "Audio mode" popup if it's visible.
- *
- * This is safe to call even if the popup is already dismissed, or even if
- * you never called showAudioModePopup() in the first place.
- */
- public void dismissAudioModePopup() {
- if (mAudioModePopup != null) {
- mAudioModePopup.dismiss(); // safe even if already dismissed
- mAudioModePopup = null;
- mAudioModePopupVisible = false;
- }
- }
-
- /**
- * Refreshes the "Audio mode" popup if it's visible. This is useful
- * (for example) when a wired headset is plugged or unplugged,
- * since we need to switch back and forth between the "earpiece"
- * and "wired headset" items.
- *
- * This is safe to call even if the popup is already dismissed, or even if
- * you never called showAudioModePopup() in the first place.
- */
- public void refreshAudioModePopup() {
- if (mAudioModePopup != null && mAudioModePopupVisible) {
- // Dismiss the previous one
- mAudioModePopup.dismiss(); // safe even if already dismissed
- // And bring up a fresh PopupMenu
- showAudioModePopup();
- }
- }
-
- // PopupMenu.OnMenuItemClickListener implementation; see showAudioModePopup()
- @Override
- public boolean onMenuItemClick(MenuItem item) {
- if (DBG) log("- onMenuItemClick: " + item);
- if (DBG) log(" id: " + item.getItemId());
- if (DBG) log(" title: '" + item.getTitle() + "'");
-
- if (mInCallScreen == null) {
- Log.w(LOG_TAG, "onMenuItemClick(" + item + "), but null mInCallScreen!");
- return true;
- }
-
- switch (item.getItemId()) {
- case R.id.audio_mode_speaker:
- mInCallScreen.switchInCallAudio(InCallScreen.InCallAudioMode.SPEAKER);
- break;
- case R.id.audio_mode_earpiece:
- case R.id.audio_mode_wired_headset:
- // InCallAudioMode.EARPIECE means either the handset earpiece,
- // or the wired headset (if connected.)
- mInCallScreen.switchInCallAudio(InCallScreen.InCallAudioMode.EARPIECE);
- break;
- case R.id.audio_mode_bluetooth:
- mInCallScreen.switchInCallAudio(InCallScreen.InCallAudioMode.BLUETOOTH);
- break;
- default:
- Log.wtf(LOG_TAG,
- "onMenuItemClick: unexpected View ID " + item.getItemId()
- + " (MenuItem = '" + item + "')");
- break;
- }
- return true;
- }
-
- // PopupMenu.OnDismissListener implementation; see showAudioModePopup().
- // This gets called when the PopupMenu gets dismissed for *any* reason, like
- // the user tapping outside its bounds, or pressing Back, or selecting one
- // of the menu items.
- @Override
- public void onDismiss(PopupMenu menu) {
- if (DBG) log("- onDismiss: " + menu);
- mAudioModePopupVisible = false;
- }
-
- /**
- * @return the amount of vertical space (in pixels) that needs to be
- * reserved for the button cluster at the bottom of the screen.
- * (The CallCard uses this measurement to determine how big
- * the main "contact photo" area can be.)
- *
- * NOTE that this returns the "canonical height" of the main in-call
- * button cluster, which may not match the amount of vertical space
- * actually used. Specifically:
- *
- * - If an incoming call is ringing, the button cluster isn't
- * visible at all. (And the GlowPadView widget is actually
- * much taller than the button cluster.)
- *
- * - If the InCallTouchUi widget's "extra button row" is visible
- * (in some rare phone states) the button cluster will actually
- * be slightly taller than the "canonical height".
- *
- * In either of these cases, we allow the bottom edge of the contact
- * photo to be covered up by whatever UI is actually onscreen.
- */
- public int getTouchUiHeight() {
- // Add up the vertical space consumed by the various rows of buttons.
- int height = 0;
-
- // - The main row of buttons:
- height += (int) getResources().getDimension(R.dimen.in_call_button_height);
-
- // - The End button:
- height += (int) getResources().getDimension(R.dimen.in_call_end_button_height);
-
- // - Note we *don't* consider the InCallTouchUi widget's "extra
- // button row" here.
-
- //- And an extra bit of margin:
- height += (int) getResources().getDimension(R.dimen.in_call_touch_ui_upper_margin);
-
- return height;
- }
-
-
- //
- // GlowPadView.OnTriggerListener implementation
- //
-
- @Override
- public void onGrabbed(View v, int handle) {
-
- }
-
- @Override
- public void onReleased(View v, int handle) {
-
- }
-
- /**
- * Handles "Answer" and "Reject" actions for an incoming call.
- * We get this callback from the incoming call widget
- * when the user triggers an action.
- */
- @Override
- public void onTrigger(View view, int whichHandle) {
- if (DBG) log("onTrigger(whichHandle = " + whichHandle + ")...");
-
- if (mInCallScreen == null) {
- Log.wtf(LOG_TAG, "onTrigger(" + whichHandle
- + ") from incoming-call widget, but null mInCallScreen!");
- return;
- }
-
- // The InCallScreen actually implements all of these actions.
- // Each possible action from the incoming call widget corresponds
- // to an R.id value; we pass those to the InCallScreen's "button
- // click" handler (even though the UI elements aren't actually
- // buttons; see InCallScreen.handleOnscreenButtonClick().)
-
- mShowInCallControlsDuringHidingAnimation = false;
- switch (whichHandle) {
- case ANSWER_CALL_ID:
- if (DBG) log("ANSWER_CALL_ID: answer!");
- mInCallScreen.handleOnscreenButtonClick(R.id.incomingCallAnswer);
- mShowInCallControlsDuringHidingAnimation = true;
-
- // ...and also prevent it from reappearing right away.
- // (This covers up a slow response from the radio for some
- // actions; see updateState().)
- mLastIncomingCallActionTime = SystemClock.uptimeMillis();
- break;
-
- case SEND_SMS_ID:
- if (DBG) log("SEND_SMS_ID!");
- mInCallScreen.handleOnscreenButtonClick(R.id.incomingCallRespondViaSms);
-
- // Watch out: mLastIncomingCallActionTime should not be updated for this case.
- //
- // The variable is originally for avoiding a problem caused by delayed phone state
- // update; RINGING state may remain just after answering/declining an incoming
- // call, so we need to wait a bit (500ms) until we get the effective phone state.
- // For this case, we shouldn't rely on that hack.
- //
- // When the user selects this case, there are two possibilities, neither of which
- // should rely on the hack.
- //
- // 1. The first possibility is that, the device eventually sends one of canned
- // responses per the user's "send" request, and reject the call after sending it.
- // At that moment the code introducing the canned responses should handle the
- // case separately.
- //
- // 2. The second possibility is that, the device will show incoming call widget
- // again per the user's "cancel" request, where the incoming call will still
- // remain. At that moment the incoming call will keep its RINGING state.
- // The remaining phone state should never be ignored by the hack for
- // answering/declining calls because the RINGING state is legitimate. If we
- // use the hack for answer/decline cases, the user loses the incoming call
- // widget, until further screen update occurs afterward, which often results in
- // missed calls.
- break;
-
- case DECLINE_CALL_ID:
- if (DBG) log("DECLINE_CALL_ID: reject!");
- mInCallScreen.handleOnscreenButtonClick(R.id.incomingCallReject);
-
- // Same as "answer" case.
- mLastIncomingCallActionTime = SystemClock.uptimeMillis();
- break;
-
- default:
- Log.wtf(LOG_TAG, "onDialTrigger: unexpected whichHandle value: " + whichHandle);
- break;
- }
-
- // On any action by the user, hide the widget.
- //
- // 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
- // the hint text we were displaying while the user was dragging.
- mInCallScreen.updateIncomingCallWidgetHint(0, 0);
- }
-
- public void onFinishFinalAnimation() {
- // Not used
- }
-
- /**
- * Apply an animation to hide the incoming call widget.
- */
- private void 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;
- }
-
- // Hide the incoming call screen with a transition
- mIncomingCallWidgetIsFadingOut = true;
- ViewPropertyAnimator animator = mIncomingCallWidget.animate();
- animator.cancel();
- animator.setDuration(AnimationUtils.ANIMATION_DURATION);
- animator.setListener(new AnimatorListenerAdapter() {
- @Override
- public void onAnimationStart(Animator animation) {
- if (mShowInCallControlsDuringHidingAnimation) {
- if (DBG) log("IncomingCallWidget's hiding animation started");
- updateInCallControls(mApp.mCM);
- mInCallControls.setVisibility(View.VISIBLE);
- }
- }
-
- @Override
- public void onAnimationEnd(Animator animation) {
- if (DBG) log("IncomingCallWidget's hiding animation ended");
- mIncomingCallWidget.setAlpha(1);
- mIncomingCallWidget.setVisibility(View.GONE);
- mIncomingCallWidget.animate().setListener(null);
- mShowInCallControlsDuringHidingAnimation = false;
- mIncomingCallWidgetIsFadingOut = false;
- mIncomingCallWidgetShouldBeReset = true;
- }
-
- @Override
- public void onAnimationCancel(Animator animation) {
- mIncomingCallWidget.animate().setListener(null);
- mShowInCallControlsDuringHidingAnimation = false;
- mIncomingCallWidgetIsFadingOut = false;
- mIncomingCallWidgetShouldBeReset = true;
-
- // Note: the code which reset this animation should be responsible for
- // alpha and visibility.
- }
- });
- animator.alpha(0f);
- }
-
- /**
- * Shows the incoming call widget and cancels any animation that may be fading it out.
- */
- private void showIncomingCallWidget(Call ringingCall) {
- if (DBG) log("showIncomingCallWidget()...");
-
- // 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());
-
- ViewPropertyAnimator animator = mIncomingCallWidget.animate();
- if (animator != null) {
- animator.cancel();
- // If animation is cancelled before it's running,
- // onAnimationCancel will not be called and mIncomingCallWidgetIsFadingOut
- // will be alway true. hideIncomingCallWidget() will not be excuted in this case.
- mIncomingCallWidgetIsFadingOut = false;
- }
- mIncomingCallWidget.setAlpha(1.0f);
-
- // 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.START);
- }
-
- mIncomingCallWidget.setVisibility(View.VISIBLE);
-
- // Finally, manually trigger a "ping" animation.
- //
- // Normally, the ping animation is triggered by RING events from
- // the telephony layer (see onIncomingRing().) But that *doesn't*
- // happen for the very first RING event of an incoming call, since
- // the incoming-call UI hasn't been set up yet at that point!
- //
- // So trigger an explicit ping() here, to force the animation to
- // run when the widget first appears.
- //
- mHandler.removeMessages(INCOMING_CALL_WIDGET_PING);
- mHandler.sendEmptyMessageDelayed(
- INCOMING_CALL_WIDGET_PING,
- // Visual polish: add a small delay here, to make the
- // GlowPadView widget visible for a brief moment
- // *before* starting the ping animation.
- // This value doesn't need to be very precise.
- 250 /* msec */);
- }
-
- /**
- * Handles state changes of the incoming-call widget.
- *
- * In previous releases (where we used a SlidingTab widget) we would
- * display an onscreen hint depending on which "handle" the user was
- * dragging. But we now use a GlowPadView widget, which has only
- * one handle, so for now we don't display a hint at all (see the TODO
- * comment below.)
- */
- @Override
- public void onGrabbedStateChange(View v, int grabbedState) {
- if (mInCallScreen != null) {
- // Look up the hint based on which handle is currently grabbed.
- // (Note we don't simply pass grabbedState thru to the InCallScreen,
- // since *this* class is the only place that knows that the left
- // handle means "Answer" and the right handle means "Decline".)
- int hintTextResId, hintColorResId;
- switch (grabbedState) {
- case GlowPadView.OnTriggerListener.NO_HANDLE:
- case GlowPadView.OnTriggerListener.CENTER_HANDLE:
- hintTextResId = 0;
- hintColorResId = 0;
- break;
- default:
- Log.e(LOG_TAG, "onGrabbedStateChange: unexpected grabbedState: "
- + grabbedState);
- hintTextResId = 0;
- hintColorResId = 0;
- break;
- }
-
- // Tell the InCallScreen to update the CallCard and force the
- // screen to redraw.
- mInCallScreen.updateIncomingCallWidgetHint(hintTextResId, hintColorResId);
- }
- }
-
- /**
- * Handles an incoming RING event from the telephony layer.
- */
- public void onIncomingRing() {
- if (ENABLE_PING_ON_RING_EVENTS) {
- // Each RING from the telephony layer triggers a "ping" animation
- // of the GlowPadView widget. (The intent here is to make the
- // pinging appear to be synchronized with the ringtone, although
- // that only works for non-looping ringtones.)
- triggerPing();
- }
- }
-
- /**
- * Runs a single "ping" animation of the GlowPadView widget,
- * or do nothing if the GlowPadView widget is no longer visible.
- *
- * Also, if ENABLE_PING_AUTO_REPEAT is true, schedule the next ping as
- * well (but again, only if the GlowPadView widget is still visible.)
- */
- public void triggerPing() {
- if (DBG) log("triggerPing: mIncomingCallWidget = " + mIncomingCallWidget);
-
- if (!mInCallScreen.isForegroundActivity()) {
- // InCallScreen has been dismissed; no need to run a ping *or*
- // schedule another one.
- log("- triggerPing: InCallScreen no longer in foreground; ignoring...");
- return;
- }
-
- if (mIncomingCallWidget == null) {
- // This shouldn't happen; the GlowPadView widget should
- // always be present in our layout file.
- Log.w(LOG_TAG, "- triggerPing: null mIncomingCallWidget!");
- return;
- }
-
- if (DBG) log("- triggerPing: mIncomingCallWidget visibility = "
- + mIncomingCallWidget.getVisibility());
-
- if (mIncomingCallWidget.getVisibility() != View.VISIBLE) {
- if (DBG) log("- triggerPing: mIncomingCallWidget no longer visible; ignoring...");
- return;
- }
-
- // Ok, run a ping (and schedule the next one too, if desired...)
-
- mIncomingCallWidget.ping();
-
- if (ENABLE_PING_AUTO_REPEAT) {
- // Schedule the next ping. (ENABLE_PING_AUTO_REPEAT mode
- // allows the ping animation to repeat much faster than in
- // the ENABLE_PING_ON_RING_EVENTS case, since telephony RING
- // events come fairly slowly (about 3 seconds apart.))
-
- // No need to check here if the call is still ringing, by
- // the way, since we hide mIncomingCallWidget as soon as the
- // ringing stops, or if the user answers. (And at that
- // point, any future triggerPing() call will be a no-op.)
-
- // TODO: Rather than having a separate timer here, maybe try
- // having these pings synchronized with the vibrator (see
- // VibratorThread in Ringer.java; we'd just need to get
- // events routed from there to here, probably via the
- // PhoneApp instance.) (But watch out: make sure pings
- // still work even if the Vibrate setting is turned off!)
-
- mHandler.sendEmptyMessageDelayed(INCOMING_CALL_WIDGET_PING,
- PING_AUTO_REPEAT_DELAY_MSEC);
- }
- }
-
- // Debugging / testing code
-
- private void log(String msg) {
- Log.d(LOG_TAG, msg);
- }
-}
diff --git a/src/com/android/phone/InCallUiState.java b/src/com/android/phone/InCallUiState.java
deleted file mode 100644
index 126ef63..0000000
--- a/src/com/android/phone/InCallUiState.java
+++ /dev/null
@@ -1,398 +0,0 @@
-/*
- * Copyright (C) 2011 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.phone.Constants.CallStatusCode;
-
-import android.content.Context;
-import android.content.Intent;
-import android.graphics.drawable.Drawable;
-import android.net.Uri;
-import android.text.TextUtils;
-import android.util.Log;
-
-
-/**
- * Helper class to keep track of "persistent state" of the in-call UI.
- *
- * The onscreen appearance of the in-call UI mostly depends on the current
- * Call/Connection state, which is owned by the telephony framework. But
- * there's some application-level "UI state" too, which lives here in the
- * phone app.
- *
- * This application-level state information is *not* maintained by the
- * InCallScreen, since it needs to persist throughout an entire phone call,
- * not just a single resume/pause cycle of the InCallScreen. So instead, that
- * state is stored here, in a singleton instance of this class.
- *
- * The state kept here is a high-level abstraction of in-call UI state: we
- * don't know about implementation details like specific widgets or strings or
- * resources, but we do understand higher level concepts (for example "is the
- * dialpad visible") and high-level modes (like InCallScreenMode) and error
- * conditions (like CallStatusCode).
- *
- * @see InCallControlState for a separate collection of "UI state" that
- * controls all the onscreen buttons of the in-call UI, based on the state of
- * the telephony layer.
- *
- * The singleton instance of this class is owned by the PhoneApp instance.
- */
-public class InCallUiState {
- private static final String TAG = "InCallUiState";
- private static final boolean DBG = false;
-
- /** The singleton InCallUiState instance. */
- private static InCallUiState sInstance;
-
- private Context mContext;
-
- /**
- * Initialize the singleton InCallUiState instance.
- *
- * This is only done once, at startup, from PhoneApp.onCreate().
- * From then on, the InCallUiState instance is available via the
- * PhoneApp's public "inCallUiState" field, which is why there's no
- * getInstance() method here.
- */
- /* package */ static InCallUiState init(Context context) {
- synchronized (InCallUiState.class) {
- if (sInstance == null) {
- sInstance = new InCallUiState(context);
- } else {
- Log.wtf(TAG, "init() called multiple times! sInstance = " + sInstance);
- }
- return sInstance;
- }
- }
-
- /**
- * Private constructor (this is a singleton).
- * @see init()
- */
- private InCallUiState(Context context) {
- mContext = context;
- }
-
-
- //
- // (1) High-level state of the whole in-call UI
- //
-
- /** High-level "modes" of the in-call UI. */
- public enum InCallScreenMode {
- /**
- * Normal in-call UI elements visible.
- */
- NORMAL,
- /**
- * "Manage conference" UI is visible, totally replacing the
- * normal in-call UI.
- */
- MANAGE_CONFERENCE,
- /**
- * Non-interactive UI state. Call card is visible,
- * displaying information about the call that just ended.
- */
- CALL_ENDED,
- /**
- * Normal OTA in-call UI elements visible.
- */
- OTA_NORMAL,
- /**
- * OTA call ended UI visible, replacing normal OTA in-call UI.
- */
- OTA_ENDED,
- /**
- * Default state when not on call
- */
- UNDEFINED
- }
-
- /** Current high-level "mode" of the in-call UI. */
- InCallScreenMode inCallScreenMode = InCallScreenMode.UNDEFINED;
-
-
- //
- // (2) State of specific UI elements
- //
-
- /**
- * Is the onscreen twelve-key dialpad visible?
- */
- boolean showDialpad;
-
- /**
- * The contents of the twelve-key dialpad's "digits" display, which is
- * visible only when the dialpad itself is visible.
- *
- * (This is basically the "history" of DTMF digits you've typed so far
- * in the current call. It's cleared out any time a new call starts,
- * to make sure the digits don't persist between two separate calls.)
- */
- String dialpadDigits;
-
- /**
- * The contact/dialed number information shown in the DTMF digits text
- * when the user has not yet typed any digits.
- *
- * Currently only used for displaying "Voice Mail" since voicemail calls
- * start directly in the dialpad view.
- */
- String dialpadContextText;
-
- //
- // (3) Error / diagnostic indications
- //
-
- // This section provides an abstract concept of an "error status
- // indication" for some kind of exceptional condition that needs to be
- // communicated to the user, in the context of the in-call UI.
- //
- // If mPendingCallStatusCode is any value other than SUCCESS, that
- // indicates that the in-call UI needs to display a dialog to the user
- // with the specified title and message text.
- //
- // When an error occurs outside of the InCallScreen itself (like
- // during CallController.placeCall() for example), we inform the user
- // by doing the following steps:
- //
- // (1) set the "pending call status code" to a value other than SUCCESS
- // (based on the specific error that happened)
- // (2) force the InCallScreen to be launched (or relaunched)
- // (3) InCallScreen.onResume() will notice that pending call status code
- // is set, and will actually bring up the desired dialog.
- //
- // Watch out: any time you set (or change!) the pending call status code
- // field you must be sure to always (re)launch the InCallScreen.
- //
- // Finally, the InCallScreen itself is responsible for resetting the
- // pending call status code, when the user dismisses the dialog (like by
- // hitting the OK button or pressing Back). The pending call status code
- // field is NOT cleared simply by the InCallScreen being paused or
- // finished, since the resulting dialog needs to persist across
- // orientation changes or if the screen turns off.
-
- // TODO: other features we might eventually need here:
- //
- // - Some error status messages stay in force till reset,
- // others may automatically clear themselves after
- // a fixed delay
- //
- // - Some error statuses may be visible as a dialog with an OK
- // button (like "call failed"), others may be an indefinite
- // progress dialog (like "turning on radio for emergency call").
- //
- // - Eventually some error statuses may have extra actions (like a
- // "retry call" button that we might provide at the bottom of the
- // "call failed because you have no signal" dialog.)
-
- /**
- * The current pending "error status indication" that we need to
- * display to the user.
- *
- * If this field is set to a value other than SUCCESS, this indicates to
- * the InCallScreen that we need to show some kind of message to the user
- * (usually an error dialog) based on the specified status code.
- */
- private CallStatusCode mPendingCallStatusCode = CallStatusCode.SUCCESS;
-
- /**
- * @return true if there's a pending "error status indication"
- * that we need to display to the user.
- */
- public boolean hasPendingCallStatusCode() {
- if (DBG) log("hasPendingCallStatusCode() ==> "
- + (mPendingCallStatusCode != CallStatusCode.SUCCESS));
- return (mPendingCallStatusCode != CallStatusCode.SUCCESS);
- }
-
- /**
- * @return the pending "error status indication" code
- * that we need to display to the user.
- */
- public CallStatusCode getPendingCallStatusCode() {
- if (DBG) log("getPendingCallStatusCode() ==> " + mPendingCallStatusCode);
- return mPendingCallStatusCode;
- }
-
- /**
- * Sets the pending "error status indication" code.
- */
- public void setPendingCallStatusCode(CallStatusCode status) {
- if (DBG) log("setPendingCallStatusCode( " + status + " )...");
- if (mPendingCallStatusCode != CallStatusCode.SUCCESS) {
- // Uh oh: mPendingCallStatusCode is already set to some value
- // other than SUCCESS (which indicates that there was some kind of
- // failure), and now we're trying to indicate another (potentially
- // different) failure. But we can only indicate one failure at a
- // time to the user, so the previous pending code is now going to
- // be lost.
- Log.w(TAG, "setPendingCallStatusCode: setting new code " + status
- + ", but a previous code " + mPendingCallStatusCode
- + " was already pending!");
- }
- mPendingCallStatusCode = status;
- }
-
- /**
- * Clears out the pending "error status indication" code.
- *
- * This indicates that there's no longer any error or "exceptional
- * condition" that needs to be displayed to the user. (Typically, this
- * method is called when the user dismisses the error dialog that came up
- * because of a previous call status code.)
- */
- public void clearPendingCallStatusCode() {
- if (DBG) log("clearPendingCallStatusCode()...");
- mPendingCallStatusCode = CallStatusCode.SUCCESS;
- }
-
- /**
- * Flag used to control the CDMA-specific "call lost" dialog.
- *
- * If true, that means that if the *next* outgoing call fails with an
- * abnormal disconnection cause, we need to display the "call lost"
- * dialog. (Normally, in CDMA we handle some types of call failures
- * by automatically retrying the call. This flag is set to true when
- * we're about to auto-retry, which means that if the *retry* also
- * fails we'll give up and display an error.)
- * See the logic in InCallScreen.onDisconnect() for the full story.
- *
- * TODO: the state machine that maintains the needToShowCallLostDialog
- * flag in InCallScreen.onDisconnect() should really be moved into the
- * CallController. Then we can get rid of this extra flag, and
- * instead simply use the CallStatusCode value CDMA_CALL_LOST to
- * trigger the "call lost" dialog.
- */
- boolean needToShowCallLostDialog;
-
-
- //
- // Progress indications
- //
-
- /**
- * Possible messages we might need to display along with
- * an indefinite progress spinner.
- */
- public enum ProgressIndicationType {
- /**
- * No progress indication needs to be shown.
- */
- NONE,
-
- /**
- * Shown when making an emergency call from airplane mode;
- * see CallController$EmergencyCallHelper.
- */
- TURNING_ON_RADIO,
-
- /**
- * Generic "retrying" state. (Specifically, this is shown while
- * retrying after an initial failure from the "emergency call from
- * airplane mode" sequence.)
- */
- RETRYING
- }
-
- /**
- * The current progress indication that should be shown
- * to the user. Any value other than NONE will cause the InCallScreen
- * to bring up an indefinite progress spinner along with a message
- * corresponding to the specified ProgressIndicationType.
- */
- private ProgressIndicationType progressIndication = ProgressIndicationType.NONE;
-
- /** Sets the current progressIndication. */
- public void setProgressIndication(ProgressIndicationType value) {
- progressIndication = value;
- }
-
- /** Clears the current progressIndication. */
- public void clearProgressIndication() {
- progressIndication = ProgressIndicationType.NONE;
- }
-
- /**
- * @return the current progress indication type, or ProgressIndicationType.NONE
- * if no progress indication is currently active.
- */
- public ProgressIndicationType getProgressIndication() {
- return progressIndication;
- }
-
- /** @return true if a progress indication is currently active. */
- public boolean isProgressIndicationActive() {
- return (progressIndication != ProgressIndicationType.NONE);
- }
-
- /**
- * "Call origin" of the most recent phone call.
- *
- * Watch out: right now this is only used to determine where the user should go after the phone
- * call. See also {@link InCallScreen} for more detail. There is *no* specific specification
- * about how this variable will be used.
- *
- * @see PhoneGlobals#setLatestActiveCallOrigin(String)
- * @see PhoneGlobals#createPhoneEndIntentUsingCallOrigin()
- *
- * TODO: we should determine some public behavior for this variable.
- */
- String latestActiveCallOrigin;
-
- /**
- * Timestamp for "Call origin". This will be used to preserve when the call origin was set.
- * {@link android.os.SystemClock#elapsedRealtime()} will be used.
- */
- long latestActiveCallOriginTimeStamp;
-
- /**
- * Flag forcing Phone app to show in-call UI even when there's no phone call and thus Phone
- * is in IDLE state. This will be turned on only when:
- *
- * - the last phone call is hung up, and
- * - the screen is being turned off in the middle of in-call UI (and thus when the screen being
- * turned on in-call UI is expected to be the next foreground activity)
- *
- * At that moment whole UI should show "previously disconnected phone call" for a moment and
- * exit itself. {@link InCallScreen#onPause()} will turn this off and prevent possible weird
- * cases which may happen with that exceptional case.
- */
- boolean showAlreadyDisconnectedState;
-
- //
- // Debugging
- //
-
- public void dumpState() {
- log("dumpState():");
- log(" - showDialpad: " + showDialpad);
- log(" - dialpadContextText: " + dialpadContextText);
- if (hasPendingCallStatusCode()) {
- log(" - status indication is pending!");
- log(" - pending call status code = " + mPendingCallStatusCode);
- } else {
- log(" - pending call status code: none");
- }
- log(" - progressIndication: " + progressIndication);
- log(" - latestActiveCallOrigin: " + latestActiveCallOrigin);
- }
-
- private static void log(String msg) {
- Log.d(TAG, msg);
- }
-}
diff --git a/src/com/android/phone/ManageConferenceUtils.java b/src/com/android/phone/ManageConferenceUtils.java
deleted file mode 100644
index 62e9a99..0000000
--- a/src/com/android/phone/ManageConferenceUtils.java
+++ /dev/null
@@ -1,356 +0,0 @@
-/*
- * Copyright (C) 2009 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.os.SystemProperties;
-import android.text.TextUtils;
-import android.util.Log;
-import android.view.View;
-import android.view.ViewGroup;
-import android.view.ViewStub;
-import android.widget.Chronometer;
-import android.widget.TextView;
-
-import com.android.internal.telephony.CallerInfo;
-import com.android.internal.telephony.CallerInfoAsyncQuery;
-import com.android.internal.telephony.CallManager;
-import com.android.internal.telephony.Connection;
-
-import java.util.List;
-
-
-/**
- * Helper class to initialize and run the InCallScreen's "Manage conference" UI.
- */
-public class ManageConferenceUtils {
- private static final String LOG_TAG = "ManageConferenceUtils";
- private static final boolean DBG =
- (PhoneGlobals.DBG_LEVEL >= 1) && (SystemProperties.getInt("ro.debuggable", 0) == 1);
-
- /**
- * CallerInfoAsyncQuery.OnQueryCompleteListener implementation.
- *
- * This object listens for results from the caller-id info queries we
- * fire off in updateManageConferenceRow(), and updates the
- * corresponding conference row.
- */
- private final class QueryCompleteListener
- implements CallerInfoAsyncQuery.OnQueryCompleteListener {
- private final int mConferencCallListIndex;
-
- public QueryCompleteListener(int index) {
- mConferencCallListIndex = index;
- }
-
- @Override
- public void onQueryComplete(int token, Object cookie, CallerInfo ci) {
- if (DBG) log("callerinfo query complete, updating UI." + ci);
-
- Connection connection = (Connection) cookie;
- int presentation = connection.getNumberPresentation();
-
- // get the viewgroup (conference call list item) and make it visible
- ViewGroup viewGroup = mConferenceCallList[mConferencCallListIndex];
- viewGroup.setVisibility(View.VISIBLE);
-
- // update the list item with this information.
- displayCallerInfoForConferenceRow(ci, presentation,
- (TextView) viewGroup.findViewById(R.id.conferenceCallerName),
- (TextView) viewGroup.findViewById(R.id.conferenceCallerNumberType),
- (TextView) viewGroup.findViewById(R.id.conferenceCallerNumber));
- }
- }
-
- private InCallScreen mInCallScreen;
- private CallManager mCM;
-
- // "Manage conference" UI elements and state
- private ViewGroup mManageConferencePanel;
- private View mButtonManageConferenceDone;
- private ViewGroup[] mConferenceCallList;
- private int mNumCallersInConference;
- private Chronometer mConferenceTime;
-
- // See CallTracker.MAX_CONNECTIONS_PER_CALL
- private static final int MAX_CALLERS_IN_CONFERENCE = 5;
-
- public ManageConferenceUtils(InCallScreen inCallScreen, CallManager cm) {
- if (DBG) log("ManageConferenceUtils constructor...");
- mInCallScreen = inCallScreen;
- mCM = cm;
- }
-
- public void initManageConferencePanel() {
- if (DBG) log("initManageConferencePanel()...");
- if (mManageConferencePanel == null) {
- if (DBG) log("initManageConferencePanel: first-time initialization!");
-
- // Inflate the ViewStub, look up and initialize the UI elements.
- ViewStub stub = (ViewStub) mInCallScreen.findViewById(R.id.manageConferencePanelStub);
- stub.inflate();
-
- mManageConferencePanel =
- (ViewGroup) mInCallScreen.findViewById(R.id.manageConferencePanel);
- if (mManageConferencePanel == null) {
- throw new IllegalStateException("Couldn't find manageConferencePanel!");
- }
-
- // set up the Conference Call chronometer
- mConferenceTime =
- (Chronometer) mInCallScreen.findViewById(R.id.manageConferencePanelHeader);
- mConferenceTime.setFormat(mInCallScreen.getString(R.string.caller_manage_header));
-
- // Create list of conference call widgets
- mConferenceCallList = new ViewGroup[MAX_CALLERS_IN_CONFERENCE];
-
- final int[] viewGroupIdList = { R.id.caller0, R.id.caller1, R.id.caller2,
- R.id.caller3, R.id.caller4 };
- for (int i = 0; i < MAX_CALLERS_IN_CONFERENCE; i++) {
- mConferenceCallList[i] =
- (ViewGroup) mInCallScreen.findViewById(viewGroupIdList[i]);
- }
-
- mButtonManageConferenceDone = mInCallScreen.findViewById(R.id.manage_done);
- mButtonManageConferenceDone.setOnClickListener(mInCallScreen);
- }
- }
-
- /**
- * Shows or hides the manageConferencePanel.
- */
- public void setPanelVisible(boolean visible) {
- if (mManageConferencePanel != null) {
- mManageConferencePanel.setVisibility(visible ? View.VISIBLE : View.GONE);
- }
- }
-
- /**
- * Starts the "conference time" chronometer.
- */
- public void startConferenceTime(long base) {
- if (mConferenceTime != null) {
- mConferenceTime.setBase(base);
- mConferenceTime.start();
- }
- }
-
- /**
- * Stops the "conference time" chronometer.
- */
- public void stopConferenceTime() {
- if (mConferenceTime != null) {
- mConferenceTime.stop();
- }
- }
-
- public int getNumCallersInConference() {
- return mNumCallersInConference;
- }
-
- /**
- * Updates the "Manage conference" UI based on the specified List of
- * connections.
- *
- * @param connections the List of connections belonging to
- * the current foreground call; size must be greater than 1
- * (or it wouldn't be a conference call in the first place.)
- */
- public void updateManageConferencePanel(List<Connection> connections) {
- mNumCallersInConference = connections.size();
- if (DBG) log("updateManageConferencePanel()... num connections in conference = "
- + mNumCallersInConference);
-
- // Can we give the user the option to separate out ("go private with") a single
- // caller from this conference?
- final boolean hasActiveCall = mCM.hasActiveFgCall();
- final boolean hasHoldingCall = mCM.hasActiveBgCall();
- boolean canSeparate = !(hasActiveCall && hasHoldingCall);
-
- for (int i = 0; i < MAX_CALLERS_IN_CONFERENCE; i++) {
- if (i < mNumCallersInConference) {
- // Fill in the row in the UI for this caller.
- Connection connection = (Connection) connections.get(i);
- updateManageConferenceRow(i, connection, canSeparate);
- } else {
- // Blank out this row in the UI
- updateManageConferenceRow(i, null, false);
- }
- }
- }
-
- /**
- * Updates a single row of the "Manage conference" UI. (One row in this
- * UI represents a single caller in the conference.)
- *
- * @param i the row to update
- * @param connection the Connection corresponding to this caller.
- * If null, that means this is an "empty slot" in the conference,
- * so hide this row in the UI.
- * @param canSeparate if true, show a "Separate" (i.e. "Private") button
- * on this row in the UI.
- */
- public void updateManageConferenceRow(final int i,
- final Connection connection,
- boolean canSeparate) {
- if (DBG) log("updateManageConferenceRow(" + i + ")... connection = " + connection);
-
- if (connection != null) {
- // Activate this row of the Manage conference panel:
- mConferenceCallList[i].setVisibility(View.VISIBLE);
-
- // get the relevant children views
- View endButton = mConferenceCallList[i].findViewById(R.id.conferenceCallerDisconnect);
- View separateButton = mConferenceCallList[i].findViewById(
- R.id.conferenceCallerSeparate);
- TextView nameTextView = (TextView) mConferenceCallList[i].findViewById(
- R.id.conferenceCallerName);
- TextView numberTextView = (TextView) mConferenceCallList[i].findViewById(
- R.id.conferenceCallerNumber);
- TextView numberTypeTextView = (TextView) mConferenceCallList[i].findViewById(
- R.id.conferenceCallerNumberType);
-
- if (DBG) log("- button: " + endButton + ", nameTextView: " + nameTextView);
-
- // Hook up this row's buttons.
- View.OnClickListener endThisConnection = new View.OnClickListener() {
- @Override
- public void onClick(View v) {
- endConferenceConnection(i, connection);
- PhoneGlobals.getInstance().pokeUserActivity();
- }
- };
- endButton.setOnClickListener(endThisConnection);
- //
- if (canSeparate) {
- View.OnClickListener separateThisConnection = new View.OnClickListener() {
- @Override
- public void onClick(View v) {
- separateConferenceConnection(i, connection);
- PhoneGlobals.getInstance().pokeUserActivity();
- }
- };
- separateButton.setOnClickListener(separateThisConnection);
- separateButton.setVisibility(View.VISIBLE);
- } else {
- separateButton.setVisibility(View.INVISIBLE);
- }
-
- // Name/number for this caller.
- QueryCompleteListener listener = new QueryCompleteListener(i);
- PhoneUtils.CallerInfoToken info =
- PhoneUtils.startGetCallerInfo(mInCallScreen,
- connection, listener, connection);
- if (DBG) log(" - got info from startGetCallerInfo(): " + info);
-
- // display the CallerInfo.
- displayCallerInfoForConferenceRow(info.currentInfo, connection.getNumberPresentation(),
- nameTextView, numberTypeTextView, numberTextView);
- } else {
- // Disable this row of the Manage conference panel:
- mConferenceCallList[i].setVisibility(View.GONE);
- }
- }
-
- /**
- * Helper function to fill out the Conference Call(er) information
- * for each item in the "Manage Conference Call" list.
- *
- * @param presentation presentation specified by {@link Connection}.
- */
- public final void displayCallerInfoForConferenceRow(CallerInfo ci, int presentation,
- TextView nameTextView, TextView numberTypeTextView, TextView numberTextView) {
- // gather the correct name and number information.
- String callerName = "";
- String callerNumber = "";
- String callerNumberType = "";
- if (ci != null) {
- callerName = ci.name;
- if (TextUtils.isEmpty(callerName)) {
- // Do similar fallback as CallCard does.
- // See also CallCard#updateDisplayForPerson().
- if (TextUtils.isEmpty(ci.phoneNumber)) {
- callerName = PhoneUtils.getPresentationString(mInCallScreen, presentation);
- } else if (!TextUtils.isEmpty(ci.cnapName)) {
- // No name, but we do have a valid CNAP name, so use that.
- callerName = ci.cnapName;
- } else {
- callerName = ci.phoneNumber;
- }
- } else {
- callerNumber = ci.phoneNumber;
- callerNumberType = ci.phoneLabel;
- }
- }
-
- // set the caller name
- nameTextView.setText(callerName);
-
- // set the caller number in subscript, or make the field disappear.
- if (TextUtils.isEmpty(callerNumber)) {
- numberTextView.setVisibility(View.GONE);
- numberTypeTextView.setVisibility(View.GONE);
- } else {
- numberTextView.setVisibility(View.VISIBLE);
- numberTextView.setText(callerNumber);
- numberTypeTextView.setVisibility(View.VISIBLE);
- numberTypeTextView.setText(callerNumberType);
- }
- }
-
- /**
- * Ends the specified connection on a conference call. This method is
- * run (via a closure containing a row index and Connection) when the
- * user clicks the "End" button on a specific row in the Manage
- * conference UI.
- */
- public void endConferenceConnection(int i, Connection connection) {
- if (DBG) log("===> ENDING conference connection " + i
- + ": Connection " + connection);
- // The actual work of ending the connection:
- PhoneUtils.hangup(connection);
- // No need to manually update the "Manage conference" UI here;
- // that'll happen automatically very soon (when we get the
- // onDisconnect() callback triggered by this hangup() call.)
- }
-
- /**
- * Separates out the specified connection on a conference call. This
- * method is run (via a closure containing a row index and Connection)
- * when the user clicks the "Separate" (i.e. "Private") button on a
- * specific row in the Manage conference UI.
- */
- public void separateConferenceConnection(int i, Connection connection) {
- if (DBG) log("===> SEPARATING conference connection " + i
- + ": Connection " + connection);
-
- PhoneUtils.separateCall(connection);
-
- // Note that separateCall() automagically makes the
- // newly-separated call into the foreground call (which is the
- // desired UI), so there's no need to do any further
- // call-switching here.
- // There's also no need to manually update (or hide) the "Manage
- // conference" UI; that'll happen on its own in a moment (when we
- // get the phone state change event triggered by the call to
- // separateCall().)
- }
-
-
- private void log(String msg) {
- Log.d(LOG_TAG, msg);
- }
-}
diff --git a/src/com/android/phone/NotificationMgr.java b/src/com/android/phone/NotificationMgr.java
index 4c0c8ed..3e30798 100644
--- a/src/com/android/phone/NotificationMgr.java
+++ b/src/com/android/phone/NotificationMgr.java
@@ -67,7 +67,7 @@
*
* @see PhoneGlobals.notificationMgr
*/
-public class NotificationMgr implements CallerInfoAsyncQuery.OnQueryCompleteListener{
+public class NotificationMgr {
private static final String LOG_TAG = "NotificationMgr";
private static final boolean DBG =
(PhoneGlobals.DBG_LEVEL >= 1) && (SystemProperties.getInt("ro.debuggable", 0) == 1);
@@ -103,7 +103,6 @@
private Context mContext;
private NotificationManager mNotificationManager;
private StatusBarManager mStatusBarManager;
- private PowerManager mPowerManager;
private Toast mToast;
private boolean mShowingSpeakerphoneIcon;
private boolean mShowingMuteIcon;
@@ -113,10 +112,6 @@
// used to track the missed call counter, default to 0.
private int mNumberMissedCalls = 0;
- // Currently-displayed resource IDs for some status bar icons (or zero
- // if no notification is active):
- private int mInCallResId;
-
// used to track the notification of selected network unavailable
private boolean mSelectedUnavailableNotify = false;
@@ -141,8 +136,6 @@
(NotificationManager) app.getSystemService(Context.NOTIFICATION_SERVICE);
mStatusBarManager =
(StatusBarManager) app.getSystemService(Context.STATUS_BAR_SERVICE);
- mPowerManager =
- (PowerManager) app.getSystemService(Context.POWER_SERVICE);
mPhone = app.phone; // TODO: better style to use mCM.getDefaultPhone() everywhere instead
mCM = app.mCM;
statusBarHelper = new StatusBarHelper();
@@ -256,6 +249,7 @@
state |= StatusBarManager.DISABLE_HOME;
state |= StatusBarManager.DISABLE_RECENT;
state |= StatusBarManager.DISABLE_BACK;
+ state |= StatusBarManager.DISABLE_SEARCH;
}
if (DBG) log("updateStatusBar: state = 0x" + Integer.toHexString(state));
@@ -283,10 +277,6 @@
mQueryHandler.startQuery(CALL_LOG_TOKEN, null, Calls.CONTENT_URI, CALL_LOG_PROJECTION,
where.toString(), null, Calls.DEFAULT_SORT_ORDER);
- // Update (or cancel) the in-call notification
- if (DBG) log("- updating in-call notification at startup...");
- updateInCallNotification();
-
// Depend on android.app.StatusBarManager to be set to
// disable(DISABLE_NONE) upon startup. This will be the
// case even if the phone app crashes.
@@ -656,10 +646,6 @@
// activity, since the in-call UI already provides an onscreen
// indication of the speaker state. (This reduces clutter in the
// status bar.)
- if (mApp.isShowingCallScreen()) {
- cancelSpeakerphone();
- return;
- }
if (showNotification) {
notifySpeakerphone();
@@ -695,10 +681,6 @@
// foreground activity, since the in-call UI already provides an
// onscreen indication of the mute state. (This reduces clutter
// in the status bar.)
- if (mApp.isShowingCallScreen()) {
- cancelMute();
- return;
- }
if ((mCM.getState() == PhoneConstants.State.OFFHOOK) && PhoneUtils.getMute()) {
if (DBG) log("updateMuteNotification: MUTED");
@@ -710,470 +692,11 @@
}
/**
- * Updates the phone app's status bar notification based on the
- * current telephony state, or cancels the notification if the phone
- * is totally idle.
- *
- * This method will never actually launch the incoming-call UI.
- * (Use updateNotificationAndLaunchIncomingCallUi() for that.)
- */
- public void updateInCallNotification() {
- // allowFullScreenIntent=false means *don't* allow the incoming
- // call UI to be launched.
- updateInCallNotification(false);
- }
-
- /**
- * Updates the phone app's status bar notification *and* launches the
- * incoming call UI in response to a new incoming call.
- *
- * This is just like updateInCallNotification(), with one exception:
- * If an incoming call is ringing (or call-waiting), the notification
- * will also include a "fullScreenIntent" that will cause the
- * InCallScreen to be launched immediately, unless the current
- * foreground activity is marked as "immersive".
- *
- * (This is the mechanism that actually brings up the incoming call UI
- * when we receive a "new ringing connection" event from the telephony
- * layer.)
- *
- * Watch out: this method should ONLY be called directly from the code
- * path in CallNotifier that handles the "new ringing connection"
- * event from the telephony layer. All other places that update the
- * in-call notification (like for phone state changes) should call
- * updateInCallNotification() instead. (This ensures that we don't
- * end up launching the InCallScreen multiple times for a single
- * incoming call, which could cause slow responsiveness and/or visible
- * glitches.)
- *
- * Also note that this method is safe to call even if the phone isn't
- * actually ringing (or, more likely, if an incoming call *was*
- * ringing briefly but then disconnected). In that case, we'll simply
- * update or cancel the in-call notification based on the current
- * phone state.
- *
- * @see #updateInCallNotification(boolean)
- */
- public void updateNotificationAndLaunchIncomingCallUi() {
- // Set allowFullScreenIntent=true to indicate that we *should*
- // launch the incoming call UI if necessary.
- updateInCallNotification(true);
- }
-
- /**
- * Helper method for updateInCallNotification() and
- * updateNotificationAndLaunchIncomingCallUi(): Update the phone app's
- * status bar notification based on the current telephony state, or
- * cancels the notification if the phone is totally idle.
- *
- * @param allowFullScreenIntent If true, *and* an incoming call is
- * ringing, the notification will include a "fullScreenIntent"
- * pointing at the InCallScreen (which will cause the InCallScreen
- * to be launched.)
- * Watch out: This should be set to true *only* when directly
- * handling the "new ringing connection" event from the telephony
- * layer (see updateNotificationAndLaunchIncomingCallUi().)
- */
- private void updateInCallNotification(boolean allowFullScreenIntent) {
- int resId;
- if (DBG) log("updateInCallNotification(allowFullScreenIntent = "
- + allowFullScreenIntent + ")...");
-
- // 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 (!PhoneGlobals.sVoiceCapable) {
- if (DBG) log("- non-voice-capable device; suppressing notification.");
- return;
- }
-
- // If the phone is idle, completely clean up all call-related
- // notifications.
- if (mCM.getState() == PhoneConstants.State.IDLE) {
- cancelInCall();
- cancelMute();
- cancelSpeakerphone();
- return;
- }
-
- final boolean hasRingingCall = mCM.hasActiveRingingCall();
- final boolean hasActiveCall = mCM.hasActiveFgCall();
- final boolean hasHoldingCall = mCM.hasActiveBgCall();
- if (DBG) {
- log(" - hasRingingCall = " + hasRingingCall);
- log(" - hasActiveCall = " + hasActiveCall);
- log(" - hasHoldingCall = " + hasHoldingCall);
- }
-
- // Suppress the in-call notification if the InCallScreen is the
- // foreground activity, since it's already obvious that you're on a
- // call. (The status bar icon is needed only if you navigate *away*
- // from the in-call UI.)
- boolean suppressNotification = mApp.isShowingCallScreen();
- // if (DBG) log("- suppressNotification: initial value: " + suppressNotification);
-
- // ...except for a couple of cases where we *never* suppress the
- // notification:
- //
- // - If there's an incoming ringing call: always show the
- // notification, since the in-call notification is what actually
- // launches the incoming call UI in the first place (see
- // notification.fullScreenIntent below.) This makes sure that we'll
- // correctly handle the case where a new incoming call comes in but
- // the InCallScreen is already in the foreground.
- if (hasRingingCall) suppressNotification = false;
-
- // - If "voice privacy" mode is active: always show the notification,
- // since that's the only "voice privacy" indication we have.
- boolean enhancedVoicePrivacy = mApp.notifier.getVoicePrivacyState();
- // if (DBG) log("updateInCallNotification: enhancedVoicePrivacy = " + enhancedVoicePrivacy);
- if (enhancedVoicePrivacy) suppressNotification = false;
-
- if (suppressNotification) {
- if (DBG) log("- suppressNotification = true; reducing clutter in status bar...");
- cancelInCall();
- // Suppress the mute and speaker status bar icons too
- // (also to reduce clutter in the status bar.)
- cancelSpeakerphone();
- cancelMute();
- return;
- }
-
- // Display the appropriate icon in the status bar,
- // based on the current phone and/or bluetooth state.
-
- if (hasRingingCall) {
- // There's an incoming ringing call.
- resId = R.drawable.stat_sys_phone_call;
- } else if (!hasActiveCall && hasHoldingCall) {
- // There's only one call, and it's on hold.
- if (enhancedVoicePrivacy) {
- resId = R.drawable.stat_sys_vp_phone_call_on_hold;
- } else {
- resId = R.drawable.stat_sys_phone_call_on_hold;
- }
- } else {
- if (enhancedVoicePrivacy) {
- resId = R.drawable.stat_sys_vp_phone_call;
- } else {
- resId = R.drawable.stat_sys_phone_call;
- }
- }
-
- // Note we can't just bail out now if (resId == mInCallResId),
- // since even if the status icon hasn't changed, some *other*
- // notification-related info may be different from the last time
- // we were here (like the caller-id info of the foreground call,
- // if the user swapped calls...)
-
- if (DBG) log("- Updating status bar icon: resId = " + resId);
- mInCallResId = resId;
-
- // Even if both lines are in use, we only show a single item in
- // the expanded Notifications UI. It's labeled "Ongoing call"
- // (or "On hold" if there's only one call, and it's on hold.)
- // Also, we don't have room to display caller-id info from two
- // different calls. So if both lines are in use, display info
- // from the foreground call. And if there's a ringing call,
- // display that regardless of the state of the other calls.
-
- Call currentCall;
- if (hasRingingCall) {
- currentCall = mCM.getFirstActiveRingingCall();
- } else if (hasActiveCall) {
- currentCall = mCM.getActiveFgCall();
- } else {
- currentCall = mCM.getFirstActiveBgCall();
- }
- Connection currentConn = currentCall.getEarliestConnection();
-
- final Notification.Builder builder = new Notification.Builder(mContext);
- builder.setSmallIcon(mInCallResId).setOngoing(true);
-
- // PendingIntent that can be used to launch the InCallScreen. The
- // system fires off this intent if the user pulls down the windowshade
- // and clicks the notification's expanded view. It's also used to
- // launch the InCallScreen immediately when when there's an incoming
- // call (see the "fullScreenIntent" field below).
- PendingIntent inCallPendingIntent =
- PendingIntent.getActivity(mContext, 0,
- PhoneGlobals.createInCallIntent(), 0);
- builder.setContentIntent(inCallPendingIntent);
-
- // Update icon on the left of the notification.
- // - If it is directly available from CallerInfo, we'll just use that.
- // - If it is not, use the same icon as in the status bar.
- CallerInfo callerInfo = null;
- if (currentConn != null) {
- Object o = currentConn.getUserData();
- if (o instanceof CallerInfo) {
- callerInfo = (CallerInfo) o;
- } else if (o instanceof PhoneUtils.CallerInfoToken) {
- callerInfo = ((PhoneUtils.CallerInfoToken) o).currentInfo;
- } else {
- Log.w(LOG_TAG, "CallerInfo isn't available while Call object is available.");
- }
- }
- boolean largeIconWasSet = false;
- if (callerInfo != null) {
- // In most cases, the user will see the notification after CallerInfo is already
- // available, so photo will be available from this block.
- if (callerInfo.isCachedPhotoCurrent) {
- // .. and in that case CallerInfo's cachedPhotoIcon should also be available.
- // If it happens not, then try using cachedPhoto, assuming Drawable coming from
- // ContactProvider will be BitmapDrawable.
- if (callerInfo.cachedPhotoIcon != null) {
- builder.setLargeIcon(callerInfo.cachedPhotoIcon);
- largeIconWasSet = true;
- } else if (callerInfo.cachedPhoto instanceof BitmapDrawable) {
- if (DBG) log("- BitmapDrawable found for large icon");
- Bitmap bitmap = ((BitmapDrawable) callerInfo.cachedPhoto).getBitmap();
- builder.setLargeIcon(bitmap);
- largeIconWasSet = true;
- } else {
- if (DBG) {
- log("- Failed to fetch icon from CallerInfo's cached photo."
- + " (cachedPhotoIcon: " + callerInfo.cachedPhotoIcon
- + ", cachedPhoto: " + callerInfo.cachedPhoto + ")."
- + " Ignore it.");
- }
- }
- }
-
- if (!largeIconWasSet && callerInfo.photoResource > 0) {
- if (DBG) {
- log("- BitmapDrawable nor person Id not found for large icon."
- + " Use photoResource: " + callerInfo.photoResource);
- }
- Drawable drawable =
- mContext.getResources().getDrawable(callerInfo.photoResource);
- if (drawable instanceof BitmapDrawable) {
- Bitmap bitmap = ((BitmapDrawable) drawable).getBitmap();
- builder.setLargeIcon(bitmap);
- largeIconWasSet = true;
- } else {
- if (DBG) {
- log("- PhotoResource was found but it didn't return BitmapDrawable."
- + " Ignore it");
- }
- }
- }
- } else {
- if (DBG) log("- CallerInfo not found. Use the same icon as in the status bar.");
- }
-
- // Failed to fetch Bitmap.
- if (!largeIconWasSet && DBG) {
- log("- No useful Bitmap was found for the photo."
- + " Use the same icon as in the status bar.");
- }
-
- // If the connection is valid, then build what we need for the
- // content text of notification, and start the chronometer.
- // Otherwise, don't bother and just stick with content title.
- if (currentConn != null) {
- if (DBG) log("- Updating context text and chronometer.");
- if (hasRingingCall) {
- // Incoming call is ringing.
- builder.setContentText(mContext.getString(R.string.notification_incoming_call));
- builder.setUsesChronometer(false);
- } else if (hasHoldingCall && !hasActiveCall) {
- // Only one call, and it's on hold.
- builder.setContentText(mContext.getString(R.string.notification_on_hold));
- builder.setUsesChronometer(false);
- } else {
- // We show the elapsed time of the current call using Chronometer.
- builder.setUsesChronometer(true);
-
- // Determine the "start time" of the current connection.
- // We can't use currentConn.getConnectTime(), because (1) that's
- // in the currentTimeMillis() time base, and (2) it's zero when
- // the phone first goes off hook, since the getConnectTime counter
- // doesn't start until the DIALING -> ACTIVE transition.
- // Instead we start with the current connection's duration,
- // and translate that into the elapsedRealtime() timebase.
- long callDurationMsec = currentConn.getDurationMillis();
- builder.setWhen(System.currentTimeMillis() - callDurationMsec);
-
- 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.");
- }
-
- // display conference call string if this call is a conference
- // call, otherwise display the connection information.
-
- // Line 2 of the expanded view (smaller text). This is usually a
- // contact name or phone number.
- String expandedViewLine2 = "";
- // TODO: it may not make sense for every point to make separate
- // checks for isConferenceCall, so we need to think about
- // possibly including this in startGetCallerInfo or some other
- // common point.
- if (PhoneUtils.isConferenceCall(currentCall)) {
- // if this is a conference call, just use that as the caller name.
- expandedViewLine2 = mContext.getString(R.string.card_title_conf_call);
- } else {
- // If necessary, start asynchronous query to do the caller-id lookup.
- PhoneUtils.CallerInfoToken cit =
- PhoneUtils.startGetCallerInfo(mContext, currentCall, this, this);
- expandedViewLine2 = PhoneUtils.getCompactNameFromCallerInfo(cit.currentInfo, mContext);
- // Note: For an incoming call, the very first time we get here we
- // won't have a contact name yet, since we only just started the
- // caller-id query. So expandedViewLine2 will start off as a raw
- // phone number, but we'll update it very quickly when the query
- // completes (see onQueryComplete() below.)
- }
-
- if (DBG) log("- Updating expanded view: line 2 '" + /*expandedViewLine2*/ "xxxxxxx" + "'");
- builder.setContentTitle(expandedViewLine2);
-
- // TODO: We also need to *update* this notification in some cases,
- // like when a call ends on one line but the other is still in use
- // (ie. make sure the caller info here corresponds to the active
- // line), and maybe even when the user swaps calls (ie. if we only
- // show info here for the "current active call".)
-
- // Activate a couple of special Notification features if an
- // incoming call is ringing:
- if (hasRingingCall) {
- if (DBG) log("- Using hi-pri notification for ringing call!");
-
- // This is a high-priority event that should be shown even if the
- // status bar is hidden or if an immersive activity is running.
- builder.setPriority(Notification.PRIORITY_HIGH);
-
- // If an immersive activity is running, we have room for a single
- // line of text in the small notification popup window.
- // We use expandedViewLine2 for this (i.e. the name or number of
- // the incoming caller), since that's more relevant than
- // expandedViewLine1 (which is something generic like "Incoming
- // call".)
- builder.setTicker(expandedViewLine2);
-
- if (allowFullScreenIntent) {
- // Ok, we actually want to launch the incoming call
- // UI at this point (in addition to simply posting a notification
- // to the status bar). Setting fullScreenIntent will cause
- // the InCallScreen to be launched immediately *unless* the
- // current foreground activity is marked as "immersive".
- if (DBG) log("- Setting fullScreenIntent: " + inCallPendingIntent);
- builder.setFullScreenIntent(inCallPendingIntent, true);
-
- // Ugly hack alert:
- //
- // The NotificationManager has the (undocumented) behavior
- // that it will *ignore* the fullScreenIntent field if you
- // post a new Notification that matches the ID of one that's
- // already active. Unfortunately this is exactly what happens
- // when you get an incoming call-waiting call: the
- // "ongoing call" notification is already visible, so the
- // InCallScreen won't get launched in this case!
- // (The result: if you bail out of the in-call UI while on a
- // call and then get a call-waiting call, the incoming call UI
- // won't come up automatically.)
- //
- // The workaround is to just notice this exact case (this is a
- // call-waiting call *and* the InCallScreen is not in the
- // foreground) and manually cancel the in-call notification
- // before (re)posting it.
- //
- // TODO: there should be a cleaner way of avoiding this
- // problem (see discussion in bug 3184149.)
- Call ringingCall = mCM.getFirstActiveRingingCall();
- if ((ringingCall.getState() == Call.State.WAITING) && !mApp.isShowingCallScreen()) {
- Log.i(LOG_TAG, "updateInCallNotification: call-waiting! force relaunch...");
- // Cancel the IN_CALL_NOTIFICATION immediately before
- // (re)posting it; this seems to force the
- // NotificationManager to launch the fullScreenIntent.
- mNotificationManager.cancel(IN_CALL_NOTIFICATION);
- }
- }
- } else { // not ringing call
- // Make the notification prioritized over the other normal notifications.
- builder.setPriority(Notification.PRIORITY_HIGH);
-
- // TODO: use "if (DBG)" for this comment.
- log("Will show \"hang-up\" action in the ongoing active call Notification");
- // TODO: use better asset.
- builder.addAction(R.drawable.stat_sys_phone_call_end,
- mContext.getText(R.string.notification_action_end_call),
- PhoneGlobals.createHangUpOngoingCallPendingIntent(mContext));
- }
-
- Notification notification = builder.getNotification();
- if (DBG) log("Notifying IN_CALL_NOTIFICATION: " + notification);
- // TODO(klp): not needed anymore. Possibly delete this and move notification to incallui.
- //mNotificationManager.notify(IN_CALL_NOTIFICATION, notification);
-
- // Finally, refresh the mute and speakerphone notifications (since
- // some phone state changes can indirectly affect the mute and/or
- // speaker state).
- updateSpeakerNotification();
- updateMuteNotification();
- }
-
- /**
- * Implemented for CallerInfoAsyncQuery.OnQueryCompleteListener interface.
- * refreshes the contentView when called.
- */
- @Override
- public void onQueryComplete(int token, Object cookie, CallerInfo ci){
- if (DBG) log("CallerInfo query complete (for NotificationMgr), "
- + "updating in-call notification..");
- if (DBG) log("- cookie: " + cookie);
- if (DBG) log("- ci: " + ci);
-
- if (cookie == this) {
- // Ok, this is the caller-id query we fired off in
- // updateInCallNotification(), presumably when an incoming call
- // first appeared. If the caller-id info matched any contacts,
- // compactName should now be a real person name rather than a raw
- // phone number:
- if (DBG) log("- compactName is now: "
- + PhoneUtils.getCompactNameFromCallerInfo(ci, mContext));
-
- // Now that our CallerInfo object has been fully filled-in,
- // refresh the in-call notification.
- if (DBG) log("- updating notification after query complete...");
- updateInCallNotification();
- } else {
- Log.w(LOG_TAG, "onQueryComplete: caller-id query from unknown source! "
- + "cookie = " + cookie);
- }
- }
-
- /**
- * Take down the in-call notification.
- * @see updateInCallNotification()
- */
- private void cancelInCall() {
- if (DBG) log("cancelInCall()...");
- mNotificationManager.cancel(IN_CALL_NOTIFICATION);
- mInCallResId = 0;
- }
-
- /**
* Completely take down the in-call notification *and* the mute/speaker
* notifications as well, to indicate that the phone is now idle.
*/
/* package */ void cancelCallInProgressNotifications() {
- if (DBG) log("cancelCallInProgressNotifications()...");
- if (mInCallResId == 0) {
- return;
- }
-
- if (DBG) log("cancelCallInProgressNotifications: " + mInCallResId);
- cancelInCall();
+ if (DBG) log("cancelCallInProgressNotifications");
cancelMute();
cancelSpeakerphone();
}
diff --git a/src/com/android/phone/OtaUtils.java b/src/com/android/phone/OtaUtils.java
index e713df9..fe11831 100644
--- a/src/com/android/phone/OtaUtils.java
+++ b/src/com/android/phone/OtaUtils.java
@@ -125,8 +125,11 @@
// Extra attached to the above PendingIntent that indicates
// success or failure.
- public static final String EXTRA_OTASP_RESULT_CODE =
- "otasp_result_code";
+ public static final String EXTRA_OTASP_RESULT_CODE = "otasp_result_code";
+
+ // Extra attached to the above PendingIntent that contains an error code.
+ public static final String EXTRA_OTASP_ERROR_CODE = "otasp_error_code";
+
public static final int OTASP_UNKNOWN = 0;
public static final int OTASP_USER_SKIPPED = 1; // Only meaningful with interactive OTASP
public static final int OTASP_SUCCESS = 2;
@@ -141,17 +144,9 @@
private static final String OTASP_NUMBER = "*228";
private static final String OTASP_NUMBER_NON_INTERACTIVE = "*22899";
- private InCallScreen mInCallScreen;
private Context mContext;
private PhoneGlobals mApplication;
private OtaWidgetData mOtaWidgetData;
- private ViewGroup mInCallTouchUi; // UI controls for regular calls
- private CallCard mCallCard;
-
- // The DTMFTwelveKeyDialer instance. We create this in
- // initOtaInCallScreen(), and attach it to the DTMFTwelveKeyDialerView
- // ("otaDtmfDialerView") that comes from otacall_card.xml.
- private DTMFTwelveKeyDialer mOtaCallCardDtmfDialer;
private static boolean sIsWizardMode = true;
@@ -201,7 +196,6 @@
public AlertDialog otaFailureDialog;
public AlertDialog otaSkipConfirmationDialog;
public TextView otaTitle;
- public DTMFTwelveKeyDialerView otaDtmfDialerView;
public Button otaTryAgainButton;
}
@@ -225,59 +219,6 @@
}
/**
- * Updates the OtaUtils object's references to some UI elements belonging to
- * the InCallScreen. This is used only in interactive mode.
- *
- * Use clearUiWidgets() to clear out these references. (The InCallScreen
- * is responsible for doing this from its onDestroy() method.)
- *
- * This method has no effect if the UI widgets have already been set up.
- * (In other words, it's safe to call this every time through
- * InCallScreen.onResume().)
- */
- public void updateUiWidgets(InCallScreen inCallScreen,
- ViewGroup inCallTouchUi, CallCard callCard) {
- if (DBG) log("updateUiWidgets()... mInCallScreen = " + mInCallScreen);
-
- if (!mInteractive) {
- throw new IllegalStateException("updateUiWidgets() called in non-interactive mode");
- }
-
- if (mInCallScreen != null) {
- if (DBG) log("updateUiWidgets(): widgets already set up, nothing to do...");
- return;
- }
-
- mInCallScreen = inCallScreen;
- mInCallTouchUi = inCallTouchUi;
- mCallCard = callCard;
- mOtaWidgetData = new OtaWidgetData();
-
- // Inflate OTASP-specific UI elements:
- ViewStub otaCallCardStub = (ViewStub) mInCallScreen.findViewById(R.id.otaCallCardStub);
- if (otaCallCardStub != null) {
- // If otaCallCardStub is null here, that means it's already been
- // inflated (which could have happened in the current InCallScreen
- // instance for a *prior* OTASP call.)
- otaCallCardStub.inflate();
- }
-
- readXmlSettings();
- initOtaInCallScreen();
- }
-
- /**
- * Clear out the OtaUtils object's references to any InCallScreen UI
- * elements. This is the opposite of updateUiWidgets().
- */
- public void clearUiWidgets() {
- mInCallScreen = null;
- mInCallTouchUi = null;
- mCallCard = null;
- mOtaWidgetData = null;
- }
-
- /**
* Starts the OTA provisioning call. If the MIN isn't available yet, it returns false and adds
* an event to return the request to the calling app when it becomes available.
*
@@ -583,7 +524,7 @@
// TODO(OTASP): note app.inCallUiState.inCallScreenMode and
// app.cdmaOtaInCallScreenUiState.state are mostly redundant. Combine them.
- app.inCallUiState.inCallScreenMode = InCallUiState.InCallScreenMode.OTA_NORMAL;
+ // app.inCallUiState.inCallScreenMode = InCallUiState.InCallScreenMode.OTA_NORMAL;
// TODO(OTASP / bug 5092031): we ideally should call
// otaShowListeningScreen() here to make sure that the DTMF dialpad
@@ -714,7 +655,7 @@
if (DBG) log("otaShowHome()...");
mApplication.cdmaOtaScreenState.otaScreenState =
CdmaOtaScreenState.OtaScreenState.OTA_STATUS_UNDEFINED;
- mInCallScreen.endInCallScreenSession();
+ // mInCallScreen.endInCallScreenSession();
Intent intent = new Intent(Intent.ACTION_MAIN);
intent.addCategory (Intent.CATEGORY_HOME);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
@@ -727,7 +668,7 @@
sendOtaspResult(OTASP_USER_SKIPPED);
- if (mInteractive) mInCallScreen.finish();
+ // if (mInteractive) mInCallScreen.finish();
return;
}
@@ -753,7 +694,7 @@
// ...and get the OTASP-specific UI into the right state.
otaShowListeningScreen();
- mInCallScreen.requestUpdateScreen();
+ // mInCallScreen.requestUpdateScreen();
}
return;
}
@@ -804,7 +745,7 @@
otaScreenInitialize();
mOtaWidgetData.otaTextListenProgress.setVisibility(View.VISIBLE);
mOtaWidgetData.otaTextListenProgress.setText(R.string.ota_listen);
- mOtaWidgetData.otaDtmfDialerView.setVisibility(View.VISIBLE);
+ // mOtaWidgetData.otaDtmfDialerView.setVisibility(View.VISIBLE);
mOtaWidgetData.callCardOtaButtonsListenProgress.setVisibility(View.VISIBLE);
mOtaWidgetData.otaSpeakerButton.setVisibility(View.VISIBLE);
boolean speakerOn = PhoneUtils.isSpeakerOn(mContext);
@@ -923,7 +864,7 @@
mApplication.cdmaOtaScreenState.otaScreenState =
CdmaOtaScreenState.OtaScreenState.OTA_STATUS_PROGRESS;
- if ((mOtaWidgetData == null) || (mInCallScreen == null)) {
+ if ((mOtaWidgetData == null) /* || (mInCallScreen == null) */) {
Log.w(LOG_TAG, "otaShowInProgressScreen: UI widgets not set up yet!");
// TODO(OTASP): our CdmaOtaScreenState is now correct; we just set
@@ -1008,9 +949,9 @@
mOtaWidgetData.callCardOtaButtonsFailSuccess.setVisibility(View.VISIBLE);
mOtaWidgetData.otaTryAgainButton.setVisibility(View.VISIBLE);
//close the dialer if open
- if (isDialerOpened()) {
- mOtaCallCardDtmfDialer.closeDialer(false);
- }
+ // if (isDialerOpened()) {
+ // mOtaCallCardDtmfDialer.closeDialer(false);
+ // }
}
/**
@@ -1026,9 +967,9 @@
mOtaWidgetData.callCardOtaButtonsFailSuccess.setVisibility(View.VISIBLE);
mOtaWidgetData.otaNextButton.setVisibility(View.VISIBLE);
//close the dialer if open
- if (isDialerOpened()) {
- mOtaCallCardDtmfDialer.closeDialer(false);
- }
+ // if (isDialerOpened()) {
+ // mOtaCallCardDtmfDialer.closeDialer(false);
+ // }
}
/**
@@ -1047,7 +988,7 @@
log("Ignoring key events...");
return true;
}};
- mOtaWidgetData.spcErrorDialog = new AlertDialog.Builder(mInCallScreen)
+ mOtaWidgetData.spcErrorDialog = new AlertDialog.Builder(null /* mInCallScreen */)
.setMessage(R.string.ota_spc_failure)
.setOnKeyListener(keyListener)
.create();
@@ -1056,12 +997,12 @@
| WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
mOtaWidgetData.spcErrorDialog.show();
//close the dialer if open
- if (isDialerOpened()) {
- mOtaCallCardDtmfDialer.closeDialer(false);
- }
+ // if (isDialerOpened()) {
+ // mOtaCallCardDtmfDialer.closeDialer(false);
+ // }
long noticeTime = length*1000;
if (DBG) log("otaShowSpcErrorNotice(), remaining SPC noticeTime" + noticeTime);
- mInCallScreen.requestCloseSpcErrorNotice(noticeTime);
+ // mInCallScreen.requestCloseSpcErrorNotice(noticeTime);
}
}
@@ -1083,7 +1024,7 @@
private void otaShowProgramFailureNotice(int length) {
if (DBG) log("otaShowProgramFailureNotice()...");
if (mOtaWidgetData.otaFailureDialog == null) {
- mOtaWidgetData.otaFailureDialog = new AlertDialog.Builder(mInCallScreen)
+ mOtaWidgetData.otaFailureDialog = new AlertDialog.Builder(null /* mInCallScreen */)
.setMessage(R.string.ota_failure)
.create();
mOtaWidgetData.otaFailureDialog.getWindow().addFlags(
@@ -1092,7 +1033,7 @@
mOtaWidgetData.otaFailureDialog.show();
long noticeTime = length*1000;
- mInCallScreen.requestCloseOtaFailureNotice(noticeTime);
+ // mInCallScreen.requestCloseOtaFailureNotice(noticeTime);
}
}
@@ -1124,12 +1065,12 @@
return;
}
- if (mInCallTouchUi != null) mInCallTouchUi.setVisibility(View.GONE);
- if (mCallCard != null) {
- mCallCard.setVisibility(View.GONE);
- // TODO: try removing this.
- mCallCard.hideCallCardElements();
- }
+ // if (mInCallTouchUi != null) mInCallTouchUi.setVisibility(View.GONE);
+ // if (mCallCard != null) {
+ // mCallCard.setVisibility(View.GONE);
+ // // TODO: try removing this.
+ // mCallCard.hideCallCardElements();
+ // }
mOtaWidgetData.otaTitle.setText(R.string.ota_title_activate);
mOtaWidgetData.otaTextActivate.setVisibility(View.GONE);
@@ -1139,7 +1080,7 @@
mOtaWidgetData.callCardOtaButtonsActivate.setVisibility(View.GONE);
mOtaWidgetData.callCardOtaButtonsListenProgress.setVisibility(View.GONE);
mOtaWidgetData.callCardOtaButtonsFailSuccess.setVisibility(View.GONE);
- mOtaWidgetData.otaDtmfDialerView.setVisibility(View.GONE);
+ // mOtaWidgetData.otaDtmfDialerView.setVisibility(View.GONE);
mOtaWidgetData.otaSpeakerButton.setVisibility(View.GONE);
mOtaWidgetData.otaTryAgainButton.setVisibility(View.GONE);
mOtaWidgetData.otaNextButton.setVisibility(View.GONE);
@@ -1157,7 +1098,8 @@
}
public boolean isDialerOpened() {
- boolean retval = (mOtaCallCardDtmfDialer != null && mOtaCallCardDtmfDialer.isOpened());
+ // boolean retval = (mOtaCallCardDtmfDialer != null && mOtaCallCardDtmfDialer.isOpened());
+ boolean retval = false;
if (DBG) log("- isDialerOpened() ==> " + retval);
return retval;
}
@@ -1180,30 +1122,30 @@
return;
}
- if ((mInCallScreen != null) && mInCallScreen.isForegroundActivity()) {
- if (DBG) log("otaShowProperScreen(): InCallScreen in foreground, currentstate = "
- + mApplication.cdmaOtaScreenState.otaScreenState);
- if (mInCallTouchUi != null) {
- mInCallTouchUi.setVisibility(View.GONE);
- }
- if (mCallCard != null) {
- mCallCard.setVisibility(View.GONE);
- }
- if (mApplication.cdmaOtaScreenState.otaScreenState
- == CdmaOtaScreenState.OtaScreenState.OTA_STATUS_ACTIVATION) {
- otaShowActivateScreen();
- } else if (mApplication.cdmaOtaScreenState.otaScreenState
- == CdmaOtaScreenState.OtaScreenState.OTA_STATUS_LISTENING) {
- otaShowListeningScreen();
- } else if (mApplication.cdmaOtaScreenState.otaScreenState
- == CdmaOtaScreenState.OtaScreenState.OTA_STATUS_PROGRESS) {
- otaShowInProgressScreen();
- }
+ // if ((mInCallScreen != null) && mInCallScreen.isForegroundActivity()) {
+ // if (DBG) log("otaShowProperScreen(): InCallScreen in foreground, currentstate = "
+ // + mApplication.cdmaOtaScreenState.otaScreenState);
+ // if (mInCallTouchUi != null) {
+ // mInCallTouchUi.setVisibility(View.GONE);
+ // }
+ // if (mCallCard != null) {
+ // mCallCard.setVisibility(View.GONE);
+ // }
+ // if (mApplication.cdmaOtaScreenState.otaScreenState
+ // == CdmaOtaScreenState.OtaScreenState.OTA_STATUS_ACTIVATION) {
+ // otaShowActivateScreen();
+ // } else if (mApplication.cdmaOtaScreenState.otaScreenState
+ // == CdmaOtaScreenState.OtaScreenState.OTA_STATUS_LISTENING) {
+ // otaShowListeningScreen();
+ // } else if (mApplication.cdmaOtaScreenState.otaScreenState
+ // == CdmaOtaScreenState.OtaScreenState.OTA_STATUS_PROGRESS) {
+ // otaShowInProgressScreen();
+ // }
- if (mApplication.cdmaOtaProvisionData.inOtaSpcState) {
- otaShowSpcErrorNotice(getOtaSpcDisplayTime());
- }
- }
+ // if (mApplication.cdmaOtaProvisionData.inOtaSpcState) {
+ // otaShowSpcErrorNotice(getOtaSpcDisplayTime());
+ // }
+ // }
}
/**
@@ -1292,7 +1234,7 @@
// the screen is not updated by the call disconnect
// handler and we have to do it here
setSpeaker(false);
- mInCallScreen.handleOtaCallEnd();
+ // mInCallScreen.handleOtaCallEnd();
}
}
}
@@ -1320,7 +1262,7 @@
return true;
}
};
- mOtaWidgetData.otaSkipConfirmationDialog = new AlertDialog.Builder(mInCallScreen)
+ mOtaWidgetData.otaSkipConfirmationDialog = new AlertDialog.Builder(null /* mInCallScreen */)
.setTitle(R.string.ota_skip_activation_dialog_title)
.setMessage(R.string.ota_skip_activation_dialog_message)
.setPositiveButton(
@@ -1389,60 +1331,60 @@
*/
private void initOtaInCallScreen() {
if (DBG) log("initOtaInCallScreen()...");
- mOtaWidgetData.otaTitle = (TextView) mInCallScreen.findViewById(R.id.otaTitle);
- mOtaWidgetData.otaTextActivate = (TextView) mInCallScreen.findViewById(R.id.otaActivate);
+ // mOtaWidgetData.otaTitle = (TextView) mInCallScreen.findViewById(R.id.otaTitle);
+ // mOtaWidgetData.otaTextActivate = (TextView) mInCallScreen.findViewById(R.id.otaActivate);
mOtaWidgetData.otaTextActivate.setVisibility(View.GONE);
- mOtaWidgetData.otaTextListenProgress =
- (TextView) mInCallScreen.findViewById(R.id.otaListenProgress);
- mOtaWidgetData.otaTextProgressBar =
- (ProgressBar) mInCallScreen.findViewById(R.id.progress_large);
+ // mOtaWidgetData.otaTextListenProgress =
+ // (TextView) mInCallScreen.findViewById(R.id.otaListenProgress);
+ // mOtaWidgetData.otaTextProgressBar =
+ // (ProgressBar) mInCallScreen.findViewById(R.id.progress_large);
mOtaWidgetData.otaTextProgressBar.setIndeterminate(true);
- mOtaWidgetData.otaTextSuccessFail =
- (TextView) mInCallScreen.findViewById(R.id.otaSuccessFailStatus);
+ // mOtaWidgetData.otaTextSuccessFail =
+ // (TextView) mInCallScreen.findViewById(R.id.otaSuccessFailStatus);
- mOtaWidgetData.otaUpperWidgets =
- (ViewGroup) mInCallScreen.findViewById(R.id.otaUpperWidgets);
- mOtaWidgetData.callCardOtaButtonsListenProgress =
- (View) mInCallScreen.findViewById(R.id.callCardOtaListenProgress);
- mOtaWidgetData.callCardOtaButtonsActivate =
- (View) mInCallScreen.findViewById(R.id.callCardOtaActivate);
- mOtaWidgetData.callCardOtaButtonsFailSuccess =
- (View) mInCallScreen.findViewById(R.id.callCardOtaFailOrSuccessful);
+ // mOtaWidgetData.otaUpperWidgets =
+ // (ViewGroup) mInCallScreen.findViewById(R.id.otaUpperWidgets);
+ // mOtaWidgetData.callCardOtaButtonsListenProgress =
+ // (View) mInCallScreen.findViewById(R.id.callCardOtaListenProgress);
+ // mOtaWidgetData.callCardOtaButtonsActivate =
+ // (View) mInCallScreen.findViewById(R.id.callCardOtaActivate);
+ // mOtaWidgetData.callCardOtaButtonsFailSuccess =
+ // (View) mInCallScreen.findViewById(R.id.callCardOtaFailOrSuccessful);
- mOtaWidgetData.otaEndButton = (Button) mInCallScreen.findViewById(R.id.otaEndButton);
- mOtaWidgetData.otaEndButton.setOnClickListener(mInCallScreen);
- mOtaWidgetData.otaSpeakerButton =
- (ToggleButton) mInCallScreen.findViewById(R.id.otaSpeakerButton);
- mOtaWidgetData.otaSpeakerButton.setOnClickListener(mInCallScreen);
- mOtaWidgetData.otaActivateButton =
- (Button) mInCallScreen.findViewById(R.id.otaActivateButton);
- mOtaWidgetData.otaActivateButton.setOnClickListener(mInCallScreen);
- mOtaWidgetData.otaSkipButton = (Button) mInCallScreen.findViewById(R.id.otaSkipButton);
- mOtaWidgetData.otaSkipButton.setOnClickListener(mInCallScreen);
- mOtaWidgetData.otaNextButton = (Button) mInCallScreen.findViewById(R.id.otaNextButton);
- mOtaWidgetData.otaNextButton.setOnClickListener(mInCallScreen);
- mOtaWidgetData.otaTryAgainButton =
- (Button) mInCallScreen.findViewById(R.id.otaTryAgainButton);
- mOtaWidgetData.otaTryAgainButton.setOnClickListener(mInCallScreen);
+ // mOtaWidgetData.otaEndButton = (Button) mInCallScreen.findViewById(R.id.otaEndButton);
+ // mOtaWidgetData.otaEndButton.setOnClickListener(mInCallScreen);
+ // mOtaWidgetData.otaSpeakerButton =
+ // (ToggleButton) mInCallScreen.findViewById(R.id.otaSpeakerButton);
+ // mOtaWidgetData.otaSpeakerButton.setOnClickListener(mInCallScreen);
+ // mOtaWidgetData.otaActivateButton =
+ // (Button) mInCallScreen.findViewById(R.id.otaActivateButton);
+ // mOtaWidgetData.otaActivateButton.setOnClickListener(mInCallScreen);
+ // mOtaWidgetData.otaSkipButton = (Button) mInCallScreen.findViewById(R.id.otaSkipButton);
+ // mOtaWidgetData.otaSkipButton.setOnClickListener(mInCallScreen);
+ // mOtaWidgetData.otaNextButton = (Button) mInCallScreen.findViewById(R.id.otaNextButton);
+ // mOtaWidgetData.otaNextButton.setOnClickListener(mInCallScreen);
+ // mOtaWidgetData.otaTryAgainButton =
+ // (Button) mInCallScreen.findViewById(R.id.otaTryAgainButton);
+ // mOtaWidgetData.otaTryAgainButton.setOnClickListener(mInCallScreen);
- mOtaWidgetData.otaDtmfDialerView =
- (DTMFTwelveKeyDialerView) mInCallScreen.findViewById(R.id.otaDtmfDialerView);
+ // mOtaWidgetData.otaDtmfDialerView =
+ // (DTMFTwelveKeyDialerView) mInCallScreen.findViewById(R.id.otaDtmfDialerView);
// Sanity-check: the otaDtmfDialerView widget should *always* be present.
- if (mOtaWidgetData.otaDtmfDialerView == null) {
- throw new IllegalStateException("initOtaInCallScreen: couldn't find otaDtmfDialerView");
- }
+ // if (mOtaWidgetData.otaDtmfDialerView == null) {
+ // throw new IllegalStateException("initOtaInCallScreen: couldn't find otaDtmfDialerView");
+ // }
// Create a new DTMFTwelveKeyDialer instance purely for use by the
// DTMFTwelveKeyDialerView ("otaDtmfDialerView") that comes from
// otacall_card.xml.
- mOtaCallCardDtmfDialer = new DTMFTwelveKeyDialer(mInCallScreen,
- mOtaWidgetData.otaDtmfDialerView);
+ // mOtaCallCardDtmfDialer = new DTMFTwelveKeyDialer(mInCallScreen,
+ // mOtaWidgetData.otaDtmfDialerView);
// Initialize the new DTMFTwelveKeyDialer instance. This is
// needed to play local DTMF tones.
- mOtaCallCardDtmfDialer.startDialerSession();
+ // mOtaCallCardDtmfDialer.startDialerSession();
- mOtaWidgetData.otaDtmfDialerView.setDialer(mOtaCallCardDtmfDialer);
+ // mOtaWidgetData.otaDtmfDialerView.setDialer(mOtaCallCardDtmfDialer);
}
/**
@@ -1463,17 +1405,17 @@
mApplication.cdmaOtaInCallScreenUiState.state = State.UNDEFINED;
if (mInteractive && (mOtaWidgetData != null)) {
- if (mInCallTouchUi != null) mInCallTouchUi.setVisibility(View.VISIBLE);
- if (mCallCard != null) {
- mCallCard.setVisibility(View.VISIBLE);
- mCallCard.hideCallCardElements();
- }
+ // if (mInCallTouchUi != null) mInCallTouchUi.setVisibility(View.VISIBLE);
+ // if (mCallCard != null) {
+ // mCallCard.setVisibility(View.VISIBLE);
+ // mCallCard.hideCallCardElements();
+ // }
// Free resources from the DTMFTwelveKeyDialer instance we created
// in initOtaInCallScreen().
- if (mOtaCallCardDtmfDialer != null) {
- mOtaCallCardDtmfDialer.stopDialerSession();
- }
+ // if (mOtaCallCardDtmfDialer != null) {
+ // mOtaCallCardDtmfDialer.stopDialerSession();
+ // }
mOtaWidgetData.otaTextActivate.setVisibility(View.GONE);
mOtaWidgetData.otaTextListenProgress.setVisibility(View.GONE);
@@ -1483,7 +1425,7 @@
mOtaWidgetData.callCardOtaButtonsListenProgress.setVisibility(View.GONE);
mOtaWidgetData.callCardOtaButtonsFailSuccess.setVisibility(View.GONE);
mOtaWidgetData.otaUpperWidgets.setVisibility(View.GONE);
- mOtaWidgetData.otaDtmfDialerView.setVisibility(View.GONE);
+ // mOtaWidgetData.otaDtmfDialerView.setVisibility(View.GONE);
mOtaWidgetData.otaNextButton.setVisibility(View.GONE);
mOtaWidgetData.otaTryAgainButton.setVisibility(View.GONE);
}
diff --git a/src/com/android/phone/OutgoingCallBroadcaster.java b/src/com/android/phone/OutgoingCallBroadcaster.java
index c5e8953..6e0c13e 100644
--- a/src/com/android/phone/OutgoingCallBroadcaster.java
+++ b/src/com/android/phone/OutgoingCallBroadcaster.java
@@ -26,6 +26,7 @@
import android.content.DialogInterface;
import android.content.Intent;
import android.content.res.Configuration;
+import android.content.res.Resources;
import android.net.Uri;
import android.os.Binder;
import android.os.Bundle;
@@ -138,16 +139,29 @@
@Override
public void onReceive(Context context, Intent intent) {
mHandler.removeMessages(EVENT_OUTGOING_CALL_TIMEOUT);
- doReceive(context, intent);
+ final boolean isAttemptingCall = doReceive(context, intent);
if (DBG) Log.v(TAG, "OutgoingCallReceiver is going to finish the Activity itself.");
// We cannot finish the activity immediately here because it would cause the temporary
// black screen of OutgoingBroadcaster to go away and we need it to stay up until the
// UI (in a different process) has time to come up.
- startDelayedFinish();
+ // However, if we know we are not attemping a call, we need to finish the activity
+ // immediately so that subsequent CALL intents will retrigger a new
+ // OutgoingCallReceiver. see b/10857203
+ if (isAttemptingCall) {
+ startDelayedFinish();
+ } else {
+ finish();
+ }
}
- public void doReceive(Context context, Intent intent) {
+
+ /**
+ * Handes receipt of ordered new_outgoing_call intent. Verifies that the return from the
+ * ordered intent is valid.
+ * @return true if the call is being attempted; false if we are canceling the call.
+ */
+ public boolean doReceive(Context context, Intent intent) {
if (DBG) Log.v(TAG, "doReceive: " + intent);
boolean alreadyCalled;
@@ -158,7 +172,7 @@
OutgoingCallBroadcaster.EXTRA_ALREADY_CALLED, false);
if (alreadyCalled) {
if (DBG) Log.v(TAG, "CALL already placed -- returning.");
- return;
+ return false;
}
// Once the NEW_OUTGOING_CALL broadcast is finished, the resultData
@@ -203,37 +217,36 @@
// to take down any OTASP-related UI first.
if (dialogState) app.dismissOtaDialogs();
app.clearOtaState();
- app.clearInCallScreenMode();
} else if (isOtaCallActive) {
// The actual OTASP call is active. Don't allow new
// outgoing calls at all from this state.
Log.w(TAG, "OTASP call is active: disallowing a new outgoing call.");
- return;
+ return false;
}
}
if (number == null) {
if (DBG) Log.v(TAG, "CALL cancelled (null number), returning...");
- return;
+ return false;
} else if (TelephonyCapabilities.supportsOtasp(app.phone)
&& (app.phone.getState() != PhoneConstants.State.IDLE)
&& (app.phone.isOtaSpNumber(number))) {
if (DBG) Log.v(TAG, "Call is active, a 2nd OTA call cancelled -- returning.");
- return;
+ return false;
} else if (PhoneNumberUtils.isPotentialLocalEmergencyNumber(number, context)) {
// Just like 3rd-party apps aren't allowed to place emergency
// calls via the ACTION_CALL intent, we also don't allow 3rd
// party apps to use the NEW_OUTGOING_CALL broadcast to rewrite
// an outgoing call into an emergency number.
Log.w(TAG, "Cannot modify outgoing call to emergency number " + number + ".");
- return;
+ return false;
}
originalUri = intent.getStringExtra(
OutgoingCallBroadcaster.EXTRA_ORIGINAL_URI);
if (originalUri == null) {
Log.e(TAG, "Intent is missing EXTRA_ORIGINAL_URI -- returning.");
- return;
+ return false;
}
Uri uri = Uri.parse(originalUri);
@@ -251,6 +264,8 @@
if (VDBG) Log.v(TAG, "- actual number to dial: '" + number + "'");
startSipCallOptionHandler(context, intent, uri, number);
+
+ return true;
}
}
@@ -521,11 +536,12 @@
// use the java resolver to find the dialer class (as
// opposed to a Context which look up known android
// packages only)
- invokeFrameworkDialer.setClassName("com.android.dialer",
- "com.android.dialer.DialtactsActivity");
+ final Resources resources = getResources();
+ invokeFrameworkDialer.setClassName(
+ resources.getString(R.string.ui_default_package),
+ resources.getString(R.string.dialer_default_class));
invokeFrameworkDialer.setAction(Intent.ACTION_DIAL);
invokeFrameworkDialer.setData(intent.getData());
-
if (DBG) Log.v(TAG, "onCreate(): calling startActivity for Dialer: "
+ invokeFrameworkDialer);
startActivity(invokeFrameworkDialer);
@@ -600,17 +616,6 @@
// EXTRA_ALREADY_CALLED extra.)
}
- // 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(PhoneGlobals.EXTRA_CALL_ORIGIN);
- if (callOrigin != null) {
- if (DBG) Log.v(TAG, " - Call origin is passed (" + callOrigin + ")");
- PhoneGlobals.getInstance().setLatestActiveCallOrigin(callOrigin);
- } else {
- if (DBG) Log.v(TAG, " - Call origin is not passed. Reset current one.");
- PhoneGlobals.getInstance().resetLatestActiveCallOrigin();
- }
-
// For now, SIP calls will be processed directly without a
// NEW_OUTGOING_CALL broadcast.
//
@@ -687,33 +692,8 @@
private void handleNonVoiceCapable(Intent intent) {
if (DBG) Log.v(TAG, "handleNonVoiceCapable: handling " + intent
+ " on non-voice-capable device...");
- String action = intent.getAction();
- Uri uri = intent.getData();
- String scheme = uri.getScheme();
- // Handle one special case: If this is a regular CALL to a tel: URI,
- // bring up a UI letting you do something useful with the phone number
- // (like "Add to contacts" if it isn't a contact yet.)
- //
- // This UI is provided by the contacts app in response to a DIAL
- // intent, so we bring it up here by demoting this CALL to a DIAL and
- // relaunching.
- //
- // TODO: it's strange and unintuitive to manually launch a DIAL intent
- // to do this; it would be cleaner to have some shared UI component
- // that we could bring up directly. (But for now at least, since both
- // Contacts and Phone are built-in apps, this implementation is fine.)
-
- if (Intent.ACTION_CALL.equals(action) && (Constants.SCHEME_TEL.equals(scheme))) {
- Intent newIntent = new Intent(Intent.ACTION_DIAL, uri);
- if (DBG) Log.v(TAG, "- relaunching as a DIAL intent: " + newIntent);
- startActivity(newIntent);
- finish();
- return;
- }
-
- // In all other cases, just show a generic "voice calling not
- // supported" dialog.
+ // Just show a generic "voice calling not supported" dialog.
showDialog(DIALOG_NOT_VOICE_CAPABLE);
// ...and we'll eventually finish() when the user dismisses
// or cancels the dialog.
diff --git a/src/com/android/phone/PhoneGlobals.java b/src/com/android/phone/PhoneGlobals.java
index 45ffd33..3f35900 100644
--- a/src/com/android/phone/PhoneGlobals.java
+++ b/src/com/android/phone/PhoneGlobals.java
@@ -105,7 +105,6 @@
// Message codes; see mHandler below.
private static final int EVENT_SIM_NETWORK_LOCKED = 3;
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;
@@ -164,7 +163,6 @@
CallManager mCM;
CallNotifier notifier;
CallerInfoCache callerInfoCache;
- InCallUiState inCallUiState;
NotificationMgr notificationMgr;
Phone phone;
PhoneInterfaceManager phoneMgr;
@@ -177,7 +175,6 @@
private CallModeler callModeler;
private CallStateMonitor callStateMonitor;
private DTMFTonePlayer dtmfTonePlayer;
- private RejectWithTextMessageManager rejectWithTextMessageManager;
private IBluetoothHeadsetPhone mBluetoothPhone;
private Ringer ringer;
private WiredHeadsetManager wiredHeadsetManager;
@@ -188,10 +185,6 @@
// 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
@@ -260,15 +253,6 @@
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) {
@@ -301,16 +285,6 @@
}
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;
@@ -367,7 +341,6 @@
audioRouter.setSpeaker(inDockMode);
PhoneUtils.turnOnSpeaker(getApplicationContext(), inDockMode, true);
- updateInCallScreen(); // Has no effect if the InCallScreen isn't visible
}
break;
@@ -481,10 +454,6 @@
// (like making outgoing calls.)
callController = CallController.init(this, callLogger, callGatewayManager);
- // ...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.
//
@@ -494,12 +463,8 @@
// Monitors call activity from the telephony layer
callStateMonitor = new CallStateMonitor(mCM);
- // Rejects calls with TextMessages
- rejectWithTextMessageManager = new RejectWithTextMessageManager();
-
// Creates call models for use with CallHandlerService.
- callModeler = new CallModeler(callStateMonitor, mCM, rejectWithTextMessageManager,
- callGatewayManager);
+ callModeler = new CallModeler(callStateMonitor, mCM, callGatewayManager);
// Plays DTMF Tones
dtmfTonePlayer = new DTMFTonePlayer(mCM, callModeler);
@@ -518,7 +483,7 @@
// Service used by in-call UI to control calls
callCommandService = new CallCommandService(this, mCM, callModeler, dtmfTonePlayer,
- audioRouter, rejectWithTextMessageManager);
+ audioRouter);
// Sends call state to the UI
callHandlerServiceProxy = new CallHandlerServiceProxy(this, callModeler,
@@ -531,7 +496,7 @@
// launching the incoming-call UI when an incoming call comes
// in.)
notifier = CallNotifier.init(this, phone, ringer, callLogger, callStateMonitor,
- bluetoothManager);
+ bluetoothManager, callModeler);
// register for ICC status
IccCard sim = phone.getIccCard();
@@ -677,6 +642,14 @@
return audioRouter;
}
+ /* package */ CallModeler getCallModeler() {
+ return callModeler;
+ }
+
+ /* package */ CallManager getCallManager() {
+ return mCM;
+ }
+
/**
* Returns an Intent that can be used to go to the "Call log"
* UI (aka CallLogActivity) in the Contacts app.
@@ -699,32 +672,6 @@
}
/**
- * 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.
*/
@@ -749,37 +696,6 @@
return PendingIntent.getBroadcast(context, 0, intent, 0);
}
- private static String getCallScreenClassName() {
- //InCallScreen.class.getName();
- return "blah";
- }
-
- /**
- * 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;
}
@@ -792,59 +708,6 @@
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();
- }
-
- /**
- * 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.
*
@@ -992,16 +855,6 @@
/* 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
@@ -1018,11 +871,6 @@
// 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,
@@ -1034,13 +882,7 @@
//
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 + ")");
+ boolean keepScreenOn = isRinging || isDialing;
// keepScreenOn == true means we'll hold a full wake lock:
requestWakeState(keepScreenOn ? WakeState.FULL : WakeState.SLEEP);
}
@@ -1079,23 +921,10 @@
mUpdateLock.acquire();
}
} else {
- if (!isShowingCallScreen()) {
- if (!mUpdateLock.isHeld()) {
- mUpdateLock.release();
- }
- } else {
- // For this case InCallScreen will take care of the release() call.
+ if (mUpdateLock.isHeld()) {
+ mUpdateLock.release();
}
}
-
- // 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);
- }
}
}
@@ -1103,13 +932,6 @@
return mLastPhoneState;
}
- /**
- * Returns UpdateLock object.
- */
- /* package */ UpdateLock getUpdateLock() {
- return mUpdateLock;
- }
-
KeyguardManager getKeyguardManager() {
return mKeyguardManager;
}
@@ -1158,9 +980,6 @@
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();
@@ -1284,10 +1103,6 @@
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 {
@@ -1373,18 +1188,12 @@
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;
}
@@ -1392,8 +1201,7 @@
// 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)) {
+ if (otaUtils != null) {
otaUtils.cleanOtaScreen(true);
if (DBG) Log.d(LOG_TAG, " - clearOtaState clears OTA screen");
}
@@ -1402,45 +1210,12 @@
// 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)) {
+ if (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) {
@@ -1506,73 +1281,6 @@
*/
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.dialer", 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() {
diff --git a/src/com/android/phone/PhoneInterfaceManager.java b/src/com/android/phone/PhoneInterfaceManager.java
index c37fe07..1ce46b2 100644
--- a/src/com/android/phone/PhoneInterfaceManager.java
+++ b/src/com/android/phone/PhoneInterfaceManager.java
@@ -297,7 +297,7 @@
}
private boolean showCallScreenInternal(boolean specifyInitialDialpadState,
- boolean initialDialpadState) {
+ boolean showDialpad) {
if (!PhoneGlobals.sVoiceCapable) {
// Never allow the InCallScreen to appear on data-only devices.
return false;
@@ -308,7 +308,7 @@
// If the phone isn't idle then go to the in-call screen
long callingId = Binder.clearCallingIdentity();
- mCallHandlerService.bringToForeground();
+ mCallHandlerService.bringToForeground(showDialpad);
Binder.restoreCallingIdentity(callingId);
return true;
diff --git a/src/com/android/phone/PhoneUtils.java b/src/com/android/phone/PhoneUtils.java
index 43ad8b1..e987b94 100644
--- a/src/com/android/phone/PhoneUtils.java
+++ b/src/com/android/phone/PhoneUtils.java
@@ -326,6 +326,28 @@
}
/**
+ * Hangs up all active calls.
+ */
+ static void hangupAllCalls(CallManager cm) {
+ final Call ringing = cm.getFirstActiveRingingCall();
+ final Call fg = cm.getActiveFgCall();
+ final Call bg = cm.getFirstActiveBgCall();
+
+ // We go in reverse order, BG->FG->RINGING because hanging up a ringing call or an active
+ // call can move a bg call to a fg call which would force us to loop over each call
+ // several times. This ordering works best to ensure we dont have any more calls.
+ if (bg != null && !bg.isIdle()) {
+ hangup(bg);
+ }
+ if (fg != null && !fg.isIdle()) {
+ hangup(fg);
+ }
+ if (ringing != null && !ringing.isIdle()) {
+ hangupRingingCall(fg);
+ }
+ }
+
+ /**
* Smart "hang up" helper method which hangs up exactly one connection,
* based on the current Phone state, as follows:
* <ul>
@@ -548,7 +570,8 @@
* </pre>
* @param app The phone instance.
*/
- private static void updateCdmaCallStateOnNewOutgoingCall(PhoneGlobals app) {
+ private static void updateCdmaCallStateOnNewOutgoingCall(PhoneGlobals app,
+ Connection connection) {
if (app.cdmaPhoneCallState.getCurrentCallState() ==
CdmaPhoneCallState.PhoneCallState.IDLE) {
// This is the first outgoing call. Set the Phone Call State to ACTIVE
@@ -558,6 +581,8 @@
// This is the second outgoing call. Set the Phone Call State to 3WAY
app.cdmaPhoneCallState.setCurrentCallState(
CdmaPhoneCallState.PhoneCallState.THRWAY_ACTIVE);
+
+ app.getCallModeler().setCdmaOutgoing3WayCall(connection);
}
}
@@ -671,17 +696,9 @@
}
} else {
if (phoneType == PhoneConstants.PHONE_TYPE_CDMA) {
- updateCdmaCallStateOnNewOutgoingCall(app);
+ updateCdmaCallStateOnNewOutgoingCall(app, connection);
}
- // Clean up the number to be displayed.
- if (phoneType == PhoneConstants.PHONE_TYPE_CDMA) {
- number = CdmaConnection.formatDialString(number);
- }
- number = PhoneNumberUtils.extractNetworkPortion(number);
- number = PhoneNumberUtils.convertKeypadLettersToDigits(number);
- number = PhoneNumberUtils.formatNumber(number);
-
if (gatewayUri == null) {
// phone.dial() succeeded: we're now in a normal phone call.
// attach the URI to the CallerInfo Object if it is there,
@@ -705,25 +722,15 @@
}
}
}
- } else {
- // Get the caller info synchronously because we need the final
- // CallerInfo object to update the dialed number with the one
- // requested by the user (and not the provider's gateway number).
- CallerInfo info = null;
- String content = phone.getContext().getContentResolver().SCHEME_CONTENT;
- if ((contactRef != null) && (contactRef.getScheme().equals(content))) {
- info = CallerInfo.getCallerInfo(context, contactRef);
- }
-
- // Fallback, lookup contact using the phone number if the
- // contact's URI scheme was not content:// or if is was but
- // the lookup failed.
- if (null == info) {
- info = CallerInfo.getCallerInfo(context, number);
- }
- info.phoneNumber = number;
- connection.setUserData(info);
}
+
+ startGetCallerInfo(context, connection, null, null, gatewayInfo);
+
+ // Always set mute to off when we are dialing an emergency number
+ if (isEmergencyCall) {
+ setMute(false);
+ }
+
setAudioMode();
if (DBG) log("about to activate speaker");
@@ -1391,12 +1398,18 @@
return startGetCallerInfo(context, conn, listener, cookie);
}
+ static CallerInfoToken startGetCallerInfo(Context context, Connection c,
+ CallerInfoAsyncQuery.OnQueryCompleteListener listener, Object cookie) {
+ return startGetCallerInfo(context, c, listener, cookie, null);
+ }
+
/**
* place a temporary callerinfo object in the hands of the caller and notify
* caller when the actual query is done.
*/
static CallerInfoToken startGetCallerInfo(Context context, Connection c,
- CallerInfoAsyncQuery.OnQueryCompleteListener listener, Object cookie) {
+ CallerInfoAsyncQuery.OnQueryCompleteListener listener, Object cookie,
+ RawGatewayInfo info) {
CallerInfoToken cit;
if (c == null) {
@@ -1462,6 +1475,12 @@
// querying a new CallerInfo using the connection's phone number.
String number = c.getAddress();
+ if (info != null && info != CallGatewayManager.EMPTY_INFO) {
+ // Gateway number, the connection number is actually the gateway number.
+ // need to lookup via dialed number.
+ number = info.trueNumber;
+ }
+
if (DBG) {
log("PhoneUtils.startGetCallerInfo: new query for phone number...");
log("- number (address): " + toLogSafePhoneNumber(number));
@@ -1547,6 +1566,13 @@
} else {
// handling case where number/name gets updated later on by the network
String updatedNumber = c.getAddress();
+
+ if (info != null) {
+ // Gateway number, the connection number is actually the gateway number.
+ // need to lookup via dialed number.
+ updatedNumber = info.trueNumber;
+ }
+
if (DBG) {
log("startGetCallerInfo: updatedNumber initially = "
+ toLogSafePhoneNumber(updatedNumber));
@@ -1932,6 +1958,11 @@
static void setMute(boolean muted) {
CallManager cm = PhoneGlobals.getInstance().mCM;
+ // Emergency calls never get muted.
+ if (isInEmergencyCall(cm)) {
+ muted = false;
+ }
+
// make the call to mute the audio
setMuteInternal(cm.getFgPhone(), muted);
@@ -1943,6 +1974,27 @@
}
sConnectionMuteTable.put(cn, Boolean.valueOf(muted));
}
+
+ // update the background connections to match. This includes
+ // all the connections on conference calls.
+ if (cm.hasActiveBgCall()) {
+ for (Connection cn : cm.getFirstActiveBgCall().getConnections()) {
+ if (sConnectionMuteTable.get(cn) == null) {
+ if (DBG) log("problem retrieving mute value for this connection.");
+ }
+ sConnectionMuteTable.put(cn, Boolean.valueOf(muted));
+ }
+ }
+ }
+
+ static boolean isInEmergencyCall(CallManager cm) {
+ for (Connection cn : cm.getActiveFgCall().getConnections()) {
+ if (PhoneNumberUtils.isLocalEmergencyNumber(cn.getAddress(),
+ PhoneGlobals.getInstance())) {
+ return true;
+ }
+ }
+ return false;
}
/**
@@ -2149,6 +2201,50 @@
//
/**
+ * @return true if we're allowed to hold calls, given the current
+ * state of the Phone.
+ */
+ /* package */ static boolean okToHoldCall(CallManager cm) {
+ final Call fgCall = cm.getActiveFgCall();
+ final boolean hasHoldingCall = cm.hasActiveBgCall();
+ final Call.State fgCallState = fgCall.getState();
+
+ // The "Hold" control is disabled entirely if there's
+ // no way to either hold or unhold in the current state.
+ final boolean okToHold = (fgCallState == Call.State.ACTIVE) && !hasHoldingCall;
+ final boolean okToUnhold = cm.hasActiveBgCall() && (fgCallState == Call.State.IDLE);
+ final boolean canHold = okToHold || okToUnhold;
+
+ return canHold;
+ }
+
+ /**
+ * @return true if we support holding calls, given the current
+ * state of the Phone.
+ */
+ /* package */ static boolean okToSupportHold(CallManager cm) {
+ boolean supportsHold = false;
+
+ final Call fgCall = cm.getActiveFgCall();
+ final boolean hasHoldingCall = cm.hasActiveBgCall();
+ final Call.State fgCallState = fgCall.getState();
+
+ if (TelephonyCapabilities.supportsHoldAndUnhold(fgCall.getPhone())) {
+ // This phone has the concept of explicit "Hold" and "Unhold" actions.
+ supportsHold = true;
+ } else if (hasHoldingCall && (fgCallState == Call.State.IDLE)) {
+ // Even when foreground phone device doesn't support hold/unhold, phone devices
+ // for background holding calls may do.
+ final Call bgCall = cm.getFirstActiveBgCall();
+ if (bgCall != null &&
+ TelephonyCapabilities.supportsHoldAndUnhold(bgCall.getPhone())) {
+ supportsHold = true;
+ }
+ }
+ return supportsHold;
+ }
+
+ /**
* @return true if we're allowed to swap calls, given the current
* state of the Phone.
*/
@@ -2368,7 +2464,7 @@
if (DBG) log("activateSpeakerIfDocked(): In a dock -> may need to turn on speaker.");
final PhoneGlobals app = PhoneGlobals.getInstance();
- // TODO(klp): This function should move to AudioRouter
+ // TODO: This function should move to AudioRouter
final BluetoothManager btManager = app.getBluetoothManager();
final WiredHeadsetManager wiredHeadset = app.getWiredHeadsetManager();
final AudioRouter audioRouter = app.getAudioRouter();
diff --git a/src/com/android/phone/RejectWithTextMessageManager.java b/src/com/android/phone/RejectWithTextMessageManager.java
index fda8f78..dd4fe17 100644
--- a/src/com/android/phone/RejectWithTextMessageManager.java
+++ b/src/com/android/phone/RejectWithTextMessageManager.java
@@ -16,43 +16,27 @@
package com.android.phone;
-import android.app.ActivityManager;
-import android.app.AlertDialog;
-import android.app.Dialog;
import android.content.ComponentName;
import android.content.Context;
-import android.content.DialogInterface;
import android.content.Intent;
import android.content.SharedPreferences;
-import android.content.pm.ApplicationInfo;
-import android.content.pm.PackageManager;
-import android.content.pm.ResolveInfo;
-import android.content.pm.ServiceInfo;
import android.content.res.Resources;
-import android.graphics.drawable.Drawable;
import android.net.Uri;
import android.os.Handler;
+import android.os.Looper;
+import android.os.Message;
import android.telephony.PhoneNumberUtils;
import android.telephony.TelephonyManager;
import android.text.TextUtils;
import android.util.Log;
-import android.view.LayoutInflater;
-import android.view.View;
-import android.view.ViewGroup;
-import android.widget.BaseAdapter;
-import android.widget.CheckBox;
-import android.widget.CompoundButton;
-import android.widget.ImageView;
-import android.widget.TextView;
+import android.widget.Toast;
import com.android.internal.telephony.Call;
import com.android.internal.telephony.Connection;
import com.android.internal.telephony.PhoneConstants;
-
-import com.google.android.collect.Lists;
+import com.android.internal.telephony.SmsApplication;
import java.util.ArrayList;
-import java.util.List;
/**
* Helper class to manage the "Respond via Message" feature for incoming calls.
@@ -60,24 +44,13 @@
* @see com.android.phone.InCallScreen.internalRespondViaSms()
*/
public class RejectWithTextMessageManager {
-
private static final String TAG = RejectWithTextMessageManager.class.getSimpleName();
private static final boolean DBG = (PhoneGlobals.DBG_LEVEL >= 2);
- private static final String PERMISSION_SEND_RESPOND_VIA_MESSAGE =
- "android.permission.SEND_RESPOND_VIA_MESSAGE";
-
- /** The array of "canned responses"; see loadCannedResponses(). */
- private String[] mCannedResponses;
-
/** SharedPreferences file name for our persistent settings. */
private static final String SHARED_PREFERENCES_NAME = "respond_via_sms_prefs";
- private Intent mIntent;
-
- private ArrayList<ComponentName> mComponentsWithPermission = new ArrayList<ComponentName>();
-
- // Preference keys for the 4 "canned responses"; see RespondViaSmsManager$Settings.
+ // Preference keys for the 4 "canned responses"; see RespondViaSmsManager$Settings.
// Since (for now at least) the number of messages is fixed at 4, and since
// SharedPreferences can't deal with arrays anyway, just store the messages
// as 4 separate strings.
@@ -86,11 +59,6 @@
private static final String KEY_CANNED_RESPONSE_PREF_2 = "canned_response_pref_2";
private static final String KEY_CANNED_RESPONSE_PREF_3 = "canned_response_pref_3";
private static final String KEY_CANNED_RESPONSE_PREF_4 = "canned_response_pref_4";
- /* package */ static final String KEY_INSTANT_TEXT_DEFAULT_COMPONENT =
- "instant_text_def_component";
-
- /* package */ static final String TAG_ALL_SMS_SERVICES = "com.android.phone.AvailablePackages";
- /* package */ static final String TAG_SEND_SMS = "com.android.phone.MessageIntent";
/**
* Read the (customizable) canned responses from SharedPreferences,
@@ -125,17 +93,37 @@
return responses;
}
- private void sendTextAndExit() {
- // Send the selected message immediately with no user interaction.
- if (mIntent.getComponent() != null) {
- PhoneGlobals.getInstance().startService(mIntent);
- }
-
+ private static void showMessageSentToast(final String phoneNumber) {
// ...and show a brief confirmation to the user (since
// otherwise it's hard to be sure that anything actually
// happened.)
- // TODO(klp): Ask the InCallUI to show a confirmation
+ // Ugly hack to show a toaster from a service.
+ (new Thread(new Runnable() {
+ @Override
+ public void run() {
+ Looper.prepare();
+ Handler innerHandler = new Handler() {
+ @Override
+ public void handleMessage(Message message) {
+ final Resources res = PhoneGlobals.getInstance().getResources();
+ final String formatString = res.getString(
+ R.string.respond_via_sms_confirmation_format);
+ final String confirmationMsg = String.format(formatString, phoneNumber);
+ Toast.makeText(PhoneGlobals.getInstance(), confirmationMsg,
+ Toast.LENGTH_LONG).show();
+ }
+ @Override
+ public void dispatchMessage(Message message) {
+ handleMessage(message);
+ }
+ };
+
+ Message message = innerHandler.obtainMessage();
+ innerHandler.dispatchMessage(message);
+ Looper.loop();
+ }
+ })).start();
// TODO: If the device is locked, this toast won't actually ever
// be visible! (That's because we're about to dismiss the call
@@ -144,7 +132,7 @@
// Possible fixes:
// (1) Is it possible to allow a specific Toast to be visible
// on top of the keyguard?
- // (2) Artifically delay the dismissCallScreen() call by 3
+ // (2) Artificially delay the dismissCallScreen() call by 3
// seconds to allow the toast to be seen?
// (3) Don't use a toast at all; instead use a transient state
// of the InCallScreen (perhaps via the InCallUiState
@@ -153,124 +141,22 @@
}
/**
- * Queries the System to determine what packages contain services that can handle the instant
- * text response Action AND have permissions to do so.
+ * Reject the call with the specified message. If message is null this call is ignored.
*/
- private static ArrayList<ComponentName> getPackagesWithInstantTextPermission() {
- final PackageManager packageManager = PhoneGlobals.getInstance().getPackageManager();
-
- final ArrayList<ComponentName> componentsWithPermission = new ArrayList<ComponentName>();
-
- // Get list of all services set up to handle the Instant Text intent.
- final List<ResolveInfo> infos = packageManager.queryIntentServices(
- getInstantTextIntent("", null, null), 0);
-
- // Collect all the valid services
- for (ResolveInfo resolveInfo : infos) {
- final ServiceInfo serviceInfo = resolveInfo.serviceInfo;
- if (serviceInfo == null) {
- Log.w(TAG, "Ignore package without proper service.");
- continue;
- }
-
- // A Service is valid only if it requires the permission
- // PERMISSION_SEND_RESPOND_VIA_MESSAGE
- if (PERMISSION_SEND_RESPOND_VIA_MESSAGE.equals(serviceInfo.permission)) {
- componentsWithPermission.add(new ComponentName(serviceInfo.packageName,
- serviceInfo.name));
- }
- }
-
- return componentsWithPermission;
- }
-
- /**
- * @param phoneNumber Must not be null.
- * @param message Can be null. If message is null, the returned Intent will be configured to
- * launch the SMS compose UI. If non-null, the returned Intent will cause the specified message
- * to be sent with no interaction from the user.
- * @param component The component that should handle this intent.
- * @return Service Intent for the instant response.
- */
- private static Intent getInstantTextIntent(String phoneNumber, String message,
- ComponentName component) {
- final Uri uri = Uri.fromParts(Constants.SCHEME_SMSTO, phoneNumber, null);
- final Intent intent = new Intent(TelephonyManager.ACTION_RESPOND_VIA_MESSAGE, uri);
+ public static void rejectCallWithMessage(String phoneNumber, String message) {
if (message != null) {
- intent.putExtra(Intent.EXTRA_TEXT, message);
- } else {
- intent.putExtra("exit_on_sent", true);
- intent.putExtra("showUI", true);
- }
- if (component != null) {
- intent.setComponent(component);
- }
- return intent;
- }
-
- private boolean getSmsService() {
- if (DBG) log("sendTextToDefaultActivity()...");
- final PackageManager packageManager = PhoneGlobals.getInstance().getPackageManager();
-
- // Check to see if the default component to receive this intent is already saved
- // and check to see if it still has the corrent permissions.
- final SharedPreferences prefs = PhoneGlobals.getInstance().
- getSharedPreferences(SHARED_PREFERENCES_NAME, Context.MODE_PRIVATE);
- final String flattenedName = prefs.getString(KEY_INSTANT_TEXT_DEFAULT_COMPONENT, null);
- if (flattenedName != null) {
- if (DBG) log("Default package was found." + flattenedName);
-
- final ComponentName componentName = ComponentName.unflattenFromString(flattenedName);
- ServiceInfo serviceInfo = null;
- try {
- serviceInfo = packageManager.getServiceInfo(componentName, 0);
- } catch (PackageManager.NameNotFoundException e) {
- Log.w(TAG, "Default service does not have permission.");
+ final ComponentName component =
+ SmsApplication.getDefaultRespondViaMessageApplication(
+ PhoneGlobals.getInstance(), true /*updateIfNeeded*/);
+ if (component != null) {
+ // Build and send the intent
+ final Uri uri = Uri.fromParts(Constants.SCHEME_SMSTO, phoneNumber, null);
+ final Intent intent = new Intent(TelephonyManager.ACTION_RESPOND_VIA_MESSAGE, uri);
+ intent.putExtra(Intent.EXTRA_TEXT, message);
+ showMessageSentToast(phoneNumber);
+ intent.setComponent(component);
+ PhoneGlobals.getInstance().startService(intent);
}
-
- if (serviceInfo != null &&
- PERMISSION_SEND_RESPOND_VIA_MESSAGE.equals(serviceInfo.permission)) {
- mIntent.setComponent(componentName);
- return true;
- } else {
- SharedPreferences.Editor editor = prefs.edit();
- editor.remove(KEY_INSTANT_TEXT_DEFAULT_COMPONENT);
- editor.apply();
- }
- }
-
- mComponentsWithPermission = getPackagesWithInstantTextPermission();
-
- final int size = mComponentsWithPermission.size();
- if (size == 0) {
- Log.e(TAG, "No appropriate package receiving the Intent. Don't send anything");
- return false;
- } else if (size == 1) {
- mIntent.setComponent(mComponentsWithPermission.get(0));
- return true;
- } else {
- Log.v(TAG, "Choosing from one of the apps");
- // TODO(klp): Add an app picker.
- final Intent intent = new Intent(Intent.ACTION_VIEW, null);
- intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK |
- Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS |
- Intent.FLAG_ACTIVITY_NO_ANIMATION |
- Intent.FLAG_ACTIVITY_NO_HISTORY |
- Intent.FLAG_FROM_BACKGROUND);
- intent.setClass(PhoneGlobals.getInstance(), TextMessagePackageChooser.class);
- intent.putExtra(TAG_ALL_SMS_SERVICES, mComponentsWithPermission);
- intent.putExtra(TAG_SEND_SMS, mIntent);
- PhoneGlobals.getInstance().startActivity(intent);
- return false;
- // return componentsWithPermission.get(0);
- }
- }
-
- public void rejectCallWithMessage(Call call, String message) {
- mComponentsWithPermission.clear();
- mIntent = getInstantTextIntent(call.getLatestConnection().getAddress(), message, null);
- if (getSmsService()) {
- sendTextAndExit();
}
}
@@ -349,8 +235,9 @@
return false;
}
- // Allow the feature only when there's a destination for it.
- if (getPackagesWithInstantTextPermission().size() < 1) {
+ // Is there a valid SMS application on the phone?
+ if (SmsApplication.getDefaultRespondViaMessageApplication(PhoneGlobals.getInstance(),
+ true /*updateIfNeeded*/) == null) {
return false;
}
diff --git a/src/com/android/phone/RespondViaSmsManager.java b/src/com/android/phone/RespondViaSmsManager.java
index ffce899..a842f34 100644
--- a/src/com/android/phone/RespondViaSmsManager.java
+++ b/src/com/android/phone/RespondViaSmsManager.java
@@ -80,39 +80,6 @@
// Do not check in with VDBG = true, since that may write PII to the system log.
private static final boolean VDBG = false;
- private static final String PERMISSION_SEND_RESPOND_VIA_MESSAGE =
- "android.permission.SEND_RESPOND_VIA_MESSAGE";
-
- private int mIconSize = -1;
-
- /**
- * Reference to the InCallScreen activity that owns us. This may be
- * null if we haven't been initialized yet *or* after the InCallScreen
- * activity has been destroyed.
- */
- private InCallScreen mInCallScreen;
-
- /**
- * The popup showing the list of canned responses.
- *
- * This is an AlertDialog containing a ListView showing the possible
- * choices. This may be null if the InCallScreen hasn't ever called
- * showRespondViaSmsPopup() yet, or if the popup was visible once but
- * then got dismissed.
- */
- private Dialog mCannedResponsePopup;
-
- /**
- * The popup dialog allowing the user to chose which app handles respond-via-sms.
- *
- * An AlertDialog showing the Resolve-App UI resource from the framework wchih we then fill in
- * with the appropriate data set. Can be null when not visible.
- */
- private Dialog mPackageSelectionPopup;
-
- /** The array of "canned responses"; see loadCannedResponses(). */
- private String[] mCannedResponses;
-
/** SharedPreferences file name for our persistent settings. */
private static final String SHARED_PREFERENCES_NAME = "respond_via_sms_prefs";
@@ -129,518 +96,6 @@
private static final String KEY_INSTANT_TEXT_DEFAULT_COMPONENT = "instant_text_def_component";
/**
- * RespondViaSmsManager constructor.
- */
- public RespondViaSmsManager() {
- }
-
- public void setInCallScreenInstance(InCallScreen inCallScreen) {
- mInCallScreen = inCallScreen;
-
- if (mInCallScreen != null) {
- // Prefetch shared preferences to make the first canned response lookup faster
- // (and to prevent StrictMode violation)
- mInCallScreen.getSharedPreferences(SHARED_PREFERENCES_NAME, Context.MODE_PRIVATE);
- }
- }
-
- /**
- * Brings up the "Respond via SMS" popup for an incoming call.
- *
- * @param ringingCall the current incoming call
- */
- 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".
- mCannedResponses = loadCannedResponses();
-
- // Build the list: start with the canned responses, but manually add
- // the write-your-own option as the last choice.
- int numPopupItems = mCannedResponses.length + 1;
- String[] popupItems = Arrays.copyOf(mCannedResponses, numPopupItems);
- popupItems[numPopupItems - 1] = mInCallScreen.getResources()
- .getString(R.string.respond_via_sms_custom_message);
-
- ArrayAdapter<String> adapter =
- new ArrayAdapter<String>(mInCallScreen,
- android.R.layout.simple_list_item_1,
- android.R.id.text1,
- popupItems);
- lv.setAdapter(adapter);
-
- // Create a RespondViaSmsItemClickListener instance to handle item
- // clicks from the popup.
- // (Note we create a fresh instance for each incoming call, and
- // stash away the call's phone number, since we can't necessarily
- // assume this call will still be ringing when the user finally
- // chooses a response.)
-
- Connection c = ringingCall.getLatestConnection();
- if (VDBG) log("- connection: " + c);
-
- if (c == null) {
- // Uh oh -- the "ringingCall" doesn't have any connections any more.
- // (In other words, it's no longer ringing.) This is rare, but can
- // happen if the caller hangs up right at the exact moment the user
- // selects the "Respond via SMS" option.
- // There's nothing to do here (since the incoming call is gone),
- // so just bail out.
- Log.i(TAG, "showRespondViaSmsPopup: null connection; bailing out...");
- return;
- }
-
- // TODO: at this point we probably should re-check c.getAddress()
- // and c.getNumberPresentation() for validity. (i.e. recheck the
- // same cases in InCallTouchUi.showIncomingCallWidget() where we
- // should have disallowed the "respond via SMS" feature in the
- // first place.)
-
- String phoneNumber = c.getAddress();
- if (VDBG) log("- phoneNumber: " + phoneNumber);
- lv.setOnItemClickListener(new RespondViaSmsItemClickListener(phoneNumber));
-
- AlertDialog.Builder builder = new AlertDialog.Builder(mInCallScreen)
- .setCancelable(true)
- .setOnCancelListener(new RespondViaSmsCancelListener())
- .setView(lv);
- mCannedResponsePopup = builder.create();
- mCannedResponsePopup.show();
- }
-
- /**
- * Dismiss currently visible popups.
- *
- * This is safe to call even if the popup is already dismissed, and
- * even if you never called showRespondViaSmsPopup() in the first
- * place.
- */
- public void dismissPopup() {
- if (mCannedResponsePopup != null) {
- mCannedResponsePopup.dismiss(); // safe even if already dismissed
- mCannedResponsePopup = null;
- }
- if (mPackageSelectionPopup != null) {
- mPackageSelectionPopup.dismiss();
- mPackageSelectionPopup = null;
- }
- }
-
- public boolean isShowingPopup() {
- return (mCannedResponsePopup != null && mCannedResponsePopup.isShowing())
- || (mPackageSelectionPopup != null && mPackageSelectionPopup.isShowing());
- }
-
- /**
- * OnItemClickListener for the "Respond via SMS" popup.
- */
- public class RespondViaSmsItemClickListener implements AdapterView.OnItemClickListener {
- // Phone number to send the SMS to.
- private String mPhoneNumber;
-
- public RespondViaSmsItemClickListener(String phoneNumber) {
- mPhoneNumber = phoneNumber;
- }
-
- /**
- * Handles the user selecting an item from the popup.
- */
- @Override
- public void onItemClick(AdapterView<?> parent, // The ListView
- View view, // The TextView that was clicked
- int position,
- long id) {
- if (DBG) log("RespondViaSmsItemClickListener.onItemClick(" + position + ")...");
- String message = (String) parent.getItemAtPosition(position);
- if (VDBG) log("- message: '" + message + "'");
-
- // The "Custom" choice is a special case.
- // (For now, it's guaranteed to be the last item.)
- if (position == (parent.getCount() - 1)) {
- // Take the user to the standard SMS compose UI.
- launchSmsCompose(mPhoneNumber);
- onPostMessageSent();
- } else {
- sendTextToDefaultActivity(mPhoneNumber, message);
- }
- }
- }
-
-
- /**
- * OnCancelListener for the "Respond via SMS" popup.
- */
- public class RespondViaSmsCancelListener implements DialogInterface.OnCancelListener {
- public RespondViaSmsCancelListener() {
- }
-
- /**
- * Handles the user canceling the popup, either by touching
- * outside the popup or by pressing Back.
- */
- @Override
- public void onCancel(DialogInterface dialog) {
- if (DBG) log("RespondViaSmsCancelListener.onCancel()...");
-
- dismissPopup();
-
- 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.
- PhoneGlobals.getInstance().dismissCallScreen();
- } else {
-
- // If the user cancels the popup, this presumably means that
- // they didn't actually mean to bring up the "Respond via SMS"
- // UI in the first place (and instead want to go back to the
- // state where they can either answer or reject the call.)
- // So restart the ringer and bring back the regular incoming
- // call UI.
-
- // This will have no effect if the incoming call isn't still ringing.
- PhoneGlobals.getInstance().notifier.restartRinger();
-
- // We hid the GlowPadView widget way back in
- // InCallTouchUi.onTrigger(), when the user first selected
- // the "SMS" trigger.
- //
- // To bring it back, just force the entire InCallScreen to
- // update itself based on the current telephony state.
- // (Assuming the incoming call is still ringing, this will
- // cause the incoming call widget to reappear.)
- mInCallScreen.requestUpdateScreen();
- }
- }
- }
-
- private void sendTextToDefaultActivity(String phoneNumber, String message) {
- if (DBG) log("sendTextToDefaultActivity()...");
- final PackageManager packageManager = mInCallScreen.getPackageManager();
-
- // Check to see if the default component to receive this intent is already saved
- // and check to see if it still has the corrent permissions.
- final SharedPreferences prefs = mInCallScreen.getSharedPreferences(SHARED_PREFERENCES_NAME,
- Context.MODE_PRIVATE);
- final String flattenedName = prefs.getString(KEY_INSTANT_TEXT_DEFAULT_COMPONENT, null);
- if (flattenedName != null) {
- if (DBG) log("Default package was found." + flattenedName);
-
- final ComponentName componentName = ComponentName.unflattenFromString(flattenedName);
- ServiceInfo serviceInfo = null;
- try {
- serviceInfo = packageManager.getServiceInfo(componentName, 0);
- } catch (PackageManager.NameNotFoundException e) {
- Log.w(TAG, "Default service does not have permission.");
- }
-
- if (serviceInfo != null &&
- PERMISSION_SEND_RESPOND_VIA_MESSAGE.equals(serviceInfo.permission)) {
- sendTextAndExit(phoneNumber, message, componentName, false);
- return;
- } else {
- SharedPreferences.Editor editor = prefs.edit();
- editor.remove(KEY_INSTANT_TEXT_DEFAULT_COMPONENT);
- editor.apply();
- }
- }
-
- final ArrayList<ComponentName> componentsWithPermission =
- getPackagesWithInstantTextPermission();
-
- final int size = componentsWithPermission.size();
- if (size == 0) {
- Log.e(TAG, "No appropriate package receiving the Intent. Don't send anything");
- onPostMessageSent();
- } else if (size == 1) {
- sendTextAndExit(phoneNumber, message, componentsWithPermission.get(0), false);
- } else {
- showPackageSelectionDialog(phoneNumber, message, componentsWithPermission);
- }
- }
-
- /**
- * Queries the System to determine what packages contain services that can handle the instant
- * text response Action AND have permissions to do so.
- */
- private ArrayList<ComponentName> getPackagesWithInstantTextPermission() {
- PackageManager packageManager = mInCallScreen.getPackageManager();
-
- ArrayList<ComponentName> componentsWithPermission = Lists.newArrayList();
-
- // Get list of all services set up to handle the Instant Text intent.
- final List<ResolveInfo> infos = packageManager.queryIntentServices(
- getInstantTextIntent("", null, null), 0);
-
- // Collect all the valid services
- for (ResolveInfo resolveInfo : infos) {
- final ServiceInfo serviceInfo = resolveInfo.serviceInfo;
- if (serviceInfo == null) {
- Log.w(TAG, "Ignore package without proper service.");
- continue;
- }
-
- // A Service is valid only if it requires the permission
- // PERMISSION_SEND_RESPOND_VIA_MESSAGE
- if (PERMISSION_SEND_RESPOND_VIA_MESSAGE.equals(serviceInfo.permission)) {
- componentsWithPermission.add(new ComponentName(serviceInfo.packageName,
- serviceInfo.name));
- }
- }
-
- return componentsWithPermission;
- }
-
- private void showPackageSelectionDialog(String phoneNumber, String message,
- List<ComponentName> components) {
- if (DBG) log("showPackageSelectionDialog()...");
-
- dismissPopup();
-
- BaseAdapter adapter = new PackageSelectionAdapter(mInCallScreen, components);
-
- PackageClickListener clickListener =
- new PackageClickListener(phoneNumber, message, components);
-
- final CharSequence title = mInCallScreen.getResources().getText(
- com.android.internal.R.string.whichApplication);
- LayoutInflater inflater =
- (LayoutInflater) mInCallScreen.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
-
- final View view = inflater.inflate(com.android.internal.R.layout.always_use_checkbox, null);
- final CheckBox alwaysUse = (CheckBox) view.findViewById(
- com.android.internal.R.id.alwaysUse);
- alwaysUse.setText(com.android.internal.R.string.alwaysUse);
- alwaysUse.setOnCheckedChangeListener(clickListener);
-
- AlertDialog.Builder builder = new AlertDialog.Builder(mInCallScreen)
- .setTitle(title)
- .setCancelable(true)
- .setOnCancelListener(new RespondViaSmsCancelListener())
- .setAdapter(adapter, clickListener)
- .setView(view);
- mPackageSelectionPopup = builder.create();
- mPackageSelectionPopup.show();
- }
-
- private class PackageSelectionAdapter extends BaseAdapter {
- private final LayoutInflater mInflater;
- private final List<ComponentName> mComponents;
-
- public PackageSelectionAdapter(Context context, List<ComponentName> components) {
- mInflater = (LayoutInflater)context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
- mComponents = components;
- }
-
- @Override
- public int getCount() {
- return mComponents.size();
- }
-
- @Override
- public Object getItem(int position) {
- return mComponents.get(position);
- }
-
- @Override
- public long getItemId(int position) {
- return position;
- }
-
- @Override
- public View getView(int position, View convertView, ViewGroup parent) {
- if (convertView == null) {
- convertView = mInflater.inflate(
- com.android.internal.R.layout.resolve_list_item, parent, false);
- }
-
- final ComponentName component = mComponents.get(position);
- final String packageName = component.getPackageName();
- final PackageManager packageManager = mInCallScreen.getPackageManager();
-
- // Set the application label
- final TextView text = (TextView) convertView.findViewById(
- com.android.internal.R.id.text1);
- final TextView text2 = (TextView) convertView.findViewById(
- com.android.internal.R.id.text2);
-
- // Reset any previous values
- text.setText("");
- text2.setVisibility(View.GONE);
- try {
- final ApplicationInfo appInfo = packageManager.getApplicationInfo(packageName, 0);
- final CharSequence label = packageManager.getApplicationLabel(appInfo);
- if (label != null) {
- text.setText(label);
- }
- } catch (PackageManager.NameNotFoundException e) {
- Log.w(TAG, "Failed to load app label because package was not found.");
- }
-
- // Set the application icon
- final ImageView icon = (ImageView) convertView.findViewById(android.R.id.icon);
- Drawable drawable = null;
- try {
- drawable = mInCallScreen.getPackageManager().getApplicationIcon(packageName);
- } catch (PackageManager.NameNotFoundException e) {
- Log.w(TAG, "Failed to load icon because it wasn't found.");
- }
- if (drawable == null) {
- drawable = mInCallScreen.getPackageManager().getDefaultActivityIcon();
- }
- icon.setImageDrawable(drawable);
- ViewGroup.LayoutParams lp = (ViewGroup.LayoutParams) icon.getLayoutParams();
- lp.width = lp.height = getIconSize();
-
- return convertView;
- }
-
- }
-
- private class PackageClickListener implements DialogInterface.OnClickListener,
- CompoundButton.OnCheckedChangeListener {
- /** Phone number to send the SMS to. */
- final private String mPhoneNumber;
- final private String mMessage;
- final private List<ComponentName> mComponents;
- private boolean mMakeDefault = false;
-
- public PackageClickListener(String phoneNumber, String message,
- List<ComponentName> components) {
- mPhoneNumber = phoneNumber;
- mMessage = message;
- mComponents = components;
- }
-
- @Override
- public void onClick(DialogInterface dialog, int which) {
- ComponentName component = mComponents.get(which);
- sendTextAndExit(mPhoneNumber, mMessage, component, mMakeDefault);
- }
-
- @Override
- public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
- Log.i(TAG, "mMakeDefault : " + isChecked);
- mMakeDefault = isChecked;
- }
- }
-
- private void sendTextAndExit(String phoneNumber, String message, ComponentName component,
- boolean setDefaultComponent) {
- // Send the selected message immediately with no user interaction.
- sendText(phoneNumber, message, component);
-
- if (setDefaultComponent) {
- final SharedPreferences prefs = mInCallScreen.getSharedPreferences(
- SHARED_PREFERENCES_NAME, Context.MODE_PRIVATE);
- prefs.edit()
- .putString(KEY_INSTANT_TEXT_DEFAULT_COMPONENT, component.flattenToString())
- .apply();
- }
-
- // ...and show a brief confirmation to the user (since
- // otherwise it's hard to be sure that anything actually
- // happened.)
- final Resources res = mInCallScreen.getResources();
- final String formatString = res.getString(R.string.respond_via_sms_confirmation_format);
- final String confirmationMsg = String.format(formatString, phoneNumber);
- Toast.makeText(mInCallScreen,
- confirmationMsg,
- Toast.LENGTH_LONG).show();
-
- // TODO: If the device is locked, this toast won't actually ever
- // be visible! (That's because we're about to dismiss the call
- // screen, which means that the device will return to the
- // keyguard. But toasts aren't visible on top of the keyguard.)
- // Possible fixes:
- // (1) Is it possible to allow a specific Toast to be visible
- // on top of the keyguard?
- // (2) Artifically delay the dismissCallScreen() call by 3
- // seconds to allow the toast to be seen?
- // (3) Don't use a toast at all; instead use a transient state
- // of the InCallScreen (perhaps via the InCallUiState
- // progressIndication feature), and have that state be
- // visible for 3 seconds before calling dismissCallScreen().
-
- onPostMessageSent();
- }
-
- /**
- * Sends a text message without any interaction from the user.
- */
- private void sendText(String phoneNumber, String message, ComponentName component) {
- if (VDBG) log("sendText: number "
- + phoneNumber + ", message '" + message + "'");
-
- mInCallScreen.startService(getInstantTextIntent(phoneNumber, message, component));
- }
-
- private void onPostMessageSent() {
- // At this point the user is done dealing with the incoming call, so
- // there's no reason to keep it around. (It's also confusing for
- // the "incoming call" icon in the status bar to still be visible.)
- // So reject the call now.
- mInCallScreen.hangupRingingCall();
-
- dismissPopup();
-
- 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.
- PhoneGlobals.getInstance().dismissCallScreen();
- } else {
- // The user is still in the middle of other phone calls, so we should keep the
- // in-call screen.
- mInCallScreen.requestUpdateScreen();
- }
- }
-
- /**
- * Brings up the standard SMS compose UI.
- */
- private void launchSmsCompose(String phoneNumber) {
- if (VDBG) log("launchSmsCompose: number " + phoneNumber);
-
- Intent intent = getInstantTextIntent(phoneNumber, null, null);
-
- if (VDBG) log("- Launching SMS compose UI: " + intent);
- mInCallScreen.startService(intent);
- }
-
- /**
- * @param phoneNumber Must not be null.
- * @param message Can be null. If message is null, the returned Intent will be configured to
- * launch the SMS compose UI. If non-null, the returned Intent will cause the specified message
- * to be sent with no interaction from the user.
- * @param component The component that should handle this intent.
- * @return Service Intent for the instant response.
- */
- private static Intent getInstantTextIntent(String phoneNumber, String message,
- ComponentName component) {
- final Uri uri = Uri.fromParts(Constants.SCHEME_SMSTO, phoneNumber, null);
- Intent intent = new Intent(TelephonyManager.ACTION_RESPOND_VIA_MESSAGE, uri);
- if (message != null) {
- intent.putExtra(Intent.EXTRA_TEXT, message);
- } else {
- intent.putExtra("exit_on_sent", true);
- intent.putExtra("showUI", true);
- }
- if (component != null) {
- intent.setComponent(component);
- }
- return intent;
- }
-
- /**
* Settings activity under "Call settings" to let you manage the
* canned responses; see respond_via_sms_settings.xml
*/
@@ -737,51 +192,7 @@
}
}
- /**
- * Read the (customizable) canned responses from SharedPreferences,
- * or from defaults if the user has never actually brought up
- * the Settings UI.
- *
- * This method does disk I/O (reading the SharedPreferences file)
- * so don't call it from the main thread.
- *
- * @see RespondViaSmsManager.Settings
- */
- private String[] loadCannedResponses() {
- if (DBG) log("loadCannedResponses()...");
-
- SharedPreferences prefs = mInCallScreen.getSharedPreferences(SHARED_PREFERENCES_NAME,
- Context.MODE_PRIVATE);
- final Resources res = mInCallScreen.getResources();
-
- String[] responses = new String[NUM_CANNED_RESPONSES];
-
- // Note the default values here must agree with the corresponding
- // android:defaultValue attributes in respond_via_sms_settings.xml.
-
- responses[0] = prefs.getString(KEY_CANNED_RESPONSE_PREF_1,
- res.getString(R.string.respond_via_sms_canned_response_1));
- responses[1] = prefs.getString(KEY_CANNED_RESPONSE_PREF_2,
- res.getString(R.string.respond_via_sms_canned_response_2));
- responses[2] = prefs.getString(KEY_CANNED_RESPONSE_PREF_3,
- res.getString(R.string.respond_via_sms_canned_response_3));
- responses[3] = prefs.getString(KEY_CANNED_RESPONSE_PREF_4,
- res.getString(R.string.respond_via_sms_canned_response_4));
- return responses;
- }
-
- private int getIconSize() {
- if (mIconSize < 0) {
- final ActivityManager am =
- (ActivityManager) mInCallScreen.getSystemService(Context.ACTIVITY_SERVICE);
- mIconSize = am.getLauncherLargeIconSize();
- }
-
- return mIconSize;
- }
-
-
private static void log(String msg) {
- Log.d(TAG, msg);
+ Log.e(TAG, msg);
}
}
diff --git a/src/com/android/phone/SipCallOptionHandler.java b/src/com/android/phone/SipCallOptionHandler.java
index 295e886..5a7e91f 100644
--- a/src/com/android/phone/SipCallOptionHandler.java
+++ b/src/com/android/phone/SipCallOptionHandler.java
@@ -36,6 +36,8 @@
import android.net.sip.SipManager;
import android.net.sip.SipProfile;
import android.os.Bundle;
+import android.os.Handler;
+import android.os.Message;
import android.os.SystemProperties;
import android.provider.Settings;
import android.telephony.PhoneNumberUtils;
@@ -85,6 +87,21 @@
private boolean mUseSipPhone = false;
private boolean mMakePrimary = false;
+ private static final int EVENT_DELAYED_FINISH = 1;
+
+ private static final int DELAYED_FINISH_TIME = 2000; // msec
+
+ private final Handler mHandler = new Handler() {
+ @Override
+ public void handleMessage(Message msg) {
+ if (msg.what == EVENT_DELAYED_FINISH) {
+ finish();
+ } else {
+ Log.wtf(TAG, "Unknown message id: " + msg.what);
+ }
+ }
+ };
+
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
@@ -208,6 +225,14 @@
setResultAndFinish();
}
+ /**
+ * Starts a delayed finish() in order to give the UI
+ * some time to start up.
+ */
+ private void startDelayedFinish() {
+ mHandler.sendEmptyMessageDelayed(EVENT_DELAYED_FINISH, DELAYED_FINISH_TIME);
+ }
+
@Override
public void onPause() {
super.onPause();
@@ -394,7 +419,7 @@
// Woo hoo -- it's finally OK to initiate the outgoing call!
PhoneGlobals.getInstance().callController.placeCall(mIntent);
}
- finish();
+ startDelayedFinish();
}
});
}
diff --git a/src/com/android/phone/TextMessagePackageChooser.java b/src/com/android/phone/TextMessagePackageChooser.java
deleted file mode 100644
index ae638cb..0000000
--- a/src/com/android/phone/TextMessagePackageChooser.java
+++ /dev/null
@@ -1,218 +0,0 @@
-/*
-
- * Copyright (C) 2013 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.phone;
-
-import android.app.Activity;
-import android.app.ActivityManager;
-import android.app.AlertDialog;
-import android.content.ComponentName;
-import android.content.Context;
-import android.content.DialogInterface;
-import android.content.Intent;
-import android.content.SharedPreferences;
-import android.content.pm.ApplicationInfo;
-import android.content.pm.PackageManager;
-import android.graphics.drawable.Drawable;
-import android.os.Bundle;
-import android.util.Log;
-import android.view.LayoutInflater;
-import android.view.View;
-import android.view.ViewGroup;
-import android.widget.BaseAdapter;
-import android.widget.CheckBox;
-import android.widget.CompoundButton;
-import android.widget.ImageView;
-import android.widget.TextView;
-
-import java.util.ArrayList;
-import java.util.List;
-
-public class TextMessagePackageChooser extends Activity {
- private static final String TAG = TextMessagePackageChooser.class.getSimpleName();
-
- /** SharedPreferences file name for our persistent settings. */
- private static final String SHARED_PREFERENCES_NAME = "respond_via_sms_prefs";
-
- private int mIconSize = -1;
-
- @Override
- public void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- final ArrayList<ComponentName> components = getIntent().getParcelableArrayListExtra(
- RejectWithTextMessageManager.TAG_ALL_SMS_SERVICES);
- BaseAdapter adapter = new PackageSelectionAdapter(this, components);
-
- PackageClickListener clickListener = new PackageClickListener(components);
-
- final CharSequence title = getResources().getText(
- com.android.internal.R.string.whichApplication);
- LayoutInflater inflater =
- (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE);
-
- final View view = inflater.inflate(com.android.internal.R.layout.always_use_checkbox,
- null);
- final CheckBox alwaysUse = (CheckBox) view.findViewById(
- com.android.internal.R.id.alwaysUse);
- alwaysUse.setText(com.android.internal.R.string.alwaysUse);
- alwaysUse.setOnCheckedChangeListener(clickListener);
-
- AlertDialog.Builder builder = new AlertDialog.Builder(this)
- .setTitle(title)
- .setCancelable(true)
- .setOnCancelListener(new RespondViaSmsCancelListener())
- .setAdapter(adapter, clickListener)
- .setView(view);
-
- builder.create().show();
- }
-
- private class PackageSelectionAdapter extends BaseAdapter {
- private final LayoutInflater mInflater;
- private final List<ComponentName> mComponents;
-
- public PackageSelectionAdapter(Context context, List<ComponentName> components) {
- mInflater = (LayoutInflater)context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
- mComponents = components;
- }
-
- @Override
- public int getCount() {
- return mComponents.size();
- }
-
- @Override
- public Object getItem(int position) {
- return mComponents.get(position);
- }
-
- @Override
- public long getItemId(int position) {
- return position;
- }
-
- @Override
- public View getView(int position, View convertView, ViewGroup parent) {
- if (convertView == null) {
- convertView = mInflater.inflate(
- com.android.internal.R.layout.activity_chooser_view_list_item, parent,
- false);
- }
-
- final ComponentName component = mComponents.get(position);
- final String packageName = component.getPackageName();
- final PackageManager packageManager = getPackageManager();
-
- // Set the application label
- final TextView text = (TextView) convertView.findViewById(
- com.android.internal.R.id.title);
-
- text.setText("");
- try {
- final ApplicationInfo appInfo = packageManager.getApplicationInfo(packageName, 0);
- final CharSequence label = packageManager.getApplicationLabel(appInfo);
- if (label != null) {
- text.setText(label);
- }
- } catch (PackageManager.NameNotFoundException e) {
- Log.w(TAG, "Failed to load app label because package was not found.");
- }
-
- // Set the application icon
- final ImageView icon = (ImageView) convertView.findViewById(android.R.id.icon);
- Drawable drawable = null;
- try {
- drawable = getPackageManager().getApplicationIcon(packageName);
- } catch (PackageManager.NameNotFoundException e) {
- Log.w(TAG, "Failed to load icon because it wasn't found.");
- }
- if (drawable == null) {
- drawable = getPackageManager().getDefaultActivityIcon();
- }
- icon.setImageDrawable(drawable);
- ViewGroup.LayoutParams lp = (ViewGroup.LayoutParams) icon.getLayoutParams();
- lp.width = lp.height = getIconSize();
-
- return convertView;
- }
-
- }
-
- private class PackageClickListener implements DialogInterface.OnClickListener,
- CompoundButton.OnCheckedChangeListener {
- final private List<ComponentName> mComponents;
- private boolean mMakeDefault = false;
-
- public PackageClickListener(List<ComponentName> components) {
- mComponents = components;
- }
-
- @Override
- public void onClick(DialogInterface dialog, int which) {
- final ComponentName component = mComponents.get(which);
-
- if (mMakeDefault) {
- final SharedPreferences prefs = PhoneGlobals.getInstance().getSharedPreferences(
- SHARED_PREFERENCES_NAME, Context.MODE_PRIVATE);
- prefs.edit().putString(
- RejectWithTextMessageManager.KEY_INSTANT_TEXT_DEFAULT_COMPONENT,
- component.flattenToString()).apply();
- }
-
- final Intent messageIntent = (Intent) getIntent().getParcelableExtra(
- RejectWithTextMessageManager.TAG_SEND_SMS);
- if (messageIntent != null) {
- messageIntent.setComponent(component);
- PhoneGlobals.getInstance().startService(messageIntent);
- }
- finish();
- }
-
- @Override
- public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
- Log.i(TAG, "mMakeDefault : " + isChecked);
- mMakeDefault = isChecked;
- }
- }
-
- /**
- * OnCancelListener for the "Respond via SMS" popup.
- */
- public class RespondViaSmsCancelListener implements DialogInterface.OnCancelListener {
- public RespondViaSmsCancelListener() {
- }
-
- /**
- * Handles the user canceling the popup, either by touching
- * outside the popup or by pressing Back.
- */
- @Override
- public void onCancel(DialogInterface dialog) {
- finish();
- }
- }
-
- private int getIconSize() {
- if (mIconSize < 0) {
- final ActivityManager am =
- (ActivityManager) getSystemService(Context.ACTIVITY_SERVICE);
- mIconSize = am.getLauncherLargeIconSize();
- }
-
- return mIconSize;
- }
-}