summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChiao Cheng <chiaocheng@google.com>2013-07-15 14:54:27 -0700
committerChiao Cheng <chiaocheng@google.com>2013-07-17 11:52:49 -0700
commitd05336248c5600cde35ad564840532f59b4c085c (patch)
treea78255ce64be0b3c2e271989d4ae02c9a1a4a38f
parentc07955a31d6ef76a81eddeb77cb2d6609c8c45c1 (diff)
downloadpackages_apps_InCallUI-d05336248c5600cde35ad564840532f59b4c085c.tar.gz
packages_apps_InCallUI-d05336248c5600cde35ad564840532f59b4c085c.tar.bz2
packages_apps_InCallUI-d05336248c5600cde35ad564840532f59b4c085c.zip
Adding in call screen template.
Along with glow pad for incoming call interaction.. Change-Id: I8d518b5247bee4a10c8fd06763a7e3fe6cff5652
-rw-r--r--Android.mk2
-rw-r--r--AndroidManifest.xml17
-rw-r--r--proguard.flags3
-rw-r--r--res/color/ota_title_color.xml21
-rw-r--r--res/drawable-hdpi/dial_background_texture.pngbin0 -> 99 bytes
-rw-r--r--res/drawable-hdpi/endcall_active.pngbin0 -> 326 bytes
-rw-r--r--res/drawable-hdpi/endcall_background_texture.pngbin0 -> 99 bytes
-rw-r--r--res/drawable-hdpi/endcall_disable.pngbin0 -> 325 bytes
-rw-r--r--res/drawable-hdpi/ic_active_state_dialer_holo_dark.pngbin0 -> 450 bytes
-rw-r--r--res/drawable-hdpi/ic_add_contact_holo_dark.pngbin0 -> 1641 bytes
-rw-r--r--res/drawable-hdpi/ic_dial_end_call.pngbin0 -> 3189 bytes
-rw-r--r--res/drawable-hdpi/ic_dialpad_holo_dark.pngbin0 -> 1389 bytes
-rw-r--r--res/drawable-hdpi/ic_hold_pause_holo_dark.pngbin0 -> 669 bytes
-rw-r--r--res/drawable-hdpi/ic_in_call_touch_handle_normal.pngbin0 -> 8731 bytes
-rw-r--r--res/drawable-hdpi/ic_incall_switch_holo_dark.pngbin0 -> 1913 bytes
-rw-r--r--res/drawable-hdpi/ic_lockscreen_answer_activated.pngbin0 -> 1426 bytes
-rw-r--r--res/drawable-hdpi/ic_lockscreen_answer_normal.pngbin0 -> 1754 bytes
-rw-r--r--res/drawable-hdpi/ic_lockscreen_decline_activated.pngbin0 -> 1416 bytes
-rw-r--r--res/drawable-hdpi/ic_lockscreen_decline_normal.pngbin0 -> 1415 bytes
-rw-r--r--res/drawable-hdpi/ic_lockscreen_text_activated.pngbin0 -> 1697 bytes
-rw-r--r--res/drawable-hdpi/ic_lockscreen_text_normal.pngbin0 -> 1626 bytes
-rw-r--r--res/drawable-hdpi/ic_merge_holo_dark.pngbin0 -> 1340 bytes
-rw-r--r--res/drawable-hdpi/ic_more_indicator_holo_dark.pngbin0 -> 557 bytes
-rw-r--r--res/drawable-hdpi/ic_mute_holo_dark.pngbin0 -> 1485 bytes
-rw-r--r--res/drawable-hdpi/ic_sound_bluetooth_holo_dark.pngbin0 -> 1894 bytes
-rw-r--r--res/drawable-hdpi/ic_sound_handset_holo_dark.pngbin0 -> 1547 bytes
-rw-r--r--res/drawable-hdpi/ic_sound_holo_dark.pngbin0 -> 1996 bytes
-rw-r--r--res/drawable-hdpi/ic_sound_off_speakerphone_holo_dark.pngbin0 -> 1447 bytes
-rw-r--r--res/drawable-hdpi/ic_sound_speakerphone_holo_dark.pngbin0 -> 1953 bytes
-rw-r--r--res/drawable-hdpi/ic_videocall_holo_dark.pngbin0 -> 1273 bytes
-rw-r--r--res/drawable-hdpi/list_focused_holo.9.pngbin0 -> 159 bytes
-rw-r--r--res/drawable-hdpi/list_pressed_holo_dark.9.pngbin0 -> 159 bytes
-rw-r--r--res/drawable-hdpi/list_selector_disabled_holo_dark.9.pngbin0 -> 189 bytes
-rw-r--r--res/drawable-ldrtl-hdpi/ic_add_contact_holo_dark.pngbin0 -> 6014 bytes
-rw-r--r--res/drawable-ldrtl-hdpi/ic_in_call_touch_handle_normal.pngbin0 -> 17691 bytes
-rw-r--r--res/drawable-ldrtl-hdpi/ic_lockscreen_answer_activated.pngbin0 -> 5620 bytes
-rw-r--r--res/drawable-ldrtl-hdpi/ic_lockscreen_answer_normal.pngbin0 -> 6121 bytes
-rw-r--r--res/drawable-ldrtl-hdpi/ic_lockscreen_text_activated.pngbin0 -> 5627 bytes
-rw-r--r--res/drawable-ldrtl-hdpi/ic_lockscreen_text_normal.pngbin0 -> 5475 bytes
-rw-r--r--res/drawable-ldrtl-hdpi/ic_more_indicator_holo_dark.pngbin0 -> 4465 bytes
-rw-r--r--res/drawable-ldrtl-hdpi/ic_sound_handset_holo_dark.pngbin0 -> 5759 bytes
-rw-r--r--res/drawable-ldrtl-hdpi/ic_sound_holo_dark.pngbin0 -> 6515 bytes
-rw-r--r--res/drawable-ldrtl-hdpi/ic_sound_off_speakerphone_holo_dark.pngbin0 -> 5759 bytes
-rw-r--r--res/drawable-ldrtl-hdpi/ic_sound_speakerphone_holo_dark.pngbin0 -> 6370 bytes
-rw-r--r--res/drawable-ldrtl-mdpi/ic_add_contact_holo_dark.pngbin0 -> 5309 bytes
-rw-r--r--res/drawable-ldrtl-mdpi/ic_in_call_touch_handle_normal.pngbin0 -> 11291 bytes
-rw-r--r--res/drawable-ldrtl-mdpi/ic_lockscreen_answer_activated.pngbin0 -> 4987 bytes
-rw-r--r--res/drawable-ldrtl-mdpi/ic_lockscreen_answer_normal.pngbin0 -> 5408 bytes
-rw-r--r--res/drawable-ldrtl-mdpi/ic_lockscreen_text_activated.pngbin0 -> 5109 bytes
-rw-r--r--res/drawable-ldrtl-mdpi/ic_lockscreen_text_normal.pngbin0 -> 5053 bytes
-rw-r--r--res/drawable-ldrtl-mdpi/ic_more_indicator_holo_dark.pngbin0 -> 4278 bytes
-rw-r--r--res/drawable-ldrtl-mdpi/ic_sound_handset_holo_dark.pngbin0 -> 5127 bytes
-rw-r--r--res/drawable-ldrtl-mdpi/ic_sound_holo_dark.pngbin0 -> 5376 bytes
-rw-r--r--res/drawable-ldrtl-mdpi/ic_sound_off_speakerphone_holo_dark.pngbin0 -> 5034 bytes
-rw-r--r--res/drawable-ldrtl-mdpi/ic_sound_speakerphone_holo_dark.pngbin0 -> 5406 bytes
-rw-r--r--res/drawable-ldrtl-xhdpi/ic_add_contact_holo_dark.pngbin0 -> 6949 bytes
-rw-r--r--res/drawable-ldrtl-xhdpi/ic_in_call_touch_handle_normal.pngbin0 -> 24706 bytes
-rw-r--r--res/drawable-ldrtl-xhdpi/ic_lockscreen_answer_activated.pngbin0 -> 6245 bytes
-rw-r--r--res/drawable-ldrtl-xhdpi/ic_lockscreen_answer_normal.pngbin0 -> 7047 bytes
-rw-r--r--res/drawable-ldrtl-xhdpi/ic_lockscreen_text_activated.pngbin0 -> 6175 bytes
-rw-r--r--res/drawable-ldrtl-xhdpi/ic_lockscreen_text_normal.pngbin0 -> 6010 bytes
-rw-r--r--res/drawable-ldrtl-xhdpi/ic_more_indicator_holo_dark.pngbin0 -> 4667 bytes
-rw-r--r--res/drawable-ldrtl-xhdpi/ic_sound_handset_holo_dark.pngbin0 -> 6711 bytes
-rw-r--r--res/drawable-ldrtl-xhdpi/ic_sound_holo_dark.pngbin0 -> 7739 bytes
-rw-r--r--res/drawable-ldrtl-xhdpi/ic_sound_off_speakerphone_holo_dark.pngbin0 -> 6604 bytes
-rw-r--r--res/drawable-ldrtl-xhdpi/ic_sound_speakerphone_holo_dark.pngbin0 -> 7584 bytes
-rw-r--r--res/drawable-mdpi/dial_background_texture.pngbin0 -> 91 bytes
-rw-r--r--res/drawable-mdpi/endcall_active.pngbin0 -> 325 bytes
-rw-r--r--res/drawable-mdpi/endcall_background_texture.pngbin0 -> 90 bytes
-rw-r--r--res/drawable-mdpi/endcall_disable.pngbin0 -> 325 bytes
-rw-r--r--res/drawable-mdpi/ic_active_state_dialer_holo_dark.pngbin0 -> 409 bytes
-rw-r--r--res/drawable-mdpi/ic_add_contact_holo_dark.pngbin0 -> 1160 bytes
-rw-r--r--res/drawable-mdpi/ic_dial_end_call.pngbin0 -> 2484 bytes
-rw-r--r--res/drawable-mdpi/ic_dialpad_holo_dark.pngbin0 -> 1095 bytes
-rw-r--r--res/drawable-mdpi/ic_hold_pause_holo_dark.pngbin0 -> 492 bytes
-rw-r--r--res/drawable-mdpi/ic_in_call_touch_handle_normal.pngbin0 -> 4847 bytes
-rw-r--r--res/drawable-mdpi/ic_incall_switch_holo_dark.pngbin0 -> 1246 bytes
-rw-r--r--res/drawable-mdpi/ic_lockscreen_answer_activated.pngbin0 -> 1075 bytes
-rw-r--r--res/drawable-mdpi/ic_lockscreen_answer_normal.pngbin0 -> 1229 bytes
-rw-r--r--res/drawable-mdpi/ic_lockscreen_decline_activated.pngbin0 -> 1000 bytes
-rw-r--r--res/drawable-mdpi/ic_lockscreen_decline_normal.pngbin0 -> 1015 bytes
-rw-r--r--res/drawable-mdpi/ic_lockscreen_text_activated.pngbin0 -> 1256 bytes
-rw-r--r--res/drawable-mdpi/ic_lockscreen_text_normal.pngbin0 -> 1219 bytes
-rw-r--r--res/drawable-mdpi/ic_merge_holo_dark.pngbin0 -> 975 bytes
-rw-r--r--res/drawable-mdpi/ic_more_indicator_holo_dark.pngbin0 -> 506 bytes
-rw-r--r--res/drawable-mdpi/ic_mute_holo_dark.pngbin0 -> 1042 bytes
-rw-r--r--res/drawable-mdpi/ic_sound_bluetooth_holo_dark.pngbin0 -> 1218 bytes
-rw-r--r--res/drawable-mdpi/ic_sound_handset_holo_dark.pngbin0 -> 1067 bytes
-rw-r--r--res/drawable-mdpi/ic_sound_holo_dark.pngbin0 -> 1251 bytes
-rw-r--r--res/drawable-mdpi/ic_sound_off_speakerphone_holo_dark.pngbin0 -> 996 bytes
-rw-r--r--res/drawable-mdpi/ic_sound_speakerphone_holo_dark.pngbin0 -> 1246 bytes
-rw-r--r--res/drawable-mdpi/ic_videocall_holo_dark.pngbin0 -> 1177 bytes
-rw-r--r--res/drawable-mdpi/list_focused_holo.9.pngbin0 -> 158 bytes
-rw-r--r--res/drawable-mdpi/list_pressed_holo_dark.9.pngbin0 -> 158 bytes
-rw-r--r--res/drawable-mdpi/list_selector_disabled_holo_dark.9.pngbin0 -> 172 bytes
-rw-r--r--res/drawable-xhdpi/dial_background_texture.pngbin0 -> 114 bytes
-rw-r--r--res/drawable-xhdpi/endcall_active.pngbin0 -> 326 bytes
-rw-r--r--res/drawable-xhdpi/endcall_background_texture.pngbin0 -> 114 bytes
-rw-r--r--res/drawable-xhdpi/endcall_disable.pngbin0 -> 326 bytes
-rw-r--r--res/drawable-xhdpi/ic_active_state_dialer_holo_dark.pngbin0 -> 499 bytes
-rw-r--r--res/drawable-xhdpi/ic_add_contact_holo_dark.pngbin0 -> 2283 bytes
-rw-r--r--res/drawable-xhdpi/ic_dial_end_call.pngbin0 -> 4593 bytes
-rw-r--r--res/drawable-xhdpi/ic_dialpad_holo_dark.pngbin0 -> 1439 bytes
-rw-r--r--res/drawable-xhdpi/ic_hold_pause_holo_dark.pngbin0 -> 495 bytes
-rw-r--r--res/drawable-xhdpi/ic_in_call_touch_handle_normal.pngbin0 -> 12790 bytes
-rw-r--r--res/drawable-xhdpi/ic_incall_switch_holo_dark.pngbin0 -> 2643 bytes
-rw-r--r--res/drawable-xhdpi/ic_lockscreen_answer_activated.pngbin0 -> 1941 bytes
-rw-r--r--res/drawable-xhdpi/ic_lockscreen_answer_normal.pngbin0 -> 2295 bytes
-rw-r--r--res/drawable-xhdpi/ic_lockscreen_decline_activated.pngbin0 -> 1805 bytes
-rw-r--r--res/drawable-xhdpi/ic_lockscreen_decline_normal.pngbin0 -> 1853 bytes
-rw-r--r--res/drawable-xhdpi/ic_lockscreen_text_activated.pngbin0 -> 2116 bytes
-rw-r--r--res/drawable-xhdpi/ic_lockscreen_text_normal.pngbin0 -> 2018 bytes
-rw-r--r--res/drawable-xhdpi/ic_merge_holo_dark.pngbin0 -> 1840 bytes
-rw-r--r--res/drawable-xhdpi/ic_more_indicator_holo_dark.pngbin0 -> 713 bytes
-rw-r--r--res/drawable-xhdpi/ic_mute_holo_dark.pngbin0 -> 2205 bytes
-rw-r--r--res/drawable-xhdpi/ic_sound_bluetooth_holo_dark.pngbin0 -> 2764 bytes
-rw-r--r--res/drawable-xhdpi/ic_sound_handset_holo_dark.pngbin0 -> 2114 bytes
-rw-r--r--res/drawable-xhdpi/ic_sound_holo_dark.pngbin0 -> 2827 bytes
-rw-r--r--res/drawable-xhdpi/ic_sound_off_speakerphone_holo_dark.pngbin0 -> 1983 bytes
-rw-r--r--res/drawable-xhdpi/ic_sound_speakerphone_holo_dark.pngbin0 -> 2780 bytes
-rw-r--r--res/drawable-xhdpi/ic_videocall_holo_dark.pngbin0 -> 1339 bytes
-rw-r--r--res/drawable-xhdpi/list_focused_holo.9.pngbin0 -> 163 bytes
-rw-r--r--res/drawable-xhdpi/list_pressed_holo_dark.9.pngbin0 -> 163 bytes
-rw-r--r--res/drawable-xhdpi/list_selector_disabled_holo_dark.9.pngbin0 -> 190 bytes
-rw-r--r--res/drawable/btn_compound_audio.xml105
-rw-r--r--res/drawable/btn_compound_background.xml34
-rw-r--r--res/drawable/btn_compound_dialpad.xml30
-rw-r--r--res/drawable/btn_compound_hold.xml30
-rw-r--r--res/drawable/btn_compound_mute.xml30
-rw-r--r--res/drawable/dialpad_background.xml19
-rw-r--r--res/drawable/dialpad_background_opaque.xml30
-rw-r--r--res/drawable/end_call_background.xml45
-rw-r--r--res/drawable/ic_in_call_touch_handle.xml33
-rw-r--r--res/drawable/ic_lockscreen_answer.xml27
-rw-r--r--res/drawable/ic_lockscreen_answer_activated_layer.xml31
-rw-r--r--res/drawable/ic_lockscreen_answer_normal_layer.xml32
-rw-r--r--res/drawable/ic_lockscreen_decline.xml27
-rw-r--r--res/drawable/ic_lockscreen_decline_activated_layer.xml31
-rw-r--r--res/drawable/ic_lockscreen_decline_normal_layer.xml32
-rw-r--r--res/drawable/ic_lockscreen_text.xml27
-rw-r--r--res/drawable/ic_lockscreen_text_activated_layer.xml31
-rw-r--r--res/drawable/ic_lockscreen_text_normal_layer.xml32
-rw-r--r--res/drawable/list_selector_focused_and_checked.xml20
-rw-r--r--res/layout/incall_screen.xml55
-rw-r--r--res/layout/primary_call_info.xml213
-rw-r--r--res/values/array.xml102
-rw-r--r--res/values/attrs.xml101
-rw-r--r--res/values/colors.xml37
-rw-r--r--res/values/dimens.xml119
-rwxr-xr-x[-rw-r--r--]res/values/strings.xml1412
-rw-r--r--res/values/styles.xml144
-rw-r--r--src/com/android/incallui/CallMonitorService.java5
-rw-r--r--src/com/android/incallui/InCallActivity.java208
-rw-r--r--src/com/android/incallui/widget/multiwaveview/Ease.java132
-rw-r--r--src/com/android/incallui/widget/multiwaveview/GlowPadView.java1261
-rw-r--r--src/com/android/incallui/widget/multiwaveview/PointCloud.java236
-rw-r--r--src/com/android/incallui/widget/multiwaveview/TargetDrawable.java237
-rw-r--r--src/com/android/incallui/widget/multiwaveview/Tweener.java178
158 files changed, 5113 insertions, 16 deletions
diff --git a/Android.mk b/Android.mk
index 11a315a9..b716642b 100644
--- a/Android.mk
+++ b/Android.mk
@@ -9,6 +9,8 @@ LOCAL_PACKAGE_NAME := InCallUI
LOCAL_CERTIFICATE := platform
LOCAL_PRIVELEGED_MODULE := true
+LOCAL_PROGUARD_FLAG_FILES := proguard.flags
+
include $(BUILD_PACKAGE)
# Build the test package
diff --git a/AndroidManifest.xml b/AndroidManifest.xml
index 4ab4868b..24d54810 100644
--- a/AndroidManifest.xml
+++ b/AndroidManifest.xml
@@ -15,16 +15,31 @@
-->
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:androidprv="http://schemas.android.com/apk/prv/res/android"
package="com.android.incallui"
coreApp="true" >
<original-package android:name="com.android.incallui" />
+ <uses-permission android:name="android.permission.VIBRATE"/>
+
<application
android:label="@string/inCallLabel"
android:supportsRtl="true">
+ <!-- Main in-call UI activity. This is never launched directly
+ from outside the phone app; instead, it's either launched by
+ the OutgoingCallBroadcaster (for outgoing calls), or as the
+ fullScreenIntent of a notification (for incoming calls.) -->
+ <activity android:name=".InCallActivity"
+ android:theme="@style/Theme.InCallScreen"
+ android:label="@string/inCallLabel"
+ android:excludeFromRecents="true"
+ android:launchMode="singleInstance"
+ android:screenOrientation="nosensor"
+ android:configChanges="keyboardHidden"
+ android:exported="false">
+ </activity>
+
<service android:name="CallMonitorService">
<intent-filter>
<action android:name="com.android.services.telephony.common.ICallMonitorService" />
diff --git a/proguard.flags b/proguard.flags
new file mode 100644
index 00000000..8fa10e0d
--- /dev/null
+++ b/proguard.flags
@@ -0,0 +1,3 @@
+-keep class com.android.incallui.widget.multiwaveview.* {
+ *;
+}
diff --git a/res/color/ota_title_color.xml b/res/color/ota_title_color.xml
new file mode 100644
index 00000000..14a283a6
--- /dev/null
+++ b/res/color/ota_title_color.xml
@@ -0,0 +1,21 @@
+<?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
+ -->
+
+<selector xmlns:android="http://schemas.android.com/apk/res/android">
+ <item android:color="#FFA6C839"/>
+</selector>
+
diff --git a/res/drawable-hdpi/dial_background_texture.png b/res/drawable-hdpi/dial_background_texture.png
new file mode 100644
index 00000000..9df3b1e7
--- /dev/null
+++ b/res/drawable-hdpi/dial_background_texture.png
Binary files differ
diff --git a/res/drawable-hdpi/endcall_active.png b/res/drawable-hdpi/endcall_active.png
new file mode 100644
index 00000000..38f1e1ce
--- /dev/null
+++ b/res/drawable-hdpi/endcall_active.png
Binary files differ
diff --git a/res/drawable-hdpi/endcall_background_texture.png b/res/drawable-hdpi/endcall_background_texture.png
new file mode 100644
index 00000000..095b0b62
--- /dev/null
+++ b/res/drawable-hdpi/endcall_background_texture.png
Binary files differ
diff --git a/res/drawable-hdpi/endcall_disable.png b/res/drawable-hdpi/endcall_disable.png
new file mode 100644
index 00000000..6a0f6586
--- /dev/null
+++ b/res/drawable-hdpi/endcall_disable.png
Binary files differ
diff --git a/res/drawable-hdpi/ic_active_state_dialer_holo_dark.png b/res/drawable-hdpi/ic_active_state_dialer_holo_dark.png
new file mode 100644
index 00000000..f4a08bea
--- /dev/null
+++ b/res/drawable-hdpi/ic_active_state_dialer_holo_dark.png
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
new file mode 100644
index 00000000..88ff33b3
--- /dev/null
+++ b/res/drawable-hdpi/ic_add_contact_holo_dark.png
Binary files differ
diff --git a/res/drawable-hdpi/ic_dial_end_call.png b/res/drawable-hdpi/ic_dial_end_call.png
new file mode 100644
index 00000000..ab3adb44
--- /dev/null
+++ b/res/drawable-hdpi/ic_dial_end_call.png
Binary files differ
diff --git a/res/drawable-hdpi/ic_dialpad_holo_dark.png b/res/drawable-hdpi/ic_dialpad_holo_dark.png
new file mode 100644
index 00000000..a0ab6c45
--- /dev/null
+++ b/res/drawable-hdpi/ic_dialpad_holo_dark.png
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
new file mode 100644
index 00000000..2b3ff3d3
--- /dev/null
+++ b/res/drawable-hdpi/ic_hold_pause_holo_dark.png
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
new file mode 100644
index 00000000..e8525348
--- /dev/null
+++ b/res/drawable-hdpi/ic_in_call_touch_handle_normal.png
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
new file mode 100644
index 00000000..429511bf
--- /dev/null
+++ b/res/drawable-hdpi/ic_incall_switch_holo_dark.png
Binary files differ
diff --git a/res/drawable-hdpi/ic_lockscreen_answer_activated.png b/res/drawable-hdpi/ic_lockscreen_answer_activated.png
new file mode 100644
index 00000000..3d2752fa
--- /dev/null
+++ b/res/drawable-hdpi/ic_lockscreen_answer_activated.png
Binary files differ
diff --git a/res/drawable-hdpi/ic_lockscreen_answer_normal.png b/res/drawable-hdpi/ic_lockscreen_answer_normal.png
new file mode 100644
index 00000000..9e26edaf
--- /dev/null
+++ b/res/drawable-hdpi/ic_lockscreen_answer_normal.png
Binary files differ
diff --git a/res/drawable-hdpi/ic_lockscreen_decline_activated.png b/res/drawable-hdpi/ic_lockscreen_decline_activated.png
new file mode 100644
index 00000000..b7a438f2
--- /dev/null
+++ b/res/drawable-hdpi/ic_lockscreen_decline_activated.png
Binary files differ
diff --git a/res/drawable-hdpi/ic_lockscreen_decline_normal.png b/res/drawable-hdpi/ic_lockscreen_decline_normal.png
new file mode 100644
index 00000000..a687ae3e
--- /dev/null
+++ b/res/drawable-hdpi/ic_lockscreen_decline_normal.png
Binary files differ
diff --git a/res/drawable-hdpi/ic_lockscreen_text_activated.png b/res/drawable-hdpi/ic_lockscreen_text_activated.png
new file mode 100644
index 00000000..22cf07c5
--- /dev/null
+++ b/res/drawable-hdpi/ic_lockscreen_text_activated.png
Binary files differ
diff --git a/res/drawable-hdpi/ic_lockscreen_text_normal.png b/res/drawable-hdpi/ic_lockscreen_text_normal.png
new file mode 100644
index 00000000..db6c05d6
--- /dev/null
+++ b/res/drawable-hdpi/ic_lockscreen_text_normal.png
Binary files differ
diff --git a/res/drawable-hdpi/ic_merge_holo_dark.png b/res/drawable-hdpi/ic_merge_holo_dark.png
new file mode 100644
index 00000000..5069cbe7
--- /dev/null
+++ b/res/drawable-hdpi/ic_merge_holo_dark.png
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
new file mode 100644
index 00000000..554f7e9a
--- /dev/null
+++ b/res/drawable-hdpi/ic_more_indicator_holo_dark.png
Binary files differ
diff --git a/res/drawable-hdpi/ic_mute_holo_dark.png b/res/drawable-hdpi/ic_mute_holo_dark.png
new file mode 100644
index 00000000..f17a2daa
--- /dev/null
+++ b/res/drawable-hdpi/ic_mute_holo_dark.png
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
new file mode 100644
index 00000000..c7f2402d
--- /dev/null
+++ b/res/drawable-hdpi/ic_sound_bluetooth_holo_dark.png
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
new file mode 100644
index 00000000..288141a2
--- /dev/null
+++ b/res/drawable-hdpi/ic_sound_handset_holo_dark.png
Binary files differ
diff --git a/res/drawable-hdpi/ic_sound_holo_dark.png b/res/drawable-hdpi/ic_sound_holo_dark.png
new file mode 100644
index 00000000..08ee3e8f
--- /dev/null
+++ b/res/drawable-hdpi/ic_sound_holo_dark.png
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
new file mode 100644
index 00000000..6f12d52f
--- /dev/null
+++ b/res/drawable-hdpi/ic_sound_off_speakerphone_holo_dark.png
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
new file mode 100644
index 00000000..eadd0cda
--- /dev/null
+++ b/res/drawable-hdpi/ic_sound_speakerphone_holo_dark.png
Binary files differ
diff --git a/res/drawable-hdpi/ic_videocall_holo_dark.png b/res/drawable-hdpi/ic_videocall_holo_dark.png
new file mode 100644
index 00000000..7aa3222e
--- /dev/null
+++ b/res/drawable-hdpi/ic_videocall_holo_dark.png
Binary files differ
diff --git a/res/drawable-hdpi/list_focused_holo.9.png b/res/drawable-hdpi/list_focused_holo.9.png
new file mode 100644
index 00000000..516f5c73
--- /dev/null
+++ b/res/drawable-hdpi/list_focused_holo.9.png
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
new file mode 100644
index 00000000..5654cd69
--- /dev/null
+++ b/res/drawable-hdpi/list_pressed_holo_dark.9.png
Binary files differ
diff --git a/res/drawable-hdpi/list_selector_disabled_holo_dark.9.png b/res/drawable-hdpi/list_selector_disabled_holo_dark.9.png
new file mode 100644
index 00000000..f6fd30dc
--- /dev/null
+++ b/res/drawable-hdpi/list_selector_disabled_holo_dark.9.png
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
new file mode 100644
index 00000000..b6a1381a
--- /dev/null
+++ b/res/drawable-ldrtl-hdpi/ic_add_contact_holo_dark.png
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
new file mode 100644
index 00000000..4a3628be
--- /dev/null
+++ b/res/drawable-ldrtl-hdpi/ic_in_call_touch_handle_normal.png
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
new file mode 100644
index 00000000..f1deb759
--- /dev/null
+++ b/res/drawable-ldrtl-hdpi/ic_lockscreen_answer_activated.png
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
new file mode 100644
index 00000000..3c23fe99
--- /dev/null
+++ b/res/drawable-ldrtl-hdpi/ic_lockscreen_answer_normal.png
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
new file mode 100644
index 00000000..63afb5e7
--- /dev/null
+++ b/res/drawable-ldrtl-hdpi/ic_lockscreen_text_activated.png
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
new file mode 100644
index 00000000..74430309
--- /dev/null
+++ b/res/drawable-ldrtl-hdpi/ic_lockscreen_text_normal.png
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
new file mode 100644
index 00000000..adb18aed
--- /dev/null
+++ b/res/drawable-ldrtl-hdpi/ic_more_indicator_holo_dark.png
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
new file mode 100644
index 00000000..207d9418
--- /dev/null
+++ b/res/drawable-ldrtl-hdpi/ic_sound_handset_holo_dark.png
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
new file mode 100644
index 00000000..c2e8adbb
--- /dev/null
+++ b/res/drawable-ldrtl-hdpi/ic_sound_holo_dark.png
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
new file mode 100644
index 00000000..2f2b6745
--- /dev/null
+++ b/res/drawable-ldrtl-hdpi/ic_sound_off_speakerphone_holo_dark.png
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
new file mode 100644
index 00000000..135c7f3a
--- /dev/null
+++ b/res/drawable-ldrtl-hdpi/ic_sound_speakerphone_holo_dark.png
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
new file mode 100644
index 00000000..72abb917
--- /dev/null
+++ b/res/drawable-ldrtl-mdpi/ic_add_contact_holo_dark.png
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
new file mode 100644
index 00000000..13b2ecfb
--- /dev/null
+++ b/res/drawable-ldrtl-mdpi/ic_in_call_touch_handle_normal.png
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
new file mode 100644
index 00000000..3d68ff92
--- /dev/null
+++ b/res/drawable-ldrtl-mdpi/ic_lockscreen_answer_activated.png
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
new file mode 100644
index 00000000..2a223ea0
--- /dev/null
+++ b/res/drawable-ldrtl-mdpi/ic_lockscreen_answer_normal.png
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
new file mode 100644
index 00000000..8e9c3b61
--- /dev/null
+++ b/res/drawable-ldrtl-mdpi/ic_lockscreen_text_activated.png
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
new file mode 100644
index 00000000..8d4cb28a
--- /dev/null
+++ b/res/drawable-ldrtl-mdpi/ic_lockscreen_text_normal.png
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
new file mode 100644
index 00000000..2de388f9
--- /dev/null
+++ b/res/drawable-ldrtl-mdpi/ic_more_indicator_holo_dark.png
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
new file mode 100644
index 00000000..6bf0e8d6
--- /dev/null
+++ b/res/drawable-ldrtl-mdpi/ic_sound_handset_holo_dark.png
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
new file mode 100644
index 00000000..561e8fab
--- /dev/null
+++ b/res/drawable-ldrtl-mdpi/ic_sound_holo_dark.png
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
new file mode 100644
index 00000000..3f330acb
--- /dev/null
+++ b/res/drawable-ldrtl-mdpi/ic_sound_off_speakerphone_holo_dark.png
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
new file mode 100644
index 00000000..6cf2e3c8
--- /dev/null
+++ b/res/drawable-ldrtl-mdpi/ic_sound_speakerphone_holo_dark.png
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
new file mode 100644
index 00000000..60068fd6
--- /dev/null
+++ b/res/drawable-ldrtl-xhdpi/ic_add_contact_holo_dark.png
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
new file mode 100644
index 00000000..c7079507
--- /dev/null
+++ b/res/drawable-ldrtl-xhdpi/ic_in_call_touch_handle_normal.png
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
new file mode 100644
index 00000000..1acdc599
--- /dev/null
+++ b/res/drawable-ldrtl-xhdpi/ic_lockscreen_answer_activated.png
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
new file mode 100644
index 00000000..72c2afa5
--- /dev/null
+++ b/res/drawable-ldrtl-xhdpi/ic_lockscreen_answer_normal.png
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
new file mode 100644
index 00000000..d292a7f8
--- /dev/null
+++ b/res/drawable-ldrtl-xhdpi/ic_lockscreen_text_activated.png
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
new file mode 100644
index 00000000..8318590d
--- /dev/null
+++ b/res/drawable-ldrtl-xhdpi/ic_lockscreen_text_normal.png
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
new file mode 100644
index 00000000..6fe45cd3
--- /dev/null
+++ b/res/drawable-ldrtl-xhdpi/ic_more_indicator_holo_dark.png
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
new file mode 100644
index 00000000..1c1f1ad5
--- /dev/null
+++ b/res/drawable-ldrtl-xhdpi/ic_sound_handset_holo_dark.png
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
new file mode 100644
index 00000000..ac38205d
--- /dev/null
+++ b/res/drawable-ldrtl-xhdpi/ic_sound_holo_dark.png
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
new file mode 100644
index 00000000..5bc066ab
--- /dev/null
+++ b/res/drawable-ldrtl-xhdpi/ic_sound_off_speakerphone_holo_dark.png
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
new file mode 100644
index 00000000..3999712a
--- /dev/null
+++ b/res/drawable-ldrtl-xhdpi/ic_sound_speakerphone_holo_dark.png
Binary files differ
diff --git a/res/drawable-mdpi/dial_background_texture.png b/res/drawable-mdpi/dial_background_texture.png
new file mode 100644
index 00000000..90cd07c0
--- /dev/null
+++ b/res/drawable-mdpi/dial_background_texture.png
Binary files differ
diff --git a/res/drawable-mdpi/endcall_active.png b/res/drawable-mdpi/endcall_active.png
new file mode 100644
index 00000000..a82738bf
--- /dev/null
+++ b/res/drawable-mdpi/endcall_active.png
Binary files differ
diff --git a/res/drawable-mdpi/endcall_background_texture.png b/res/drawable-mdpi/endcall_background_texture.png
new file mode 100644
index 00000000..efa65025
--- /dev/null
+++ b/res/drawable-mdpi/endcall_background_texture.png
Binary files differ
diff --git a/res/drawable-mdpi/endcall_disable.png b/res/drawable-mdpi/endcall_disable.png
new file mode 100644
index 00000000..bd1a2f38
--- /dev/null
+++ b/res/drawable-mdpi/endcall_disable.png
Binary files differ
diff --git a/res/drawable-mdpi/ic_active_state_dialer_holo_dark.png b/res/drawable-mdpi/ic_active_state_dialer_holo_dark.png
new file mode 100644
index 00000000..6ff8e484
--- /dev/null
+++ b/res/drawable-mdpi/ic_active_state_dialer_holo_dark.png
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
new file mode 100644
index 00000000..867f494b
--- /dev/null
+++ b/res/drawable-mdpi/ic_add_contact_holo_dark.png
Binary files differ
diff --git a/res/drawable-mdpi/ic_dial_end_call.png b/res/drawable-mdpi/ic_dial_end_call.png
new file mode 100644
index 00000000..c4766422
--- /dev/null
+++ b/res/drawable-mdpi/ic_dial_end_call.png
Binary files differ
diff --git a/res/drawable-mdpi/ic_dialpad_holo_dark.png b/res/drawable-mdpi/ic_dialpad_holo_dark.png
new file mode 100644
index 00000000..b57fcf34
--- /dev/null
+++ b/res/drawable-mdpi/ic_dialpad_holo_dark.png
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
new file mode 100644
index 00000000..7d550de1
--- /dev/null
+++ b/res/drawable-mdpi/ic_hold_pause_holo_dark.png
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
new file mode 100644
index 00000000..cebdc4de
--- /dev/null
+++ b/res/drawable-mdpi/ic_in_call_touch_handle_normal.png
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
new file mode 100644
index 00000000..5b35ef1c
--- /dev/null
+++ b/res/drawable-mdpi/ic_incall_switch_holo_dark.png
Binary files differ
diff --git a/res/drawable-mdpi/ic_lockscreen_answer_activated.png b/res/drawable-mdpi/ic_lockscreen_answer_activated.png
new file mode 100644
index 00000000..6a78f817
--- /dev/null
+++ b/res/drawable-mdpi/ic_lockscreen_answer_activated.png
Binary files differ
diff --git a/res/drawable-mdpi/ic_lockscreen_answer_normal.png b/res/drawable-mdpi/ic_lockscreen_answer_normal.png
new file mode 100644
index 00000000..da15c33c
--- /dev/null
+++ b/res/drawable-mdpi/ic_lockscreen_answer_normal.png
Binary files differ
diff --git a/res/drawable-mdpi/ic_lockscreen_decline_activated.png b/res/drawable-mdpi/ic_lockscreen_decline_activated.png
new file mode 100644
index 00000000..64966268
--- /dev/null
+++ b/res/drawable-mdpi/ic_lockscreen_decline_activated.png
Binary files differ
diff --git a/res/drawable-mdpi/ic_lockscreen_decline_normal.png b/res/drawable-mdpi/ic_lockscreen_decline_normal.png
new file mode 100644
index 00000000..27fe0930
--- /dev/null
+++ b/res/drawable-mdpi/ic_lockscreen_decline_normal.png
Binary files differ
diff --git a/res/drawable-mdpi/ic_lockscreen_text_activated.png b/res/drawable-mdpi/ic_lockscreen_text_activated.png
new file mode 100644
index 00000000..e3e4fc13
--- /dev/null
+++ b/res/drawable-mdpi/ic_lockscreen_text_activated.png
Binary files differ
diff --git a/res/drawable-mdpi/ic_lockscreen_text_normal.png b/res/drawable-mdpi/ic_lockscreen_text_normal.png
new file mode 100644
index 00000000..4a2a54b0
--- /dev/null
+++ b/res/drawable-mdpi/ic_lockscreen_text_normal.png
Binary files differ
diff --git a/res/drawable-mdpi/ic_merge_holo_dark.png b/res/drawable-mdpi/ic_merge_holo_dark.png
new file mode 100644
index 00000000..bd34defc
--- /dev/null
+++ b/res/drawable-mdpi/ic_merge_holo_dark.png
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
new file mode 100644
index 00000000..27b6d33e
--- /dev/null
+++ b/res/drawable-mdpi/ic_more_indicator_holo_dark.png
Binary files differ
diff --git a/res/drawable-mdpi/ic_mute_holo_dark.png b/res/drawable-mdpi/ic_mute_holo_dark.png
new file mode 100644
index 00000000..801d1e0e
--- /dev/null
+++ b/res/drawable-mdpi/ic_mute_holo_dark.png
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
new file mode 100644
index 00000000..c0e95cbe
--- /dev/null
+++ b/res/drawable-mdpi/ic_sound_bluetooth_holo_dark.png
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
new file mode 100644
index 00000000..e5fce575
--- /dev/null
+++ b/res/drawable-mdpi/ic_sound_handset_holo_dark.png
Binary files differ
diff --git a/res/drawable-mdpi/ic_sound_holo_dark.png b/res/drawable-mdpi/ic_sound_holo_dark.png
new file mode 100644
index 00000000..060f926d
--- /dev/null
+++ b/res/drawable-mdpi/ic_sound_holo_dark.png
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
new file mode 100644
index 00000000..adaff605
--- /dev/null
+++ b/res/drawable-mdpi/ic_sound_off_speakerphone_holo_dark.png
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
new file mode 100644
index 00000000..2b9600b7
--- /dev/null
+++ b/res/drawable-mdpi/ic_sound_speakerphone_holo_dark.png
Binary files differ
diff --git a/res/drawable-mdpi/ic_videocall_holo_dark.png b/res/drawable-mdpi/ic_videocall_holo_dark.png
new file mode 100644
index 00000000..776d27a4
--- /dev/null
+++ b/res/drawable-mdpi/ic_videocall_holo_dark.png
Binary files differ
diff --git a/res/drawable-mdpi/list_focused_holo.9.png b/res/drawable-mdpi/list_focused_holo.9.png
new file mode 100644
index 00000000..7c0599e3
--- /dev/null
+++ b/res/drawable-mdpi/list_focused_holo.9.png
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
new file mode 100644
index 00000000..6e77525d
--- /dev/null
+++ b/res/drawable-mdpi/list_pressed_holo_dark.9.png
Binary files differ
diff --git a/res/drawable-mdpi/list_selector_disabled_holo_dark.9.png b/res/drawable-mdpi/list_selector_disabled_holo_dark.9.png
new file mode 100644
index 00000000..92da2f0d
--- /dev/null
+++ b/res/drawable-mdpi/list_selector_disabled_holo_dark.9.png
Binary files differ
diff --git a/res/drawable-xhdpi/dial_background_texture.png b/res/drawable-xhdpi/dial_background_texture.png
new file mode 100644
index 00000000..02aacc87
--- /dev/null
+++ b/res/drawable-xhdpi/dial_background_texture.png
Binary files differ
diff --git a/res/drawable-xhdpi/endcall_active.png b/res/drawable-xhdpi/endcall_active.png
new file mode 100644
index 00000000..5347ed29
--- /dev/null
+++ b/res/drawable-xhdpi/endcall_active.png
Binary files differ
diff --git a/res/drawable-xhdpi/endcall_background_texture.png b/res/drawable-xhdpi/endcall_background_texture.png
new file mode 100644
index 00000000..c94eeece
--- /dev/null
+++ b/res/drawable-xhdpi/endcall_background_texture.png
Binary files differ
diff --git a/res/drawable-xhdpi/endcall_disable.png b/res/drawable-xhdpi/endcall_disable.png
new file mode 100644
index 00000000..fa10196c
--- /dev/null
+++ b/res/drawable-xhdpi/endcall_disable.png
Binary files differ
diff --git a/res/drawable-xhdpi/ic_active_state_dialer_holo_dark.png b/res/drawable-xhdpi/ic_active_state_dialer_holo_dark.png
new file mode 100644
index 00000000..0211d69b
--- /dev/null
+++ b/res/drawable-xhdpi/ic_active_state_dialer_holo_dark.png
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
new file mode 100644
index 00000000..72988823
--- /dev/null
+++ b/res/drawable-xhdpi/ic_add_contact_holo_dark.png
Binary files differ
diff --git a/res/drawable-xhdpi/ic_dial_end_call.png b/res/drawable-xhdpi/ic_dial_end_call.png
new file mode 100644
index 00000000..c24ec987
--- /dev/null
+++ b/res/drawable-xhdpi/ic_dial_end_call.png
Binary files differ
diff --git a/res/drawable-xhdpi/ic_dialpad_holo_dark.png b/res/drawable-xhdpi/ic_dialpad_holo_dark.png
new file mode 100644
index 00000000..f9a002c7
--- /dev/null
+++ b/res/drawable-xhdpi/ic_dialpad_holo_dark.png
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
new file mode 100644
index 00000000..d2966755
--- /dev/null
+++ b/res/drawable-xhdpi/ic_hold_pause_holo_dark.png
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
new file mode 100644
index 00000000..1d112f2a
--- /dev/null
+++ b/res/drawable-xhdpi/ic_in_call_touch_handle_normal.png
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
new file mode 100644
index 00000000..9168c32d
--- /dev/null
+++ b/res/drawable-xhdpi/ic_incall_switch_holo_dark.png
Binary files differ
diff --git a/res/drawable-xhdpi/ic_lockscreen_answer_activated.png b/res/drawable-xhdpi/ic_lockscreen_answer_activated.png
new file mode 100644
index 00000000..cd6a6abb
--- /dev/null
+++ b/res/drawable-xhdpi/ic_lockscreen_answer_activated.png
Binary files differ
diff --git a/res/drawable-xhdpi/ic_lockscreen_answer_normal.png b/res/drawable-xhdpi/ic_lockscreen_answer_normal.png
new file mode 100644
index 00000000..983d5d94
--- /dev/null
+++ b/res/drawable-xhdpi/ic_lockscreen_answer_normal.png
Binary files differ
diff --git a/res/drawable-xhdpi/ic_lockscreen_decline_activated.png b/res/drawable-xhdpi/ic_lockscreen_decline_activated.png
new file mode 100644
index 00000000..317b3296
--- /dev/null
+++ b/res/drawable-xhdpi/ic_lockscreen_decline_activated.png
Binary files differ
diff --git a/res/drawable-xhdpi/ic_lockscreen_decline_normal.png b/res/drawable-xhdpi/ic_lockscreen_decline_normal.png
new file mode 100644
index 00000000..2cb03e7b
--- /dev/null
+++ b/res/drawable-xhdpi/ic_lockscreen_decline_normal.png
Binary files differ
diff --git a/res/drawable-xhdpi/ic_lockscreen_text_activated.png b/res/drawable-xhdpi/ic_lockscreen_text_activated.png
new file mode 100644
index 00000000..41ea18af
--- /dev/null
+++ b/res/drawable-xhdpi/ic_lockscreen_text_activated.png
Binary files differ
diff --git a/res/drawable-xhdpi/ic_lockscreen_text_normal.png b/res/drawable-xhdpi/ic_lockscreen_text_normal.png
new file mode 100644
index 00000000..15e47793
--- /dev/null
+++ b/res/drawable-xhdpi/ic_lockscreen_text_normal.png
Binary files differ
diff --git a/res/drawable-xhdpi/ic_merge_holo_dark.png b/res/drawable-xhdpi/ic_merge_holo_dark.png
new file mode 100644
index 00000000..57baa20a
--- /dev/null
+++ b/res/drawable-xhdpi/ic_merge_holo_dark.png
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
new file mode 100644
index 00000000..3d9897a1
--- /dev/null
+++ b/res/drawable-xhdpi/ic_more_indicator_holo_dark.png
Binary files differ
diff --git a/res/drawable-xhdpi/ic_mute_holo_dark.png b/res/drawable-xhdpi/ic_mute_holo_dark.png
new file mode 100644
index 00000000..a882a760
--- /dev/null
+++ b/res/drawable-xhdpi/ic_mute_holo_dark.png
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
new file mode 100644
index 00000000..867d87da
--- /dev/null
+++ b/res/drawable-xhdpi/ic_sound_bluetooth_holo_dark.png
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
new file mode 100644
index 00000000..42e19bd9
--- /dev/null
+++ b/res/drawable-xhdpi/ic_sound_handset_holo_dark.png
Binary files differ
diff --git a/res/drawable-xhdpi/ic_sound_holo_dark.png b/res/drawable-xhdpi/ic_sound_holo_dark.png
new file mode 100644
index 00000000..aa2a5af1
--- /dev/null
+++ b/res/drawable-xhdpi/ic_sound_holo_dark.png
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
new file mode 100644
index 00000000..98a449fd
--- /dev/null
+++ b/res/drawable-xhdpi/ic_sound_off_speakerphone_holo_dark.png
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
new file mode 100644
index 00000000..71aad975
--- /dev/null
+++ b/res/drawable-xhdpi/ic_sound_speakerphone_holo_dark.png
Binary files differ
diff --git a/res/drawable-xhdpi/ic_videocall_holo_dark.png b/res/drawable-xhdpi/ic_videocall_holo_dark.png
new file mode 100644
index 00000000..2b7dcab9
--- /dev/null
+++ b/res/drawable-xhdpi/ic_videocall_holo_dark.png
Binary files differ
diff --git a/res/drawable-xhdpi/list_focused_holo.9.png b/res/drawable-xhdpi/list_focused_holo.9.png
new file mode 100644
index 00000000..690cb1eb
--- /dev/null
+++ b/res/drawable-xhdpi/list_focused_holo.9.png
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
new file mode 100644
index 00000000..e4b33935
--- /dev/null
+++ b/res/drawable-xhdpi/list_pressed_holo_dark.9.png
Binary files differ
diff --git a/res/drawable-xhdpi/list_selector_disabled_holo_dark.9.png b/res/drawable-xhdpi/list_selector_disabled_holo_dark.9.png
new file mode 100644
index 00000000..88726b69
--- /dev/null
+++ b/res/drawable-xhdpi/list_selector_disabled_holo_dark.9.png
Binary files differ
diff --git a/res/drawable/btn_compound_audio.xml b/res/drawable/btn_compound_audio.xml
new file mode 100644
index 00000000..c348c98c
--- /dev/null
+++ b/res/drawable/btn_compound_audio.xml
@@ -0,0 +1,105 @@
+<?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_background.xml b/res/drawable/btn_compound_background.xml
new file mode 100644
index 00000000..6f2ef5f1
--- /dev/null
+++ b/res/drawable/btn_compound_background.xml
@@ -0,0 +1,34 @@
+<?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 resource for "compound buttons" in the in-call UI.
+ These buttons have two states (checked and unchecked), and
+ show a blue bar along the bottom edge when checked. -->
+<selector xmlns:android="http://schemas.android.com/apk/res/android">
+
+ <item android:state_pressed="true"
+ android:drawable="@drawable/list_pressed_holo_dark" />
+ <item android:state_checked="true" android:state_focused="true"
+ android:drawable="@drawable/list_selector_focused_and_checked" />
+ <item android:state_focused="true"
+ android:drawable="@drawable/list_focused_holo" />
+ <item android:state_checked="true"
+ android:drawable="@drawable/ic_active_state_dialer_holo_dark" />
+
+ <item
+ android:drawable="@android:color/transparent" />
+
+</selector>
diff --git a/res/drawable/btn_compound_dialpad.xml b/res/drawable/btn_compound_dialpad.xml
new file mode 100644
index 00000000..b44f2faf
--- /dev/null
+++ b/res/drawable/btn_compound_dialpad.xml
@@ -0,0 +1,30 @@
+<?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
new file mode 100644
index 00000000..50161eac
--- /dev/null
+++ b/res/drawable/btn_compound_hold.xml
@@ -0,0 +1,30 @@
+<?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
new file mode 100644
index 00000000..4e09bd9c
--- /dev/null
+++ b/res/drawable/btn_compound_mute.xml
@@ -0,0 +1,30 @@
+<?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/dialpad_background.xml b/res/drawable/dialpad_background.xml
new file mode 100644
index 00000000..0e31f5ea
--- /dev/null
+++ b/res/drawable/dialpad_background.xml
@@ -0,0 +1,19 @@
+<?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.
+-->
+
+<bitmap xmlns:android="http://schemas.android.com/apk/res/android"
+ android:src="@drawable/dial_background_texture"
+ android:tileMode="repeat" />
diff --git a/res/drawable/dialpad_background_opaque.xml b/res/drawable/dialpad_background_opaque.xml
new file mode 100644
index 00000000..d8792f20
--- /dev/null
+++ b/res/drawable/dialpad_background_opaque.xml
@@ -0,0 +1,30 @@
+<?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
new file mode 100644
index 00000000..33ec22fa
--- /dev/null
+++ b/res/drawable/end_call_background.xml
@@ -0,0 +1,45 @@
+<?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
new file mode 100644
index 00000000..e657e92e
--- /dev/null
+++ b/res/drawable/ic_in_call_touch_handle.xml
@@ -0,0 +1,33 @@
+<?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
new file mode 100644
index 00000000..3184111f
--- /dev/null
+++ b/res/drawable/ic_lockscreen_answer.xml
@@ -0,0 +1,27 @@
+<?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
new file mode 100644
index 00000000..6889581c
--- /dev/null
+++ b/res/drawable/ic_lockscreen_answer_activated_layer.xml
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2012 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<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
new file mode 100644
index 00000000..083fe3fb
--- /dev/null
+++ b/res/drawable/ic_lockscreen_answer_normal_layer.xml
@@ -0,0 +1,32 @@
+<?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
new file mode 100644
index 00000000..6643816d
--- /dev/null
+++ b/res/drawable/ic_lockscreen_decline.xml
@@ -0,0 +1,27 @@
+<?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
new file mode 100644
index 00000000..e3606d1e
--- /dev/null
+++ b/res/drawable/ic_lockscreen_decline_activated_layer.xml
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2012 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<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
new file mode 100644
index 00000000..2896bef8
--- /dev/null
+++ b/res/drawable/ic_lockscreen_decline_normal_layer.xml
@@ -0,0 +1,32 @@
+<?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
new file mode 100644
index 00000000..f9caac81
--- /dev/null
+++ b/res/drawable/ic_lockscreen_text.xml
@@ -0,0 +1,27 @@
+<?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
new file mode 100644
index 00000000..95141e5c
--- /dev/null
+++ b/res/drawable/ic_lockscreen_text_activated_layer.xml
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2012 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<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
new file mode 100644
index 00000000..42fd51de
--- /dev/null
+++ b/res/drawable/ic_lockscreen_text_normal_layer.xml
@@ -0,0 +1,32 @@
+<?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/drawable/list_selector_focused_and_checked.xml b/res/drawable/list_selector_focused_and_checked.xml
new file mode 100644
index 00000000..113dae82
--- /dev/null
+++ b/res/drawable/list_selector_focused_and_checked.xml
@@ -0,0 +1,20 @@
+<?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.
+-->
+
+<layer-list xmlns:android="http://schemas.android.com/apk/res/android" >
+ <item android:drawable="@drawable/ic_active_state_dialer_holo_dark" />
+ <item android:drawable="@drawable/list_focused_holo" />
+</layer-list>
diff --git a/res/layout/incall_screen.xml b/res/layout/incall_screen.xml
new file mode 100644
index 00000000..32159a68
--- /dev/null
+++ b/res/layout/incall_screen.xml
@@ -0,0 +1,55 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2007 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 InCallActivity.java. -->
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:dc="http://schemas.android.com/apk/res-auto"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:orientation="vertical">
+
+ <View android:layout_width="wrap_content"
+ android:layout_height="0dp"
+ android:layout_weight="1"
+ android:background="#ddd"/>
+
+ <!-- TODO(klp): move out to separate file -->
+ <com.android.incallui.widget.multiwaveview.GlowPadView
+ android:id="@+id/glow_pad_view"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_marginBottom="@dimen/glowpadview_margin_bottom"
+ android:focusable="true"
+ android:layout_alignParentBottom="true"
+ android:layout_centerHorizontal="true"
+ android:gravity="center"
+ android:layout_gravity="center_vertical"
+
+ dc:targetDrawables="@array/incoming_call_widget_3way_targets"
+ dc:targetDescriptions="@array/incoming_call_widget_3way_target_descriptions"
+ dc:directionDescriptions="@array/incoming_call_widget_3way_direction_descriptions"
+ dc:handleDrawable="@drawable/ic_in_call_touch_handle"
+ dc:outerRingDrawable="@*android:drawable/ic_lockscreen_outerring"
+ dc:outerRadius="@dimen/glowpadview_target_placement_radius"
+ dc:innerRadius="@dimen/glowpadview_inner_radius"
+ dc:snapMargin="@dimen/glowpadview_snap_margin"
+ dc:feedbackCount="1"
+ dc:vibrationDuration="20"
+ dc:glowRadius="@dimen/glowpadview_glow_radius"
+ dc:pointDrawable="@*android:drawable/ic_lockscreen_glowdot"
+ />
+
+</LinearLayout>
diff --git a/res/layout/primary_call_info.xml b/res/layout/primary_call_info.xml
new file mode 100644
index 00000000..39c3873d
--- /dev/null
+++ b/res/layout/primary_call_info.xml
@@ -0,0 +1,213 @@
+<?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 primary call info, which will be used by CallCard.
+ See also call_card.xml. -->
+<LinearLayout 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"
+ /> -->
+</LinearLayout>
diff --git a/res/values/array.xml b/res/values/array.xml
new file mode 100644
index 00000000..44d8d708
--- /dev/null
+++ b/res/values/array.xml
@@ -0,0 +1,102 @@
+<?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
+ -->
+
+<!-- Array resources for the Phone app. -->
+<resources>
+ <string-array translatable="false" name="transport_types">
+ <item>UDP</item>
+ <item>TCP</item>
+ </string-array>
+
+ <string-array translatable="true" name="sip_call_options_entries">
+ <item>@string/sip_call_options_entry_1</item>
+ <item>@string/sip_call_options_entry_2</item>
+ <item>@string/sip_call_options_entry_3</item>
+ </string-array>
+
+ <string-array translatable="true" name="sip_call_options_wifi_only_entries">
+ <item>@string/sip_call_options_wifi_only_entry_1</item>
+ <item>@string/sip_call_options_entry_2</item>
+ <item>@string/sip_call_options_entry_3</item>
+ </string-array>
+
+ <string-array translatable="false" name="sip_call_options_values">
+ <item>@string/sip_always</item>
+ <item>@string/sip_address_only</item>
+ <item>@string/sip_ask_me_each_time</item>
+ </string-array>
+
+ <string-array translatable="false" name="phone_type_values">
+ <item>@string/pstn_phone</item>
+ <item>@string/internet_phone</item>
+ </string-array>
+
+ <string-array translatable="true" name="sip_send_keepalive_options">
+ <item>@string/sip_system_decide</item>
+ <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/attrs.xml b/res/values/attrs.xml
new file mode 100644
index 00000000..056615d6
--- /dev/null
+++ b/res/values/attrs.xml
@@ -0,0 +1,101 @@
+<?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
+ -->
+
+<resources>
+ <declare-styleable name="EditPhoneNumberPreference">
+ <!-- The enable button text. -->
+ <attr name="enableButtonText" format="string" />
+ <!-- The disable button text. -->
+ <attr name="disableButtonText" format="string" />
+ <!-- The change / update button text. -->
+ <attr name="changeNumButtonText" format="string" />
+ <!-- The confirm button mode. -->
+ <attr name="confirmMode">
+ <!-- Traditional single action "ok" button. -->
+ <enum name="confirm" value="0" />
+ <!-- Two state "enable/disable" button. -->
+ <enum name="activation" value="1" />
+ </attr>
+ </declare-styleable>
+
+ <declare-styleable name="CallForwardEditPreference">
+ <attr name="serviceClass">
+ <!-- voice -->
+ <enum name="voice" value="1" />
+ <!-- data -->
+ <enum name="data" value="2" />
+ </attr>
+ <attr name="reason">
+ <!-- unconditional -->
+ <enum name="unconditional" value="0" />
+ <!-- busy -->
+ <enum name="busy" value="1" />
+ <!-- no_reply -->
+ <enum name="no_reply" value="2" />
+ <!-- not_reachable -->
+ <enum name="not_reachable" value="3" />
+ </attr>
+ </declare-styleable>
+
+ <declare-styleable name="GlowPadView">
+ <attr name="android:gravity"/>
+
+ <!-- Reference to an array resource that be shown as targets around a circle. -->
+ <attr name="targetDrawables" format="reference"/>
+
+ <!-- Reference to an array resource that be used as description for the targets around the circle. -->
+ <attr name="targetDescriptions" format="reference"/>
+
+ <!-- Reference to an array resource that be used to announce the directions with targets around the circle. -->
+ <attr name="directionDescriptions" format="reference"/>
+
+ <!-- Sets a drawable as the center. -->
+ <attr name="handleDrawable" format="reference"/>
+
+ <!-- Drawable to use for wave ripple animation. -->
+ <attr name="outerRingDrawable" format="reference"/>
+
+ <!-- Drawble used for drawing points -->
+ <attr name="pointDrawable" format="reference"/>
+
+ <!-- Inner radius of glow area. -->
+ <attr name="innerRadius" format="dimension"/>
+
+ <!-- Outer radius of glow area. Target icons will be drawn on this circle. -->
+ <attr name="outerRadius" format="dimension"/>
+
+ <!-- Size of target radius. Points within this distance of target center is a "hit". -->
+ <!--
+ <attr name="hitRadius" format="dimension"/>
+ -->
+
+ <!-- Radius of glow under finger. -->
+ <attr name="glowRadius" format="dimension"/>
+
+ <!-- Tactile feedback duration for actions. Set to '0' for no vibration. -->
+ <attr name="vibrationDuration" format="integer"/>
+
+ <!-- How close we need to be before snapping to a target. -->
+ <attr name="snapMargin" format="dimension"/>
+
+ <!-- Number of waves/chevrons to show in animation. -->
+ <attr name="feedbackCount" format="integer"/>
+
+ <!-- Used when the handle shouldn't wait to be hit before following the finger -->
+ <attr name="alwaysTrackFinger" format="boolean"/>
+ </declare-styleable>
+</resources>
diff --git a/res/values/colors.xml b/res/values/colors.xml
new file mode 100644
index 00000000..4040008a
--- /dev/null
+++ b/res/values/colors.xml
@@ -0,0 +1,37 @@
+<?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
+ -->
+
+<resources>
+
+ <!-- In-call UI -->
+ <color name="incall_callTypeSip">#99CE3F</color> <!-- green -->
+ <color name="incall_call_banner_background">#A0000000</color> <!-- semitransparent black -->
+ <color name="incall_secondary_info_background">#8033b5e5</color> <!-- semitransparent blueish grey -->
+ <color name="incall_call_banner_text_color">#FFFFFF</color> <!-- white -->
+
+ <!-- DTMF Dialer -->
+ <color name="dtmf_dialer_display_text">#FFFFFF</color> <!-- white -->
+
+ <!-- Color of the theme of the People app -->
+ <color name="people_app_theme_color">#33B5E5</color>
+
+ <!-- Put on top of each photo, implying 80% darker than usual. -->
+ <color name="on_hold_dim_effect">#cc000000</color>
+
+ <!-- Used with some smaller texts in manage conference screen. -->
+ <color name="manage_conference_secondary_text_color">#888888</color>
+</resources>
diff --git a/res/values/dimens.xml b/res/values/dimens.xml
new file mode 100644
index 00000000..c0a001cd
--- /dev/null
+++ b/res/values/dimens.xml
@@ -0,0 +1,119 @@
+<?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
+ -->
+
+<resources>
+ <!-- Dimensions for CallCard elements (the normal in-call UI) -->
+
+ <!-- Height of the "call banner" overlay on top of the upper part of
+ the call info area. -->
+ <dimen name="call_banner_height">80dp</dimen>
+
+ <!-- Margin between the bottom of the "call card" photo
+ and the top of the in-call button cluster. -->
+ <dimen name="in_call_touch_ui_upper_margin">2dp</dimen>
+
+ <!-- Padding at the left and right edges of the "call banner". -->
+ <dimen name="call_banner_side_padding">24dp</dimen>
+ <!-- Padding at the top and bottom edges of the "call banner". -->
+ <dimen name="call_banner_top_bottom_padding">16dp</dimen>
+
+ <!-- Padding at the top and bottom edges of the "provider information" -->
+ <dimen name="provider_info_top_bottom_padding">8dp</dimen>
+
+ <!-- Right padding for name and number fields in the call banner.
+ This padding is used to ensure that ultra-long names or
+ numbers won't overlap the elapsed time indication. -->
+ <dimen name="call_banner_name_number_right_padding">50sp</dimen>
+
+ <!-- Height of the main row of in-call buttons. -->
+ <dimen name="in_call_button_height">76dp</dimen>
+
+ <!-- Height of the in-call "End" button. Match with Contact's dimens/call_button_height -->
+ <dimen name="in_call_end_button_height">74dp</dimen>
+
+ <!-- Width of buttons in the extra button row. -->
+ <dimen name="extra_row_button_width">56dp</dimen>
+
+ <!-- Height of buttons in the extra button row. -->
+ <dimen name="extra_row_button_height">@dimen/in_call_button_height</dimen>
+
+ <!-- Padding at the left and right edges of the incall_touch_ui button
+ cluster. This padding is necessary because we can't allow the
+ buttons to be very close to the edges of the screen, due to the
+ risk of false touches (from your finger wrapping around while
+ holding the phone, *before* moving it up to your face and having
+ the prox sensor kick in.) -->
+ <dimen name="button_cluster_side_padding">20dp</dimen>
+
+
+ <!-- Dimensions for OTA Call Card -->
+ <dimen name="otaactivate_layout_marginTop">10dp</dimen>
+ <dimen name="otalistenprogress_layout_marginTop">5dp</dimen>
+ <dimen name="otasuccessfail_layout_marginTop">10dp</dimen>
+
+
+ <!-- Dimensions for Emergency Dialer and dialpad inside the in-call screen -->
+ <dimen name="dialpad_horizontal_margin">4dp</dimen>
+ <dimen name="dialpad_vertical_margin">2dp</dimen>
+ <dimen name="dialpad_digits_text_size">35sp</dimen>
+
+ <!-- Just used in landscape mode -->
+ <dimen name="emergency_dialer_digits_height">0px</dimen>
+ <dimen name="dialpad_center_margin">3dp</dimen>
+ <dimen name="dialpad_button_margin">3dp</dimen>
+
+
+ <!-- Layout weight values for dialpad screen. These layouts will be used in one
+ LinearLayout (dialpad_fragment.xml), configuring dialpad screen's vertical
+ ratio. -->
+ <integer name="dialpad_layout_weight_digits">20</integer>
+ <integer name="dialpad_layout_weight_dialpad">65</integer>
+ <integer name="dialpad_layout_weight_additional_buttons">15</integer>
+
+ <!-- Dimension used to possibly down-scale high-res photo into what is suitable
+ for notification's large icon. -->
+ <dimen name="notification_icon_size">64dp</dimen>
+
+ <!-- Circle size for incoming call widget's each item. -->
+ <dimen name="incoming_call_widget_circle_size">94dp</dimen>
+ <!-- Margin used for incoming call widget's icon for each item.
+ This should be same as "(incoming_call_widget_circle_size - icon_size)/2".
+ Right now answer/decline/reject icons have 38dp width/height.
+ So, (94 - 38)/2 ==> 28dp -->
+ <dimen name="incoming_call_widget_asset_margin">28dp</dimen>
+
+
+
+ <!-- Size of alarm alert outer ring. -->
+ <dimen name="glowpadview_outerring_diameter">270dip</dimen>
+
+ <!-- Default target placement radius for GlowPadView. Should be 1/2 of outerring diameter. -->
+ <dimen name="glowpadview_target_placement_radius">135dip</dimen>
+
+ <!-- Default glow radius for GlowPadView -->
+ <dimen name="glowpadview_glow_radius">75dip</dimen>
+
+ <!-- Default distance beyond which GlowPadView snaps to the matching target -->
+ <dimen name="glowpadview_snap_margin">40dip</dimen>
+
+ <!-- Default distance from each snap target that GlowPadView considers a "hit" -->
+ <dimen name="glowpadview_inner_radius">15dip</dimen>
+
+ <dimen name="glowpadview_margin_bottom">-64dip</dimen>
+ <dimen name="glowpadview_margin_right">0dip</dimen>
+
+</resources>
diff --git a/res/values/strings.xml b/res/values/strings.xml
index cbf3aea3..d92dc16e 100644..100755
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -1,21 +1,1405 @@
<?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.
--->
+<!--
+ ~ 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
+ -->
<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<!-- Official label for the in-call UI -->
<string name="inCallLabel">InCallUI</string>
+
+ <!-- "Audio mode" popup menu: Item label to select the speakerphone [CHAR LIMIT=25] -->
+ <string name="audio_mode_speaker">Speaker</string>
+ <!-- "Audio mode" popup menu: Item label to select the handset earpiece [CHAR LIMIT=25] -->
+ <string name="audio_mode_earpiece">Handset earpiece</string>
+ <!-- "Audio mode" popup menu: Item label to select the wired headset [CHAR LIMIT=25] -->
+ <string name="audio_mode_wired_headset">Wired headset</string>
+ <!-- "Audio mode" popup menu: Item label to select the bluetooth headset [CHAR LIMIT=25] -->
+ <string name="audio_mode_bluetooth">Bluetooth</string>
+
+ <!-- post dial -->
+ <!-- In-call screen: body text of the dialog that appears when we encounter
+ the "wait" character in a phone number to be dialed; this dialog asks the
+ user if it's OK to send the numbers following the "wait". -->
+ <string name="wait_prompt_str">Send the following tones?\n</string>
+ <!-- In-call screen: body text of the dialog that appears when we encounter
+ the "PAUSE" character in a phone number to be dialed; this dialog gives
+ informative message to the user to show the sending numbers following the "Pause". -->
+ <string name="pause_prompt_str">Sending tones\n</string>
+ <!-- In-call screen: button label on the "wait" prompt dialog -->
+ <string name="send_button">Send</string>
+ <!-- In-call screen: button label on the "wait" prompt dialog in CDMA Mode-->
+ <string name="pause_prompt_yes">Yes</string>
+ <!-- In-call screen: button label on the "wait" prompt dialog in CDMA Mode-->
+ <string name="pause_prompt_no">No</string>
+ <!-- In-call screen: on the "wild" character dialog, this is the label
+ for a text widget that lets the user enter the digits that should
+ replace the "wild" character. -->
+ <string name="wild_prompt_str">Replace wild character with</string>
+
+ <!-- missing voicemail number -->
+ <!-- Title of the "Missing voicemail number" dialog -->
+ <string name="no_vm_number">Missing voicemail number</string>
+ <!-- Body text of the "Missing voicemail number" dialog -->
+ <string name="no_vm_number_msg">No voicemail number is stored on the SIM card.</string>
+ <!-- Button label on the "Missing voicemail number" dialog -->
+ <string name="add_vm_number_str">Add number</string>
+
+ <!-- Status message displayed on SIM PIN unlock panel -->
+ <string name="puk_unlocked">Your SIM card has been unblocked. Your phone is unlocking\u2026</string>
+ <!-- network depersonalization -->
+ <!-- Label text for PIN entry widget on SIM Network Depersonalization panel -->
+ <string name="label_ndp">SIM network unlock PIN</string>
+ <!-- Button label on SIM Network Depersonalization panel -->
+ <string name="sim_ndp_unlock_text">Unlock</string>
+ <!-- Button label on SIM Network Depersonalization panel -->
+ <string name="sim_ndp_dismiss_text">Dismiss</string>
+ <!-- Status message displayed on SIM Network Depersonalization panel -->
+ <string name="requesting_unlock">Requesting network unlock\u2026</string>
+ <!-- Error message displayed on SIM Network Depersonalization panel -->
+ <string name="unlock_failed">Network unlock request unsuccessful.</string>
+ <!-- Success message displayed on SIM Network Depersonalization panel -->
+ <string name="unlock_success">Network unlock successful.</string>
+
+ <!-- settings strings -->
+
+ <!-- GSM Call settings screen, setting option name -->
+ <string name="labelGSMMore">GSM call settings</string>
+ <!-- CDM Call settings screen, setting option name -->
+ <string name="labelCDMAMore">CDMA call settings</string>
+ <!-- Mobile network settings screen, setting option name -->
+ <string name="apn_settings">Access Point Names</string>
+ <!-- Label for the "Network settings" screen in the Settings UI -->
+ <string name="settings_label">Network settings</string>
+ <!-- Call settings screen, setting option name -->
+ <string name="voicemail">Voicemail</string>
+ <!-- Call forwarding dialog box, voicemail number prefix -->
+ <string name="voicemail_abbreviated">VM:</string>
+ <!-- Mobile network settings screen, setting option name -->
+ <string name="networks">Network operators</string>
+ <!-- Call settings screen title -->
+ <string name="call_settings">Call settings</string>
+ <!-- GSM Call settings screen, setting option name -->
+ <string name="additional_gsm_call_settings">Additional settings</string>
+ <!-- GSM-only Call settings screen, setting option name-->
+ <string name="sum_gsm_call_settings">Additional GSM only call settings</string>
+ <!-- CDMA Call settings screen, setting option name -->
+ <string name="additional_cdma_call_settings">Additional CDMA call settings</string>
+ <!-- CDMA-only Call settings screen, setting option name-->
+ <string name="sum_cdma_call_settings">Additional CDMA only call settings</string>
+ <!-- Call setting screen, nework service setting name -->
+ <string name="labelNwService">Network service settings</string>
+ <!-- Call settings screen, setting option name -->
+ <string name="labelCallerId">Caller ID</string>
+ <!-- Additional call settings screen, setting summary text when the setting is being loaded [CHAR LIMIT=40] -->
+ <string name="sum_loading_settings">Loading settings\u2026</string>
+ <!-- Additional call settings screen, setting summary text when Caller ID is hidden -->
+ <string name="sum_hide_caller_id">Number hidden in outgoing calls</string>
+ <!-- Additional call settings screen, setting summary text when Caller ID is shown -->
+ <string name="sum_show_caller_id">Number displayed in outgoing calls</string>
+ <!-- Additional call settings screen, setting summary text for default Caller ID value -->
+ <string name="sum_default_caller_id">Use default operator settings to display my number in outgoing calls</string>
+ <!-- Additional call settings screen, setting check box name -->
+ <string name="labelCW">Call waiting</string>
+ <!-- Additional call settings screen, setting summary text when call waiting check box is selected -->
+ <string name="sum_cw_enabled">During a call, notify me of incoming calls</string>
+ <!-- Additional call settings screen, setting summary text when call waiting check box is clear -->
+ <string name="sum_cw_disabled">During a call, notify me of incoming calls</string>
+ <!-- Call forwarding settings screen, section heading -->
+ <string name="call_forwarding_settings">Call forwarding settings</string>
+ <!-- Call settings screen, setting option name -->
+ <string name="labelCF">Call forwarding</string>
+
+ <!-- Call forwarding settings screen, setting option name -->
+ <string name="labelCFU">Always forward</string>
+ <!-- Call forwarding dialog box, text field label -->
+ <string name="messageCFU">Always use this number</string>
+ <!-- Call forwarding settings screen, setting summary text when forwarding all calls -->
+ <string name="sum_cfu_enabled_indicator">Forwarding all calls</string>
+ <!-- Call forwarding settings screen, setting summary text the Always forward is set -->
+ <string name="sum_cfu_enabled">Forwarding all calls to <xliff:g id="phonenumber" example="555-1212">{0}</xliff:g></string>
+ <!-- Call forwarding settings screen, Always forward is enabled but the number is unavailable -->
+ <string name="sum_cfu_enabled_no_number">Number is unavailable</string>
+ <!-- Call forwarding settings screen, setting summary text when Always forward is disabled -->
+ <string name="sum_cfu_disabled">Disabled</string>
+
+ <!-- Call forwarding settings screen, setting option name -->
+ <string name="labelCFB">Forward when busy</string>
+ <!-- Call forwarding dialog box, text field label -->
+ <string name="messageCFB">Number when busy</string>
+ <!-- Call forwarding settings screen, setting summary text when forwarding to specific number when busy -->
+ <string name="sum_cfb_enabled">Forwarding to <xliff:g id="phonenumber" example="555-1212">{0}</xliff:g></string>
+ <!-- Call forwarding settings screen, setting summary text when forwarding when busy is disabled -->
+ <string name="sum_cfb_disabled">Disabled</string>
+ <!-- Error message displayed after failing to disable forwarding calls when the phone is busy -->
+ <string name="disable_cfb_forbidden">Your operator doesn\'t support disabling call forwarding when your phone is busy.</string>
+
+ <!-- Call forwarding settings screen, setting option name -->
+ <string name="labelCFNRy">Forward when unanswered</string>
+ <!-- Call forwarding dialog box, text field label -->
+ <string name="messageCFNRy">Number when unanswered</string>
+ <!-- Call forwarding settings screen, setting summary text when forwarding to a specific number when unanswered -->
+ <string name="sum_cfnry_enabled">Forwarding to <xliff:g id="phonenumber" example="555-1212">{0}</xliff:g></string>
+ <!-- Call forwarding settings screen, setting summary text when Forward when unanswered is disabled -->
+ <string name="sum_cfnry_disabled">Disabled</string>
+ <!-- Error message displayed after failing to disable forwarding calls when the phone does not answer -->
+ <string name="disable_cfnry_forbidden">Your operator doesn\'t support disabling call forwarding when your phone doesn\'t answer.</string>
+
+ <!-- Call forwarding settings screen, setting option name -->
+ <string name="labelCFNRc">Forward when unreachable</string>
+ <!-- Call forwarding dialog box, text field label -->
+ <string name="messageCFNRc">Number when unreachable</string>
+ <!-- Call forwarding settings screen, setting summary text when forwarding to a specific number when unreachable-->
+ <string name="sum_cfnrc_enabled">Forwarding to <xliff:g id="phonenumber" example="555-1212">{0}</xliff:g></string>
+ <!-- Call forwarding settings screen, setting summary text when Forward when unreachable is disabled -->
+ <string name="sum_cfnrc_disabled">Disabled</string>
+ <!-- Error message displayed after failing to disable forwarding calls when the phone is unreachable -->
+ <string name="disable_cfnrc_forbidden">Your carrier doesn\'t support disabling call forwarding when your phone is unreachable.</string>
+
+ <!-- Title of the progress dialog displayed while updating Call settings -->
+ <string name="updating_title">Call settings</string>
+ <!-- Title of the alert dialog displayed if an error occurs while updating Call settings -->
+ <string name="error_updating_title">Call settings error</string>
+ <!-- Toast in Call settings dialog while settings are being read -->
+ <string name="reading_settings">Reading settings\u2026</string>
+ <!-- Toast in Call settings dialog while settings are being saved -->
+ <string name="updating_settings">Updating settings\u2026</string>
+ <!-- Toast in Call settings dialog while settings are being reverted -->
+ <string name="reverting_settings">Reverting settings\u2026</string>
+ <!-- Status message displayed in the "Call settings error" dialog -->
+ <string name="response_error">Unexpected response from network.</string>
+ <!-- Status message displayed in the "Call settings error" dialog -->
+ <string name="exception_error">Network or SIM card error.</string>
+ <!-- Status message displayed in the "Call settings error" dialog when operation fails due to FDN
+ [CHAR LIMIT=NONE] -->
+ <string name="fdn_check_failure">Your Phone app\'s Fixed Dialing Numbers setting is turned on. As a result, some call-related features aren\'t working.</string>
+ <!-- Status message displayed in the "Call settings error" dialog -->
+ <string name="radio_off_error">Turn on the radio before viewing these settings.</string>
+ <!-- Button label used to dismiss the "Call settings error" dialog -->
+ <string name="close_dialog">OK</string>
+ <!-- Button label used in several settings-related dialogs -->
+ <string name="enable">Enable</string>
+ <!-- Button label used in several settings-related dialogs -->
+ <string name="disable">Disable</string>
+ <!-- Button label which indicates the user wants to update a stored
+ phone number; used in several settings-related dialogs -->
+ <string name="change_num">Update</string>
+ <!-- Phone settings: Caller ID preference values -->
+ <string-array name="clir_display_values">
+ <!-- Phone settings "Caller ID" preference option: use the default value -->
+ <item>Network default</item>
+ <!-- Phone settings "Caller ID" preference option: hide outgoing Caller ID info -->
+ <item>Hide number</item>
+ <!-- Phone settings "Caller ID" preference option: show outgoing Caller ID info -->
+ <item>Show number</item>
+ </string-array>
+ <!-- Phone settings: Internal keys used for Caller ID preference values. DO NOT TRANSLATE. -->
+ <string-array name="clir_values" translatable="false">
+ <!-- Phone settings: Internal key used for Caller ID preference values. DO NOT TRANSLATE. -->
+ <item><xliff:g>DEFAULT</xliff:g></item>
+ <!-- Phone settings: Internal key used for Caller ID preference values. DO NOT TRANSLATE. -->
+ <item><xliff:g>HIDE</xliff:g></item>
+ <!-- Phone settings: Internal key used for Caller ID preference values. DO NOT TRANSLATE. -->
+ <item><xliff:g>SHOW</xliff:g></item>
+ </string-array>
+
+ <!-- voicemail setting strings --><skip/>
+ <!-- Call settings screen, Set voicemail number dialog text -->
+ <string name="vm_changed">Voicemail number changed.</string>
+ <!-- Call settings screen, Set voicemail number dialog text -->
+ <string name="vm_change_failed">Couldn\'t change the voicemail number.\nContact your carrier if this problem persists.</string>
+ <!-- Call settings screen, displayed when vm provider supplied forwarding number change fails-->
+ <string name="fw_change_failed">Couldn\'t change the forwarding number.\nContact your carrier if this problem persists.</string>
+ <!-- Call settings screen, displayed when forwarding number read fails-->
+ <string name="fw_get_in_vm_failed">Couldn\'t retrieve and save current forwarding number settings.\nSwitch to the new provider anyway?</string>
+ <!-- Call settings screen, Set voicemail number dialog text -->
+ <string name="no_change">No changes were made.</string>
+ <!-- Call settings screen, "Voicemail" provider setting summary text when no provider is selected -->
+ <string name="sum_voicemail_choose_provider">Choose voicemail service</string>
+ <!-- Call settings screen, "Voicemail" screen, default option - My Carrier -->
+ <string name="voicemail_default">My carrier</string>
+
+ <!-- networks setting strings --><skip/>
+ <!-- Mobile network settings screen title -->
+ <string name="mobile_networks">Mobile network settings</string>
+ <!-- Available networks screen title/heading -->
+ <string name="label_available">Available networks</string>
+ <!-- Mobile network settings screen, toast when searching for available networks -->
+ <string name="load_networks_progress">Searching\u2026</string>
+ <!-- Available networks screen, text when no networks are found -->
+ <string name="empty_networks_list">No networks found.</string>
+ <!-- Available networks screen, setting option name -->
+ <string name="search_networks">Search networks</string>
+ <!-- Available networks screen, toast when an error is encountered when searching for networks -->
+ <string name="network_query_error">Error while searching for networks.</string>
+ <!-- Available networks screen, toast when registering on a specific network -->
+ <string name="register_on_network">Registering on <xliff:g id="network">%s</xliff:g>\u2026</string>
+ <!-- Available networks screen, toast when SIM card isn't allowed on a network -->
+ <string name="not_allowed">Your SIM card doesn\'t allow a connection to this network.</string>
+ <!-- Available networks screen, toast when unable to connect to a network temporarily -->
+ <string name="connect_later">Can\'t connect to this network right now. Try again later.</string>
+ <!-- Available networks screen, toast when registered on a specific network -->
+ <string name="registration_done">Registered on network.</string>
+ <!-- Mobile network settings screen setting option summary text -->
+ <string name="sum_carrier_select">Choose a network operator</string>
+ <!-- Available networks screen, setting summary text -->
+ <string name="sum_search_networks">Search for all available networks</string>
+ <!-- Available networks screen, setting option name -->
+ <string name="select_automatically">Choose automatically</string>
+ <!-- Available networks screen, setting summary text -->
+ <string name="sum_select_automatically">Automatically choose preferred network</string>
+ <string name="register_automatically">Automatic registration\u2026</string>
+ <string name="preferred_network_mode_title">Network Mode</string>
+ <string name="preferred_network_mode_summary">Change the network operating mode</string>
+ <string name="preferred_network_mode_dialogtitle">Preferred network mode</string>
+ <!-- Mobile network settings, summary for preferred network mode WCDMA preferred[CHAR LIMIT=100] -->
+ <string name="preferred_network_mode_wcdma_perf_summary">Preferred network mode: WCDMA preferred</string>
+ <!-- Mobile network settings, summary for preferred network mode GSM [CHAR LIMIT=100] -->
+ <string name="preferred_network_mode_gsm_only_summary">Preferred network mode: GSM only</string>
+ <!-- Mobile network settings, summary for preferred network mode WCDMA only [CHAR LIMIT=100] -->
+ <string name="preferred_network_mode_wcdma_only_summary">Preferred network mode: WCDMA only</string>
+ <!-- Mobile network settings, summary for preferred network mode GSM / UMTS [CHAR LIMIT=100] -->
+ <string name="preferred_network_mode_gsm_wcdma_summary">Preferred network mode: GSM / WCDMA</string>
+ <!-- Mobile network settings, summary for preferred network mode CDMA [CHAR LIMIT=100] -->
+ <string name="preferred_network_mode_cdma_summary">Preferred network mode: CDMA</string>
+ <!-- Mobile network settings, summary for preferred network mode CDMA / EvDo [CHAR LIMIT=100] -->
+ <string name="preferred_network_mode_cdma_evdo_summary">Preferred network mode: CDMA / EvDo</string>
+ <!-- Mobile network settings, summary for preferred network mode CDMA only [CHAR LIMIT=100] -->
+ <string name="preferred_network_mode_cdma_only_summary">Preferred network mode: CDMA only</string>
+ <!-- Mobile network settings, summary for preferred network mode EvDo only [CHAR LIMIT=100] -->
+ <string name="preferred_network_mode_evdo_only_summary">Preferred network mode: EvDo only</string>
+ <!-- Mobile network settings, summary for preferred network mode CDMA/EvDo/GSM/WCDMA[CHAR LIMIT=100] -->
+ <string name="preferred_network_mode_cdma_evdo_gsm_wcdma_summary">Preferred network mode: CDMA/EvDo/GSM/WCDMA</string>
+ <!-- Mobile network settings, summary for preferred network mode LTE [CHAR LIMIT=100] -->
+ <string name="preferred_network_mode_lte_summary">Preferred network mode: LTE </string>
+ <!-- Mobile network settings, summary for preferred network mode GSM/WCDMA/LTE [CHAR LIMIT=100] -->
+ <string name="preferred_network_mode_lte_gsm_wcdma_summary">Preferred network mode: GSM/WCDMA/LTE</string>
+ <!-- Mobile network settings, summary for preferred network mode CDMA+LTE/EVDO[CHAR LIMIT=100] -->
+ <string name="preferred_network_mode_lte_cdma_evdo_summary">Preferred network mode: CDMA+LTE/EVDO</string>
+ <!-- Mobile network settings, summary for preferred network mode Global[CHAR LIMIT=100] -->
+ <string name="preferred_network_mode_global_summary">Preferred network mode: Global</string>
+ <!-- Mobile network settings, summary for preferred network mode LTE / WCDMA[CHAR LIMIT=100] -->
+ <string name="preferred_network_mode_lte_wcdma_summary">Preferred network mode: LTE / WCDMA</string>
+
+
+ <string-array name="preferred_network_mode_choices">
+ <item>LTE / WCDMA</item>
+ <item>LTE</item>
+ <item>Global</item>
+ <item>GSM/WCDMA/LTE</item>
+ <item>CDMA + LTE/EvDo</item>
+ <item>CDMA/EvDo/GSM/WCDMA</item>
+ <item>EvDo only</item>
+ <item>CDMA w/o EvDo</item>
+ <item>CDMA/EvDo auto</item>
+ <item>GSM/WCDMA auto</item>
+ <item>WCDMA only</item>
+ <item>GSM only</item>
+ <item>GSM/WCDMA preferred</item>
+ </string-array>
+ <string-array name="preferred_network_mode_values" translatable="false">
+ <item>"12"</item>
+ <item>"11"</item>
+ <item>"10"</item>
+ <item>"9"</item>
+ <item>"8"</item>
+ <item>"7"</item>
+ <item>"6"</item>
+ <item>"5"</item>
+ <item>"4"</item>
+ <item>"3"</item>
+ <item>"2"</item>
+ <item>"1"</item>
+ <item>"0"</item>
+ </string-array>
+ <!-- Mobile network settings screen, data enabling checkbox name -->
+ <string name="data_enabled">Data enabled</string>
+ <!-- Mobile network settings screen, setting summary text when check box is not selected (explains what selecting it would do) -->
+ <string name="data_enable_summary">Enable data access over Mobile network</string>
+ <!-- Mobile network settings screen, setting check box name -->
+ <string name="roaming">Data roaming</string>
+ <!-- Mobile network settings screen, setting summary text when check box is selected -->
+ <string name="roaming_enable">Connect to data services when roaming</string>
+ <!-- Mobile network settings screen, setting summary text when check box is clear -->
+ <string name="roaming_disable">Connect to data services when roaming</string>
+ <!-- Mobile network settings UI: notification message shown when you
+ lose data connectivity because you're roaming and you have the
+ "data roaming" feature turned off. -->
+ <string name="roaming_reenable_message">You\'ve lost data connectivity because you left your home network with data roaming turned off.</string>
+ <!-- Mobile network settings screen, dialog message when user selects the Data roaming check box -->
+ <string name="roaming_warning">Allow data roaming? You may incur significant roaming charges!</string>
+ <string name="gsm_umts_options">GSM/UMTS Options</string>
+ <string name="cdma_options">CDMA Options</string>
+
+ <!-- Screen option on the mobile network settings to go into data usage settings -->
+ <string name="throttle_data_usage">Data usage</string>
+ <!-- Data usage settings screen option for checking the current usage -->
+ <string name="throttle_current_usage">Data used in current period</string>
+ <!-- Data usage settings screen option for time frame-->
+ <string name="throttle_time_frame">Data use period</string>
+ <!-- Data usage settings screen option for throttling rate-->
+ <string name="throttle_rate">Data rate policy</string>
+ <!-- Data usage settings screen option for accessing the carrier website-->
+ <string name="throttle_help">Learn more</string>
+
+ <string name="throttle_status_subtext"><xliff:g id="used">%1$s</xliff:g> (<xliff:g id="used">%2$d</xliff:g>\u066A) of <xliff:g id="used">%3$s</xliff:g> period maximum\nNext period starts in <xliff:g id="used">%4$d</xliff:g> days (<xliff:g id="used">%5$s</xliff:g>)</string>
+
+ <string name="throttle_data_usage_subtext"><xliff:g id="used">%1$s</xliff:g> (<xliff:g id="used">%2$d</xliff:g>\u066A) of <xliff:g id="used">%3$s</xliff:g> period maximum</string>
+
+ <string name="throttle_data_rate_reduced_subtext"><xliff:g id="used">%1$s</xliff:g> maximum exceeded\nData rate reduced to <xliff:g id="used">%2$d</xliff:g> Kb/s</string>
+
+ <string name="throttle_time_frame_subtext"><xliff:g id="used">%1$d</xliff:g>\u066A of cycle elapsed\nNext period starts in <xliff:g id="used">%2$d</xliff:g> days (<xliff:g id="used">%3$s</xliff:g>)</string>
+
+ <string name="throttle_rate_subtext">Data rate reduced to <xliff:g id="used">%1$d</xliff:g> Kb/s if data use limit is exceeded</string>
+
+ <string name="throttle_help_subtext">More information about your carrier\'s mobile network data use policy</string>
+
+ <string name="cell_broadcast_sms">Cell Broadcast SMS</string>
+
+ <string name="enable_disable_cell_bc_sms">Cell Broadcast SMS</string>
+ <string name="cell_bc_sms_enable">Cell Broadcast SMS enabled</string>
+ <string name="cell_bc_sms_disable">Cell Broadcast SMS disabled</string>
+
+ <string name="cb_sms_settings">Cell Broadcast SMS settings</string>
+
+ <string name="enable_disable_emergency_broadcast">Emergency Broadcast</string>
+ <string name="emergency_broadcast_enable">Emergency Broadcast enabled</string>
+ <string name="emergency_broadcast_disable">Emergency Broadcast disabled</string>
+
+ <string name="enable_disable_administrative">Administrative</string>
+ <string name="administrative_enable">Administrative enabled</string>
+ <string name="administrative_disable">Administrative disabled</string>
+
+ <string name="enable_disable_maintenance">Maintenance</string>
+ <string name="maintenance_enable">Maintenance enabled</string>
+ <string name="maintenance_disable">Maintenance disabled</string>
+
+ <string name="general_news_settings">General News</string>
+ <string name="bf_news_settings">Business and Financial News</string>
+ <string name="sports_news_settings">Sports News</string>
+ <string name="entertainment_news_settings">Entertainment News</string>
+
+ <string name="enable_disable_local">Local</string>
+ <string name="local_enable">Local news enabled</string>
+ <string name="local_disable">Local news disabled</string>
+
+ <string name="enable_disable_regional">Regional</string>
+ <string name="regional_enable">Regional news enabled</string>
+ <string name="regional_disable">Regional news disabled</string>
+
+ <string name="enable_disable_national">National</string>
+ <string name="national_enable">National news enabled</string>
+ <string name="national_disable">National news disabled</string>
+
+ <string name="enable_disable_international">International</string>
+ <string name="international_enable">International news enabled</string>
+ <string name="international_disable">International news disabled</string>
+
+ <string name="list_language_title">Language</string>
+ <string name="list_language_summary">Select the news language</string>
+ <string-array name="list_language_entries">
+ <item>English</item>
+ <item>French</item>
+ <item>Spanish</item>
+ <item>Japanese</item>
+ <item>Korean</item>
+ <item>Chinese</item>
+ <item>Hebrew</item>
+ </string-array>
+ <string-array name="list_language_values">
+ <item>"1"</item>
+ <item>"2"</item>
+ <item>"3"</item>
+ <item>"4"</item>
+ <item>"5"</item>
+ <item>"6"</item>
+ <item>"7"</item>
+ </string-array>
+ <string name="list_language_dtitle">Languages</string>
+
+ <string name="enable_disable_local_weather">Local Weather</string>
+ <string name="local_weather_enable">Local Weather enabled</string>
+ <string name="local_weather_disable">Local Weather disabled</string>
+
+ <string name="enable_disable_atr">Area Traffic Reports</string>
+ <string name="atr_enable">Area Traffic Reports enabled</string>
+ <string name="atr_disable">Area Traffic Reports disabled</string>
+
+ <string name="enable_disable_lafs">Local Airport Flight Schedules</string>
+ <string name="lafs_enable">Local Airport Flight Schedules enabled</string>
+ <string name="lafs_disable">Local Airport Flight Schedules disabled</string>
+
+ <string name="enable_disable_restaurants">Restaurants</string>
+ <string name="restaurants_enable">Restaurants enabled</string>
+ <string name="restaurants_disable">Restaurants disabled</string>
+
+ <string name="enable_disable_lodgings">Lodgings</string>
+ <string name="lodgings_enable">Lodgings enabled</string>
+ <string name="lodgings_disable">Lodgings disabled</string>
+
+ <string name="enable_disable_retail_directory">Retail Directory</string>
+ <string name="retail_directory_enable">Retail Directory enabled</string>
+ <string name="retail_directory_disable">Retail Directory disabled</string>
+
+ <string name="enable_disable_advertisements">Advertisements</string>
+ <string name="advertisements_enable">Advertisements enabled</string>
+ <string name="advertisements_disable">Advertisements disabled</string>
+
+ <string name="enable_disable_stock_quotes">Stock Quotes</string>
+ <string name="stock_quotes_enable">Stock Quotes enabled</string>
+ <string name="stock_quotes_disable">Stock Quotes disabled</string>
+
+ <string name="enable_disable_eo">Employment Opportunities</string>
+ <string name="eo_enable">Employment Opportunities enabled</string>
+ <string name="eo_disable">Employment Opportunities disabled</string>
+
+ <string name="enable_disable_mhh">Medical, Health, and Hospital</string>
+ <string name="mhh_enable">Medical, Health, and Hospital enabled</string>
+ <string name="mhh_disable">Medical, Health, and Hospital disabled</string>
+
+ <string name="enable_disable_technology_news">Technology News</string>
+ <string name="technology_news_enable">Technology News enabled</string>
+ <string name="technology_news_disable">Technology News disabled</string>
+
+ <string name="enable_disable_multi_category">Multi-category</string>
+ <string name="multi_category_enable">Multi-category enabled</string>
+ <string name="multi_category_disable">Multi-category disabled</string>
+
+ <!-- Mobile network settings screen, setting option name -->
+ <string name="prefer_2g">Use only 2G networks</string>
+ <!-- Mobile network settings screen, setting summary text -->
+ <string name="prefer_2g_summary">Saves battery</string>
+
+ <!-- CDMA System select strings -->
+ <!-- Mobile network settings screen, setting option name -->
+ <string name="cdma_system_select_title">System select</string>
+ <!-- Mobile network settings screen, setting summary text -->
+ <string name="cdma_system_select_summary">Change the CDMA roaming mode</string>
+ <!-- System select settings screen title -->
+ <string name="cdma_system_select_dialogtitle">System select</string>
+ <string-array name="cdma_system_select_choices">
+ <!-- System select dialog screen, setting option name -->
+ <item>Home only</item>
+ <!-- Remove the following option "Affiliated Networks" from the option list -->
+ <!-- <item>Affiliated Networks</item> -->
+ <!-- System select dialog screen, setting option name -->
+ <item>Automatic</item>
+ </string-array>
+ <string-array name="cdma_system_select_values" translatable="false">
+ <!-- Do not translate. -->
+ <item>"0"</item>
+ <!-- Remove the following value "1" which corresponds to "Affiliated Networks" above -->
+ <!-- <item>"1"</item> -->
+ <!-- Do not translate. -->
+ <item>"2"</item>
+ </string-array>
+
+ <string name="cdma_subscription_title">CDMA subscription</string>
+ <string name="cdma_subscription_summary">Change between RUIM/SIM and NV</string>
+ <string name="cdma_subscription_dialogtitle">subscription</string>
+ <string-array name="cdma_subscription_choices">
+ <item>RUIM/SIM</item>
+ <item>NV</item>
+ </string-array>
+ <string-array name="cdma_subscription_values">
+ <item>"0"</item>
+ <item>"1"</item>
+ </string-array>
+ <!-- Preference title with which users can activate CDMA network [CHAR LIMIT=30] -->
+ <string name="cdma_activate_device">Activate device</string>
+ <!-- Preference title for launching an account manager page for prepaid LTE [CHAR LIMIT=30] -->
+ <string name="cdma_lte_data_service">Set up data service</string>
+
+ <!-- FDN settings strings -->
+ <!-- Call settings screen, setting option name -->
+ <string name="fdn">Fixed Dialing Numbers</string>
+ <!-- Call settings screen, button label that takes you to
+ the Fixed Dialing Number management screen -->
+ <string name="manage_fdn_list">FDN list</string>
+ <!-- Call settings screen, preference item label -->
+ <string name="fdn_activation">FDN activation</string>
+ <!-- Call settings setting option name when FDN is enabled -->
+ <string name="fdn_enabled">Fixed Dialing Numbers are enabled</string>
+ <!-- Call settings setting option name when FDN is disabled-->
+ <string name="fdn_disabled">Fixed Dialing Numbers are disabled</string>
+ <!-- Call settings screen, setting option name -->
+ <string name="enable_fdn">Enable FDN</string>
+ <!-- Call settings screen, setting option name -->
+ <string name="disable_fdn">Disable FDN</string>
+ <!-- Call settings screen, setting option name -->
+ <string name="change_pin2">Change PIN2</string>
+ <!-- Call settings screen, setting option name when FDN is enabled -->
+ <string name="enable_fdn_ok">Disable FDN</string>
+ <!-- Call settings screen, setting option name when FDN is disabled -->
+ <string name="disable_fdn_ok">Enable FDN</string>
+ <!-- Call settings screen, setting summary text -->
+ <string name="sum_fdn">Manage Fixed Dialing Numbers</string>
+ <!-- Call settings, FDN screen, setting option name -->
+ <string name="sum_fdn_change_pin">Change PIN for FDN access</string>
+ <!-- Call settings, FDN screen, setting option name -->
+ <string name="sum_fdn_manage_list">Manage phone number list</string>
+ <!-- Voice privacy on CDMA is an added layer of voice encryption. Theoretically, it would be harder to break in to a phone call with this feature enabled. -->
+ <string name="voice_privacy">Voice privacy</string>
+ <string name="voice_privacy_summary">Enable enhanced privacy mode</string>
+ <string name="tty_mode_option_title">TTY mode</string>
+ <string name="tty_mode_option_summary">Set TTY mode</string>
+ <string name="auto_retry_mode_title">Auto-retry</string>
+ <string name="auto_retry_mode_summary">Enable Auto-retry mode</string>
+
+ <!-- FDN list screen: menu item label -->
+ <string name="menu_add">Add contact</string>
+ <!-- FDN list screen: menu item label -->
+ <string name="menu_edit">Edit contact</string>
+ <!-- FDN list screen: menu item label -->
+ <string name="menu_delete">Delete contact</string>
+
+ <!-- FDN related strings -->
+ <!-- Label for PIN2 entry screen -->
+ <string name="get_pin2">Type PIN2</string>
+ <!-- "Edit FDN Contact" screen: Label for the "name" text field -->
+ <string name="name">Name</string>
+ <!-- "Edit FDN Contact" screen: Label for the "number" text field -->
+ <string name="number">Number</string>
+ <!-- "Edit FDN Contact" screen: Button label for "save" action -->
+ <string name="save">Save</string>
+ <!-- Title of "Edit FDN Contact" screen for a new contact -->
+ <string name="add_fdn_contact">Add fixed dialing number</string>
+ <!-- "Edit FDN Contact" screen: status message displayed in a popup (toast) -->
+ <string name="adding_fdn_contact">Adding fixed dialing number\u2026</string>
+ <!-- "Edit FDN Contact" screen: status message displayed in a popup (toast) -->
+ <string name="fdn_contact_added">Fixed dialing number added.</string>
+ <!-- Title of "Edit FDN Contact" screen when editing an already-existing contact -->
+ <string name="edit_fdn_contact">Edit fixed dialing number</string>
+ <!-- "Edit FDN Contact" screen: status message displayed in a popup (toast) -->
+ <string name="updating_fdn_contact">Updating fixed dialing number\u2026</string>
+ <!-- "Edit FDN Contact" screen: status message displayed in a popup (toast) -->
+ <string name="fdn_contact_updated">Fixed dialing number updated.</string>
+ <!-- Title of "Delete FDN Contact" screen -->
+ <string name="delete_fdn_contact">Delete fixed dialing number</string>
+ <!-- "Delete FDN Contact" screen: status message displayed in a popup (toast) -->
+ <string name="deleting_fdn_contact">Deleting fixed dialing number\u2026</string>
+ <!-- "Delete FDN Contact" screen: status message displayed in a popup (toast) -->
+ <string name="fdn_contact_deleted">Fixed dialing number deleted.</string>
+ <!-- FDN settings: error message displayed in a popup (toast) -->
+ <string name="pin2_invalid">FDN wasn\'t updated because you typed an incorrect PIN.</string>
+ <!-- FDN settings: error message displayed in a popup (toast) -->
+ <string name="fdn_invalid_number">FDN wasn\'t updated because the number can\'t exceed 20 digits.</string>
+ <!-- FDN settings: error message displayed in a popup (toast), when the entered
+ FDN number was inappropriate, OR, PIN2 the user entered was incorrect.
+ Because of API restriction, there's no way to determine which is the exact
+ cause of the failure.
+ [CHAR LIMIT=NONE] -->
+ <string name="pin2_or_fdn_invalid">FDN wasn\'t updated. The PIN2 was incorrect, or the phone number was rejected.</string>
+
+ <!-- ADN related strings -->
+ <!-- Placeholder text displayed while loading the list of SIM contacts -->
+ <string name="simContacts_emptyLoading">Reading from SIM card\u2026</string>
+ <!-- Call settings, string that appears on FDN contact list when there are no contacts on the SIM. -->
+ <string name="simContacts_empty">No contacts on your SIM card.</string>
+ <!-- Call settings: title of the dialog that lets you select contacts from the SIM. -->
+ <string name="simContacts_title">Select contacts to import</string>
+ <!-- Appears when user tries to import contacts in SIM during Airplane mode
+ [CHAR LIMIT=NONE] -->
+ <string name="simContacts_airplaneMode">To import contacts from the SIM card, first turn off Airplane mode.</string>
+
+ <!-- SIM PIN strings -->
+ <!-- Title of "Enable/disable SIM PIN" screen -->
+ <string name="enable_pin">Enable/disable SIM PIN</string>
+ <!-- Title of "Change SIM PIN" screen -->
+ <string name="change_pin">Change SIM PIN</string>
+ <!-- SIM PIN screen: label for PIN entry widget -->
+ <string name="enter_pin_text">SIM PIN:</string>
+ <!-- SIM PIN screen: label for PIN entry widget -->
+ <string name="oldPinLabel">Old PIN</string>
+ <!-- SIM PIN screen: label for PIN entry widget -->
+ <string name="newPinLabel">New PIN</string>
+ <!-- SIM PIN screen: label for PIN entry widget -->
+ <string name="confirmPinLabel">Confirm new PIN</string>
+ <!-- SIM PIN screen: error message -->
+ <string name="badPin">The old PIN you typed isn\'t correct. Try again.</string>
+ <!-- SIM PIN screen: error message -->
+ <string name="mismatchPin">The PINs you typed don\'t match. Try again.</string>
+ <!-- SIM PIN screen: error message when PIN is too short or too long -->
+ <string name="invalidPin">Type a PIN that is 4 to 8 numbers.</string>
+ <!-- Title of "Disable SIM PIN" screen -->
+ <string name="disable_sim_pin">Disable SIM PIN</string>
+ <!-- Title of "Enable SIM PIN" screen -->
+ <string name="enable_sim_pin">Enable SIM PIN</string>
+ <!-- SIM PIN screen: progress message displayed while enabling -->
+ <string name="enable_in_progress">Please wait\u2026</string>
+ <!-- SIM PIN screen: status message displayed in a popup (toast) -->
+ <string name="enable_pin_ok">SIM PIN enabled.</string>
+ <!-- SIM PIN screen: status message displayed in a popup (toast) -->
+ <string name="disable_pin_ok">SIM PIN disabled.</string>
+ <!-- SIM PIN screen: error message displayed in a popup (toast) -->
+ <string name="pin_failed">The PIN you typed was incorrect.</string>
+ <!-- SIM PIN screen: status message displayed in a popup (toast) -->
+ <string name="pin_changed">SIM PIN changed successfully.</string>
+ <!-- SIM PIN screen: error message displayed in a dialog -->
+ <string name="puk_requested">Password incorrect, SIM is locked! PUK2 requested.</string>
+
+ <!-- SIM PIN2 strings -->
+ <!-- SIM PIN2 screen: label for PIN entry widget -->
+ <string name="enter_pin2_text">PIN2</string>
+ <!-- SIM PIN2 screen: label for PIN entry widget -->
+ <string name="oldPin2Label">Old PIN2</string>
+ <!-- SIM PIN2 screen: label for PIN entry widget -->
+ <string name="newPin2Label">New PIN2</string>
+ <!-- SIM PIN2 screen: label for PIN entry widget -->
+ <string name="confirmPin2Label">Confirm new PIN2</string>
+ <!-- SIM PIN2 screen: error message -->
+ <string name="badPuk2">The PUK2 you typed isn\'t correct. Try again. </string>
+ <!-- SIM PIN2 screen: error message -->
+ <string name="badPin2">The old PIN2 you typed isn\'t correct. Try again.</string>
+ <!-- SIM PIN2 screen: error message -->
+ <string name="mismatchPin2">The PIN2s you typed don\'t match. Try again.</string>
+ <!-- SIM PIN2 screen: error message -->
+ <string name="invalidPin2">Type a PIN2 that is 4 to 8 numbers.</string>
+ <!-- SIM PIN2 screen: error message -->
+ <string name="invalidPuk2">Type a PUK2 that is 8 numbers.</string>
+ <!-- SIM PIN2 screen: status message displayed in a popup (toast) -->
+ <string name="pin2_changed">PIN2 changed successfully.</string>
+ <!-- SIM PIN2 screen: label for PUK2 entry widget -->
+ <string name="label_puk2_code">Type PUK2 code</string>
+ <!-- SIM PIN2 screen: error message displayed in a dialog -->
+ <string name="fdn_enable_puk2_requested">Password incorrect. Change PIN2 and retry.</string>
+ <!-- SIM PIN2 screen: error message displayed in a dialog -->
+ <string name="puk2_requested">Password incorrect, SIM is locked. PUK2 requested.</string>
+
+ <!-- SIM PIN screen: button label -->
+ <string name="doneButton">Done</string>
+
+ <!-- In-call screen: status label for a conference call -->
+ <string name="caller_manage_header">Conference call <xliff:g id="conf_call_time">%s</xliff:g></string>
+
+ <!-- Used in FakePhoneActivity test code. DO NOT TRANSLATE. -->
+ <string name="fake_phone_activity_phoneNumber_text" translatable="false">(650) 555-1234</string>
+ <!-- Used in FakePhoneActivity test code. DO NOT TRANSLATE. -->
+ <string name="fake_phone_activity_infoText_text" translatable="false">Incoming phone number</string>
+ <!-- Used in FakePhoneActivity test code. DO NOT TRANSLATE. -->
+ <string name="fake_phone_activity_placeCall_text" translatable="false">Fake Incoming Call</string>
+
+ <!-- Call settings screen, Set voicemail dialog title -->
+ <string name="voicemail_settings_number_label">Voicemail number</string>
+
+ <!-- Card titles -->
+ <!-- In-call screen: status label for a call in the "dialing" state -->
+ <string name="card_title_dialing">Dialing</string>
+ <!-- In-call screen: status label for a re-dialing call -->
+ <string name="card_title_redialing">Retrying</string>
+ <!-- In-call screen: status label for a conference call -->
+ <string name="card_title_conf_call">Conference call</string>
+ <!-- In-call screen: status label for an incoming call -->
+ <string name="card_title_incoming_call">Incoming call</string>
+ <!-- In-call screen: status label displayed briefly after a call ends -->
+ <string name="card_title_call_ended">Call ended</string>
+ <!-- In-call screen: status label for call that's on hold -->
+ <string name="card_title_on_hold">On hold</string>
+ <!-- In-call screen: status label for a call that's in the process of hanging up -->
+ <string name="card_title_hanging_up">Hanging up</string>
+ <!-- In-call screen: status label for a call that's in CDMA flash mode -->
+ <string name="card_title_in_call">In call</string>
+ <!-- In-call screen: special status label that shows your own phone
+ number during emergency callback mode (ECM) [CHAR LIMIT=30] -->
+ <string name="card_title_my_phone_number">My number is <xliff:g id="my_phone_number">%s</xliff:g></string>
+
+ <!-- Notification strings -->
+ <!-- The "label" of the in-call Notification for a dialing call, used
+ as the format string for a Chronometer widget. [CHAR LIMIT=60] -->
+ <string name="notification_dialing">Dialing</string>
+ <!-- Missed call notification label, used when there's exactly one missed call -->
+ <string name="notification_missedCallTitle">Missed call</string>
+ <!-- Missed call notification label, used when there are two or more missed calls -->
+ <string name="notification_missedCallsTitle">Missed calls</string>
+ <!-- Missed call notification message used when there are multiple missed calls -->
+ <string name="notification_missedCallsMsg"><xliff:g id="num_missed_calls">%s</xliff:g> missed calls</string>
+ <!-- Missed call notification message used for a single missed call, including
+ the caller-id info from the missed call -->
+ <string name="notification_missedCallTicker">Missed call from <xliff:g id="missed_call_from">%s</xliff:g></string>
+ <!-- The "label" of the in-call Notification for an ongoing call, used
+ as the format string for a Chronometer widget. [CHAR LIMIT=60] -->
+ <string name="notification_ongoing_call">Ongoing call</string>
+ <!-- The "label" of the in-call Notification for a call that's on hold -->
+ <string name="notification_on_hold">On hold</string>
+ <!-- The "label" of the in-call Notification for an incoming ringing call -->
+ <string name="notification_incoming_call">Incoming call</string>
+ <!-- Label for the "Voicemail" notification item, when expanded. -->
+ <string name="notification_voicemail_title">New voicemail</string>
+ <!-- Label for the expanded "Voicemail" notification item,
+ including a count of messages. -->
+ <string name="notification_voicemail_title_count">New voicemail (<xliff:g id="count">%d</xliff:g>)</string>
+ <!-- Message displayed in the "Voicemail" notification item, allowing the user
+ to dial the indicated number. -->
+ <string name="notification_voicemail_text_format">Dial <xliff:g id="voicemail_number">%s</xliff:g></string>
+ <!-- Message displayed in the "Voicemail" notification item,
+ indicating that there's no voicemail number available -->
+ <string name="notification_voicemail_no_vm_number">Voicemail number unknown</string>
+ <!-- Label for the "No service" notification item, when expanded. -->
+ <string name="notification_network_selection_title">No service</string>
+ <!-- Label for the expanded "No service" notification item, including the
+ operator name set by user -->
+ <string name="notification_network_selection_text">Selected network (<xliff:g id="operator_name">%s</xliff:g>) unavailable</string>
+ <!-- Message for "end call" Action.
+ It is displayed in the "Ongoing call" notification, which is shown
+ when the user is outside the in-call screen while the phone call is still
+ active. [CHAR LIMIT=40] -->
+ <string name="notification_action_end_call">Hang up</string>
+ <!-- Message for "call back" Action, which is displayed in the missed call notificaiton.
+ The user will be able to call back to the person or the phone number.
+ [CHAR LIMIT=60] -->
+ <string name="notification_missedCall_call_back">Call back</string>
+ <!-- Message for "reply via sms" action, which is displayed in the missed call notification.
+ The user will be able to send text messages using the phone number.
+ [CHAR LIMIT=60] -->
+ <string name="notification_missedCall_message">Message</string>
+
+ <!-- In-call screen: call failure message displayed in an error dialog -->
+ <string name="incall_error_power_off">To place a call, first turn off Airplane mode.</string>
+ <!-- In-call screen: call failure message displayed in an error dialog.
+ This string is currently unused (see comments in InCallActivity.java.) -->
+ <string name="incall_error_emergency_only">Not registered on network.</string>
+ <!-- In-call screen: call failure message displayed in an error dialog -->
+ <string name="incall_error_out_of_service">Mobile network not available.</string>
+ <!-- In-call screen: call failure message displayed in an error dialog -->
+ <string name="incall_error_no_phone_number_supplied">Call not sent, no valid number entered.</string>
+ <!-- In-call screen: call failure message displayed in an error dialog -->
+ <string name="incall_error_call_failed">Call not sent.</string>
+ <!-- In-call screen: status message displayed in a dialog when starting an MMI -->
+ <string name="incall_status_dialed_mmi">Starting MMI sequence\u2026</string>
+ <!-- In-call screen: message displayed in an error dialog -->
+ <string name="incall_error_supp_service_unknown">Unsupported service.</string>
+ <!-- In-call screen: message displayed in an error dialog -->
+ <string name="incall_error_supp_service_switch">Unable to switch calls.</string>
+ <!-- In-call screen: message displayed in an error dialog -->
+ <string name="incall_error_supp_service_separate">Unable to separate call.</string>
+ <!-- In-call screen: message displayed in an error dialog -->
+ <string name="incall_error_supp_service_transfer">Unable to transfer call.</string>
+ <!-- In-call screen: message displayed in an error dialog -->
+ <string name="incall_error_supp_service_conference">Unable to conference calls.</string>
+ <!-- In-call screen: message displayed in an error dialog -->
+ <string name="incall_error_supp_service_reject">Unable to reject call.</string>
+ <!-- In-call screen: message displayed in an error dialog -->
+ <string name="incall_error_supp_service_hangup">Unable to release call(s).</string>
+
+ <!-- In-call screen: "call type" indication for a SIP call [CHAR LIMIT=30] -->
+ <string name="incall_call_type_label_sip">Internet call</string>
+
+ <!-- Dialog title for the "radio enable" UI for emergency calls -->
+ <string name="emergency_enable_radio_dialog_title">Emergency call</string>
+ <!-- Status message for the "radio enable" UI for emergency calls -->
+ <string name="emergency_enable_radio_dialog_message">Turning on radio\u2026</string>
+ <!-- Status message for the "radio enable" UI for emergency calls -->
+ <string name="emergency_enable_radio_dialog_retry">Out of service area, retrying\u2026</string>
+
+ <!-- Dialer text on Emergency Dialer -->
+ <!-- Emergency dialer: message displayed in an error dialog -->
+ <string name="dial_emergency_error">Call not sent. <xliff:g id="non_emergency_number">%s</xliff:g> is not an emergency number!</string>
+ <!-- Emergency dialer: message displayed in an error dialog -->
+ <string name="dial_emergency_empty_error">Call not sent. Dial an emergency number!</string>
+
+ <!-- Displayed in the text entry box in the dialer when in landscape mode to guide the user
+ to dial using the physical keyboard -->
+ <string name="dialerKeyboardHintText">Use keyboard to dial</string>
+
+ <!-- Text for the onscreen "Hold" button -->
+ <string name="onscreenHoldText">Hold</string>
+ <!-- Text for the onscreen "End call" button -->
+ <string name="onscreenEndCallText">End</string>
+ <!-- Text for the onscreen "Show Dialpad" button -->
+ <string name="onscreenShowDialpadText">Dialpad</string>
+ <!-- Text for the onscreen "Mute" button -->
+ <string name="onscreenMuteText">Mute</string>
+ <!-- Text for the onscreen "Add call" button -->
+ <string name="onscreenAddCallText">Add call</string>
+ <!-- Text for the onscreen "Merge calls" button -->
+ <string name="onscreenMergeCallsText">Merge calls</string>
+ <!-- Text for the onscreen "Swap calls" button -->
+ <string name="onscreenSwapCallsText">Swap</string>
+ <!-- Text for the onscreen "Manage calls" button -->
+ <string name="onscreenManageCallsText">Manage calls</string>
+ <!-- Text for the onscreen "Manage conference" button [CHAR LIMIT=20] -->
+ <string name="onscreenManageConferenceText">Manage conference</string>
+ <!-- Text for the onscreen "Audio" button that lets you switch
+ between speaker / bluetooth / earpiece [CHAR LIMIT=10] -->
+ <string name="onscreenAudioText">Audio</string>
+ <!-- Text for the onscreen "Video call" button used to change a voice call
+ to a video call. [CHAR LIMIT=10] -->
+ <string name="onscreenVideoCallText">Video call</string>
+
+ <!-- Menu item label in SIM Contacts: Import a single contact entry from the SIM card -->
+ <string name="importSimEntry">Import</string>
+ <!-- Menu item label in SIM Contacts: Import all contact entries from the SIM card -->
+ <string name="importAllSimEntries">Import all</string>
+ <!-- SIM Contacts: status message displayed while importing card -->
+ <string name="importingSimContacts">Importing SIM contacts</string>
+ <!-- Import a single contact entry from contacts to the SIM card -->
+ <string name="importToFDNfromContacts">Import from contacts</string>
+
+ <!-- Hearing aid settings -->
+ <string name="hac_mode_title">Hearing aids</string>
+ <string name="hac_mode_summary">Turn on hearing aid compatibility</string>
+
+ <!-- Service option entries. -->
+ <string-array name="tty_mode_entries">
+ <item>TTY Off</item>
+ <item>TTY Full</item>
+ <item>TTY HCO</item>
+ <item>TTY VCO</item>
+ </string-array>
+
+ <!-- Do not translate. -->
+ <string-array name="tty_mode_values" translatable="false">
+ <!-- Do not translate. -->
+ <item>0</item>
+ <!-- Do not translate. -->
+ <item>1</item>
+ <!-- Do not translate. -->
+ <item>2</item>
+ <!-- Do not translate. -->
+ <item>3</item>
+ </string-array>
+
+ <!-- Dtmf tones settings -->
+ <!-- Title for the DTMF Tones options displayed in Call Settings -->
+ <string name="dtmf_tones_title">DTMF tones</string>
+ <!-- Summary for the DTMF Tones options displayed in Call Settings -->
+ <string name="dtmf_tones_summary">Set the length of DTMF tones</string>
+ <!-- Options displayed as part of DTMF Tones in Call Settings -->
+ <string-array name="dtmf_tone_entries">
+ <item>Normal</item>
+ <item>Long</item>
+ </string-array>
+ <!-- Do not translate. -->
+ <string-array name="dtmf_tone_values" translatable="false">
+ <item>0</item>
+ <item>1</item>
+ </string-array>
+
+ <!-- Title for the dialog used to display CDMA DisplayInfo -->
+ <string name="network_message">Network message</string>
+
+ <!-- OTA-specific strings -->
+ <!-- Title shown on OTA screen -->
+ <string name="ota_title_activate">Activate your phone</string>
+ <!-- Message displayed on the OTA activation screen. -->
+ <string name="ota_touch_activate">A special call needs to be made to activate your phone service.
+ \n\nAfter pressing \u201CActivate\u201D, listen to the instructions provided to activate your phone.</string>
+
+ <!-- Title of skip activation dialog -->
+ <string name="ota_skip_activation_dialog_title">Skip activation\?</string>
+ <!-- Message displayed in skip activation dialog -->
+ <string name="ota_skip_activation_dialog_message">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 you turn it on.</string>
+ <!-- Label shown on dialog button that allows the user to skip activation -->
+ <string name="ota_skip_activation_dialog_skip_label">Skip</string>
+
+ <!-- Button label within the OTA activation screen -->
+ <string name="ota_activate">Activate</string>
+ <!-- Title text shown when phone activation is successful -->
+ <string name="ota_title_activate_success">Phone is activated.</string>
+ <!-- Title text shown on screen where activation fails -->
+ <string name="ota_title_problem_with_activation">Problem with activation</string>
+ <!-- Message displayed on the OTA "listening" screen. This message
+ needs to be kept at 2 lines or less to be sure that there's
+ enough room for the dialpad. [CHAR LIMIT=80] -->
+ <string name="ota_listen">Follow the spoken instructions until you hear that activation is complete.</string>
+
+ <!-- Button label within the OTA listen screen -->
+ <string name="ota_speaker">Speaker</string>
+ <!-- String to be displayed on OTA listen screen once user has selected the
+ correct option to begin provisioning -->
+ <string name="ota_progress">Wait while your phone is being programmed.</string>
+ <!-- String to display within the OTA Fail Notice dialog -->
+ <string name="ota_failure">Programming unsuccessful</string>
+ <!-- String to be displayed on the OTA Fail/Success screen upon successful provisioning -->
+ <string name="ota_successful">Your phone is now activated. It may take up to 15 minutes for service to start.</string>
+ <!-- String to be displayed on the OTA Fail/Success screen upon unsuccessful provisioning -->
+ <string name="ota_unsuccessful">Your phone didn\'t activate.
+ \nYou may need to find an area with better coverage (near a window, or outside).
+ \n\nTry again or call customer service for more options.</string>
+ <!-- String to display within the OTA SPC Fail Notice dialog -->
+ <string name="ota_spc_failure">EXCESS SPC FAILURES</string>
+ <!-- Button label in OTA listen screen that cancels activation and goes to the previous screen -->
+ <string name="ota_call_end">Back</string>
+ <!-- Button label shown on OTA error screen to allow the user to try again -->
+ <string name="ota_try_again">Try again</string>
+ <!-- Button label shown on OTA screens that have a next screen -->
+ <string name="ota_next">Next</string>
+
+ <!-- Emergency Callback Mode (ECM) -->
+ <string name="ecm_exit_dialog">EcmExitDialog</string>
+ <!-- ECM: Status bar notification message -->
+ <string name="phone_entered_ecm_text">Entered Emergency Callback Mode</string>
+ <!-- ECM: Notification title -->
+ <string name="phone_in_ecm_notification_title">Emergency Callback Mode</string>
+ <!-- ECM: Notification body -->
+ <string name="phone_in_ecm_call_notification_text">Data connection disabled</string>
+ <plurals name="phone_in_ecm_notification_time">
+ <!-- number of minutes is one -->
+ <item quantity="one">No data connection for <xliff:g id="count">%s</xliff:g> minute</item>
+ <!-- number of minutes is not equal to one -->
+ <item quantity="other">No data connection for <xliff:g id="count">%s</xliff:g> minutes</item>
+ </plurals>
+ <!-- ECM: Dialog box message for exiting from the notifications screen -->
+ <plurals name="alert_dialog_exit_ecm">
+ <!-- number of minutes is one -->
+ <item quantity="one">The phone will be in Emergency Callback mode for <xliff:g id="count">%s</xliff:g> minute. While in this mode no apps using a data connection can be used. Do you want to exit now?</item>
+ <!-- number of minutes is not equal to one -->
+ <item quantity="other">The phone will be in Emergency Callback mode for <xliff:g id="count">%s</xliff:g> minutes. While in this mode no applications using a data connection can be used. Do you want to exit now?</item>
+ </plurals>
+ <!-- ECM: Dialog box message for exiting from any other app -->
+ <plurals name="alert_dialog_not_avaialble_in_ecm">
+ <!-- number of minutes is one -->
+ <item quantity="one">The selected action isn\'t available while in the Emergency Callback mode. The phone will be in this mode for <xliff:g id="count">%s</xliff:g> minute. Do you want to exit now?</item>
+ <!-- number of minutes is not equal to one -->
+ <item quantity="other">The selected action isn\'t available while in the Emergency Callback mode. The phone will be in this mode for <xliff:g id="count">%s</xliff:g> minutes. Do you want to exit now?</item>
+ </plurals>
+ <!-- ECM: Dialog box message while in emergency call -->
+ <string name="alert_dialog_in_ecm_call">The selected action isn\'t available while in an emergency call.</string>
+ <!-- ECM: Progress text -->
+ <string name="progress_dialog_exiting_ecm">Exiting Emergency Callback mode</string>
+ <!-- ECM: ECM exit dialog choice -->
+ <string name="alert_dialog_yes">Yes</string>
+ <!-- ECM: ECM exit dialog choice -->
+ <string name="alert_dialog_no">No</string>
+ <!-- ECM: ECM exit dialog choice -->
+ <string name="alert_dialog_dismiss">Dismiss</string>
+
+ <!-- For incoming calls, this is a string we can get from a CDMA network instead of
+ the actual phone number, to indicate there's no number present. DO NOT TRANSLATE. -->
+ <string-array name="absent_num" translatable="false">
+ <item>ABSENT NUMBER</item>
+ <item>ABSENTNUMBER</item>
+ </string-array>
+
+ <!-- Preference for Voicemail service provider under "Voicemail" settings.
+ [CHAR LIMIT=40] -->
+ <string name="voicemail_provider">Service</string>
+
+ <!-- Preference for Voicemail setting of each provider.
+ [CHAR LIMIT=40] -->
+ <string name="voicemail_settings">Setup</string>
+
+ <!-- String to display in voicemail number summary when no voicemail num is set -->
+ <string name="voicemail_number_not_set">&lt;Not set&gt;</string>
+
+ <!-- Title displayed above settings coming after voicemail in the call features screen -->
+ <string name="other_settings">Other call settings</string>
+
+ <!-- Title displayed in the overlay when a call is placed using a 3rd party provider.
+ [CHAR LIMIT=40] -->
+ <string name="calling_via_template">Calling via <xliff:g id="provider_name">%s</xliff:g></string>
+
+ <!-- Use this as a default to describe the contact photo; currently for screen readers through accessibility. -->
+ <string name="contactPhoto">contact photo</string>
+ <!-- Use this to describe the separate conference call button; currently for screen readers through accessibility. -->
+ <string name="goPrivate">go private</string>
+ <!-- Use this to describe the select contact button in EditPhoneNumberPreference; currently for screen readers through accessibility. -->
+ <string name="selectContact">select contact</string>
+
+
+ <!-- Start of SIP related strings defined from here. -->
+
+ <!-- Title displayed SIP settings coming after other call settings in the call features screen. [CHAR LIMIT=NONE] -->
+ <string name="sip_settings">Internet call settings</string>
+ <!-- Title displayed SIP account settings in the sip settings category. [CHAR LIMIT=NONE] -->
+ <string name="sip_accounts">Internet calling (SIP) accounts</string>
+ <!-- Title displayed SIP account settings in the sip settings category. [CHAR LIMIT=NONE] -->
+ <string name="sip_accounts_title">Accounts</string>
+ <!-- Title displayed for the button of receiving incoming SIP calls flag. Enabled for receiving calls. [CHAR LIMIT=NONE] -->
+ <string name="sip_receive_calls">Receive incoming calls</string>
+ <!-- Help user to understand that it will require more battery usage if the 'receiving incoming call' is enabled. [CHAR LIMIT=NONE] -->
+ <string name="sip_receive_calls_summary">Reduces battery life</string>
+ <!-- Title for the dialog of selecting the way we handle an outgoing call. [CHAR LIMIT=NONE] -->
+ <string name="sip_call_options_title">Use Internet calling</string>
+ <!-- Title for the dialog of selecting the way we handle an outgoing call (Wi-Fi only). [CHAR LIMIT=NONE] -->
+ <string name="sip_call_options_wifi_only_title">Use Internet calling (Wi-Fi only)</string>
+
+ <!-- Item of the Internet call option dialog: for routing all outgoing calls via SIP. [CHAR LIMIT=NONE] -->
+ <string name="sip_call_options_entry_1">For all calls when data network is available</string>
+ <!-- Item of the Internet call option dialog: for routing a outgoing call via SIP if the destination is a SIP URI. [CHAR LIMIT=NONE] -->
+ <string name="sip_call_options_entry_2">Only for Internet calls</string>
+ <!-- Item of the Internet call option dialog: for asking user to select the way for each outgoing call. [CHAR LIMIT=NONE] -->
+ <string name="sip_call_options_entry_3">Ask for each call</string>
+ <!-- Item of the Internet call (Wi-Fi only) option dialog: for routing all outgoing calls via SIP. [CHAR LIMIT=NONE] -->
+ <string name="sip_call_options_wifi_only_entry_1">For all calls</string>
+
+ <!-- Title of the dialog to select the phone type for the outgoing call. [CHAR LIMIT=NONE] -->
+ <string name ="pick_outgoing_call_phone_type">Place call</string>
+
+ <!-- Title of the dialog to select the phone among the list of phones for the outgoing call. [CHAR LIMIT=NONE] -->
+ <string name ="pick_outgoing_sip_phone">Use Internet calling account:</string>
+
+ <!-- Text of checkbox to remember the sip phone for all outbound calls. [CHAR LIMIT=NONE] -->
+ <string name ="remember_my_choice">Always use to place Internet calls</string>
+
+ <!-- Help text of checkbox to unset the default sip phone for all outbound calls. [CHAR LIMIT=NONE] -->
+ <string name ="reset_my_choice_hint">You can change which Internet calling account to use by default from the Phone &gt; Settings &gt; Internet call settings &gt; Accounts screen.</string>
+
+ <!-- Item of the dialog to select the phone type for outgoing call. [CHAR LIMIT=NONE] -->
+ <string name ="pstn_phone">Cell phone call</string>
+
+ <!-- Item of the dialog to select the phone type for outgoing call. [CHAR LIMIT=NONE] -->
+ <string name ="internet_phone">Internet call</string>
+
+ <!-- Title of the dialog to redirect the user to SIP settings. [CHAR LIMIT=NONE] -->
+ <string name ="no_sip_account_found_title">No Internet calling account</string>
+ <!-- Message of the dialog to redirect the user to SIP settings. [CHAR LIMIT=NONE] -->
+ <string name ="no_sip_account_found">There are no Internet calling accounts on this phone. Do you want to add one now?</string>
+ <!-- Menu item for no sip account found dialog -->
+ <string name="sip_menu_add">Add</string>
+
+ <!-- Title for the button to add a new sip account. [CHAR LIMIT=NONE] -->
+ <string name="add_sip_account">Add account</string>
+ <!-- Title for the button to remove a sip account. [CHAR LIMIT=NONE] -->
+ <string name="remove_sip_account">Remove account</string>
+ <!-- String of the category which lists all sip accounts. [CHAR LIMIT=NONE] -->
+ <string name="sip_account_list">SIP accounts</string>
+ <!-- Toast message to indicate that the system is saving the account. [CHAR LIMIT=NONE] -->
+ <string name="saving_account">Saving the account\u2026</string>
+ <!-- Toast message to indicate that the system is removing the account. [CHAR LIMIT=NONE] -->
+ <string name="removing_account">Removing the account\u2026</string>
+
+ <!-- Menu item when the menu button is pressed in the sip account editor. [CHAR LIMIT=NONE] -->
+ <string name="sip_menu_save">Save</string>
+ <!-- Menu item when the menu button is pressed in the sip account editor. [CHAR LIMIT=NONE] -->
+ <string name="sip_menu_discard">Discard</string>
+
+ <!-- Title of the alert dialog. [CHAR LIMIT=NONE] -->
+ <string name="alert_dialog_close">Close the profile</string>
+ <!-- Title of the button to show in a alert dialog. [CHAR LIMIT=NONE] -->
+ <string name="alert_dialog_ok">OK</string>
+ <!-- Title of the button to show in a alert dialog. [CHAR LIMIT=NONE] -->
+ <string name="close_profile">Close</string>
+
+ <!-- Summary of a SIP account in the list of SIP accounts, consists of primary account status and registration status. This string indicates that this SIP account is a primary account and the string placeholder is the registration status, which will be one of the strings with name starting with "registration_status_" below. [CHAR LIMIT=NONE] -->
+ <string name="primary_account_summary_with">Primary account. <xliff:g id="registration_status" example="Registering...">%s</xliff:g></string>
+ <!-- Text of Internet-call registration status, checking current registration status with SIP service [CHAR LIMIT=NONE] -->
+ <string name="registration_status_checking_status">Checking status...</string>
+ <!-- Text of Internet-call registration status, registering with SIP server in order to receive calls on this account [CHAR LIMIT=NONE] -->
+ <string name="registration_status_registering">Registering\u2026</string>
+ <!-- Text of Internet-call registration status, still trying to register with SIP server [CHAR LIMIT=NONE] -->
+ <string name="registration_status_still_trying">Still trying\u2026</string>
+ <!-- Text of Internet-call registration status, currently not receiving calls on this account [CHAR LIMIT=NONE] -->
+ <string name="registration_status_not_receiving">Not receiving calls.</string>
+ <!-- Text of Internet-call registration status, no data connection [CHAR LIMIT=NONE] -->
+ <string name="registration_status_no_data">Account registration stopped because there is no Internet connection.</string>
+ <!-- Text of Internet-call registration status, no Wi-Fi connection [CHAR LIMIT=NONE] -->
+ <string name="registration_status_no_wifi_data">Account registration stopped because there is no Wi-Fi connection.</string>
+ <!-- Text of Internet-call registration status, registration process is not running due to some error [CHAR LIMIT=NONE] -->
+ <string name="registration_status_not_running">Account registration unsuccessful.</string>
+ <!-- Text of Internet-call registration status, currently we can receive calls on this account [CHAR LIMIT=NONE] -->
+ <string name="registration_status_done">Receiving calls.</string>
+ <!-- Text of Internet-call registration status, registration failed with a reason; will try again later [CHAR LIMIT=NONE] -->
+ <string name="registration_status_failed_try_later">Account registration unsuccessful: (<xliff:g id="registration_error_message" example="timed out">%s</xliff:g>); will try later</string>
+ <!-- Text of Internet-call registration status, registration failed due to invalid credentials [CHAR LIMIT=NONE] -->
+ <string name="registration_status_invalid_credentials">Account registration unsuccessful: Incorrect username or password.</string>
+ <!-- Text of Internet-call registration status, registration failed due to unknown host exception [CHAR LIMIT=NONE] -->
+ <string name="registration_status_server_unreachable">Account registration unsuccessful: Check the server name.</string>
+ <!-- Text for describing the account's owner and status. For example, 'Active, in use by Google Talk', it means that the account managed by SIP service was registered by the application 'Google Talk' and the status is active. [CHAR LIMIT=NONE] -->
+ <string name="third_party_account_summary">This account is currently in use by the <xliff:g id="account_owner" example="Google Talk">%s</xliff:g> app.</string>
+
+
+ <!-- Title of the sip editor screen. [CHAR LIMIT=NONE] -->
+ <string name="sip_edit_title">SIP account details</string>
+ <!-- Title of the sip editor screen. [CHAR LIMIT=NONE] -->
+ <string name="sip_edit_new_title">SIP account details</string>
+
+ <!-- Text of the domain address preference. [CHAR LIMIT=NONE] -->
+ <string name="domain_address_title">Server</string>
+ <!-- Text of the username preference. [CHAR LIMIT=NONE] -->
+ <string name="username_title">Username</string>
+ <!-- Text of the password preference. [CHAR LIMIT=NONE] -->
+ <string name="password_title">Password</string>
+ <!-- Text of the display name preference. [CHAR LIMIT=NONE] -->
+ <string name="display_name_title">Display name</string>
+ <!-- Text of the outbound proxy address preference. [CHAR LIMIT=NONE] -->
+ <string name="proxy_address_title">Outbound proxy address</string>
+ <!-- Text of the sip server/proxy port number. [CHAR LIMIT=NONE] -->
+ <string name="port_title">Port number</string>
+ <!-- Text of the transport type preference. [CHAR LIMIT=NONE] -->
+ <string name="transport_title">Transport type</string>
+ <!-- Text of the keepalive preference. [CHAR LIMIT=NONE] -->
+ <string name="send_keepalive_title">Send keep-alive</string>
+ <!-- Text of the set-primary preference. Simplified from "Make this my primary account". [CHAR LIMIT=NONE] -->
+ <string name="set_primary_title">Set as primary account</string>
+ <!-- Text of the set-primary preference summary. [CHAR LIMIT=NONE] -->
+ <string name="set_primary_summary">Used for outbound calls</string>
+ <!-- Text of the advanced settings section. [CHAR LIMIT=NONE] -->
+ <string name="advanced_settings">Optional settings</string>
+ <!-- Text of the username used in authentication. [CHAR LIMIT=NONE] -->
+ <string name="auth_username_title">Authentication username</string>
+ <!-- Help text of the auth_username field. [CHAR LIMIT=NONE] -->
+ <string name="auth_username_summary">Username used for authentication</string>
+
+ <!-- Initial status of the preferences is '<Not set>'. [CHAR LIMIT=NONE] -->
+ <string name="default_preference_summary">&lt;Not set&gt;</string>
+ <!-- Default value for the display-name preference summary. [CHAR LIMIT=NONE] -->
+ <string name="display_name_summary">&lt;Same as username&gt;</string>
+ <!-- Default value for the outbound-proxy-address preference summary. [CHAR LIMIT=NONE] -->
+ <string name="optional_summary">&lt;Optional&gt;</string>
+
+ <!-- Default sip server/proxy port number. -->
+ <string translatable="false" name="default_port">5060</string>
+ <!-- Default sip server/proxy transport protocol. -->
+ <string translatable="false" name="default_transport">UDP</string>
+
+
+ <!-- Hint to show the advanced settings section. [CHAR LIMIT=NONE] -->
+ <string name="advanced_settings_show">â–· Touch to show all</string>
+ <!-- Hint to hide the advanced settings section. [CHAR LIMIT=NONE] -->
+ <string name="advanced_settings_hide">â–½ Touch to hide all</string>
+
+ <!-- Text in an alert dialog telling the user that some input field (name of which is also part of the strings being translated above) is required and can not be left blank. [CHAR LIMIT=NONE] -->
+ <string name="empty_alert"><xliff:g id="input_field_name" example="Username, Password...">%s</xliff:g> is required and can\'t be left blank.</string>
+ <!-- Showing that port number is out of range in an alert dialog. [CHAR LIMIT=NONE] -->
+ <string name="not_a_valid_port">Port number should be within 1000 and 65534.</string>
+
+ <!-- Title of the alert dialog to notify user that there is no Internet connectivity. [CHAR LIMIT=40] -->
+ <string name="no_internet_available_title">No Internet connection</string>
+ <!-- Title of the alert dialog to notify user that there is no Wi-Fi connectivity. [CHAR LIMIT=40] -->
+ <string name="no_wifi_available_title">No Wi-Fi connection</string>
+ <!-- Message of the alert dialog to notify user that there is no Internet connectivity. [CHAR LIMIT=NONE] -->
+ <string name="no_internet_available">To place an Internet call, check your Internet connection first.</string>
+ <!-- Message of the alert dialog to notify user that there is no Wi-Fi connectivity. [CHAR LIMIT=NONE] -->
+ <string name="no_wifi_available">You need to be connected to a Wi-Fi network for Internet calls (use the Wireless &amp; Network settings).</string>
+ <!-- Title of the alert dialog to notify user that Internet call is not supported. [CHAR LIMIT=40] -->
+ <string name="no_voip">Internet calling not supported</string>
+
+ <!-- Option for whether the SIP service should send keepalive messages. [CHAR LIMIT=40] -->
+ <string translatable="true" name="sip_system_decide">Automatic</string>
+ <!-- Option for whether the SIP service should send keepalive messages. [CHAR LIMIT=40] -->
+ <string translatable="true" name="sip_always_send_keepalive">Always send</string>
+
+ <!-- Do not translate the following strings. Used for the Internet call options. Need to be in-sync with Settings.System.SIP_ strings. -->
+ <string translatable="false" name="sip_always">SIP_ALWAYS</string>
+ <string translatable="false" name="sip_address_only">SIP_ADDRESS_ONLY</string>
+ <string translatable="false" name="sip_ask_me_each_time">SIP_ASK_ME_EACH_TIME</string>
+
+ <!-- Do not translate the following strings. Used for the preference keys -->
+ <string translatable="false" name="domain_address">SipDomain</string>
+ <string translatable="false" name="username">UserName</string>
+ <string translatable="false" name="password">Password</string>
+ <string translatable="false" name="display_name">DisplayName</string>
+ <string translatable="false" name="proxy_address">ProxyAddress</string>
+ <string translatable="false" name="port">Port</string>
+ <string translatable="false" name="transport">Protocol</string>
+ <string translatable="false" name="send_keepalive">SendKeepAlive</string>
+ <string translatable="false" name="set_primary">SetPrimary</string>
+ <string translatable="false" name="advanced_settings_container">advanced settings container</string>
+ <string translatable="false" name="auth_username">AuthUserName</string>
+ <!-- End of SIP settings related strings -->
+
+ <!-- Dialog title to notify user that Voice calling is not supported
+ on this device. [CHAR LIMIT=40] -->
+ <string name="not_voice_capable">Voice calling not supported</string>
+
+ <!-- Canned response for the "Respond via SMS" feature for incoming calls. [CHAR LIMIT=35] -->
+ <string name="respond_via_sms_canned_response_1">Can\'t talk now. What\'s up?</string>
+ <!-- Canned response for the "Respond via SMS" feature for incoming calls. [CHAR LIMIT=35] -->
+ <string name="respond_via_sms_canned_response_2">I\'ll call you right back.</string>
+ <!-- Canned response for the "Respond via SMS" feature for incoming calls. [CHAR LIMIT=35] -->
+ <string name="respond_via_sms_canned_response_3">I\'ll call you later.</string>
+ <!-- Canned response for the "Respond via SMS" feature for incoming calls. [CHAR LIMIT=35] -->
+ <string name="respond_via_sms_canned_response_4">Can\'t talk now. Call me later?</string>
+ <!-- "Respond via SMS" option that lets you compose a custom response. [CHAR LIMIT=30] -->
+ <string name="respond_via_sms_custom_message">Write your own...</string>
+
+ <!-- Title of settings screen for managing the "Respond via SMS" feature. [CHAR LIMIT=30] -->
+ <string name="respond_via_sms_setting_title">Quick responses</string>
+ <!-- Slightly more verbose title of settings screen for managing the
+ "Respond via SMS" feature. [CHAR LIMIT=30] -->
+ <string name="respond_via_sms_setting_title_2">Edit quick responses</string>
+ <!-- Settings summary string for the "Respond via SMS" feature. [CHAR LIMIT=40] -->
+ <string name="respond_via_sms_setting_summary"></string>
+ <!-- Dialog title when changing a string for the "Respond via SMS" feature. [CHAR LIMIT=30] -->
+ <string name="respond_via_sms_edittext_dialog_title">Quick response</string>
+ <!-- Menu option in "Respond via SMS" that allows user to reset the default
+ activity used to handle "Respond via SMS" [CHAR LIMIT=30] -->
+ <string name="respond_via_sms_menu_reset_default_activity">Reset default app</string>
+
+ <!-- "Respond via SMS": Confirmation message shown after sending
+ a text response. [CHAR LIMIT=40] -->
+ <string name="respond_via_sms_confirmation_format">Message sent to <xliff:g id="phone_number">%s</xliff:g>.</string>
+
+ <!-- String describing the image on ImageButton one
+
+ Note: AccessibilityServices use this attribute to announce what the view represents.
+ This is especially valuable for views without textual representation like ImageView.
+ [CHAR LIMIT=NONE]
+ -->
+ <string name="description_image_button_one">one</string>
+
+ <!-- String describing the image on ImageButton two
+
+ Note: AccessibilityServices use this attribute to announce what the view represents.
+ This is especially valuable for views without textual representation like ImageView.
+ [CHAR LIMIT=NONE]
+ -->
+ <string name="description_image_button_two">two</string>
+
+ <!-- String describing the image on ImageButton three
+
+ Note: AccessibilityServices use this attribute to announce what the view represents.
+ This is especially valuable for views without textual representation like ImageView.
+ [CHAR LIMIT=NONE]
+ -->
+ <string name="description_image_button_three">three</string>
+
+ <!-- String describing the image on ImageButton four
+
+ Note: AccessibilityServices use this attribute to announce what the view represents.
+ This is especially valuable for views without textual representation like ImageView.
+ [CHAR LIMIT=NONE]
+ -->
+ <string name="description_image_button_four">four</string>
+
+ <!-- String describing the image on ImageButton five
+
+ Note: AccessibilityServices use this attribute to announce what the view represents.
+ This is especially valuable for views without textual representation like ImageView.
+ [CHAR LIMIT=NONE]
+ -->
+ <string name="description_image_button_five">five</string>
+
+ <!-- String describing the image on ImageButton six
+
+ Note: AccessibilityServices use this attribute to announce what the view represents.
+ This is especially valuable for views without textual representation like ImageView.
+ [CHAR LIMIT=NONE]
+ -->
+ <string name="description_image_button_six">six</string>
+
+ <!-- String describing the image on ImageButton seven
+
+ Note: AccessibilityServices use this attribute to announce what the view represents.
+ This is especially valuable for views without textual representation like ImageView.
+ [CHAR LIMIT=NONE]
+ -->
+ <string name="description_image_button_seven">seven</string>
+
+ <!-- String describing the image on ImageButton eight
+
+ Note: AccessibilityServices use this attribute to announce what the view represents.
+ This is especially valuable for views without textual representation like ImageView.
+ [CHAR LIMIT=NONE]
+ -->
+ <string name="description_image_button_eight">eight</string>
+
+ <!-- String describing the image on ImageButton nine
+
+ Note: AccessibilityServices use this attribute to announce what the view represents.
+ This is especially valuable for views without textual representation like ImageView.
+ [CHAR LIMIT=NONE]
+ -->
+ <string name="description_image_button_nine">nine</string>
+
+ <!-- String describing the image on ImageButton star
+
+ Note: AccessibilityServices use this attribute to announce what the view represents.
+ This is especially valuable for views without textual representation like ImageView.
+ [CHAR LIMIT=NONE]
+ -->
+ <string name="description_image_button_star">star</string>
+
+ <!-- String describing the image on ImageButton zero
+
+ Note: AccessibilityServices use this attribute to announce what the view represents.
+ This is especially valuable for views without textual representation like ImageView.
+ [CHAR LIMIT=NONE]
+ -->
+ <string name="description_image_button_zero">zero</string>
+
+ <!-- String describing the image on ImageButton pound
+
+ Note: AccessibilityServices use this attribute to announce what the view represents.
+ This is especially valuable for views without textual representation like ImageView.
+ [CHAR LIMIT=NONE]
+ -->
+ <string name="description_image_button_pound">pound</string>
+
+ <!-- String describing the Dial ImageButton
+
+ Used by AccessibilityService to announce the purpose of the button.
+ [CHAR LIMIT=NONE]
+ -->
+ <string name="description_dial_button">dial</string>
+
+ <!-- String describing the Delete/Backspace ImageButton
+
+ Used by AccessibilityService to announce the purpose of the button.
+ [CHAR LIMIT=NONE]
+ -->
+ <string name="description_delete_button">backspace</string>
+
+ <!-- Content description of the speakerphone enabled notification icon for accessibility (not shown on the screen). [CHAR LIMIT=NONE] -->
+ <string name="accessibility_speakerphone_enabled">Speakerphone enabled.</string>
+
+ <!-- Content description of the call muted notification icon for accessibility (not shown on the screen). [CHAR LIMIT=NONE] -->
+ <string name="accessibility_call_muted">Call muted.</string>
+
+ <!-- Description of the answer target in the Slide unlock screen of Phone. [CHAR LIMIT=NONE] -->
+ <string name="description_target_answer">Answer</string>
+ <!-- Description of the send_sms target in the Slide unlock screen of Phone. [CHAR LIMIT=NONE] -->
+ <string name="description_target_send_sms">Send SMS</string>
+ <!-- Description of the decline on target in the Slide unlock screen. [CHAR LIMIT=NONE] -->
+ <string name="description_target_decline">Decline</string>
+
+ <!-- Dialog title for the vibration settings for voicemail notifications [CHAR LIMIT=40] -->
+ <string name="voicemail_notification_vibrate_when_title" msgid="8731372580674292759">Vibrate</string>
+ <!-- Dialog title for the vibration settings for voice mail notifications [CHAR LIMIT=40]-->
+ <string name="voicemail_notification_vibarte_when_dialog_title" msgid="8995274609647451109">Vibrate</string>
+
+ <!-- Voicemail ringtone title. The user clicks on this preference to select
+ which sound to play when a voicemail notification is received.
+ [CHAR LIMIT=30] -->
+ <string name="voicemail_notification_ringtone_title">Sound</string>
+
+ <!-- The string used to describe a notification if it is the default one in the system. For
+ example, if the user selects the default notification, it will appear as something like
+ Default sound(Capella) in the notification summary.
+ [CHAR LIMIT=40] -->
+ <string name="default_notification_description">Default sound (<xliff:g id="default_sound_title">%1$s</xliff:g>)</string>
+
+ <!-- The default value value for voicemail notification. -->
+ <string name="voicemail_notification_vibrate_when_default" translatable="false">never</string>
+
+ <!-- Actual values used in our code for voicemail notifications. DO NOT TRANSLATE -->
+ <string-array name="voicemail_notification_vibrate_when_values" translatable="false">
+ <item>always</item>
+ <item>silent</item>
+ <item>never</item>
+ </string-array>
+
+ <!-- Setting option name to pick ringtone (a list dialog comes up). [CHAR LIMIT=30] -->
+ <string name="ringtone_title" msgid="5379026328015343686">Phone ringtone</string>
+
+ <!-- Setting option name to enable or disable vibration when ringing
+ the phone.
+ [CHAR LIMIT=30] -->
+ <string name="vibrate_on_ring_title">Vibrate when ringing</string>
+
+ <!-- Setting option name to enable or disable DTMF tone sound
+ [CHAR LIMIT=30] -->
+ <string name="dtmf_tone_enable_title">Dial pad touch tones</string>
+
+ <!-- Setting option name to enable or disable dialpad autocomplete functionality
+ [CHAR LIMIT=30] -->
+ <string name="dial_pad_autocomplete">Dial pad autocomplete</string>
+
+ <!-- Title for the category "ringtone", which is shown above ringtone and vibration
+ related settings.
+ [CHAR LIMIT=30] -->
+ <string name="preference_category_ringtone">Ringtone &amp; Vibrate</string>
</resources>
diff --git a/res/values/styles.xml b/res/values/styles.xml
new file mode 100644
index 00000000..c86e570b
--- /dev/null
+++ b/res/values/styles.xml
@@ -0,0 +1,144 @@
+<?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
+ -->
+
+<resources>
+ <drawable name="grayBg">#FF333333</drawable>
+
+ <style name="info_label">
+ <item name="android:layout_height">wrap_content</item>
+ <item name="android:layout_width">wrap_content</item>
+ <item name="android:textAppearance">@style/TextAppearance.info_label</item>
+ <item name="android:paddingEnd">4dip</item>
+ </style>
+
+ <style name="info_layout">
+ <item name="android:orientation">vertical</item>
+ <item name="android:paddingStart">10dip</item>
+ <item name="android:paddingTop">10dip</item>
+ <item name="android:paddingEnd">10dip</item>
+ <item name="android:paddingBottom">10dip</item>
+ <item name="android:layout_width">match_parent</item>
+ <item name="android:layout_height">match_parent</item>
+ </style>
+
+ <style name="entry_layout">
+ <item name="android:orientation">vertical</item>
+ <item name="android:layout_width">wrap_content</item>
+ <item name="android:layout_height">wrap_content</item>
+ </style>
+
+ <style name="TextAppearance" parent="android:TextAppearance">
+ </style>
+
+ <style name="TextAppearance.info_label">
+ <item name="android:textSize">14sp</item>
+ <item name="android:textStyle">bold</item>
+ </style>
+
+
+ <!-- Buttons in the main "button row" of the in-call onscreen touch UI. -->
+ <style name="InCallButton">
+ <item name="android:layout_width">0px</item>
+ <item name="android:layout_height">@dimen/in_call_button_height</item>
+ <item name="android:layout_weight">1</item>
+ <item name="android:background">?android:attr/selectableItemBackground</item>
+ </style>
+
+ <!-- "Compound button" variation of InCallButton.
+ These buttons have the concept of two states: checked and unchecked.
+ (This style is just like "InCallButton" except that we also
+ clear out android:textOn and android:textOff, to avoid the default
+ text label behavior of the ToggleButton class.) -->
+ <style name="InCallCompoundButton" parent="InCallButton">
+ <item name="android:textOn">@null</item>
+ <item name="android:textOff">@null</item>
+ </style>
+
+ <style name="VerticalSeparator">
+ <item name="android:layout_width">2dp</item>
+ <item name="android:layout_height">match_parent</item>
+ <item name="android:background">@android:color/black</item>
+ </style>
+
+ <!-- "End" button; similar to InCallButton. -->
+ <style name="InCallEndButton">
+ <item name="android:layout_width">0dip</item>
+ <item name="android:layout_height">@dimen/in_call_end_button_height</item>
+ <item name="android:layout_weight">1</item>
+ </style>
+
+ <style name="InCallAnimationStyle" parent="@*android:style/Animation.Holo.Activity">
+ <!-- Suppress task-to-task animation happening during the transition from
+ OutgoingCallBroadcaster (and SipOptionHandler) to InCallActivity.
+ The transition unexpectedly happens during the transition (inside the phone task),
+ because InCallActivity is using android:launchMode="singleInstance".
+
+ - taskOpenEnterAnimation/taskOpenExitAnimation is used for the first time
+ InCallActivity instance is created.
+
+ - taskToFrontEnterAnimation/taskToFrontExitAnimation is used when InCallActivity
+ is already available.
+ (Note that InCallActivity won't be destroyed once it is created)
+
+ TODO: try removing the flag instead -->
+ <item name="*android:taskOpenEnterAnimation">@*android:anim/activity_open_enter</item>
+ <item name="*android:taskOpenExitAnimation">@*android:anim/activity_open_exit</item>
+ <item name="*android:taskToFrontEnterAnimation">@*android:anim/activity_open_enter</item>
+ <item name="*android:taskToFrontExitAnimation">@*android:anim/activity_open_exit</item>
+ </style>
+
+ <!-- Theme for the InCallActivity activity. This gives us a totally black
+ window background instead of the default dark grey. (We don't just use
+ Theme.Black.NoTitleBar directly, since we want any popups or dialogs
+ from the InCallActivity to have the correct holo style. -->
+ <style name="Theme.InCallScreen" parent="@android:style/Theme.Holo.NoActionBar">
+ <item name="android:windowBackground">@android:color/black</item>
+
+ <item name="*android:windowAnimationStyle">@style/InCallAnimationStyle</item>
+ </style>
+
+ <style name="DialpadButtonStyle">
+ <item name="android:layout_width">0dip</item>
+ <item name="android:layout_height">match_parent</item>
+ <item name="android:layout_weight">1</item>
+ <item name="android:background">?android:attr/selectableItemBackground</item>
+ <item name="android:soundEffectsEnabled">false</item>
+ </style>
+
+ <style name="DialtactsDigitsTextAppearance">
+ <item name="android:maxLines">1</item>
+ <item name="android:textSize">@dimen/dialpad_digits_text_size</item>
+ <item name="android:textColor">?android:attr/textColorPrimary</item>
+ <item name="android:freezesText">true</item>
+ <item name="android:editable">true</item>
+ <item name="android:cursorVisible">false</item>
+ </style>
+
+ <style name="PrimaryCallInfoPrimaryCallBanner">
+ <item name="android:layout_alignParentTop">true</item>
+ </style>
+ <style name="PrimaryCallInfoSecondaryInfoContainer">
+ <item name="android:layout_below">@id/primary_call_banner</item>
+ </style>
+
+ <style name="SecondaryCallInfoSecondaryCallName">
+ <item name="android:layout_gravity">top|left</item>
+ </style>
+ <style name="SecondaryCallInfoSecondaryCallStatus">
+ <item name="android:layout_gravity">top|right</item>
+ </style>
+</resources>
diff --git a/src/com/android/incallui/CallMonitorService.java b/src/com/android/incallui/CallMonitorService.java
index 7ac47785..00244158 100644
--- a/src/com/android/incallui/CallMonitorService.java
+++ b/src/com/android/incallui/CallMonitorService.java
@@ -19,7 +19,6 @@ package com.android.incallui;
import android.app.Service;
import android.content.Context;
import android.content.Intent;
-import android.content.ServiceConnection;
import android.os.Handler;
import android.os.IBinder;
import android.os.Message;
@@ -59,6 +58,10 @@ public class CallMonitorService extends Service {
final Message msg = mMainHandler.obtainMessage(DO_SHOW_ALERT, 0, 0,
"Incoming call with call Id: " + callId);
mMainHandler.sendMessage(msg);
+
+ final Intent intent = new Intent(getApplication(), InCallActivity.class);
+ intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+ startActivity(intent);
}
};
diff --git a/src/com/android/incallui/InCallActivity.java b/src/com/android/incallui/InCallActivity.java
new file mode 100644
index 00000000..ea06af8b
--- /dev/null
+++ b/src/com/android/incallui/InCallActivity.java
@@ -0,0 +1,208 @@
+/*
+ * 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.incallui;
+
+import android.app.Activity;
+import android.content.Intent;
+import android.os.Bundle;
+import android.util.Log;
+import android.view.KeyEvent;
+import android.view.View;
+import android.view.Window;
+import android.view.WindowManager;
+import android.widget.Toast;
+
+/**
+ * Phone app "in call" screen.
+ */
+public class InCallActivity extends Activity {
+
+ private static final String TAG = InCallActivity.class.getSimpleName();
+
+ private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);
+ private static final boolean VERBOSE = Log.isLoggable(TAG, Log.VERBOSE);
+
+ @Override
+ protected void onCreate(Bundle icicle) {
+ logD("onCreate()... this = " + this);
+
+ super.onCreate(icicle);
+
+ // set this flag so this activity will stay in front of the keyguard
+ // Have the WindowManager filter out touch events that are "too fat".
+ getWindow().addFlags(WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED
+ | WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON
+ | WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD
+ | WindowManager.LayoutParams.FLAG_IGNORE_CHEEK_PRESSES);
+
+ requestWindowFeature(Window.FEATURE_NO_TITLE);
+
+ // Inflate everything in incall_screen.xml and add it to the screen.
+ setContentView(R.layout.incall_screen);
+
+ // Initialize the UI
+ //findViewById(R.id.callCard);
+ //findViewById(R.id.inCallTouchUi);
+ //ViewStub stub = (ViewStub) findViewById(R.id.dtmf_twelve_key_dialer_stub);
+
+ logD("onCreate(): exit");
+ }
+
+ @Override
+ protected void onResume() {
+ logD("onResume()...");
+ super.onResume();
+ }
+
+ // onPause is guaranteed to be called when the InCallActivity goes
+ // in the background.
+ @Override
+ protected void onPause() {
+ logD("onPause()...");
+ super.onPause();
+ }
+
+ @Override
+ protected void onStop() {
+ logD("onStop()...");
+ super.onStop();
+ }
+
+ @Override
+ protected void onDestroy() {
+ logD("onDestroy()... this = " + this);
+ super.onDestroy();
+ }
+
+ /**
+ * Dismisses the in-call screen.
+ *
+ * We never *really* finish() the InCallActivity, 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
+ * InCallActivity instance around for the entire uptime of the device. This noticeably improves
+ * the UI responsiveness for incoming calls.)
+ */
+ @Override
+ public void finish() {
+ logD("finish()...");
+ moveTaskToBack(true);
+ }
+
+ @Override
+ protected void onNewIntent(Intent intent) {
+ logD("onNewIntent: intent = " + intent);
+
+ // We're being re-launched with a new Intent. Since it's possible for a
+ // single InCallActivity instance to persist indefinitely (even if we
+ // finish() ourselves), this sequence can potentially happen any time
+ // the InCallActivity 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.
+ //TODO(klp): handle intent
+ }
+
+ @Override
+ public void onBackPressed() {
+ // TODO(klp): implement
+
+ // Nothing special to do. Fall back to the default behavior.
+ super.onBackPressed();
+ }
+
+ @Override
+ public boolean onKeyDown(int keyCode, KeyEvent event) {
+ switch (keyCode) {
+ case KeyEvent.KEYCODE_CALL:
+ // TODO(klp): handle call key
+ // 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:
+ // Not sure if needed. If so, silence ringer.
+ break;
+
+ case KeyEvent.KEYCODE_MUTE:
+ toast("mute");
+ return true;
+
+ // Various testing/debugging features, enabled ONLY when VERBOSE == true.
+ case KeyEvent.KEYCODE_SLASH:
+ if (VERBOSE) {
+ Log.v(TAG, "----------- InCallActivity 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:
+ // TODO(klp): Dump phone state?
+ break;
+ }
+
+ // TODO(klp): handle dialer key down
+
+ return super.onKeyDown(keyCode, event);
+ }
+
+ private void toast(String text) {
+ final Toast toast = Toast.makeText(this, text, Toast.LENGTH_SHORT);
+ toast.show();
+ }
+
+ private void logD(String msg) {
+ if (DEBUG) {
+ Log.d(TAG, msg);
+ }
+ }
+
+ private void logV(String msg) {
+ if (VERBOSE) {
+ Log.v(TAG, msg);
+ }
+ }
+}
diff --git a/src/com/android/incallui/widget/multiwaveview/Ease.java b/src/com/android/incallui/widget/multiwaveview/Ease.java
new file mode 100644
index 00000000..5ef68977
--- /dev/null
+++ b/src/com/android/incallui/widget/multiwaveview/Ease.java
@@ -0,0 +1,132 @@
+/*
+ * 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.incallui.widget.multiwaveview;
+
+import android.animation.TimeInterpolator;
+
+class Ease {
+ private static final float DOMAIN = 1.0f;
+ private static final float DURATION = 1.0f;
+ private static final float START = 0.0f;
+
+ static class Linear {
+ public static final TimeInterpolator easeNone = new TimeInterpolator() {
+ public float getInterpolation(float input) {
+ return input;
+ }
+ };
+ }
+
+ static class Cubic {
+ public static final TimeInterpolator easeIn = new TimeInterpolator() {
+ public float getInterpolation(float input) {
+ return DOMAIN*(input/=DURATION)*input*input + START;
+ }
+ };
+ public static final TimeInterpolator easeOut = new TimeInterpolator() {
+ public float getInterpolation(float input) {
+ return DOMAIN*((input=input/DURATION-1)*input*input + 1) + START;
+ }
+ };
+ public static final TimeInterpolator easeInOut = new TimeInterpolator() {
+ public float getInterpolation(float input) {
+ return ((input/=DURATION/2) < 1.0f) ?
+ (DOMAIN/2*input*input*input + START)
+ : (DOMAIN/2*((input-=2)*input*input + 2) + START);
+ }
+ };
+ }
+
+ static class Quad {
+ public static final TimeInterpolator easeIn = new TimeInterpolator() {
+ public float getInterpolation (float input) {
+ return DOMAIN*(input/=DURATION)*input + START;
+ }
+ };
+ public static final TimeInterpolator easeOut = new TimeInterpolator() {
+ public float getInterpolation(float input) {
+ return -DOMAIN *(input/=DURATION)*(input-2) + START;
+ }
+ };
+ public static final TimeInterpolator easeInOut = new TimeInterpolator() {
+ public float getInterpolation(float input) {
+ return ((input/=DURATION/2) < 1) ?
+ (DOMAIN/2*input*input + START)
+ : (-DOMAIN/2 * ((--input)*(input-2) - 1) + START);
+ }
+ };
+ }
+
+ static class Quart {
+ public static final TimeInterpolator easeIn = new TimeInterpolator() {
+ public float getInterpolation(float input) {
+ return DOMAIN*(input/=DURATION)*input*input*input + START;
+ }
+ };
+ public static final TimeInterpolator easeOut = new TimeInterpolator() {
+ public float getInterpolation(float input) {
+ return -DOMAIN * ((input=input/DURATION-1)*input*input*input - 1) + START;
+ }
+ };
+ public static final TimeInterpolator easeInOut = new TimeInterpolator() {
+ public float getInterpolation(float input) {
+ return ((input/=DURATION/2) < 1) ?
+ (DOMAIN/2*input*input*input*input + START)
+ : (-DOMAIN/2 * ((input-=2)*input*input*input - 2) + START);
+ }
+ };
+ }
+
+ static class Quint {
+ public static final TimeInterpolator easeIn = new TimeInterpolator() {
+ public float getInterpolation(float input) {
+ return DOMAIN*(input/=DURATION)*input*input*input*input + START;
+ }
+ };
+ public static final TimeInterpolator easeOut = new TimeInterpolator() {
+ public float getInterpolation(float input) {
+ return DOMAIN*((input=input/DURATION-1)*input*input*input*input + 1) + START;
+ }
+ };
+ public static final TimeInterpolator easeInOut = new TimeInterpolator() {
+ public float getInterpolation(float input) {
+ return ((input/=DURATION/2) < 1) ?
+ (DOMAIN/2*input*input*input*input*input + START)
+ : (DOMAIN/2*((input-=2)*input*input*input*input + 2) + START);
+ }
+ };
+ }
+
+ static class Sine {
+ public static final TimeInterpolator easeIn = new TimeInterpolator() {
+ public float getInterpolation(float input) {
+ return -DOMAIN * (float) Math.cos(input/DURATION * (Math.PI/2)) + DOMAIN + START;
+ }
+ };
+ public static final TimeInterpolator easeOut = new TimeInterpolator() {
+ public float getInterpolation(float input) {
+ return DOMAIN * (float) Math.sin(input/DURATION * (Math.PI/2)) + START;
+ }
+ };
+ public static final TimeInterpolator easeInOut = new TimeInterpolator() {
+ public float getInterpolation(float input) {
+ return -DOMAIN/2 * ((float)Math.cos(Math.PI*input/DURATION) - 1.0f) + START;
+ }
+ };
+ }
+
+}
diff --git a/src/com/android/incallui/widget/multiwaveview/GlowPadView.java b/src/com/android/incallui/widget/multiwaveview/GlowPadView.java
new file mode 100644
index 00000000..b577b7cc
--- /dev/null
+++ b/src/com/android/incallui/widget/multiwaveview/GlowPadView.java
@@ -0,0 +1,1261 @@
+/*
+ * 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.incallui.widget.multiwaveview;
+
+import android.animation.Animator;
+import android.animation.Animator.AnimatorListener;
+import android.animation.AnimatorListenerAdapter;
+import android.animation.TimeInterpolator;
+import android.animation.ValueAnimator;
+import android.animation.ValueAnimator.AnimatorUpdateListener;
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.pm.PackageManager;
+import android.content.pm.PackageManager.NameNotFoundException;
+import android.content.res.Resources;
+import android.content.res.TypedArray;
+import android.graphics.Canvas;
+import android.graphics.drawable.Drawable;
+import android.os.Bundle;
+import android.os.Vibrator;
+import android.text.TextUtils;
+import android.util.AttributeSet;
+import android.util.Log;
+import android.util.TypedValue;
+import android.view.Gravity;
+import android.view.MotionEvent;
+import android.view.View;
+import android.view.accessibility.AccessibilityManager;
+
+import com.android.incallui.R;
+
+import java.util.ArrayList;
+
+/**
+ * This is a copy of com.android.internal.widget.multiwaveview.GlowPadView with minor changes
+ * to remove dependencies on private api's.
+ *
+ * Contains changes up to If296b60af2421bfa1a9a082e608ba77b2392a218
+ *
+ * A re-usable widget containing a center, outer ring and wave animation.
+ */
+public class GlowPadView extends View {
+ private static final String TAG = "GlowPadView";
+ private static final boolean DEBUG = false;
+
+ // Wave state machine
+ private static final int STATE_IDLE = 0;
+ private static final int STATE_START = 1;
+ private static final int STATE_FIRST_TOUCH = 2;
+ private static final int STATE_TRACKING = 3;
+ private static final int STATE_SNAP = 4;
+ private static final int STATE_FINISH = 5;
+
+ // Animation properties.
+ private static final float SNAP_MARGIN_DEFAULT = 20.0f; // distance to ring before we snap to it
+
+ public interface OnTriggerListener {
+ int NO_HANDLE = 0;
+ int CENTER_HANDLE = 1;
+ public void onGrabbed(View v, int handle);
+ public void onReleased(View v, int handle);
+ public void onTrigger(View v, int target);
+ public void onGrabbedStateChange(View v, int handle);
+ public void onFinishFinalAnimation();
+ }
+
+ // Tuneable parameters for animation
+ private static final int WAVE_ANIMATION_DURATION = 1350;
+ private static final int RETURN_TO_HOME_DELAY = 1200;
+ private static final int RETURN_TO_HOME_DURATION = 200;
+ private static final int HIDE_ANIMATION_DELAY = 200;
+ private static final int HIDE_ANIMATION_DURATION = 200;
+ private static final int SHOW_ANIMATION_DURATION = 200;
+ private static final int SHOW_ANIMATION_DELAY = 50;
+ private static final int INITIAL_SHOW_HANDLE_DURATION = 200;
+ private static final int REVEAL_GLOW_DELAY = 0;
+ private static final int REVEAL_GLOW_DURATION = 0;
+
+ private static final float TAP_RADIUS_SCALE_ACCESSIBILITY_ENABLED = 1.3f;
+ private static final float TARGET_SCALE_EXPANDED = 1.0f;
+ private static final float TARGET_SCALE_COLLAPSED = 0.8f;
+ private static final float RING_SCALE_EXPANDED = 1.0f;
+ private static final float RING_SCALE_COLLAPSED = 0.5f;
+
+ private ArrayList<TargetDrawable> mTargetDrawables = new ArrayList<TargetDrawable>();
+ private AnimationBundle mWaveAnimations = new AnimationBundle();
+ private AnimationBundle mTargetAnimations = new AnimationBundle();
+ private AnimationBundle mGlowAnimations = new AnimationBundle();
+ private ArrayList<String> mTargetDescriptions;
+ private ArrayList<String> mDirectionDescriptions;
+ private OnTriggerListener mOnTriggerListener;
+ private TargetDrawable mHandleDrawable;
+ private TargetDrawable mOuterRing;
+ private Vibrator mVibrator;
+
+ private int mFeedbackCount = 3;
+ private int mVibrationDuration = 0;
+ private int mGrabbedState;
+ private int mActiveTarget = -1;
+ private float mGlowRadius;
+ private float mWaveCenterX;
+ private float mWaveCenterY;
+ private int mMaxTargetHeight;
+ private int mMaxTargetWidth;
+
+ private float mOuterRadius = 0.0f;
+ private float mSnapMargin = 0.0f;
+ private boolean mDragging;
+ private int mNewTargetResources;
+
+ private class AnimationBundle extends ArrayList<Tweener> {
+ private static final long serialVersionUID = 0xA84D78726F127468L;
+ private boolean mSuspended;
+
+ public void start() {
+ if (mSuspended) return; // ignore attempts to start animations
+ final int count = size();
+ for (int i = 0; i < count; i++) {
+ Tweener anim = get(i);
+ anim.animator.start();
+ }
+ }
+
+ public void cancel() {
+ final int count = size();
+ for (int i = 0; i < count; i++) {
+ Tweener anim = get(i);
+ anim.animator.cancel();
+ }
+ clear();
+ }
+
+ public void stop() {
+ final int count = size();
+ for (int i = 0; i < count; i++) {
+ Tweener anim = get(i);
+ anim.animator.end();
+ }
+ clear();
+ }
+
+ public void setSuspended(boolean suspend) {
+ mSuspended = suspend;
+ }
+ };
+
+ private AnimatorListener mResetListener = new AnimatorListenerAdapter() {
+ public void onAnimationEnd(Animator animator) {
+ switchToState(STATE_IDLE, mWaveCenterX, mWaveCenterY);
+ dispatchOnFinishFinalAnimation();
+ }
+ };
+
+ private AnimatorListener mResetListenerWithPing = new AnimatorListenerAdapter() {
+ public void onAnimationEnd(Animator animator) {
+ ping();
+ switchToState(STATE_IDLE, mWaveCenterX, mWaveCenterY);
+ dispatchOnFinishFinalAnimation();
+ }
+ };
+
+ private AnimatorUpdateListener mUpdateListener = new AnimatorUpdateListener() {
+ public void onAnimationUpdate(ValueAnimator animation) {
+ invalidate();
+ }
+ };
+
+ private boolean mAnimatingTargets;
+ private AnimatorListener mTargetUpdateListener = new AnimatorListenerAdapter() {
+ public void onAnimationEnd(Animator animator) {
+ if (mNewTargetResources != 0) {
+ internalSetTargetResources(mNewTargetResources);
+ mNewTargetResources = 0;
+ hideTargets(false, false);
+ }
+ mAnimatingTargets = false;
+ }
+ };
+ private int mTargetResourceId;
+ private int mTargetDescriptionsResourceId;
+ private int mDirectionDescriptionsResourceId;
+ private boolean mAlwaysTrackFinger;
+ private int mHorizontalInset;
+ private int mVerticalInset;
+ private int mGravity = Gravity.TOP;
+ private boolean mInitialLayout = true;
+ private Tweener mBackgroundAnimator;
+ private PointCloud mPointCloud;
+ private float mInnerRadius;
+ private int mPointerId;
+
+ public GlowPadView(Context context) {
+ this(context, null);
+ }
+
+ public GlowPadView(Context context, AttributeSet attrs) {
+ super(context, attrs);
+ Resources res = context.getResources();
+
+ TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.GlowPadView);
+ mInnerRadius = a.getDimension(R.styleable.GlowPadView_innerRadius, mInnerRadius);
+ mOuterRadius = a.getDimension(R.styleable.GlowPadView_outerRadius, mOuterRadius);
+ mSnapMargin = a.getDimension(R.styleable.GlowPadView_snapMargin, mSnapMargin);
+ mVibrationDuration = a.getInt(R.styleable.GlowPadView_vibrationDuration,
+ mVibrationDuration);
+ mFeedbackCount = a.getInt(R.styleable.GlowPadView_feedbackCount,
+ mFeedbackCount);
+ TypedValue handle = a.peekValue(R.styleable.GlowPadView_handleDrawable);
+ mHandleDrawable = new TargetDrawable(res, handle != null ? handle.resourceId : 0, 2);
+ mHandleDrawable.setState(TargetDrawable.STATE_INACTIVE);
+ mOuterRing = new TargetDrawable(res,
+ getResourceId(a, R.styleable.GlowPadView_outerRingDrawable), 1);
+
+ mAlwaysTrackFinger = a.getBoolean(R.styleable.GlowPadView_alwaysTrackFinger, false);
+
+ int pointId = getResourceId(a, R.styleable.GlowPadView_pointDrawable);
+ Drawable pointDrawable = pointId != 0 ? res.getDrawable(pointId) : null;
+ mGlowRadius = a.getDimension(R.styleable.GlowPadView_glowRadius, 0.0f);
+
+ TypedValue outValue = new TypedValue();
+
+ // Read array of target drawables
+ if (a.getValue(R.styleable.GlowPadView_targetDrawables, outValue)) {
+ internalSetTargetResources(outValue.resourceId);
+ }
+ if (mTargetDrawables == null || mTargetDrawables.size() == 0) {
+ throw new IllegalStateException("Must specify at least one target drawable");
+ }
+
+ // Read array of target descriptions
+ if (a.getValue(R.styleable.GlowPadView_targetDescriptions, outValue)) {
+ final int resourceId = outValue.resourceId;
+ if (resourceId == 0) {
+ throw new IllegalStateException("Must specify target descriptions");
+ }
+ setTargetDescriptionsResourceId(resourceId);
+ }
+
+ // Read array of direction descriptions
+ if (a.getValue(R.styleable.GlowPadView_directionDescriptions, outValue)) {
+ final int resourceId = outValue.resourceId;
+ if (resourceId == 0) {
+ throw new IllegalStateException("Must specify direction descriptions");
+ }
+ setDirectionDescriptionsResourceId(resourceId);
+ }
+
+ a.recycle();
+
+ // Use gravity attribute from LinearLayout
+ //a = context.obtainStyledAttributes(attrs, R.styleable.LinearLayout);
+ mGravity = a.getInt(R.styleable.GlowPadView_android_gravity, Gravity.TOP);
+ a.recycle();
+
+
+ setVibrateEnabled(mVibrationDuration > 0);
+
+ assignDefaultsIfNeeded();
+
+ mPointCloud = new PointCloud(pointDrawable);
+ mPointCloud.makePointCloud(mInnerRadius, mOuterRadius);
+ mPointCloud.glowManager.setRadius(mGlowRadius);
+ }
+
+ private int getResourceId(TypedArray a, int id) {
+ TypedValue tv = a.peekValue(id);
+ return tv == null ? 0 : tv.resourceId;
+ }
+
+ private void dump() {
+ Log.v(TAG, "Outer Radius = " + mOuterRadius);
+ Log.v(TAG, "SnapMargin = " + mSnapMargin);
+ Log.v(TAG, "FeedbackCount = " + mFeedbackCount);
+ Log.v(TAG, "VibrationDuration = " + mVibrationDuration);
+ Log.v(TAG, "GlowRadius = " + mGlowRadius);
+ Log.v(TAG, "WaveCenterX = " + mWaveCenterX);
+ Log.v(TAG, "WaveCenterY = " + mWaveCenterY);
+ }
+
+ public void suspendAnimations() {
+ mWaveAnimations.setSuspended(true);
+ mTargetAnimations.setSuspended(true);
+ mGlowAnimations.setSuspended(true);
+ }
+
+ public void resumeAnimations() {
+ mWaveAnimations.setSuspended(false);
+ mTargetAnimations.setSuspended(false);
+ mGlowAnimations.setSuspended(false);
+ mWaveAnimations.start();
+ mTargetAnimations.start();
+ mGlowAnimations.start();
+ }
+
+ @Override
+ protected int getSuggestedMinimumWidth() {
+ // View should be large enough to contain the background + handle and
+ // target drawable on either edge.
+ return (int) (Math.max(mOuterRing.getWidth(), 2 * mOuterRadius) + mMaxTargetWidth);
+ }
+
+ @Override
+ protected int getSuggestedMinimumHeight() {
+ // View should be large enough to contain the unlock ring + target and
+ // target drawable on either edge
+ return (int) (Math.max(mOuterRing.getHeight(), 2 * mOuterRadius) + mMaxTargetHeight);
+ }
+
+ private int resolveMeasured(int measureSpec, int desired)
+ {
+ int result = 0;
+ int specSize = MeasureSpec.getSize(measureSpec);
+ switch (MeasureSpec.getMode(measureSpec)) {
+ case MeasureSpec.UNSPECIFIED:
+ result = desired;
+ break;
+ case MeasureSpec.AT_MOST:
+ result = Math.min(specSize, desired);
+ break;
+ case MeasureSpec.EXACTLY:
+ default:
+ result = specSize;
+ }
+ return result;
+ }
+
+ @Override
+ protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
+ final int minimumWidth = getSuggestedMinimumWidth();
+ final int minimumHeight = getSuggestedMinimumHeight();
+ int computedWidth = resolveMeasured(widthMeasureSpec, minimumWidth);
+ int computedHeight = resolveMeasured(heightMeasureSpec, minimumHeight);
+ computeInsets((computedWidth - minimumWidth), (computedHeight - minimumHeight));
+ setMeasuredDimension(computedWidth, computedHeight);
+ }
+
+ private void switchToState(int state, float x, float y) {
+ switch (state) {
+ case STATE_IDLE:
+ deactivateTargets();
+ hideGlow(0, 0, 0.0f, null);
+ startBackgroundAnimation(0, 0.0f);
+ mHandleDrawable.setState(TargetDrawable.STATE_INACTIVE);
+ mHandleDrawable.setAlpha(1.0f);
+ break;
+
+ case STATE_START:
+ startBackgroundAnimation(0, 0.0f);
+ break;
+
+ case STATE_FIRST_TOUCH:
+ mHandleDrawable.setAlpha(0.0f);
+ deactivateTargets();
+ showTargets(true);
+ startBackgroundAnimation(INITIAL_SHOW_HANDLE_DURATION, 1.0f);
+ setGrabbedState(OnTriggerListener.CENTER_HANDLE);
+
+ final AccessibilityManager accessibilityManager =
+ (AccessibilityManager) getContext().getSystemService(
+ Context.ACCESSIBILITY_SERVICE);
+ if (accessibilityManager.isEnabled()) {
+ announceTargets();
+ }
+ break;
+
+ case STATE_TRACKING:
+ mHandleDrawable.setAlpha(0.0f);
+ showGlow(REVEAL_GLOW_DURATION , REVEAL_GLOW_DELAY, 1.0f, null);
+ break;
+
+ case STATE_SNAP:
+ // TODO: Add transition states (see list_selector_background_transition.xml)
+ mHandleDrawable.setAlpha(0.0f);
+ showGlow(REVEAL_GLOW_DURATION , REVEAL_GLOW_DELAY, 0.0f, null);
+ break;
+
+ case STATE_FINISH:
+ doFinish();
+ break;
+ }
+ }
+
+ private void showGlow(int duration, int delay, float finalAlpha,
+ AnimatorListener finishListener) {
+ mGlowAnimations.cancel();
+ mGlowAnimations.add(Tweener.to(mPointCloud.glowManager, duration,
+ "ease", Ease.Cubic.easeIn,
+ "delay", delay,
+ "alpha", finalAlpha,
+ "onUpdate", mUpdateListener,
+ "onComplete", finishListener));
+ mGlowAnimations.start();
+ }
+
+ private void hideGlow(int duration, int delay, float finalAlpha,
+ AnimatorListener finishListener) {
+ mGlowAnimations.cancel();
+ mGlowAnimations.add(Tweener.to(mPointCloud.glowManager, duration,
+ "ease", Ease.Quart.easeOut,
+ "delay", delay,
+ "alpha", finalAlpha,
+ "x", 0.0f,
+ "y", 0.0f,
+ "onUpdate", mUpdateListener,
+ "onComplete", finishListener));
+ mGlowAnimations.start();
+ }
+
+ private void deactivateTargets() {
+ final int count = mTargetDrawables.size();
+ for (int i = 0; i < count; i++) {
+ TargetDrawable target = mTargetDrawables.get(i);
+ target.setState(TargetDrawable.STATE_INACTIVE);
+ }
+ mActiveTarget = -1;
+ }
+
+ /**
+ * Dispatches a trigger event to listener. Ignored if a listener is not set.
+ * @param whichTarget the target that was triggered.
+ */
+ private void dispatchTriggerEvent(int whichTarget) {
+ vibrate();
+ if (mOnTriggerListener != null) {
+ mOnTriggerListener.onTrigger(this, whichTarget);
+ }
+ }
+
+ private void dispatchOnFinishFinalAnimation() {
+ if (mOnTriggerListener != null) {
+ mOnTriggerListener.onFinishFinalAnimation();
+ }
+ }
+
+ private void doFinish() {
+ final int activeTarget = mActiveTarget;
+ final boolean targetHit = activeTarget != -1;
+
+ if (targetHit) {
+ if (DEBUG) Log.v(TAG, "Finish with target hit = " + targetHit);
+
+ highlightSelected(activeTarget);
+
+ // Inform listener of any active targets. Typically only one will be active.
+ hideGlow(RETURN_TO_HOME_DURATION, RETURN_TO_HOME_DELAY, 0.0f, mResetListener);
+ dispatchTriggerEvent(activeTarget);
+ if (!mAlwaysTrackFinger) {
+ // Force ring and targets to finish animation to final expanded state
+ mTargetAnimations.stop();
+ }
+ } else {
+ // Animate handle back to the center based on current state.
+ hideGlow(HIDE_ANIMATION_DURATION, 0, 0.0f, mResetListenerWithPing);
+ hideTargets(true, false);
+ }
+
+ setGrabbedState(OnTriggerListener.NO_HANDLE);
+ }
+
+ private void highlightSelected(int activeTarget) {
+ // Highlight the given target and fade others
+ mTargetDrawables.get(activeTarget).setState(TargetDrawable.STATE_ACTIVE);
+ hideUnselected(activeTarget);
+ }
+
+ private void hideUnselected(int active) {
+ for (int i = 0; i < mTargetDrawables.size(); i++) {
+ if (i != active) {
+ mTargetDrawables.get(i).setAlpha(0.0f);
+ }
+ }
+ }
+
+ private void hideTargets(boolean animate, boolean expanded) {
+ mTargetAnimations.cancel();
+ // Note: these animations should complete at the same time so that we can swap out
+ // the target assets asynchronously from the setTargetResources() call.
+ mAnimatingTargets = animate;
+ final int duration = animate ? HIDE_ANIMATION_DURATION : 0;
+ final int delay = animate ? HIDE_ANIMATION_DELAY : 0;
+
+ final float targetScale = expanded ?
+ TARGET_SCALE_EXPANDED : TARGET_SCALE_COLLAPSED;
+ final int length = mTargetDrawables.size();
+ final TimeInterpolator interpolator = Ease.Cubic.easeOut;
+ for (int i = 0; i < length; i++) {
+ TargetDrawable target = mTargetDrawables.get(i);
+ target.setState(TargetDrawable.STATE_INACTIVE);
+ mTargetAnimations.add(Tweener.to(target, duration,
+ "ease", interpolator,
+ "alpha", 0.0f,
+ "scaleX", targetScale,
+ "scaleY", targetScale,
+ "delay", delay,
+ "onUpdate", mUpdateListener));
+ }
+
+ final float ringScaleTarget = expanded ?
+ RING_SCALE_EXPANDED : RING_SCALE_COLLAPSED;
+ mTargetAnimations.add(Tweener.to(mOuterRing, duration,
+ "ease", interpolator,
+ "alpha", 0.0f,
+ "scaleX", ringScaleTarget,
+ "scaleY", ringScaleTarget,
+ "delay", delay,
+ "onUpdate", mUpdateListener,
+ "onComplete", mTargetUpdateListener));
+
+ mTargetAnimations.start();
+ }
+
+ private void showTargets(boolean animate) {
+ mTargetAnimations.stop();
+ mAnimatingTargets = animate;
+ final int delay = animate ? SHOW_ANIMATION_DELAY : 0;
+ final int duration = animate ? SHOW_ANIMATION_DURATION : 0;
+ final int length = mTargetDrawables.size();
+ for (int i = 0; i < length; i++) {
+ TargetDrawable target = mTargetDrawables.get(i);
+ target.setState(TargetDrawable.STATE_INACTIVE);
+ mTargetAnimations.add(Tweener.to(target, duration,
+ "ease", Ease.Cubic.easeOut,
+ "alpha", 1.0f,
+ "scaleX", 1.0f,
+ "scaleY", 1.0f,
+ "delay", delay,
+ "onUpdate", mUpdateListener));
+ }
+ mTargetAnimations.add(Tweener.to(mOuterRing, duration,
+ "ease", Ease.Cubic.easeOut,
+ "alpha", 1.0f,
+ "scaleX", 1.0f,
+ "scaleY", 1.0f,
+ "delay", delay,
+ "onUpdate", mUpdateListener,
+ "onComplete", mTargetUpdateListener));
+
+ mTargetAnimations.start();
+ }
+
+ private void vibrate() {
+ if (mVibrator != null) {
+ mVibrator.vibrate(mVibrationDuration);
+ }
+ }
+
+ private ArrayList<TargetDrawable> loadDrawableArray(int resourceId) {
+ Resources res = getContext().getResources();
+ TypedArray array = res.obtainTypedArray(resourceId);
+ final int count = array.length();
+ ArrayList<TargetDrawable> drawables = new ArrayList<TargetDrawable>(count);
+ for (int i = 0; i < count; i++) {
+ TypedValue value = array.peekValue(i);
+ TargetDrawable target = new TargetDrawable(res, value != null ? value.resourceId : 0, 3);
+ drawables.add(target);
+ }
+ array.recycle();
+ return drawables;
+ }
+
+ private void internalSetTargetResources(int resourceId) {
+ final ArrayList<TargetDrawable> targets = loadDrawableArray(resourceId);
+ mTargetDrawables = targets;
+ mTargetResourceId = resourceId;
+
+ int maxWidth = mHandleDrawable.getWidth();
+ int maxHeight = mHandleDrawable.getHeight();
+ final int count = targets.size();
+ for (int i = 0; i < count; i++) {
+ TargetDrawable target = targets.get(i);
+ maxWidth = Math.max(maxWidth, target.getWidth());
+ maxHeight = Math.max(maxHeight, target.getHeight());
+ }
+ if (mMaxTargetWidth != maxWidth || mMaxTargetHeight != maxHeight) {
+ mMaxTargetWidth = maxWidth;
+ mMaxTargetHeight = maxHeight;
+ requestLayout(); // required to resize layout and call updateTargetPositions()
+ } else {
+ updateTargetPositions(mWaveCenterX, mWaveCenterY);
+ updatePointCloudPosition(mWaveCenterX, mWaveCenterY);
+ }
+ }
+
+ /**
+ * Loads an array of drawables from the given resourceId.
+ *
+ * @param resourceId
+ */
+ public void setTargetResources(int resourceId) {
+ if (mAnimatingTargets) {
+ // postpone this change until we return to the initial state
+ mNewTargetResources = resourceId;
+ } else {
+ internalSetTargetResources(resourceId);
+ }
+ }
+
+ public int getTargetResourceId() {
+ return mTargetResourceId;
+ }
+
+ /**
+ * Sets the resource id specifying the target descriptions for accessibility.
+ *
+ * @param resourceId The resource id.
+ */
+ public void setTargetDescriptionsResourceId(int resourceId) {
+ mTargetDescriptionsResourceId = resourceId;
+ if (mTargetDescriptions != null) {
+ mTargetDescriptions.clear();
+ }
+ }
+
+ /**
+ * Gets the resource id specifying the target descriptions for accessibility.
+ *
+ * @return The resource id.
+ */
+ public int getTargetDescriptionsResourceId() {
+ return mTargetDescriptionsResourceId;
+ }
+
+ /**
+ * Sets the resource id specifying the target direction descriptions for accessibility.
+ *
+ * @param resourceId The resource id.
+ */
+ public void setDirectionDescriptionsResourceId(int resourceId) {
+ mDirectionDescriptionsResourceId = resourceId;
+ if (mDirectionDescriptions != null) {
+ mDirectionDescriptions.clear();
+ }
+ }
+
+ /**
+ * Gets the resource id specifying the target direction descriptions.
+ *
+ * @return The resource id.
+ */
+ public int getDirectionDescriptionsResourceId() {
+ return mDirectionDescriptionsResourceId;
+ }
+
+ /**
+ * Enable or disable vibrate on touch.
+ *
+ * @param enabled
+ */
+ public void setVibrateEnabled(boolean enabled) {
+ if (enabled && mVibrator == null) {
+ mVibrator = (Vibrator) getContext().getSystemService(Context.VIBRATOR_SERVICE);
+ } else {
+ mVibrator = null;
+ }
+ }
+
+ /**
+ * Starts wave animation.
+ *
+ */
+ public void ping() {
+ if (mFeedbackCount > 0) {
+ boolean doWaveAnimation = true;
+ final AnimationBundle waveAnimations = mWaveAnimations;
+
+ // Don't do a wave if there's already one in progress
+ if (waveAnimations.size() > 0 && waveAnimations.get(0).animator.isRunning()) {
+ long t = waveAnimations.get(0).animator.getCurrentPlayTime();
+ if (t < WAVE_ANIMATION_DURATION/2) {
+ doWaveAnimation = false;
+ }
+ }
+
+ if (doWaveAnimation) {
+ startWaveAnimation();
+ }
+ }
+ }
+
+ private void stopAndHideWaveAnimation() {
+ mWaveAnimations.cancel();
+ mPointCloud.waveManager.setAlpha(0.0f);
+ }
+
+ private void startWaveAnimation() {
+ mWaveAnimations.cancel();
+ mPointCloud.waveManager.setAlpha(1.0f);
+ mPointCloud.waveManager.setRadius(mHandleDrawable.getWidth()/2.0f);
+ mWaveAnimations.add(Tweener.to(mPointCloud.waveManager, WAVE_ANIMATION_DURATION,
+ "ease", Ease.Quad.easeOut,
+ "delay", 0,
+ "radius", 2.0f * mOuterRadius,
+ "onUpdate", mUpdateListener,
+ "onComplete",
+ new AnimatorListenerAdapter() {
+ public void onAnimationEnd(Animator animator) {
+ mPointCloud.waveManager.setRadius(0.0f);
+ mPointCloud.waveManager.setAlpha(0.0f);
+ }
+ }));
+ mWaveAnimations.start();
+ }
+
+ /**
+ * Resets the widget to default state and cancels all animation. If animate is 'true', will
+ * animate objects into place. Otherwise, objects will snap back to place.
+ *
+ * @param animate
+ */
+ public void reset(boolean animate) {
+ mGlowAnimations.stop();
+ mTargetAnimations.stop();
+ startBackgroundAnimation(0, 0.0f);
+ stopAndHideWaveAnimation();
+ hideTargets(animate, false);
+ hideGlow(0, 0, 0.0f, null);
+ Tweener.reset();
+ }
+
+ private void startBackgroundAnimation(int duration, float alpha) {
+ final Drawable background = getBackground();
+ if (mAlwaysTrackFinger && background != null) {
+ if (mBackgroundAnimator != null) {
+ mBackgroundAnimator.animator.cancel();
+ }
+ mBackgroundAnimator = Tweener.to(background, duration,
+ "ease", Ease.Cubic.easeIn,
+ "alpha", (int)(255.0f * alpha),
+ "delay", SHOW_ANIMATION_DELAY);
+ mBackgroundAnimator.animator.start();
+ }
+ }
+
+ @Override
+ public boolean onTouchEvent(MotionEvent event) {
+ final int action = event.getActionMasked();
+ boolean handled = false;
+ switch (action) {
+ case MotionEvent.ACTION_POINTER_DOWN:
+ case MotionEvent.ACTION_DOWN:
+ if (DEBUG) Log.v(TAG, "*** DOWN ***");
+ handleDown(event);
+ handleMove(event);
+ handled = true;
+ break;
+
+ case MotionEvent.ACTION_MOVE:
+ if (DEBUG) Log.v(TAG, "*** MOVE ***");
+ handleMove(event);
+ handled = true;
+ break;
+
+ case MotionEvent.ACTION_POINTER_UP:
+ case MotionEvent.ACTION_UP:
+ if (DEBUG) Log.v(TAG, "*** UP ***");
+ handleMove(event);
+ handleUp(event);
+ handled = true;
+ break;
+
+ case MotionEvent.ACTION_CANCEL:
+ if (DEBUG) Log.v(TAG, "*** CANCEL ***");
+ handleMove(event);
+ handleCancel(event);
+ handled = true;
+ break;
+ }
+ invalidate();
+ return handled ? true : super.onTouchEvent(event);
+ }
+
+ private void updateGlowPosition(float x, float y) {
+ mPointCloud.glowManager.setX(x);
+ mPointCloud.glowManager.setY(y);
+ }
+
+ private void handleDown(MotionEvent event) {
+ int actionIndex = event.getActionIndex();
+ float eventX = event.getX(actionIndex);
+ float eventY = event.getY(actionIndex);
+ switchToState(STATE_START, eventX, eventY);
+ if (!trySwitchToFirstTouchState(eventX, eventY)) {
+ mDragging = false;
+ } else {
+ mPointerId = event.getPointerId(actionIndex);
+ updateGlowPosition(eventX, eventY);
+ }
+ }
+
+ private void handleUp(MotionEvent event) {
+ if (DEBUG && mDragging) Log.v(TAG, "** Handle RELEASE");
+ int actionIndex = event.getActionIndex();
+ if (event.getPointerId(actionIndex) == mPointerId) {
+ switchToState(STATE_FINISH, event.getX(actionIndex), event.getY(actionIndex));
+ }
+ }
+
+ private void handleCancel(MotionEvent event) {
+ if (DEBUG && mDragging) Log.v(TAG, "** Handle CANCEL");
+
+ // We should drop the active target here but it interferes with
+ // moving off the screen in the direction of the navigation bar. At some point we may
+ // want to revisit how we handle this. For now we'll allow a canceled event to
+ // activate the current target.
+
+ // mActiveTarget = -1; // Drop the active target if canceled.
+
+ int actionIndex = event.findPointerIndex(mPointerId);
+ actionIndex = actionIndex == -1 ? 0 : actionIndex;
+ switchToState(STATE_FINISH, event.getX(actionIndex), event.getY(actionIndex));
+ }
+
+ private void handleMove(MotionEvent event) {
+ int activeTarget = -1;
+ final int historySize = event.getHistorySize();
+ ArrayList<TargetDrawable> targets = mTargetDrawables;
+ int ntargets = targets.size();
+ float x = 0.0f;
+ float y = 0.0f;
+ int actionIndex = event.findPointerIndex(mPointerId);
+
+ if (actionIndex == -1) {
+ return; // no data for this pointer
+ }
+
+ for (int k = 0; k < historySize + 1; k++) {
+ float eventX = k < historySize ? event.getHistoricalX(actionIndex, k)
+ : event.getX(actionIndex);
+ float eventY = k < historySize ? event.getHistoricalY(actionIndex, k)
+ :event.getY(actionIndex);
+ // tx and ty are relative to wave center
+ float tx = eventX - mWaveCenterX;
+ float ty = eventY - mWaveCenterY;
+ float touchRadius = (float) Math.sqrt(dist2(tx, ty));
+ final float scale = touchRadius > mOuterRadius ? mOuterRadius / touchRadius : 1.0f;
+ float limitX = tx * scale;
+ float limitY = ty * scale;
+ double angleRad = Math.atan2(-ty, tx);
+
+ if (!mDragging) {
+ trySwitchToFirstTouchState(eventX, eventY);
+ }
+
+ if (mDragging) {
+ // For multiple targets, snap to the one that matches
+ final float snapRadius = mOuterRadius - mSnapMargin;
+ final float snapDistance2 = snapRadius * snapRadius;
+ // Find first target in range
+ for (int i = 0; i < ntargets; i++) {
+ TargetDrawable target = targets.get(i);
+
+ double targetMinRad = (i - 0.5) * 2 * Math.PI / ntargets;
+ double targetMaxRad = (i + 0.5) * 2 * Math.PI / ntargets;
+ if (target.isEnabled()) {
+ boolean angleMatches =
+ (angleRad > targetMinRad && angleRad <= targetMaxRad) ||
+ (angleRad + 2 * Math.PI > targetMinRad &&
+ angleRad + 2 * Math.PI <= targetMaxRad);
+ if (angleMatches && (dist2(tx, ty) > snapDistance2)) {
+ activeTarget = i;
+ }
+ }
+ }
+ }
+ x = limitX;
+ y = limitY;
+ }
+
+ if (!mDragging) {
+ return;
+ }
+
+ if (activeTarget != -1) {
+ switchToState(STATE_SNAP, x,y);
+ updateGlowPosition(x, y);
+ } else {
+ switchToState(STATE_TRACKING, x, y);
+ updateGlowPosition(x, y);
+ }
+
+ if (mActiveTarget != activeTarget) {
+ // Defocus the old target
+ if (mActiveTarget != -1) {
+ TargetDrawable target = targets.get(mActiveTarget);
+ target.setState(TargetDrawable.STATE_INACTIVE);
+ }
+ // Focus the new target
+ if (activeTarget != -1) {
+ TargetDrawable target = targets.get(activeTarget);
+ target.setState(TargetDrawable.STATE_FOCUSED);
+ final AccessibilityManager accessibilityManager =
+ (AccessibilityManager) getContext().getSystemService(
+ Context.ACCESSIBILITY_SERVICE);
+ if (accessibilityManager.isEnabled()) {
+ String targetContentDescription = getTargetDescription(activeTarget);
+ announceForAccessibility(targetContentDescription);
+ }
+ }
+ }
+ mActiveTarget = activeTarget;
+ }
+
+ @Override
+ public boolean onHoverEvent(MotionEvent event) {
+ final AccessibilityManager accessibilityManager =
+ (AccessibilityManager) getContext().getSystemService(
+ Context.ACCESSIBILITY_SERVICE);
+ if (accessibilityManager.isTouchExplorationEnabled()) {
+ final int action = event.getAction();
+ switch (action) {
+ case MotionEvent.ACTION_HOVER_ENTER:
+ event.setAction(MotionEvent.ACTION_DOWN);
+ break;
+ case MotionEvent.ACTION_HOVER_MOVE:
+ event.setAction(MotionEvent.ACTION_MOVE);
+ break;
+ case MotionEvent.ACTION_HOVER_EXIT:
+ event.setAction(MotionEvent.ACTION_UP);
+ break;
+ }
+ onTouchEvent(event);
+ event.setAction(action);
+ }
+ super.onHoverEvent(event);
+ return true;
+ }
+
+ /**
+ * Sets the current grabbed state, and dispatches a grabbed state change
+ * event to our listener.
+ */
+ private void setGrabbedState(int newState) {
+ if (newState != mGrabbedState) {
+ if (newState != OnTriggerListener.NO_HANDLE) {
+ vibrate();
+ }
+ mGrabbedState = newState;
+ if (mOnTriggerListener != null) {
+ if (newState == OnTriggerListener.NO_HANDLE) {
+ mOnTriggerListener.onReleased(this, OnTriggerListener.CENTER_HANDLE);
+ } else {
+ mOnTriggerListener.onGrabbed(this, OnTriggerListener.CENTER_HANDLE);
+ }
+ mOnTriggerListener.onGrabbedStateChange(this, newState);
+ }
+ }
+ }
+
+ private boolean trySwitchToFirstTouchState(float x, float y) {
+ final float tx = x - mWaveCenterX;
+ final float ty = y - mWaveCenterY;
+ if (mAlwaysTrackFinger || dist2(tx,ty) <= getScaledGlowRadiusSquared()) {
+ if (DEBUG) Log.v(TAG, "** Handle HIT");
+ switchToState(STATE_FIRST_TOUCH, x, y);
+ updateGlowPosition(tx, ty);
+ mDragging = true;
+ return true;
+ }
+ return false;
+ }
+
+ private void assignDefaultsIfNeeded() {
+ if (mOuterRadius == 0.0f) {
+ mOuterRadius = Math.max(mOuterRing.getWidth(), mOuterRing.getHeight())/2.0f;
+ }
+ if (mSnapMargin == 0.0f) {
+ mSnapMargin = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP,
+ SNAP_MARGIN_DEFAULT, getContext().getResources().getDisplayMetrics());
+ }
+ if (mInnerRadius == 0.0f) {
+ mInnerRadius = mHandleDrawable.getWidth() / 10.0f;
+ }
+ }
+
+ private void computeInsets(int dx, int dy) {
+ final int layoutDirection = getLayoutDirection();
+ final int absoluteGravity = Gravity.getAbsoluteGravity(mGravity, layoutDirection);
+
+ switch (absoluteGravity & Gravity.HORIZONTAL_GRAVITY_MASK) {
+ case Gravity.LEFT:
+ mHorizontalInset = 0;
+ break;
+ case Gravity.RIGHT:
+ mHorizontalInset = dx;
+ break;
+ case Gravity.CENTER_HORIZONTAL:
+ default:
+ mHorizontalInset = dx / 2;
+ break;
+ }
+ switch (absoluteGravity & Gravity.VERTICAL_GRAVITY_MASK) {
+ case Gravity.TOP:
+ mVerticalInset = 0;
+ break;
+ case Gravity.BOTTOM:
+ mVerticalInset = dy;
+ break;
+ case Gravity.CENTER_VERTICAL:
+ default:
+ mVerticalInset = dy / 2;
+ break;
+ }
+ }
+
+ @Override
+ protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
+ super.onLayout(changed, left, top, right, bottom);
+ final int width = right - left;
+ final int height = bottom - top;
+
+ // Target placement width/height. This puts the targets on the greater of the ring
+ // width or the specified outer radius.
+ final float placementWidth = Math.max(mOuterRing.getWidth(), 2 * mOuterRadius);
+ final float placementHeight = Math.max(mOuterRing.getHeight(), 2 * mOuterRadius);
+ float newWaveCenterX = mHorizontalInset
+ + Math.max(width, mMaxTargetWidth + placementWidth) / 2;
+ float newWaveCenterY = mVerticalInset
+ + Math.max(height, + mMaxTargetHeight + placementHeight) / 2;
+
+ if (mInitialLayout) {
+ stopAndHideWaveAnimation();
+ hideTargets(false, false);
+ mInitialLayout = false;
+ }
+
+ mOuterRing.setPositionX(newWaveCenterX);
+ mOuterRing.setPositionY(newWaveCenterY);
+
+ mHandleDrawable.setPositionX(newWaveCenterX);
+ mHandleDrawable.setPositionY(newWaveCenterY);
+
+ updateTargetPositions(newWaveCenterX, newWaveCenterY);
+ updatePointCloudPosition(newWaveCenterX, newWaveCenterY);
+ updateGlowPosition(newWaveCenterX, newWaveCenterY);
+
+ mWaveCenterX = newWaveCenterX;
+ mWaveCenterY = newWaveCenterY;
+
+ if (DEBUG) dump();
+ }
+
+ private void updateTargetPositions(float centerX, float centerY) {
+ // Reposition the target drawables if the view changed.
+ ArrayList<TargetDrawable> targets = mTargetDrawables;
+ final int size = targets.size();
+ final float alpha = (float) (-2.0f * Math.PI / size);
+ for (int i = 0; i < size; i++) {
+ final TargetDrawable targetIcon = targets.get(i);
+ final float angle = alpha * i;
+ targetIcon.setPositionX(centerX);
+ targetIcon.setPositionY(centerY);
+ targetIcon.setX(mOuterRadius * (float) Math.cos(angle));
+ targetIcon.setY(mOuterRadius * (float) Math.sin(angle));
+ }
+ }
+
+ private void updatePointCloudPosition(float centerX, float centerY) {
+ mPointCloud.setCenter(centerX, centerY);
+ }
+
+ @Override
+ protected void onDraw(Canvas canvas) {
+ mPointCloud.draw(canvas);
+ mOuterRing.draw(canvas);
+ final int ntargets = mTargetDrawables.size();
+ for (int i = 0; i < ntargets; i++) {
+ TargetDrawable target = mTargetDrawables.get(i);
+ if (target != null) {
+ target.draw(canvas);
+ }
+ }
+ mHandleDrawable.draw(canvas);
+ }
+
+ public void setOnTriggerListener(OnTriggerListener listener) {
+ mOnTriggerListener = listener;
+ }
+
+ private float square(float d) {
+ return d * d;
+ }
+
+ private float dist2(float dx, float dy) {
+ return dx*dx + dy*dy;
+ }
+
+ private float getScaledGlowRadiusSquared() {
+ final float scaledTapRadius;
+ final AccessibilityManager accessibilityManager =
+ (AccessibilityManager) getContext().getSystemService(
+ Context.ACCESSIBILITY_SERVICE);
+ if (accessibilityManager.isEnabled()) {
+ scaledTapRadius = TAP_RADIUS_SCALE_ACCESSIBILITY_ENABLED * mGlowRadius;
+ } else {
+ scaledTapRadius = mGlowRadius;
+ }
+ return square(scaledTapRadius);
+ }
+
+ private void announceTargets() {
+ StringBuilder utterance = new StringBuilder();
+ final int targetCount = mTargetDrawables.size();
+ for (int i = 0; i < targetCount; i++) {
+ String targetDescription = getTargetDescription(i);
+ String directionDescription = getDirectionDescription(i);
+ if (!TextUtils.isEmpty(targetDescription)
+ && !TextUtils.isEmpty(directionDescription)) {
+ String text = String.format(directionDescription, targetDescription);
+ utterance.append(text);
+ }
+ }
+ if (utterance.length() > 0) {
+ announceForAccessibility(utterance.toString());
+ }
+ }
+
+ private String getTargetDescription(int index) {
+ if (mTargetDescriptions == null || mTargetDescriptions.isEmpty()) {
+ mTargetDescriptions = loadDescriptions(mTargetDescriptionsResourceId);
+ if (mTargetDrawables.size() != mTargetDescriptions.size()) {
+ Log.w(TAG, "The number of target drawables must be"
+ + " equal to the number of target descriptions.");
+ return null;
+ }
+ }
+ return mTargetDescriptions.get(index);
+ }
+
+ private String getDirectionDescription(int index) {
+ if (mDirectionDescriptions == null || mDirectionDescriptions.isEmpty()) {
+ mDirectionDescriptions = loadDescriptions(mDirectionDescriptionsResourceId);
+ if (mTargetDrawables.size() != mDirectionDescriptions.size()) {
+ Log.w(TAG, "The number of target drawables must be"
+ + " equal to the number of direction descriptions.");
+ return null;
+ }
+ }
+ return mDirectionDescriptions.get(index);
+ }
+
+ private ArrayList<String> loadDescriptions(int resourceId) {
+ TypedArray array = getContext().getResources().obtainTypedArray(resourceId);
+ final int count = array.length();
+ ArrayList<String> targetContentDescriptions = new ArrayList<String>(count);
+ for (int i = 0; i < count; i++) {
+ String contentDescription = array.getString(i);
+ targetContentDescriptions.add(contentDescription);
+ }
+ array.recycle();
+ return targetContentDescriptions;
+ }
+
+ public int getResourceIdForTarget(int index) {
+ final TargetDrawable drawable = mTargetDrawables.get(index);
+ return drawable == null ? 0 : drawable.getResourceId();
+ }
+
+ public void setEnableTarget(int resourceId, boolean enabled) {
+ for (int i = 0; i < mTargetDrawables.size(); i++) {
+ final TargetDrawable target = mTargetDrawables.get(i);
+ if (target.getResourceId() == resourceId) {
+ target.setEnabled(enabled);
+ break; // should never be more than one match
+ }
+ }
+ }
+
+ /**
+ * Gets the position of a target in the array that matches the given resource.
+ * @param resourceId
+ * @return the index or -1 if not found
+ */
+ public int getTargetPosition(int resourceId) {
+ for (int i = 0; i < mTargetDrawables.size(); i++) {
+ final TargetDrawable target = mTargetDrawables.get(i);
+ if (target.getResourceId() == resourceId) {
+ return i; // should never be more than one match
+ }
+ }
+ return -1;
+ }
+
+ private boolean replaceTargetDrawables(Resources res, int existingResourceId,
+ int newResourceId) {
+ if (existingResourceId == 0 || newResourceId == 0) {
+ return false;
+ }
+
+ boolean result = false;
+ final ArrayList<TargetDrawable> drawables = mTargetDrawables;
+ final int size = drawables.size();
+ for (int i = 0; i < size; i++) {
+ final TargetDrawable target = drawables.get(i);
+ if (target != null && target.getResourceId() == existingResourceId) {
+ target.setDrawable(res, newResourceId);
+ result = true;
+ }
+ }
+
+ if (result) {
+ requestLayout(); // in case any given drawable's size changes
+ }
+
+ return result;
+ }
+
+ /**
+ * Searches the given package for a resource to use to replace the Drawable on the
+ * target with the given resource id
+ * @param component of the .apk that contains the resource
+ * @param name of the metadata in the .apk
+ * @param existingResId the resource id of the target to search for
+ * @return true if found in the given package and replaced at least one target Drawables
+ */
+ public boolean replaceTargetDrawablesIfPresent(ComponentName component, String name,
+ int existingResId) {
+ if (existingResId == 0) return false;
+
+ boolean replaced = false;
+ if (component != null) {
+ try {
+ PackageManager packageManager = getContext().getPackageManager();
+ // Look for the search icon specified in the activity meta-data
+ Bundle metaData = packageManager.getActivityInfo(
+ component, PackageManager.GET_META_DATA).metaData;
+ if (metaData != null) {
+ int iconResId = metaData.getInt(name);
+ if (iconResId != 0) {
+ Resources res = packageManager.getResourcesForActivity(component);
+ replaced = replaceTargetDrawables(res, existingResId, iconResId);
+ }
+ }
+ } catch (NameNotFoundException e) {
+ Log.w(TAG, "Failed to swap drawable; "
+ + component.flattenToShortString() + " not found", e);
+ } catch (Resources.NotFoundException nfe) {
+ Log.w(TAG, "Failed to swap drawable from "
+ + component.flattenToShortString(), nfe);
+ }
+ }
+ if (!replaced) {
+ // Restore the original drawable
+ replaceTargetDrawables(getContext().getResources(), existingResId, existingResId);
+ }
+ return replaced;
+ }
+}
diff --git a/src/com/android/incallui/widget/multiwaveview/PointCloud.java b/src/com/android/incallui/widget/multiwaveview/PointCloud.java
new file mode 100644
index 00000000..77aac2bd
--- /dev/null
+++ b/src/com/android/incallui/widget/multiwaveview/PointCloud.java
@@ -0,0 +1,236 @@
+/*
+ * 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.incallui.widget.multiwaveview;
+
+import android.graphics.Canvas;
+import android.graphics.Color;
+import android.graphics.Paint;
+import android.graphics.drawable.Drawable;
+import android.util.FloatMath;
+import android.util.Log;
+
+import java.util.ArrayList;
+
+public class PointCloud {
+ private static final float MIN_POINT_SIZE = 2.0f;
+ private static final float MAX_POINT_SIZE = 4.0f;
+ private static final int INNER_POINTS = 8;
+ private static final String TAG = "PointCloud";
+ private ArrayList<Point> mPointCloud = new ArrayList<Point>();
+ private Drawable mDrawable;
+ private float mCenterX;
+ private float mCenterY;
+ private Paint mPaint;
+ private float mScale = 1.0f;
+ private static final float PI = (float) Math.PI;
+
+ // These allow us to have multiple concurrent animations.
+ WaveManager waveManager = new WaveManager();
+ GlowManager glowManager = new GlowManager();
+ private float mOuterRadius;
+
+ public class WaveManager {
+ private float radius = 50;
+ private float width = 200.0f; // TODO: Make configurable
+ private float alpha = 0.0f;
+ public void setRadius(float r) {
+ radius = r;
+ }
+
+ public float getRadius() {
+ return radius;
+ }
+
+ public void setAlpha(float a) {
+ alpha = a;
+ }
+
+ public float getAlpha() {
+ return alpha;
+ }
+ };
+
+ public class GlowManager {
+ private float x;
+ private float y;
+ private float radius = 0.0f;
+ private float alpha = 0.0f;
+
+ public void setX(float x1) {
+ x = x1;
+ }
+
+ public float getX() {
+ return x;
+ }
+
+ public void setY(float y1) {
+ y = y1;
+ }
+
+ public float getY() {
+ return y;
+ }
+
+ public void setAlpha(float a) {
+ alpha = a;
+ }
+
+ public float getAlpha() {
+ return alpha;
+ }
+
+ public void setRadius(float r) {
+ radius = r;
+ }
+
+ public float getRadius() {
+ return radius;
+ }
+ }
+
+ class Point {
+ float x;
+ float y;
+ float radius;
+
+ public Point(float x2, float y2, float r) {
+ x = (float) x2;
+ y = (float) y2;
+ radius = r;
+ }
+ }
+
+ public PointCloud(Drawable drawable) {
+ mPaint = new Paint();
+ mPaint.setFilterBitmap(true);
+ mPaint.setColor(Color.rgb(255, 255, 255)); // TODO: make configurable
+ mPaint.setAntiAlias(true);
+ mPaint.setDither(true);
+
+ mDrawable = drawable;
+ if (mDrawable != null) {
+ drawable.setBounds(0, 0, drawable.getIntrinsicWidth(), drawable.getIntrinsicHeight());
+ }
+ }
+
+ public void setCenter(float x, float y) {
+ mCenterX = x;
+ mCenterY = y;
+ }
+
+ public void makePointCloud(float innerRadius, float outerRadius) {
+ if (innerRadius == 0) {
+ Log.w(TAG, "Must specify an inner radius");
+ return;
+ }
+ mOuterRadius = outerRadius;
+ mPointCloud.clear();
+ final float pointAreaRadius = (outerRadius - innerRadius);
+ final float ds = (2.0f * PI * innerRadius / INNER_POINTS);
+ final int bands = (int) Math.round(pointAreaRadius / ds);
+ final float dr = pointAreaRadius / bands;
+ float r = innerRadius;
+ for (int b = 0; b <= bands; b++, r += dr) {
+ float circumference = 2.0f * PI * r;
+ final int pointsInBand = (int) (circumference / ds);
+ float eta = PI/2.0f;
+ float dEta = 2.0f * PI / pointsInBand;
+ for (int i = 0; i < pointsInBand; i++) {
+ float x = r * FloatMath.cos(eta);
+ float y = r * FloatMath.sin(eta);
+ eta += dEta;
+ mPointCloud.add(new Point(x, y, r));
+ }
+ }
+ }
+
+ public void setScale(float scale) {
+ mScale = scale;
+ }
+
+ public float getScale() {
+ return mScale;
+ }
+
+ private static float hypot(float x, float y) {
+ return FloatMath.sqrt(x*x + y*y);
+ }
+
+ private static float max(float a, float b) {
+ return a > b ? a : b;
+ }
+
+ public int getAlphaForPoint(Point point) {
+ // Contribution from positional glow
+ float glowDistance = hypot(glowManager.x - point.x, glowManager.y - point.y);
+ float glowAlpha = 0.0f;
+
+ if (glowDistance < glowManager.radius) {
+ float cosf = FloatMath.cos(PI * 0.25f * glowDistance / glowManager.radius);
+ glowAlpha = glowManager.alpha * max(0.0f, (float) Math.pow(cosf, 10.0f));
+ }
+
+ // Compute contribution from Wave
+ float radius = hypot(point.x, point.y);
+ float distanceToWaveRing = (radius - waveManager.radius);
+ float waveAlpha = 0.0f;
+ if (distanceToWaveRing < waveManager.width * 0.5f && distanceToWaveRing < 0.0f) {
+ float cosf = FloatMath.cos(PI * 0.25f * distanceToWaveRing / waveManager.width);
+ waveAlpha = waveManager.alpha * max(0.0f, (float) Math.pow(cosf, 20.0f));
+ }
+
+ return (int) (max(glowAlpha, waveAlpha) * 255);
+ }
+
+ private float interp(float min, float max, float f) {
+ return min + (max - min) * f;
+ }
+
+ public void draw(Canvas canvas) {
+ ArrayList<Point> points = mPointCloud;
+ canvas.save(Canvas.MATRIX_SAVE_FLAG);
+ canvas.scale(mScale, mScale, mCenterX, mCenterY);
+ for (int i = 0; i < points.size(); i++) {
+ Point point = points.get(i);
+ final float pointSize = interp(MAX_POINT_SIZE, MIN_POINT_SIZE,
+ point.radius / mOuterRadius);
+ final float px = point.x + mCenterX;
+ final float py = point.y + mCenterY;
+ int alpha = getAlphaForPoint(point);
+
+ if (alpha == 0) continue;
+
+ if (mDrawable != null) {
+ canvas.save(Canvas.MATRIX_SAVE_FLAG);
+ final float cx = mDrawable.getIntrinsicWidth() * 0.5f;
+ final float cy = mDrawable.getIntrinsicHeight() * 0.5f;
+ final float s = pointSize / MAX_POINT_SIZE;
+ canvas.scale(s, s, px, py);
+ canvas.translate(px - cx, py - cy);
+ mDrawable.setAlpha(alpha);
+ mDrawable.draw(canvas);
+ canvas.restore();
+ } else {
+ mPaint.setAlpha(alpha);
+ canvas.drawCircle(px, py, pointSize, mPaint);
+ }
+ }
+ canvas.restore();
+ }
+
+}
diff --git a/src/com/android/incallui/widget/multiwaveview/TargetDrawable.java b/src/com/android/incallui/widget/multiwaveview/TargetDrawable.java
new file mode 100644
index 00000000..d83a28c1
--- /dev/null
+++ b/src/com/android/incallui/widget/multiwaveview/TargetDrawable.java
@@ -0,0 +1,237 @@
+/*
+ * 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.incallui.widget.multiwaveview;
+
+import android.content.res.Resources;
+import android.graphics.Canvas;
+import android.graphics.ColorFilter;
+import android.graphics.drawable.Drawable;
+import android.graphics.drawable.StateListDrawable;
+import android.util.Log;
+
+public class TargetDrawable {
+ private static final String TAG = "TargetDrawable";
+ private static final boolean DEBUG = false;
+
+ public static final int[] STATE_ACTIVE =
+ { android.R.attr.state_enabled, android.R.attr.state_active };
+ public static final int[] STATE_INACTIVE =
+ { android.R.attr.state_enabled, -android.R.attr.state_active };
+ public static final int[] STATE_FOCUSED =
+ { android.R.attr.state_enabled, -android.R.attr.state_active,
+ android.R.attr.state_focused };
+
+ private float mTranslationX = 0.0f;
+ private float mTranslationY = 0.0f;
+ private float mPositionX = 0.0f;
+ private float mPositionY = 0.0f;
+ private float mScaleX = 1.0f;
+ private float mScaleY = 1.0f;
+ private float mAlpha = 1.0f;
+ private Drawable mDrawable;
+ private boolean mEnabled = true;
+ private final int mResourceId;
+ private int mNumDrawables = 1;
+
+ /**
+ * This is changed from the framework version to pass in the number of drawables in the
+ * container. The framework version relies on private api's to get the count from
+ * StateListDrawable.
+ *
+ * @param res
+ * @param resId
+ * @param count The number of drawables in the resource.
+ */
+ public TargetDrawable(Resources res, int resId, int count) {
+ mResourceId = resId;
+ setDrawable(res, resId);
+ mNumDrawables = count;
+ }
+
+ public void setDrawable(Resources res, int resId) {
+ // Note we explicitly don't set mResourceId to resId since we allow the drawable to be
+ // swapped at runtime and want to re-use the existing resource id for identification.
+ Drawable drawable = resId == 0 ? null : res.getDrawable(resId);
+ // Mutate the drawable so we can animate shared drawable properties.
+ mDrawable = drawable != null ? drawable.mutate() : null;
+ resizeDrawables();
+ setState(STATE_INACTIVE);
+ }
+
+ public TargetDrawable(TargetDrawable other) {
+ mResourceId = other.mResourceId;
+ // Mutate the drawable so we can animate shared drawable properties.
+ mDrawable = other.mDrawable != null ? other.mDrawable.mutate() : null;
+ resizeDrawables();
+ setState(STATE_INACTIVE);
+ }
+
+ public void setState(int [] state) {
+ if (mDrawable instanceof StateListDrawable) {
+ StateListDrawable d = (StateListDrawable) mDrawable;
+ d.setState(state);
+ }
+ }
+
+ /**
+ * Returns true if the drawable is a StateListDrawable and is in the focused state.
+ *
+ * @return
+ */
+ public boolean isActive() {
+ if (mDrawable instanceof StateListDrawable) {
+ StateListDrawable d = (StateListDrawable) mDrawable;
+ int[] states = d.getState();
+ for (int i = 0; i < states.length; i++) {
+ if (states[i] == android.R.attr.state_focused) {
+ return true;
+ }
+ }
+ }
+ return false;
+ }
+
+ /**
+ * Returns true if this target is enabled. Typically an enabled target contains a valid
+ * drawable in a valid state. Currently all targets with valid drawables are valid.
+ *
+ * @return
+ */
+ public boolean isEnabled() {
+ return mDrawable != null && mEnabled;
+ }
+
+ /**
+ * Makes drawables in a StateListDrawable all the same dimensions.
+ * If not a StateListDrawable, then justs sets the bounds to the intrinsic size of the
+ * drawable.
+ */
+ private void resizeDrawables() {
+ if (mDrawable instanceof StateListDrawable) {
+ StateListDrawable d = (StateListDrawable) mDrawable;
+ int maxWidth = 0;
+ int maxHeight = 0;
+
+ for (int i = 0; i < mNumDrawables; i++) {
+ d.selectDrawable(i);
+ Drawable childDrawable = d.getCurrent();
+ maxWidth = Math.max(maxWidth, childDrawable.getIntrinsicWidth());
+ maxHeight = Math.max(maxHeight, childDrawable.getIntrinsicHeight());
+ }
+
+ if (DEBUG) Log.v(TAG, "union of childDrawable rects " + d + " to: "
+ + maxWidth + "x" + maxHeight);
+ d.setBounds(0, 0, maxWidth, maxHeight);
+
+ for (int i = 0; i < mNumDrawables; i++) {
+ d.selectDrawable(i);
+ Drawable childDrawable = d.getCurrent();
+ if (DEBUG) Log.v(TAG, "sizing drawable " + childDrawable + " to: "
+ + maxWidth + "x" + maxHeight);
+ childDrawable.setBounds(0, 0, maxWidth, maxHeight);
+ }
+ } else if (mDrawable != null) {
+ mDrawable.setBounds(0, 0,
+ mDrawable.getIntrinsicWidth(), mDrawable.getIntrinsicHeight());
+ }
+ }
+
+ public void setX(float x) {
+ mTranslationX = x;
+ }
+
+ public void setY(float y) {
+ mTranslationY = y;
+ }
+
+ public void setScaleX(float x) {
+ mScaleX = x;
+ }
+
+ public void setScaleY(float y) {
+ mScaleY = y;
+ }
+
+ public void setAlpha(float alpha) {
+ mAlpha = alpha;
+ }
+
+ public float getX() {
+ return mTranslationX;
+ }
+
+ public float getY() {
+ return mTranslationY;
+ }
+
+ public float getScaleX() {
+ return mScaleX;
+ }
+
+ public float getScaleY() {
+ return mScaleY;
+ }
+
+ public float getAlpha() {
+ return mAlpha;
+ }
+
+ public void setPositionX(float x) {
+ mPositionX = x;
+ }
+
+ public void setPositionY(float y) {
+ mPositionY = y;
+ }
+
+ public float getPositionX() {
+ return mPositionX;
+ }
+
+ public float getPositionY() {
+ return mPositionY;
+ }
+
+ public int getWidth() {
+ return mDrawable != null ? mDrawable.getIntrinsicWidth() : 0;
+ }
+
+ public int getHeight() {
+ return mDrawable != null ? mDrawable.getIntrinsicHeight() : 0;
+ }
+
+ public void draw(Canvas canvas) {
+ if (mDrawable == null || !mEnabled) {
+ return;
+ }
+ canvas.save(Canvas.MATRIX_SAVE_FLAG);
+ canvas.scale(mScaleX, mScaleY, mPositionX, mPositionY);
+ canvas.translate(mTranslationX + mPositionX, mTranslationY + mPositionY);
+ canvas.translate(-0.5f * getWidth(), -0.5f * getHeight());
+ mDrawable.setAlpha((int) Math.round(mAlpha * 255f));
+ mDrawable.draw(canvas);
+ canvas.restore();
+ }
+
+ public void setEnabled(boolean enabled) {
+ mEnabled = enabled;
+ }
+
+ public int getResourceId() {
+ return mResourceId;
+ }
+}
diff --git a/src/com/android/incallui/widget/multiwaveview/Tweener.java b/src/com/android/incallui/widget/multiwaveview/Tweener.java
new file mode 100644
index 00000000..7222442f
--- /dev/null
+++ b/src/com/android/incallui/widget/multiwaveview/Tweener.java
@@ -0,0 +1,178 @@
+/*
+ * 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.incallui.widget.multiwaveview;
+
+import android.animation.Animator;
+import android.animation.Animator.AnimatorListener;
+import android.animation.AnimatorListenerAdapter;
+import android.animation.ObjectAnimator;
+import android.animation.PropertyValuesHolder;
+import android.animation.TimeInterpolator;
+import android.animation.ValueAnimator.AnimatorUpdateListener;
+import android.util.Log;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map.Entry;
+
+class Tweener {
+ private static final String TAG = "Tweener";
+ private static final boolean DEBUG = false;
+
+ ObjectAnimator animator;
+ private static HashMap<Object, Tweener> sTweens = new HashMap<Object, Tweener>();
+
+ public Tweener(ObjectAnimator anim) {
+ animator = anim;
+ }
+
+ private static void remove(Animator animator) {
+ Iterator<Entry<Object, Tweener>> iter = sTweens.entrySet().iterator();
+ while (iter.hasNext()) {
+ Entry<Object, Tweener> entry = iter.next();
+ if (entry.getValue().animator == animator) {
+ if (DEBUG) Log.v(TAG, "Removing tweener " + sTweens.get(entry.getKey())
+ + " sTweens.size() = " + sTweens.size());
+ iter.remove();
+ break; // an animator can only be attached to one object
+ }
+ }
+ }
+
+ public static Tweener to(Object object, long duration, Object... vars) {
+ long delay = 0;
+ AnimatorUpdateListener updateListener = null;
+ AnimatorListener listener = null;
+ TimeInterpolator interpolator = null;
+
+ // Iterate through arguments and discover properties to animate
+ ArrayList<PropertyValuesHolder> props = new ArrayList<PropertyValuesHolder>(vars.length/2);
+ for (int i = 0; i < vars.length; i+=2) {
+ if (!(vars[i] instanceof String)) {
+ throw new IllegalArgumentException("Key must be a string: " + vars[i]);
+ }
+ String key = (String) vars[i];
+ Object value = vars[i+1];
+
+ if ("simultaneousTween".equals(key)) {
+ // TODO
+ } else if ("ease".equals(key)) {
+ interpolator = (TimeInterpolator) value; // TODO: multiple interpolators?
+ } else if ("onUpdate".equals(key) || "onUpdateListener".equals(key)) {
+ updateListener = (AnimatorUpdateListener) value;
+ } else if ("onComplete".equals(key) || "onCompleteListener".equals(key)) {
+ listener = (AnimatorListener) value;
+ } else if ("delay".equals(key)) {
+ delay = ((Number) value).longValue();
+ } else if ("syncWith".equals(key)) {
+ // TODO
+ } else if (value instanceof float[]) {
+ props.add(PropertyValuesHolder.ofFloat(key,
+ ((float[])value)[0], ((float[])value)[1]));
+ } else if (value instanceof int[]) {
+ props.add(PropertyValuesHolder.ofInt(key,
+ ((int[])value)[0], ((int[])value)[1]));
+ } else if (value instanceof Number) {
+ float floatValue = ((Number)value).floatValue();
+ props.add(PropertyValuesHolder.ofFloat(key, floatValue));
+ } else {
+ throw new IllegalArgumentException(
+ "Bad argument for key \"" + key + "\" with value " + value.getClass());
+ }
+ }
+
+ // Re-use existing tween, if present
+ Tweener tween = sTweens.get(object);
+ ObjectAnimator anim = null;
+ if (tween == null) {
+ anim = ObjectAnimator.ofPropertyValuesHolder(object,
+ props.toArray(new PropertyValuesHolder[props.size()]));
+ tween = new Tweener(anim);
+ sTweens.put(object, tween);
+ if (DEBUG) Log.v(TAG, "Added new Tweener " + tween);
+ } else {
+ anim = sTweens.get(object).animator;
+ replace(props, object); // Cancel all animators for given object
+ }
+
+ if (interpolator != null) {
+ anim.setInterpolator(interpolator);
+ }
+
+ // Update animation with properties discovered in loop above
+ anim.setStartDelay(delay);
+ anim.setDuration(duration);
+ if (updateListener != null) {
+ anim.removeAllUpdateListeners(); // There should be only one
+ anim.addUpdateListener(updateListener);
+ }
+ if (listener != null) {
+ anim.removeAllListeners(); // There should be only one.
+ anim.addListener(listener);
+ }
+ anim.addListener(mCleanupListener);
+
+ return tween;
+ }
+
+ Tweener from(Object object, long duration, Object... vars) {
+ // TODO: for v of vars
+ // toVars[v] = object[v]
+ // object[v] = vars[v]
+ return Tweener.to(object, duration, vars);
+ }
+
+ // Listener to watch for completed animations and remove them.
+ private static AnimatorListener mCleanupListener = new AnimatorListenerAdapter() {
+
+ @Override
+ public void onAnimationEnd(Animator animation) {
+ remove(animation);
+ }
+
+ @Override
+ public void onAnimationCancel(Animator animation) {
+ remove(animation);
+ }
+ };
+
+ public static void reset() {
+ if (DEBUG) {
+ Log.v(TAG, "Reset()");
+ if (sTweens.size() > 0) {
+ Log.v(TAG, "Cleaning up " + sTweens.size() + " animations");
+ }
+ }
+ sTweens.clear();
+ }
+
+ private static void replace(ArrayList<PropertyValuesHolder> props, Object... args) {
+ for (final Object killobject : args) {
+ Tweener tween = sTweens.get(killobject);
+ if (tween != null) {
+ tween.animator.cancel();
+ if (props != null) {
+ tween.animator.setValues(
+ props.toArray(new PropertyValuesHolder[props.size()]));
+ } else {
+ sTweens.remove(tween);
+ }
+ }
+ }
+ }
+}