From a44c5910391e2c80f00a7873fca2032d08323eeb Mon Sep 17 00:00:00 2001 From: Chiao Cheng Date: Mon, 15 Jul 2013 14:54:27 -0700 Subject: Adding in call screen template. Along with glow pad for incoming call interaction.. Change-Id: I8d518b5247bee4a10c8fd06763a7e3fe6cff5652 --- InCallUI/Android.mk | 2 + InCallUI/AndroidManifest.xml | 17 +- InCallUI/proguard.flags | 3 + InCallUI/res/color/ota_title_color.xml | 21 + .../res/drawable-hdpi/dial_background_texture.png | Bin 0 -> 99 bytes InCallUI/res/drawable-hdpi/endcall_active.png | Bin 0 -> 326 bytes .../drawable-hdpi/endcall_background_texture.png | Bin 0 -> 99 bytes InCallUI/res/drawable-hdpi/endcall_disable.png | Bin 0 -> 325 bytes .../ic_active_state_dialer_holo_dark.png | Bin 0 -> 450 bytes .../res/drawable-hdpi/ic_add_contact_holo_dark.png | Bin 0 -> 1641 bytes InCallUI/res/drawable-hdpi/ic_dial_end_call.png | Bin 0 -> 3189 bytes .../res/drawable-hdpi/ic_dialpad_holo_dark.png | Bin 0 -> 1389 bytes .../res/drawable-hdpi/ic_hold_pause_holo_dark.png | Bin 0 -> 669 bytes .../ic_in_call_touch_handle_normal.png | Bin 0 -> 8731 bytes .../drawable-hdpi/ic_incall_switch_holo_dark.png | Bin 0 -> 1913 bytes .../ic_lockscreen_answer_activated.png | Bin 0 -> 1426 bytes .../drawable-hdpi/ic_lockscreen_answer_normal.png | Bin 0 -> 1754 bytes .../ic_lockscreen_decline_activated.png | Bin 0 -> 1416 bytes .../drawable-hdpi/ic_lockscreen_decline_normal.png | Bin 0 -> 1415 bytes .../drawable-hdpi/ic_lockscreen_text_activated.png | Bin 0 -> 1697 bytes .../drawable-hdpi/ic_lockscreen_text_normal.png | Bin 0 -> 1626 bytes InCallUI/res/drawable-hdpi/ic_merge_holo_dark.png | Bin 0 -> 1340 bytes .../drawable-hdpi/ic_more_indicator_holo_dark.png | Bin 0 -> 557 bytes InCallUI/res/drawable-hdpi/ic_mute_holo_dark.png | Bin 0 -> 1485 bytes .../drawable-hdpi/ic_sound_bluetooth_holo_dark.png | Bin 0 -> 1894 bytes .../drawable-hdpi/ic_sound_handset_holo_dark.png | Bin 0 -> 1547 bytes InCallUI/res/drawable-hdpi/ic_sound_holo_dark.png | Bin 0 -> 1996 bytes .../ic_sound_off_speakerphone_holo_dark.png | Bin 0 -> 1447 bytes .../ic_sound_speakerphone_holo_dark.png | Bin 0 -> 1953 bytes .../res/drawable-hdpi/ic_videocall_holo_dark.png | Bin 0 -> 1273 bytes InCallUI/res/drawable-hdpi/list_focused_holo.9.png | Bin 0 -> 159 bytes .../res/drawable-hdpi/list_pressed_holo_dark.9.png | Bin 0 -> 159 bytes .../list_selector_disabled_holo_dark.9.png | Bin 0 -> 189 bytes .../ic_add_contact_holo_dark.png | Bin 0 -> 6014 bytes .../ic_in_call_touch_handle_normal.png | Bin 0 -> 17691 bytes .../ic_lockscreen_answer_activated.png | Bin 0 -> 5620 bytes .../ic_lockscreen_answer_normal.png | Bin 0 -> 6121 bytes .../ic_lockscreen_text_activated.png | Bin 0 -> 5627 bytes .../ic_lockscreen_text_normal.png | Bin 0 -> 5475 bytes .../ic_more_indicator_holo_dark.png | Bin 0 -> 4465 bytes .../ic_sound_handset_holo_dark.png | Bin 0 -> 5759 bytes .../res/drawable-ldrtl-hdpi/ic_sound_holo_dark.png | Bin 0 -> 6515 bytes .../ic_sound_off_speakerphone_holo_dark.png | Bin 0 -> 5759 bytes .../ic_sound_speakerphone_holo_dark.png | Bin 0 -> 6370 bytes .../ic_add_contact_holo_dark.png | Bin 0 -> 5309 bytes .../ic_in_call_touch_handle_normal.png | Bin 0 -> 11291 bytes .../ic_lockscreen_answer_activated.png | Bin 0 -> 4987 bytes .../ic_lockscreen_answer_normal.png | Bin 0 -> 5408 bytes .../ic_lockscreen_text_activated.png | Bin 0 -> 5109 bytes .../ic_lockscreen_text_normal.png | Bin 0 -> 5053 bytes .../ic_more_indicator_holo_dark.png | Bin 0 -> 4278 bytes .../ic_sound_handset_holo_dark.png | Bin 0 -> 5127 bytes .../res/drawable-ldrtl-mdpi/ic_sound_holo_dark.png | Bin 0 -> 5376 bytes .../ic_sound_off_speakerphone_holo_dark.png | Bin 0 -> 5034 bytes .../ic_sound_speakerphone_holo_dark.png | Bin 0 -> 5406 bytes .../ic_add_contact_holo_dark.png | Bin 0 -> 6949 bytes .../ic_in_call_touch_handle_normal.png | Bin 0 -> 24706 bytes .../ic_lockscreen_answer_activated.png | Bin 0 -> 6245 bytes .../ic_lockscreen_answer_normal.png | Bin 0 -> 7047 bytes .../ic_lockscreen_text_activated.png | Bin 0 -> 6175 bytes .../ic_lockscreen_text_normal.png | Bin 0 -> 6010 bytes .../ic_more_indicator_holo_dark.png | Bin 0 -> 4667 bytes .../ic_sound_handset_holo_dark.png | Bin 0 -> 6711 bytes .../drawable-ldrtl-xhdpi/ic_sound_holo_dark.png | Bin 0 -> 7739 bytes .../ic_sound_off_speakerphone_holo_dark.png | Bin 0 -> 6604 bytes .../ic_sound_speakerphone_holo_dark.png | Bin 0 -> 7584 bytes .../res/drawable-mdpi/dial_background_texture.png | Bin 0 -> 91 bytes InCallUI/res/drawable-mdpi/endcall_active.png | Bin 0 -> 325 bytes .../drawable-mdpi/endcall_background_texture.png | Bin 0 -> 90 bytes InCallUI/res/drawable-mdpi/endcall_disable.png | Bin 0 -> 325 bytes .../ic_active_state_dialer_holo_dark.png | Bin 0 -> 409 bytes .../res/drawable-mdpi/ic_add_contact_holo_dark.png | Bin 0 -> 1160 bytes InCallUI/res/drawable-mdpi/ic_dial_end_call.png | Bin 0 -> 2484 bytes .../res/drawable-mdpi/ic_dialpad_holo_dark.png | Bin 0 -> 1095 bytes .../res/drawable-mdpi/ic_hold_pause_holo_dark.png | Bin 0 -> 492 bytes .../ic_in_call_touch_handle_normal.png | Bin 0 -> 4847 bytes .../drawable-mdpi/ic_incall_switch_holo_dark.png | Bin 0 -> 1246 bytes .../ic_lockscreen_answer_activated.png | Bin 0 -> 1075 bytes .../drawable-mdpi/ic_lockscreen_answer_normal.png | Bin 0 -> 1229 bytes .../ic_lockscreen_decline_activated.png | Bin 0 -> 1000 bytes .../drawable-mdpi/ic_lockscreen_decline_normal.png | Bin 0 -> 1015 bytes .../drawable-mdpi/ic_lockscreen_text_activated.png | Bin 0 -> 1256 bytes .../drawable-mdpi/ic_lockscreen_text_normal.png | Bin 0 -> 1219 bytes InCallUI/res/drawable-mdpi/ic_merge_holo_dark.png | Bin 0 -> 975 bytes .../drawable-mdpi/ic_more_indicator_holo_dark.png | Bin 0 -> 506 bytes InCallUI/res/drawable-mdpi/ic_mute_holo_dark.png | Bin 0 -> 1042 bytes .../drawable-mdpi/ic_sound_bluetooth_holo_dark.png | Bin 0 -> 1218 bytes .../drawable-mdpi/ic_sound_handset_holo_dark.png | Bin 0 -> 1067 bytes InCallUI/res/drawable-mdpi/ic_sound_holo_dark.png | Bin 0 -> 1251 bytes .../ic_sound_off_speakerphone_holo_dark.png | Bin 0 -> 996 bytes .../ic_sound_speakerphone_holo_dark.png | Bin 0 -> 1246 bytes .../res/drawable-mdpi/ic_videocall_holo_dark.png | Bin 0 -> 1177 bytes InCallUI/res/drawable-mdpi/list_focused_holo.9.png | Bin 0 -> 158 bytes .../res/drawable-mdpi/list_pressed_holo_dark.9.png | Bin 0 -> 158 bytes .../list_selector_disabled_holo_dark.9.png | Bin 0 -> 172 bytes .../res/drawable-xhdpi/dial_background_texture.png | Bin 0 -> 114 bytes InCallUI/res/drawable-xhdpi/endcall_active.png | Bin 0 -> 326 bytes .../drawable-xhdpi/endcall_background_texture.png | Bin 0 -> 114 bytes InCallUI/res/drawable-xhdpi/endcall_disable.png | Bin 0 -> 326 bytes .../ic_active_state_dialer_holo_dark.png | Bin 0 -> 499 bytes .../drawable-xhdpi/ic_add_contact_holo_dark.png | Bin 0 -> 2283 bytes InCallUI/res/drawable-xhdpi/ic_dial_end_call.png | Bin 0 -> 4593 bytes .../res/drawable-xhdpi/ic_dialpad_holo_dark.png | Bin 0 -> 1439 bytes .../res/drawable-xhdpi/ic_hold_pause_holo_dark.png | Bin 0 -> 495 bytes .../ic_in_call_touch_handle_normal.png | Bin 0 -> 12790 bytes .../drawable-xhdpi/ic_incall_switch_holo_dark.png | Bin 0 -> 2643 bytes .../ic_lockscreen_answer_activated.png | Bin 0 -> 1941 bytes .../drawable-xhdpi/ic_lockscreen_answer_normal.png | Bin 0 -> 2295 bytes .../ic_lockscreen_decline_activated.png | Bin 0 -> 1805 bytes .../ic_lockscreen_decline_normal.png | Bin 0 -> 1853 bytes .../ic_lockscreen_text_activated.png | Bin 0 -> 2116 bytes .../drawable-xhdpi/ic_lockscreen_text_normal.png | Bin 0 -> 2018 bytes InCallUI/res/drawable-xhdpi/ic_merge_holo_dark.png | Bin 0 -> 1840 bytes .../drawable-xhdpi/ic_more_indicator_holo_dark.png | Bin 0 -> 713 bytes InCallUI/res/drawable-xhdpi/ic_mute_holo_dark.png | Bin 0 -> 2205 bytes .../ic_sound_bluetooth_holo_dark.png | Bin 0 -> 2764 bytes .../drawable-xhdpi/ic_sound_handset_holo_dark.png | Bin 0 -> 2114 bytes InCallUI/res/drawable-xhdpi/ic_sound_holo_dark.png | Bin 0 -> 2827 bytes .../ic_sound_off_speakerphone_holo_dark.png | Bin 0 -> 1983 bytes .../ic_sound_speakerphone_holo_dark.png | Bin 0 -> 2780 bytes .../res/drawable-xhdpi/ic_videocall_holo_dark.png | Bin 0 -> 1339 bytes .../res/drawable-xhdpi/list_focused_holo.9.png | Bin 0 -> 163 bytes .../drawable-xhdpi/list_pressed_holo_dark.9.png | Bin 0 -> 163 bytes .../list_selector_disabled_holo_dark.9.png | Bin 0 -> 190 bytes InCallUI/res/drawable/btn_compound_audio.xml | 105 ++ InCallUI/res/drawable/btn_compound_background.xml | 34 + InCallUI/res/drawable/btn_compound_dialpad.xml | 30 + InCallUI/res/drawable/btn_compound_hold.xml | 30 + InCallUI/res/drawable/btn_compound_mute.xml | 30 + InCallUI/res/drawable/dialpad_background.xml | 19 + .../res/drawable/dialpad_background_opaque.xml | 30 + InCallUI/res/drawable/end_call_background.xml | 45 + InCallUI/res/drawable/ic_in_call_touch_handle.xml | 33 + InCallUI/res/drawable/ic_lockscreen_answer.xml | 27 + .../ic_lockscreen_answer_activated_layer.xml | 31 + .../drawable/ic_lockscreen_answer_normal_layer.xml | 32 + InCallUI/res/drawable/ic_lockscreen_decline.xml | 27 + .../ic_lockscreen_decline_activated_layer.xml | 31 + .../ic_lockscreen_decline_normal_layer.xml | 32 + InCallUI/res/drawable/ic_lockscreen_text.xml | 27 + .../ic_lockscreen_text_activated_layer.xml | 31 + .../drawable/ic_lockscreen_text_normal_layer.xml | 32 + .../drawable/list_selector_focused_and_checked.xml | 20 + InCallUI/res/layout/incall_screen.xml | 55 + InCallUI/res/layout/primary_call_info.xml | 213 +++ InCallUI/res/values/array.xml | 102 ++ InCallUI/res/values/attrs.xml | 101 ++ InCallUI/res/values/colors.xml | 37 + InCallUI/res/values/dimens.xml | 119 ++ InCallUI/res/values/strings.xml | 1412 +++++++++++++++++++- InCallUI/res/values/styles.xml | 144 ++ .../com/android/incallui/CallMonitorService.java | 5 +- .../src/com/android/incallui/InCallActivity.java | 208 +++ .../incallui/widget/multiwaveview/Ease.java | 132 ++ .../incallui/widget/multiwaveview/GlowPadView.java | 1261 +++++++++++++++++ .../incallui/widget/multiwaveview/PointCloud.java | 236 ++++ .../widget/multiwaveview/TargetDrawable.java | 237 ++++ .../incallui/widget/multiwaveview/Tweener.java | 178 +++ 158 files changed, 5113 insertions(+), 16 deletions(-) create mode 100644 InCallUI/proguard.flags create mode 100644 InCallUI/res/color/ota_title_color.xml create mode 100644 InCallUI/res/drawable-hdpi/dial_background_texture.png create mode 100644 InCallUI/res/drawable-hdpi/endcall_active.png create mode 100644 InCallUI/res/drawable-hdpi/endcall_background_texture.png create mode 100644 InCallUI/res/drawable-hdpi/endcall_disable.png create mode 100644 InCallUI/res/drawable-hdpi/ic_active_state_dialer_holo_dark.png create mode 100644 InCallUI/res/drawable-hdpi/ic_add_contact_holo_dark.png create mode 100644 InCallUI/res/drawable-hdpi/ic_dial_end_call.png create mode 100644 InCallUI/res/drawable-hdpi/ic_dialpad_holo_dark.png create mode 100644 InCallUI/res/drawable-hdpi/ic_hold_pause_holo_dark.png create mode 100644 InCallUI/res/drawable-hdpi/ic_in_call_touch_handle_normal.png create mode 100644 InCallUI/res/drawable-hdpi/ic_incall_switch_holo_dark.png create mode 100644 InCallUI/res/drawable-hdpi/ic_lockscreen_answer_activated.png create mode 100644 InCallUI/res/drawable-hdpi/ic_lockscreen_answer_normal.png create mode 100644 InCallUI/res/drawable-hdpi/ic_lockscreen_decline_activated.png create mode 100644 InCallUI/res/drawable-hdpi/ic_lockscreen_decline_normal.png create mode 100644 InCallUI/res/drawable-hdpi/ic_lockscreen_text_activated.png create mode 100644 InCallUI/res/drawable-hdpi/ic_lockscreen_text_normal.png create mode 100644 InCallUI/res/drawable-hdpi/ic_merge_holo_dark.png create mode 100644 InCallUI/res/drawable-hdpi/ic_more_indicator_holo_dark.png create mode 100644 InCallUI/res/drawable-hdpi/ic_mute_holo_dark.png create mode 100644 InCallUI/res/drawable-hdpi/ic_sound_bluetooth_holo_dark.png create mode 100644 InCallUI/res/drawable-hdpi/ic_sound_handset_holo_dark.png create mode 100644 InCallUI/res/drawable-hdpi/ic_sound_holo_dark.png create mode 100644 InCallUI/res/drawable-hdpi/ic_sound_off_speakerphone_holo_dark.png create mode 100644 InCallUI/res/drawable-hdpi/ic_sound_speakerphone_holo_dark.png create mode 100644 InCallUI/res/drawable-hdpi/ic_videocall_holo_dark.png create mode 100644 InCallUI/res/drawable-hdpi/list_focused_holo.9.png create mode 100644 InCallUI/res/drawable-hdpi/list_pressed_holo_dark.9.png create mode 100644 InCallUI/res/drawable-hdpi/list_selector_disabled_holo_dark.9.png create mode 100644 InCallUI/res/drawable-ldrtl-hdpi/ic_add_contact_holo_dark.png create mode 100644 InCallUI/res/drawable-ldrtl-hdpi/ic_in_call_touch_handle_normal.png create mode 100644 InCallUI/res/drawable-ldrtl-hdpi/ic_lockscreen_answer_activated.png create mode 100644 InCallUI/res/drawable-ldrtl-hdpi/ic_lockscreen_answer_normal.png create mode 100644 InCallUI/res/drawable-ldrtl-hdpi/ic_lockscreen_text_activated.png create mode 100644 InCallUI/res/drawable-ldrtl-hdpi/ic_lockscreen_text_normal.png create mode 100644 InCallUI/res/drawable-ldrtl-hdpi/ic_more_indicator_holo_dark.png create mode 100644 InCallUI/res/drawable-ldrtl-hdpi/ic_sound_handset_holo_dark.png create mode 100644 InCallUI/res/drawable-ldrtl-hdpi/ic_sound_holo_dark.png create mode 100644 InCallUI/res/drawable-ldrtl-hdpi/ic_sound_off_speakerphone_holo_dark.png create mode 100644 InCallUI/res/drawable-ldrtl-hdpi/ic_sound_speakerphone_holo_dark.png create mode 100644 InCallUI/res/drawable-ldrtl-mdpi/ic_add_contact_holo_dark.png create mode 100644 InCallUI/res/drawable-ldrtl-mdpi/ic_in_call_touch_handle_normal.png create mode 100644 InCallUI/res/drawable-ldrtl-mdpi/ic_lockscreen_answer_activated.png create mode 100644 InCallUI/res/drawable-ldrtl-mdpi/ic_lockscreen_answer_normal.png create mode 100644 InCallUI/res/drawable-ldrtl-mdpi/ic_lockscreen_text_activated.png create mode 100644 InCallUI/res/drawable-ldrtl-mdpi/ic_lockscreen_text_normal.png create mode 100644 InCallUI/res/drawable-ldrtl-mdpi/ic_more_indicator_holo_dark.png create mode 100644 InCallUI/res/drawable-ldrtl-mdpi/ic_sound_handset_holo_dark.png create mode 100644 InCallUI/res/drawable-ldrtl-mdpi/ic_sound_holo_dark.png create mode 100644 InCallUI/res/drawable-ldrtl-mdpi/ic_sound_off_speakerphone_holo_dark.png create mode 100644 InCallUI/res/drawable-ldrtl-mdpi/ic_sound_speakerphone_holo_dark.png create mode 100644 InCallUI/res/drawable-ldrtl-xhdpi/ic_add_contact_holo_dark.png create mode 100644 InCallUI/res/drawable-ldrtl-xhdpi/ic_in_call_touch_handle_normal.png create mode 100644 InCallUI/res/drawable-ldrtl-xhdpi/ic_lockscreen_answer_activated.png create mode 100644 InCallUI/res/drawable-ldrtl-xhdpi/ic_lockscreen_answer_normal.png create mode 100644 InCallUI/res/drawable-ldrtl-xhdpi/ic_lockscreen_text_activated.png create mode 100644 InCallUI/res/drawable-ldrtl-xhdpi/ic_lockscreen_text_normal.png create mode 100644 InCallUI/res/drawable-ldrtl-xhdpi/ic_more_indicator_holo_dark.png create mode 100644 InCallUI/res/drawable-ldrtl-xhdpi/ic_sound_handset_holo_dark.png create mode 100644 InCallUI/res/drawable-ldrtl-xhdpi/ic_sound_holo_dark.png create mode 100644 InCallUI/res/drawable-ldrtl-xhdpi/ic_sound_off_speakerphone_holo_dark.png create mode 100644 InCallUI/res/drawable-ldrtl-xhdpi/ic_sound_speakerphone_holo_dark.png create mode 100644 InCallUI/res/drawable-mdpi/dial_background_texture.png create mode 100644 InCallUI/res/drawable-mdpi/endcall_active.png create mode 100644 InCallUI/res/drawable-mdpi/endcall_background_texture.png create mode 100644 InCallUI/res/drawable-mdpi/endcall_disable.png create mode 100644 InCallUI/res/drawable-mdpi/ic_active_state_dialer_holo_dark.png create mode 100644 InCallUI/res/drawable-mdpi/ic_add_contact_holo_dark.png create mode 100644 InCallUI/res/drawable-mdpi/ic_dial_end_call.png create mode 100644 InCallUI/res/drawable-mdpi/ic_dialpad_holo_dark.png create mode 100644 InCallUI/res/drawable-mdpi/ic_hold_pause_holo_dark.png create mode 100644 InCallUI/res/drawable-mdpi/ic_in_call_touch_handle_normal.png create mode 100644 InCallUI/res/drawable-mdpi/ic_incall_switch_holo_dark.png create mode 100644 InCallUI/res/drawable-mdpi/ic_lockscreen_answer_activated.png create mode 100644 InCallUI/res/drawable-mdpi/ic_lockscreen_answer_normal.png create mode 100644 InCallUI/res/drawable-mdpi/ic_lockscreen_decline_activated.png create mode 100644 InCallUI/res/drawable-mdpi/ic_lockscreen_decline_normal.png create mode 100644 InCallUI/res/drawable-mdpi/ic_lockscreen_text_activated.png create mode 100644 InCallUI/res/drawable-mdpi/ic_lockscreen_text_normal.png create mode 100644 InCallUI/res/drawable-mdpi/ic_merge_holo_dark.png create mode 100644 InCallUI/res/drawable-mdpi/ic_more_indicator_holo_dark.png create mode 100644 InCallUI/res/drawable-mdpi/ic_mute_holo_dark.png create mode 100644 InCallUI/res/drawable-mdpi/ic_sound_bluetooth_holo_dark.png create mode 100644 InCallUI/res/drawable-mdpi/ic_sound_handset_holo_dark.png create mode 100644 InCallUI/res/drawable-mdpi/ic_sound_holo_dark.png create mode 100644 InCallUI/res/drawable-mdpi/ic_sound_off_speakerphone_holo_dark.png create mode 100644 InCallUI/res/drawable-mdpi/ic_sound_speakerphone_holo_dark.png create mode 100644 InCallUI/res/drawable-mdpi/ic_videocall_holo_dark.png create mode 100644 InCallUI/res/drawable-mdpi/list_focused_holo.9.png create mode 100644 InCallUI/res/drawable-mdpi/list_pressed_holo_dark.9.png create mode 100644 InCallUI/res/drawable-mdpi/list_selector_disabled_holo_dark.9.png create mode 100644 InCallUI/res/drawable-xhdpi/dial_background_texture.png create mode 100644 InCallUI/res/drawable-xhdpi/endcall_active.png create mode 100644 InCallUI/res/drawable-xhdpi/endcall_background_texture.png create mode 100644 InCallUI/res/drawable-xhdpi/endcall_disable.png create mode 100644 InCallUI/res/drawable-xhdpi/ic_active_state_dialer_holo_dark.png create mode 100644 InCallUI/res/drawable-xhdpi/ic_add_contact_holo_dark.png create mode 100644 InCallUI/res/drawable-xhdpi/ic_dial_end_call.png create mode 100644 InCallUI/res/drawable-xhdpi/ic_dialpad_holo_dark.png create mode 100644 InCallUI/res/drawable-xhdpi/ic_hold_pause_holo_dark.png create mode 100644 InCallUI/res/drawable-xhdpi/ic_in_call_touch_handle_normal.png create mode 100644 InCallUI/res/drawable-xhdpi/ic_incall_switch_holo_dark.png create mode 100644 InCallUI/res/drawable-xhdpi/ic_lockscreen_answer_activated.png create mode 100644 InCallUI/res/drawable-xhdpi/ic_lockscreen_answer_normal.png create mode 100644 InCallUI/res/drawable-xhdpi/ic_lockscreen_decline_activated.png create mode 100644 InCallUI/res/drawable-xhdpi/ic_lockscreen_decline_normal.png create mode 100644 InCallUI/res/drawable-xhdpi/ic_lockscreen_text_activated.png create mode 100644 InCallUI/res/drawable-xhdpi/ic_lockscreen_text_normal.png create mode 100644 InCallUI/res/drawable-xhdpi/ic_merge_holo_dark.png create mode 100644 InCallUI/res/drawable-xhdpi/ic_more_indicator_holo_dark.png create mode 100644 InCallUI/res/drawable-xhdpi/ic_mute_holo_dark.png create mode 100644 InCallUI/res/drawable-xhdpi/ic_sound_bluetooth_holo_dark.png create mode 100644 InCallUI/res/drawable-xhdpi/ic_sound_handset_holo_dark.png create mode 100644 InCallUI/res/drawable-xhdpi/ic_sound_holo_dark.png create mode 100644 InCallUI/res/drawable-xhdpi/ic_sound_off_speakerphone_holo_dark.png create mode 100644 InCallUI/res/drawable-xhdpi/ic_sound_speakerphone_holo_dark.png create mode 100644 InCallUI/res/drawable-xhdpi/ic_videocall_holo_dark.png create mode 100644 InCallUI/res/drawable-xhdpi/list_focused_holo.9.png create mode 100644 InCallUI/res/drawable-xhdpi/list_pressed_holo_dark.9.png create mode 100644 InCallUI/res/drawable-xhdpi/list_selector_disabled_holo_dark.9.png create mode 100644 InCallUI/res/drawable/btn_compound_audio.xml create mode 100644 InCallUI/res/drawable/btn_compound_background.xml create mode 100644 InCallUI/res/drawable/btn_compound_dialpad.xml create mode 100644 InCallUI/res/drawable/btn_compound_hold.xml create mode 100644 InCallUI/res/drawable/btn_compound_mute.xml create mode 100644 InCallUI/res/drawable/dialpad_background.xml create mode 100644 InCallUI/res/drawable/dialpad_background_opaque.xml create mode 100644 InCallUI/res/drawable/end_call_background.xml create mode 100644 InCallUI/res/drawable/ic_in_call_touch_handle.xml create mode 100644 InCallUI/res/drawable/ic_lockscreen_answer.xml create mode 100644 InCallUI/res/drawable/ic_lockscreen_answer_activated_layer.xml create mode 100644 InCallUI/res/drawable/ic_lockscreen_answer_normal_layer.xml create mode 100644 InCallUI/res/drawable/ic_lockscreen_decline.xml create mode 100644 InCallUI/res/drawable/ic_lockscreen_decline_activated_layer.xml create mode 100644 InCallUI/res/drawable/ic_lockscreen_decline_normal_layer.xml create mode 100644 InCallUI/res/drawable/ic_lockscreen_text.xml create mode 100644 InCallUI/res/drawable/ic_lockscreen_text_activated_layer.xml create mode 100644 InCallUI/res/drawable/ic_lockscreen_text_normal_layer.xml create mode 100644 InCallUI/res/drawable/list_selector_focused_and_checked.xml create mode 100644 InCallUI/res/layout/incall_screen.xml create mode 100644 InCallUI/res/layout/primary_call_info.xml create mode 100644 InCallUI/res/values/array.xml create mode 100644 InCallUI/res/values/attrs.xml create mode 100644 InCallUI/res/values/colors.xml create mode 100644 InCallUI/res/values/dimens.xml mode change 100644 => 100755 InCallUI/res/values/strings.xml create mode 100644 InCallUI/res/values/styles.xml create mode 100644 InCallUI/src/com/android/incallui/InCallActivity.java create mode 100644 InCallUI/src/com/android/incallui/widget/multiwaveview/Ease.java create mode 100644 InCallUI/src/com/android/incallui/widget/multiwaveview/GlowPadView.java create mode 100644 InCallUI/src/com/android/incallui/widget/multiwaveview/PointCloud.java create mode 100644 InCallUI/src/com/android/incallui/widget/multiwaveview/TargetDrawable.java create mode 100644 InCallUI/src/com/android/incallui/widget/multiwaveview/Tweener.java diff --git a/InCallUI/Android.mk b/InCallUI/Android.mk index 11a315a91..b716642b1 100644 --- a/InCallUI/Android.mk +++ b/InCallUI/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/InCallUI/AndroidManifest.xml b/InCallUI/AndroidManifest.xml index 4ab4868bc..24d548109 100644 --- a/InCallUI/AndroidManifest.xml +++ b/InCallUI/AndroidManifest.xml @@ -15,16 +15,31 @@ --> + + + + + + diff --git a/InCallUI/proguard.flags b/InCallUI/proguard.flags new file mode 100644 index 000000000..8fa10e0d1 --- /dev/null +++ b/InCallUI/proguard.flags @@ -0,0 +1,3 @@ +-keep class com.android.incallui.widget.multiwaveview.* { + *; +} diff --git a/InCallUI/res/color/ota_title_color.xml b/InCallUI/res/color/ota_title_color.xml new file mode 100644 index 000000000..14a283a6b --- /dev/null +++ b/InCallUI/res/color/ota_title_color.xml @@ -0,0 +1,21 @@ + + + + + + + diff --git a/InCallUI/res/drawable-hdpi/dial_background_texture.png b/InCallUI/res/drawable-hdpi/dial_background_texture.png new file mode 100644 index 000000000..9df3b1e75 Binary files /dev/null and b/InCallUI/res/drawable-hdpi/dial_background_texture.png differ diff --git a/InCallUI/res/drawable-hdpi/endcall_active.png b/InCallUI/res/drawable-hdpi/endcall_active.png new file mode 100644 index 000000000..38f1e1ce1 Binary files /dev/null and b/InCallUI/res/drawable-hdpi/endcall_active.png differ diff --git a/InCallUI/res/drawable-hdpi/endcall_background_texture.png b/InCallUI/res/drawable-hdpi/endcall_background_texture.png new file mode 100644 index 000000000..095b0b627 Binary files /dev/null and b/InCallUI/res/drawable-hdpi/endcall_background_texture.png differ diff --git a/InCallUI/res/drawable-hdpi/endcall_disable.png b/InCallUI/res/drawable-hdpi/endcall_disable.png new file mode 100644 index 000000000..6a0f65867 Binary files /dev/null and b/InCallUI/res/drawable-hdpi/endcall_disable.png differ diff --git a/InCallUI/res/drawable-hdpi/ic_active_state_dialer_holo_dark.png b/InCallUI/res/drawable-hdpi/ic_active_state_dialer_holo_dark.png new file mode 100644 index 000000000..f4a08bea0 Binary files /dev/null and b/InCallUI/res/drawable-hdpi/ic_active_state_dialer_holo_dark.png differ diff --git a/InCallUI/res/drawable-hdpi/ic_add_contact_holo_dark.png b/InCallUI/res/drawable-hdpi/ic_add_contact_holo_dark.png new file mode 100644 index 000000000..88ff33b3d Binary files /dev/null and b/InCallUI/res/drawable-hdpi/ic_add_contact_holo_dark.png differ diff --git a/InCallUI/res/drawable-hdpi/ic_dial_end_call.png b/InCallUI/res/drawable-hdpi/ic_dial_end_call.png new file mode 100644 index 000000000..ab3adb443 Binary files /dev/null and b/InCallUI/res/drawable-hdpi/ic_dial_end_call.png differ diff --git a/InCallUI/res/drawable-hdpi/ic_dialpad_holo_dark.png b/InCallUI/res/drawable-hdpi/ic_dialpad_holo_dark.png new file mode 100644 index 000000000..a0ab6c453 Binary files /dev/null and b/InCallUI/res/drawable-hdpi/ic_dialpad_holo_dark.png differ diff --git a/InCallUI/res/drawable-hdpi/ic_hold_pause_holo_dark.png b/InCallUI/res/drawable-hdpi/ic_hold_pause_holo_dark.png new file mode 100644 index 000000000..2b3ff3d3f Binary files /dev/null and b/InCallUI/res/drawable-hdpi/ic_hold_pause_holo_dark.png differ diff --git a/InCallUI/res/drawable-hdpi/ic_in_call_touch_handle_normal.png b/InCallUI/res/drawable-hdpi/ic_in_call_touch_handle_normal.png new file mode 100644 index 000000000..e85253489 Binary files /dev/null and b/InCallUI/res/drawable-hdpi/ic_in_call_touch_handle_normal.png differ diff --git a/InCallUI/res/drawable-hdpi/ic_incall_switch_holo_dark.png b/InCallUI/res/drawable-hdpi/ic_incall_switch_holo_dark.png new file mode 100644 index 000000000..429511bff Binary files /dev/null and b/InCallUI/res/drawable-hdpi/ic_incall_switch_holo_dark.png differ diff --git a/InCallUI/res/drawable-hdpi/ic_lockscreen_answer_activated.png b/InCallUI/res/drawable-hdpi/ic_lockscreen_answer_activated.png new file mode 100644 index 000000000..3d2752fa7 Binary files /dev/null and b/InCallUI/res/drawable-hdpi/ic_lockscreen_answer_activated.png differ diff --git a/InCallUI/res/drawable-hdpi/ic_lockscreen_answer_normal.png b/InCallUI/res/drawable-hdpi/ic_lockscreen_answer_normal.png new file mode 100644 index 000000000..9e26edaf5 Binary files /dev/null and b/InCallUI/res/drawable-hdpi/ic_lockscreen_answer_normal.png differ diff --git a/InCallUI/res/drawable-hdpi/ic_lockscreen_decline_activated.png b/InCallUI/res/drawable-hdpi/ic_lockscreen_decline_activated.png new file mode 100644 index 000000000..b7a438f2e Binary files /dev/null and b/InCallUI/res/drawable-hdpi/ic_lockscreen_decline_activated.png differ diff --git a/InCallUI/res/drawable-hdpi/ic_lockscreen_decline_normal.png b/InCallUI/res/drawable-hdpi/ic_lockscreen_decline_normal.png new file mode 100644 index 000000000..a687ae3ee Binary files /dev/null and b/InCallUI/res/drawable-hdpi/ic_lockscreen_decline_normal.png differ diff --git a/InCallUI/res/drawable-hdpi/ic_lockscreen_text_activated.png b/InCallUI/res/drawable-hdpi/ic_lockscreen_text_activated.png new file mode 100644 index 000000000..22cf07c5d Binary files /dev/null and b/InCallUI/res/drawable-hdpi/ic_lockscreen_text_activated.png differ diff --git a/InCallUI/res/drawable-hdpi/ic_lockscreen_text_normal.png b/InCallUI/res/drawable-hdpi/ic_lockscreen_text_normal.png new file mode 100644 index 000000000..db6c05d6c Binary files /dev/null and b/InCallUI/res/drawable-hdpi/ic_lockscreen_text_normal.png differ diff --git a/InCallUI/res/drawable-hdpi/ic_merge_holo_dark.png b/InCallUI/res/drawable-hdpi/ic_merge_holo_dark.png new file mode 100644 index 000000000..5069cbe74 Binary files /dev/null and b/InCallUI/res/drawable-hdpi/ic_merge_holo_dark.png differ diff --git a/InCallUI/res/drawable-hdpi/ic_more_indicator_holo_dark.png b/InCallUI/res/drawable-hdpi/ic_more_indicator_holo_dark.png new file mode 100644 index 000000000..554f7e9a7 Binary files /dev/null and b/InCallUI/res/drawable-hdpi/ic_more_indicator_holo_dark.png differ diff --git a/InCallUI/res/drawable-hdpi/ic_mute_holo_dark.png b/InCallUI/res/drawable-hdpi/ic_mute_holo_dark.png new file mode 100644 index 000000000..f17a2daa8 Binary files /dev/null and b/InCallUI/res/drawable-hdpi/ic_mute_holo_dark.png differ diff --git a/InCallUI/res/drawable-hdpi/ic_sound_bluetooth_holo_dark.png b/InCallUI/res/drawable-hdpi/ic_sound_bluetooth_holo_dark.png new file mode 100644 index 000000000..c7f2402dd Binary files /dev/null and b/InCallUI/res/drawable-hdpi/ic_sound_bluetooth_holo_dark.png differ diff --git a/InCallUI/res/drawable-hdpi/ic_sound_handset_holo_dark.png b/InCallUI/res/drawable-hdpi/ic_sound_handset_holo_dark.png new file mode 100644 index 000000000..288141a2a Binary files /dev/null and b/InCallUI/res/drawable-hdpi/ic_sound_handset_holo_dark.png differ diff --git a/InCallUI/res/drawable-hdpi/ic_sound_holo_dark.png b/InCallUI/res/drawable-hdpi/ic_sound_holo_dark.png new file mode 100644 index 000000000..08ee3e8fe Binary files /dev/null and b/InCallUI/res/drawable-hdpi/ic_sound_holo_dark.png differ diff --git a/InCallUI/res/drawable-hdpi/ic_sound_off_speakerphone_holo_dark.png b/InCallUI/res/drawable-hdpi/ic_sound_off_speakerphone_holo_dark.png new file mode 100644 index 000000000..6f12d52f9 Binary files /dev/null and b/InCallUI/res/drawable-hdpi/ic_sound_off_speakerphone_holo_dark.png differ diff --git a/InCallUI/res/drawable-hdpi/ic_sound_speakerphone_holo_dark.png b/InCallUI/res/drawable-hdpi/ic_sound_speakerphone_holo_dark.png new file mode 100644 index 000000000..eadd0cda6 Binary files /dev/null and b/InCallUI/res/drawable-hdpi/ic_sound_speakerphone_holo_dark.png differ diff --git a/InCallUI/res/drawable-hdpi/ic_videocall_holo_dark.png b/InCallUI/res/drawable-hdpi/ic_videocall_holo_dark.png new file mode 100644 index 000000000..7aa3222eb Binary files /dev/null and b/InCallUI/res/drawable-hdpi/ic_videocall_holo_dark.png differ diff --git a/InCallUI/res/drawable-hdpi/list_focused_holo.9.png b/InCallUI/res/drawable-hdpi/list_focused_holo.9.png new file mode 100644 index 000000000..516f5c739 Binary files /dev/null and b/InCallUI/res/drawable-hdpi/list_focused_holo.9.png differ diff --git a/InCallUI/res/drawable-hdpi/list_pressed_holo_dark.9.png b/InCallUI/res/drawable-hdpi/list_pressed_holo_dark.9.png new file mode 100644 index 000000000..5654cd694 Binary files /dev/null and b/InCallUI/res/drawable-hdpi/list_pressed_holo_dark.9.png differ diff --git a/InCallUI/res/drawable-hdpi/list_selector_disabled_holo_dark.9.png b/InCallUI/res/drawable-hdpi/list_selector_disabled_holo_dark.9.png new file mode 100644 index 000000000..f6fd30dcd Binary files /dev/null and b/InCallUI/res/drawable-hdpi/list_selector_disabled_holo_dark.9.png differ diff --git a/InCallUI/res/drawable-ldrtl-hdpi/ic_add_contact_holo_dark.png b/InCallUI/res/drawable-ldrtl-hdpi/ic_add_contact_holo_dark.png new file mode 100644 index 000000000..b6a1381a1 Binary files /dev/null and b/InCallUI/res/drawable-ldrtl-hdpi/ic_add_contact_holo_dark.png differ diff --git a/InCallUI/res/drawable-ldrtl-hdpi/ic_in_call_touch_handle_normal.png b/InCallUI/res/drawable-ldrtl-hdpi/ic_in_call_touch_handle_normal.png new file mode 100644 index 000000000..4a3628bef Binary files /dev/null and b/InCallUI/res/drawable-ldrtl-hdpi/ic_in_call_touch_handle_normal.png differ diff --git a/InCallUI/res/drawable-ldrtl-hdpi/ic_lockscreen_answer_activated.png b/InCallUI/res/drawable-ldrtl-hdpi/ic_lockscreen_answer_activated.png new file mode 100644 index 000000000..f1deb759b Binary files /dev/null and b/InCallUI/res/drawable-ldrtl-hdpi/ic_lockscreen_answer_activated.png differ diff --git a/InCallUI/res/drawable-ldrtl-hdpi/ic_lockscreen_answer_normal.png b/InCallUI/res/drawable-ldrtl-hdpi/ic_lockscreen_answer_normal.png new file mode 100644 index 000000000..3c23fe992 Binary files /dev/null and b/InCallUI/res/drawable-ldrtl-hdpi/ic_lockscreen_answer_normal.png differ diff --git a/InCallUI/res/drawable-ldrtl-hdpi/ic_lockscreen_text_activated.png b/InCallUI/res/drawable-ldrtl-hdpi/ic_lockscreen_text_activated.png new file mode 100644 index 000000000..63afb5e76 Binary files /dev/null and b/InCallUI/res/drawable-ldrtl-hdpi/ic_lockscreen_text_activated.png differ diff --git a/InCallUI/res/drawable-ldrtl-hdpi/ic_lockscreen_text_normal.png b/InCallUI/res/drawable-ldrtl-hdpi/ic_lockscreen_text_normal.png new file mode 100644 index 000000000..744303098 Binary files /dev/null and b/InCallUI/res/drawable-ldrtl-hdpi/ic_lockscreen_text_normal.png differ diff --git a/InCallUI/res/drawable-ldrtl-hdpi/ic_more_indicator_holo_dark.png b/InCallUI/res/drawable-ldrtl-hdpi/ic_more_indicator_holo_dark.png new file mode 100644 index 000000000..adb18aed0 Binary files /dev/null and b/InCallUI/res/drawable-ldrtl-hdpi/ic_more_indicator_holo_dark.png differ diff --git a/InCallUI/res/drawable-ldrtl-hdpi/ic_sound_handset_holo_dark.png b/InCallUI/res/drawable-ldrtl-hdpi/ic_sound_handset_holo_dark.png new file mode 100644 index 000000000..207d94180 Binary files /dev/null and b/InCallUI/res/drawable-ldrtl-hdpi/ic_sound_handset_holo_dark.png differ diff --git a/InCallUI/res/drawable-ldrtl-hdpi/ic_sound_holo_dark.png b/InCallUI/res/drawable-ldrtl-hdpi/ic_sound_holo_dark.png new file mode 100644 index 000000000..c2e8adbbf Binary files /dev/null and b/InCallUI/res/drawable-ldrtl-hdpi/ic_sound_holo_dark.png differ diff --git a/InCallUI/res/drawable-ldrtl-hdpi/ic_sound_off_speakerphone_holo_dark.png b/InCallUI/res/drawable-ldrtl-hdpi/ic_sound_off_speakerphone_holo_dark.png new file mode 100644 index 000000000..2f2b67456 Binary files /dev/null and b/InCallUI/res/drawable-ldrtl-hdpi/ic_sound_off_speakerphone_holo_dark.png differ diff --git a/InCallUI/res/drawable-ldrtl-hdpi/ic_sound_speakerphone_holo_dark.png b/InCallUI/res/drawable-ldrtl-hdpi/ic_sound_speakerphone_holo_dark.png new file mode 100644 index 000000000..135c7f3a0 Binary files /dev/null and b/InCallUI/res/drawable-ldrtl-hdpi/ic_sound_speakerphone_holo_dark.png differ diff --git a/InCallUI/res/drawable-ldrtl-mdpi/ic_add_contact_holo_dark.png b/InCallUI/res/drawable-ldrtl-mdpi/ic_add_contact_holo_dark.png new file mode 100644 index 000000000..72abb9177 Binary files /dev/null and b/InCallUI/res/drawable-ldrtl-mdpi/ic_add_contact_holo_dark.png differ diff --git a/InCallUI/res/drawable-ldrtl-mdpi/ic_in_call_touch_handle_normal.png b/InCallUI/res/drawable-ldrtl-mdpi/ic_in_call_touch_handle_normal.png new file mode 100644 index 000000000..13b2ecfb5 Binary files /dev/null and b/InCallUI/res/drawable-ldrtl-mdpi/ic_in_call_touch_handle_normal.png differ diff --git a/InCallUI/res/drawable-ldrtl-mdpi/ic_lockscreen_answer_activated.png b/InCallUI/res/drawable-ldrtl-mdpi/ic_lockscreen_answer_activated.png new file mode 100644 index 000000000..3d68ff923 Binary files /dev/null and b/InCallUI/res/drawable-ldrtl-mdpi/ic_lockscreen_answer_activated.png differ diff --git a/InCallUI/res/drawable-ldrtl-mdpi/ic_lockscreen_answer_normal.png b/InCallUI/res/drawable-ldrtl-mdpi/ic_lockscreen_answer_normal.png new file mode 100644 index 000000000..2a223ea06 Binary files /dev/null and b/InCallUI/res/drawable-ldrtl-mdpi/ic_lockscreen_answer_normal.png differ diff --git a/InCallUI/res/drawable-ldrtl-mdpi/ic_lockscreen_text_activated.png b/InCallUI/res/drawable-ldrtl-mdpi/ic_lockscreen_text_activated.png new file mode 100644 index 000000000..8e9c3b619 Binary files /dev/null and b/InCallUI/res/drawable-ldrtl-mdpi/ic_lockscreen_text_activated.png differ diff --git a/InCallUI/res/drawable-ldrtl-mdpi/ic_lockscreen_text_normal.png b/InCallUI/res/drawable-ldrtl-mdpi/ic_lockscreen_text_normal.png new file mode 100644 index 000000000..8d4cb28ad Binary files /dev/null and b/InCallUI/res/drawable-ldrtl-mdpi/ic_lockscreen_text_normal.png differ diff --git a/InCallUI/res/drawable-ldrtl-mdpi/ic_more_indicator_holo_dark.png b/InCallUI/res/drawable-ldrtl-mdpi/ic_more_indicator_holo_dark.png new file mode 100644 index 000000000..2de388f96 Binary files /dev/null and b/InCallUI/res/drawable-ldrtl-mdpi/ic_more_indicator_holo_dark.png differ diff --git a/InCallUI/res/drawable-ldrtl-mdpi/ic_sound_handset_holo_dark.png b/InCallUI/res/drawable-ldrtl-mdpi/ic_sound_handset_holo_dark.png new file mode 100644 index 000000000..6bf0e8d6d Binary files /dev/null and b/InCallUI/res/drawable-ldrtl-mdpi/ic_sound_handset_holo_dark.png differ diff --git a/InCallUI/res/drawable-ldrtl-mdpi/ic_sound_holo_dark.png b/InCallUI/res/drawable-ldrtl-mdpi/ic_sound_holo_dark.png new file mode 100644 index 000000000..561e8fab1 Binary files /dev/null and b/InCallUI/res/drawable-ldrtl-mdpi/ic_sound_holo_dark.png differ diff --git a/InCallUI/res/drawable-ldrtl-mdpi/ic_sound_off_speakerphone_holo_dark.png b/InCallUI/res/drawable-ldrtl-mdpi/ic_sound_off_speakerphone_holo_dark.png new file mode 100644 index 000000000..3f330acb6 Binary files /dev/null and b/InCallUI/res/drawable-ldrtl-mdpi/ic_sound_off_speakerphone_holo_dark.png differ diff --git a/InCallUI/res/drawable-ldrtl-mdpi/ic_sound_speakerphone_holo_dark.png b/InCallUI/res/drawable-ldrtl-mdpi/ic_sound_speakerphone_holo_dark.png new file mode 100644 index 000000000..6cf2e3c8b Binary files /dev/null and b/InCallUI/res/drawable-ldrtl-mdpi/ic_sound_speakerphone_holo_dark.png differ diff --git a/InCallUI/res/drawable-ldrtl-xhdpi/ic_add_contact_holo_dark.png b/InCallUI/res/drawable-ldrtl-xhdpi/ic_add_contact_holo_dark.png new file mode 100644 index 000000000..60068fd6e Binary files /dev/null and b/InCallUI/res/drawable-ldrtl-xhdpi/ic_add_contact_holo_dark.png differ diff --git a/InCallUI/res/drawable-ldrtl-xhdpi/ic_in_call_touch_handle_normal.png b/InCallUI/res/drawable-ldrtl-xhdpi/ic_in_call_touch_handle_normal.png new file mode 100644 index 000000000..c70795071 Binary files /dev/null and b/InCallUI/res/drawable-ldrtl-xhdpi/ic_in_call_touch_handle_normal.png differ diff --git a/InCallUI/res/drawable-ldrtl-xhdpi/ic_lockscreen_answer_activated.png b/InCallUI/res/drawable-ldrtl-xhdpi/ic_lockscreen_answer_activated.png new file mode 100644 index 000000000..1acdc5991 Binary files /dev/null and b/InCallUI/res/drawable-ldrtl-xhdpi/ic_lockscreen_answer_activated.png differ diff --git a/InCallUI/res/drawable-ldrtl-xhdpi/ic_lockscreen_answer_normal.png b/InCallUI/res/drawable-ldrtl-xhdpi/ic_lockscreen_answer_normal.png new file mode 100644 index 000000000..72c2afa5b Binary files /dev/null and b/InCallUI/res/drawable-ldrtl-xhdpi/ic_lockscreen_answer_normal.png differ diff --git a/InCallUI/res/drawable-ldrtl-xhdpi/ic_lockscreen_text_activated.png b/InCallUI/res/drawable-ldrtl-xhdpi/ic_lockscreen_text_activated.png new file mode 100644 index 000000000..d292a7f86 Binary files /dev/null and b/InCallUI/res/drawable-ldrtl-xhdpi/ic_lockscreen_text_activated.png differ diff --git a/InCallUI/res/drawable-ldrtl-xhdpi/ic_lockscreen_text_normal.png b/InCallUI/res/drawable-ldrtl-xhdpi/ic_lockscreen_text_normal.png new file mode 100644 index 000000000..8318590d1 Binary files /dev/null and b/InCallUI/res/drawable-ldrtl-xhdpi/ic_lockscreen_text_normal.png differ diff --git a/InCallUI/res/drawable-ldrtl-xhdpi/ic_more_indicator_holo_dark.png b/InCallUI/res/drawable-ldrtl-xhdpi/ic_more_indicator_holo_dark.png new file mode 100644 index 000000000..6fe45cd36 Binary files /dev/null and b/InCallUI/res/drawable-ldrtl-xhdpi/ic_more_indicator_holo_dark.png differ diff --git a/InCallUI/res/drawable-ldrtl-xhdpi/ic_sound_handset_holo_dark.png b/InCallUI/res/drawable-ldrtl-xhdpi/ic_sound_handset_holo_dark.png new file mode 100644 index 000000000..1c1f1ad56 Binary files /dev/null and b/InCallUI/res/drawable-ldrtl-xhdpi/ic_sound_handset_holo_dark.png differ diff --git a/InCallUI/res/drawable-ldrtl-xhdpi/ic_sound_holo_dark.png b/InCallUI/res/drawable-ldrtl-xhdpi/ic_sound_holo_dark.png new file mode 100644 index 000000000..ac38205d1 Binary files /dev/null and b/InCallUI/res/drawable-ldrtl-xhdpi/ic_sound_holo_dark.png differ diff --git a/InCallUI/res/drawable-ldrtl-xhdpi/ic_sound_off_speakerphone_holo_dark.png b/InCallUI/res/drawable-ldrtl-xhdpi/ic_sound_off_speakerphone_holo_dark.png new file mode 100644 index 000000000..5bc066abb Binary files /dev/null and b/InCallUI/res/drawable-ldrtl-xhdpi/ic_sound_off_speakerphone_holo_dark.png differ diff --git a/InCallUI/res/drawable-ldrtl-xhdpi/ic_sound_speakerphone_holo_dark.png b/InCallUI/res/drawable-ldrtl-xhdpi/ic_sound_speakerphone_holo_dark.png new file mode 100644 index 000000000..3999712a5 Binary files /dev/null and b/InCallUI/res/drawable-ldrtl-xhdpi/ic_sound_speakerphone_holo_dark.png differ diff --git a/InCallUI/res/drawable-mdpi/dial_background_texture.png b/InCallUI/res/drawable-mdpi/dial_background_texture.png new file mode 100644 index 000000000..90cd07c02 Binary files /dev/null and b/InCallUI/res/drawable-mdpi/dial_background_texture.png differ diff --git a/InCallUI/res/drawable-mdpi/endcall_active.png b/InCallUI/res/drawable-mdpi/endcall_active.png new file mode 100644 index 000000000..a82738bfc Binary files /dev/null and b/InCallUI/res/drawable-mdpi/endcall_active.png differ diff --git a/InCallUI/res/drawable-mdpi/endcall_background_texture.png b/InCallUI/res/drawable-mdpi/endcall_background_texture.png new file mode 100644 index 000000000..efa65025f Binary files /dev/null and b/InCallUI/res/drawable-mdpi/endcall_background_texture.png differ diff --git a/InCallUI/res/drawable-mdpi/endcall_disable.png b/InCallUI/res/drawable-mdpi/endcall_disable.png new file mode 100644 index 000000000..bd1a2f380 Binary files /dev/null and b/InCallUI/res/drawable-mdpi/endcall_disable.png differ diff --git a/InCallUI/res/drawable-mdpi/ic_active_state_dialer_holo_dark.png b/InCallUI/res/drawable-mdpi/ic_active_state_dialer_holo_dark.png new file mode 100644 index 000000000..6ff8e4844 Binary files /dev/null and b/InCallUI/res/drawable-mdpi/ic_active_state_dialer_holo_dark.png differ diff --git a/InCallUI/res/drawable-mdpi/ic_add_contact_holo_dark.png b/InCallUI/res/drawable-mdpi/ic_add_contact_holo_dark.png new file mode 100644 index 000000000..867f494bc Binary files /dev/null and b/InCallUI/res/drawable-mdpi/ic_add_contact_holo_dark.png differ diff --git a/InCallUI/res/drawable-mdpi/ic_dial_end_call.png b/InCallUI/res/drawable-mdpi/ic_dial_end_call.png new file mode 100644 index 000000000..c47664226 Binary files /dev/null and b/InCallUI/res/drawable-mdpi/ic_dial_end_call.png differ diff --git a/InCallUI/res/drawable-mdpi/ic_dialpad_holo_dark.png b/InCallUI/res/drawable-mdpi/ic_dialpad_holo_dark.png new file mode 100644 index 000000000..b57fcf344 Binary files /dev/null and b/InCallUI/res/drawable-mdpi/ic_dialpad_holo_dark.png differ diff --git a/InCallUI/res/drawable-mdpi/ic_hold_pause_holo_dark.png b/InCallUI/res/drawable-mdpi/ic_hold_pause_holo_dark.png new file mode 100644 index 000000000..7d550de17 Binary files /dev/null and b/InCallUI/res/drawable-mdpi/ic_hold_pause_holo_dark.png differ diff --git a/InCallUI/res/drawable-mdpi/ic_in_call_touch_handle_normal.png b/InCallUI/res/drawable-mdpi/ic_in_call_touch_handle_normal.png new file mode 100644 index 000000000..cebdc4dee Binary files /dev/null and b/InCallUI/res/drawable-mdpi/ic_in_call_touch_handle_normal.png differ diff --git a/InCallUI/res/drawable-mdpi/ic_incall_switch_holo_dark.png b/InCallUI/res/drawable-mdpi/ic_incall_switch_holo_dark.png new file mode 100644 index 000000000..5b35ef1c0 Binary files /dev/null and b/InCallUI/res/drawable-mdpi/ic_incall_switch_holo_dark.png differ diff --git a/InCallUI/res/drawable-mdpi/ic_lockscreen_answer_activated.png b/InCallUI/res/drawable-mdpi/ic_lockscreen_answer_activated.png new file mode 100644 index 000000000..6a78f817e Binary files /dev/null and b/InCallUI/res/drawable-mdpi/ic_lockscreen_answer_activated.png differ diff --git a/InCallUI/res/drawable-mdpi/ic_lockscreen_answer_normal.png b/InCallUI/res/drawable-mdpi/ic_lockscreen_answer_normal.png new file mode 100644 index 000000000..da15c33c7 Binary files /dev/null and b/InCallUI/res/drawable-mdpi/ic_lockscreen_answer_normal.png differ diff --git a/InCallUI/res/drawable-mdpi/ic_lockscreen_decline_activated.png b/InCallUI/res/drawable-mdpi/ic_lockscreen_decline_activated.png new file mode 100644 index 000000000..649662681 Binary files /dev/null and b/InCallUI/res/drawable-mdpi/ic_lockscreen_decline_activated.png differ diff --git a/InCallUI/res/drawable-mdpi/ic_lockscreen_decline_normal.png b/InCallUI/res/drawable-mdpi/ic_lockscreen_decline_normal.png new file mode 100644 index 000000000..27fe09306 Binary files /dev/null and b/InCallUI/res/drawable-mdpi/ic_lockscreen_decline_normal.png differ diff --git a/InCallUI/res/drawable-mdpi/ic_lockscreen_text_activated.png b/InCallUI/res/drawable-mdpi/ic_lockscreen_text_activated.png new file mode 100644 index 000000000..e3e4fc13d Binary files /dev/null and b/InCallUI/res/drawable-mdpi/ic_lockscreen_text_activated.png differ diff --git a/InCallUI/res/drawable-mdpi/ic_lockscreen_text_normal.png b/InCallUI/res/drawable-mdpi/ic_lockscreen_text_normal.png new file mode 100644 index 000000000..4a2a54b01 Binary files /dev/null and b/InCallUI/res/drawable-mdpi/ic_lockscreen_text_normal.png differ diff --git a/InCallUI/res/drawable-mdpi/ic_merge_holo_dark.png b/InCallUI/res/drawable-mdpi/ic_merge_holo_dark.png new file mode 100644 index 000000000..bd34defc0 Binary files /dev/null and b/InCallUI/res/drawable-mdpi/ic_merge_holo_dark.png differ diff --git a/InCallUI/res/drawable-mdpi/ic_more_indicator_holo_dark.png b/InCallUI/res/drawable-mdpi/ic_more_indicator_holo_dark.png new file mode 100644 index 000000000..27b6d33e9 Binary files /dev/null and b/InCallUI/res/drawable-mdpi/ic_more_indicator_holo_dark.png differ diff --git a/InCallUI/res/drawable-mdpi/ic_mute_holo_dark.png b/InCallUI/res/drawable-mdpi/ic_mute_holo_dark.png new file mode 100644 index 000000000..801d1e0ec Binary files /dev/null and b/InCallUI/res/drawable-mdpi/ic_mute_holo_dark.png differ diff --git a/InCallUI/res/drawable-mdpi/ic_sound_bluetooth_holo_dark.png b/InCallUI/res/drawable-mdpi/ic_sound_bluetooth_holo_dark.png new file mode 100644 index 000000000..c0e95cbeb Binary files /dev/null and b/InCallUI/res/drawable-mdpi/ic_sound_bluetooth_holo_dark.png differ diff --git a/InCallUI/res/drawable-mdpi/ic_sound_handset_holo_dark.png b/InCallUI/res/drawable-mdpi/ic_sound_handset_holo_dark.png new file mode 100644 index 000000000..e5fce5754 Binary files /dev/null and b/InCallUI/res/drawable-mdpi/ic_sound_handset_holo_dark.png differ diff --git a/InCallUI/res/drawable-mdpi/ic_sound_holo_dark.png b/InCallUI/res/drawable-mdpi/ic_sound_holo_dark.png new file mode 100644 index 000000000..060f926d3 Binary files /dev/null and b/InCallUI/res/drawable-mdpi/ic_sound_holo_dark.png differ diff --git a/InCallUI/res/drawable-mdpi/ic_sound_off_speakerphone_holo_dark.png b/InCallUI/res/drawable-mdpi/ic_sound_off_speakerphone_holo_dark.png new file mode 100644 index 000000000..adaff6052 Binary files /dev/null and b/InCallUI/res/drawable-mdpi/ic_sound_off_speakerphone_holo_dark.png differ diff --git a/InCallUI/res/drawable-mdpi/ic_sound_speakerphone_holo_dark.png b/InCallUI/res/drawable-mdpi/ic_sound_speakerphone_holo_dark.png new file mode 100644 index 000000000..2b9600b7f Binary files /dev/null and b/InCallUI/res/drawable-mdpi/ic_sound_speakerphone_holo_dark.png differ diff --git a/InCallUI/res/drawable-mdpi/ic_videocall_holo_dark.png b/InCallUI/res/drawable-mdpi/ic_videocall_holo_dark.png new file mode 100644 index 000000000..776d27a40 Binary files /dev/null and b/InCallUI/res/drawable-mdpi/ic_videocall_holo_dark.png differ diff --git a/InCallUI/res/drawable-mdpi/list_focused_holo.9.png b/InCallUI/res/drawable-mdpi/list_focused_holo.9.png new file mode 100644 index 000000000..7c0599e3a Binary files /dev/null and b/InCallUI/res/drawable-mdpi/list_focused_holo.9.png differ diff --git a/InCallUI/res/drawable-mdpi/list_pressed_holo_dark.9.png b/InCallUI/res/drawable-mdpi/list_pressed_holo_dark.9.png new file mode 100644 index 000000000..6e77525d2 Binary files /dev/null and b/InCallUI/res/drawable-mdpi/list_pressed_holo_dark.9.png differ diff --git a/InCallUI/res/drawable-mdpi/list_selector_disabled_holo_dark.9.png b/InCallUI/res/drawable-mdpi/list_selector_disabled_holo_dark.9.png new file mode 100644 index 000000000..92da2f0dd Binary files /dev/null and b/InCallUI/res/drawable-mdpi/list_selector_disabled_holo_dark.9.png differ diff --git a/InCallUI/res/drawable-xhdpi/dial_background_texture.png b/InCallUI/res/drawable-xhdpi/dial_background_texture.png new file mode 100644 index 000000000..02aacc87d Binary files /dev/null and b/InCallUI/res/drawable-xhdpi/dial_background_texture.png differ diff --git a/InCallUI/res/drawable-xhdpi/endcall_active.png b/InCallUI/res/drawable-xhdpi/endcall_active.png new file mode 100644 index 000000000..5347ed29e Binary files /dev/null and b/InCallUI/res/drawable-xhdpi/endcall_active.png differ diff --git a/InCallUI/res/drawable-xhdpi/endcall_background_texture.png b/InCallUI/res/drawable-xhdpi/endcall_background_texture.png new file mode 100644 index 000000000..c94eeeceb Binary files /dev/null and b/InCallUI/res/drawable-xhdpi/endcall_background_texture.png differ diff --git a/InCallUI/res/drawable-xhdpi/endcall_disable.png b/InCallUI/res/drawable-xhdpi/endcall_disable.png new file mode 100644 index 000000000..fa10196c7 Binary files /dev/null and b/InCallUI/res/drawable-xhdpi/endcall_disable.png differ diff --git a/InCallUI/res/drawable-xhdpi/ic_active_state_dialer_holo_dark.png b/InCallUI/res/drawable-xhdpi/ic_active_state_dialer_holo_dark.png new file mode 100644 index 000000000..0211d69b9 Binary files /dev/null and b/InCallUI/res/drawable-xhdpi/ic_active_state_dialer_holo_dark.png differ diff --git a/InCallUI/res/drawable-xhdpi/ic_add_contact_holo_dark.png b/InCallUI/res/drawable-xhdpi/ic_add_contact_holo_dark.png new file mode 100644 index 000000000..729888234 Binary files /dev/null and b/InCallUI/res/drawable-xhdpi/ic_add_contact_holo_dark.png differ diff --git a/InCallUI/res/drawable-xhdpi/ic_dial_end_call.png b/InCallUI/res/drawable-xhdpi/ic_dial_end_call.png new file mode 100644 index 000000000..c24ec9872 Binary files /dev/null and b/InCallUI/res/drawable-xhdpi/ic_dial_end_call.png differ diff --git a/InCallUI/res/drawable-xhdpi/ic_dialpad_holo_dark.png b/InCallUI/res/drawable-xhdpi/ic_dialpad_holo_dark.png new file mode 100644 index 000000000..f9a002c79 Binary files /dev/null and b/InCallUI/res/drawable-xhdpi/ic_dialpad_holo_dark.png differ diff --git a/InCallUI/res/drawable-xhdpi/ic_hold_pause_holo_dark.png b/InCallUI/res/drawable-xhdpi/ic_hold_pause_holo_dark.png new file mode 100644 index 000000000..d2966755d Binary files /dev/null and b/InCallUI/res/drawable-xhdpi/ic_hold_pause_holo_dark.png differ diff --git a/InCallUI/res/drawable-xhdpi/ic_in_call_touch_handle_normal.png b/InCallUI/res/drawable-xhdpi/ic_in_call_touch_handle_normal.png new file mode 100644 index 000000000..1d112f2aa Binary files /dev/null and b/InCallUI/res/drawable-xhdpi/ic_in_call_touch_handle_normal.png differ diff --git a/InCallUI/res/drawable-xhdpi/ic_incall_switch_holo_dark.png b/InCallUI/res/drawable-xhdpi/ic_incall_switch_holo_dark.png new file mode 100644 index 000000000..9168c32de Binary files /dev/null and b/InCallUI/res/drawable-xhdpi/ic_incall_switch_holo_dark.png differ diff --git a/InCallUI/res/drawable-xhdpi/ic_lockscreen_answer_activated.png b/InCallUI/res/drawable-xhdpi/ic_lockscreen_answer_activated.png new file mode 100644 index 000000000..cd6a6abb2 Binary files /dev/null and b/InCallUI/res/drawable-xhdpi/ic_lockscreen_answer_activated.png differ diff --git a/InCallUI/res/drawable-xhdpi/ic_lockscreen_answer_normal.png b/InCallUI/res/drawable-xhdpi/ic_lockscreen_answer_normal.png new file mode 100644 index 000000000..983d5d941 Binary files /dev/null and b/InCallUI/res/drawable-xhdpi/ic_lockscreen_answer_normal.png differ diff --git a/InCallUI/res/drawable-xhdpi/ic_lockscreen_decline_activated.png b/InCallUI/res/drawable-xhdpi/ic_lockscreen_decline_activated.png new file mode 100644 index 000000000..317b3296c Binary files /dev/null and b/InCallUI/res/drawable-xhdpi/ic_lockscreen_decline_activated.png differ diff --git a/InCallUI/res/drawable-xhdpi/ic_lockscreen_decline_normal.png b/InCallUI/res/drawable-xhdpi/ic_lockscreen_decline_normal.png new file mode 100644 index 000000000..2cb03e7b1 Binary files /dev/null and b/InCallUI/res/drawable-xhdpi/ic_lockscreen_decline_normal.png differ diff --git a/InCallUI/res/drawable-xhdpi/ic_lockscreen_text_activated.png b/InCallUI/res/drawable-xhdpi/ic_lockscreen_text_activated.png new file mode 100644 index 000000000..41ea18af0 Binary files /dev/null and b/InCallUI/res/drawable-xhdpi/ic_lockscreen_text_activated.png differ diff --git a/InCallUI/res/drawable-xhdpi/ic_lockscreen_text_normal.png b/InCallUI/res/drawable-xhdpi/ic_lockscreen_text_normal.png new file mode 100644 index 000000000..15e477934 Binary files /dev/null and b/InCallUI/res/drawable-xhdpi/ic_lockscreen_text_normal.png differ diff --git a/InCallUI/res/drawable-xhdpi/ic_merge_holo_dark.png b/InCallUI/res/drawable-xhdpi/ic_merge_holo_dark.png new file mode 100644 index 000000000..57baa20a1 Binary files /dev/null and b/InCallUI/res/drawable-xhdpi/ic_merge_holo_dark.png differ diff --git a/InCallUI/res/drawable-xhdpi/ic_more_indicator_holo_dark.png b/InCallUI/res/drawable-xhdpi/ic_more_indicator_holo_dark.png new file mode 100644 index 000000000..3d9897a1b Binary files /dev/null and b/InCallUI/res/drawable-xhdpi/ic_more_indicator_holo_dark.png differ diff --git a/InCallUI/res/drawable-xhdpi/ic_mute_holo_dark.png b/InCallUI/res/drawable-xhdpi/ic_mute_holo_dark.png new file mode 100644 index 000000000..a882a760f Binary files /dev/null and b/InCallUI/res/drawable-xhdpi/ic_mute_holo_dark.png differ diff --git a/InCallUI/res/drawable-xhdpi/ic_sound_bluetooth_holo_dark.png b/InCallUI/res/drawable-xhdpi/ic_sound_bluetooth_holo_dark.png new file mode 100644 index 000000000..867d87da9 Binary files /dev/null and b/InCallUI/res/drawable-xhdpi/ic_sound_bluetooth_holo_dark.png differ diff --git a/InCallUI/res/drawable-xhdpi/ic_sound_handset_holo_dark.png b/InCallUI/res/drawable-xhdpi/ic_sound_handset_holo_dark.png new file mode 100644 index 000000000..42e19bd95 Binary files /dev/null and b/InCallUI/res/drawable-xhdpi/ic_sound_handset_holo_dark.png differ diff --git a/InCallUI/res/drawable-xhdpi/ic_sound_holo_dark.png b/InCallUI/res/drawable-xhdpi/ic_sound_holo_dark.png new file mode 100644 index 000000000..aa2a5af1f Binary files /dev/null and b/InCallUI/res/drawable-xhdpi/ic_sound_holo_dark.png differ diff --git a/InCallUI/res/drawable-xhdpi/ic_sound_off_speakerphone_holo_dark.png b/InCallUI/res/drawable-xhdpi/ic_sound_off_speakerphone_holo_dark.png new file mode 100644 index 000000000..98a449fde Binary files /dev/null and b/InCallUI/res/drawable-xhdpi/ic_sound_off_speakerphone_holo_dark.png differ diff --git a/InCallUI/res/drawable-xhdpi/ic_sound_speakerphone_holo_dark.png b/InCallUI/res/drawable-xhdpi/ic_sound_speakerphone_holo_dark.png new file mode 100644 index 000000000..71aad9759 Binary files /dev/null and b/InCallUI/res/drawable-xhdpi/ic_sound_speakerphone_holo_dark.png differ diff --git a/InCallUI/res/drawable-xhdpi/ic_videocall_holo_dark.png b/InCallUI/res/drawable-xhdpi/ic_videocall_holo_dark.png new file mode 100644 index 000000000..2b7dcab95 Binary files /dev/null and b/InCallUI/res/drawable-xhdpi/ic_videocall_holo_dark.png differ diff --git a/InCallUI/res/drawable-xhdpi/list_focused_holo.9.png b/InCallUI/res/drawable-xhdpi/list_focused_holo.9.png new file mode 100644 index 000000000..690cb1eb6 Binary files /dev/null and b/InCallUI/res/drawable-xhdpi/list_focused_holo.9.png differ diff --git a/InCallUI/res/drawable-xhdpi/list_pressed_holo_dark.9.png b/InCallUI/res/drawable-xhdpi/list_pressed_holo_dark.9.png new file mode 100644 index 000000000..e4b33935a Binary files /dev/null and b/InCallUI/res/drawable-xhdpi/list_pressed_holo_dark.9.png differ diff --git a/InCallUI/res/drawable-xhdpi/list_selector_disabled_holo_dark.9.png b/InCallUI/res/drawable-xhdpi/list_selector_disabled_holo_dark.9.png new file mode 100644 index 000000000..88726b691 Binary files /dev/null and b/InCallUI/res/drawable-xhdpi/list_selector_disabled_holo_dark.9.png differ diff --git a/InCallUI/res/drawable/btn_compound_audio.xml b/InCallUI/res/drawable/btn_compound_audio.xml new file mode 100644 index 000000000..c348c98c1 --- /dev/null +++ b/InCallUI/res/drawable/btn_compound_audio.xml @@ -0,0 +1,105 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/InCallUI/res/drawable/btn_compound_background.xml b/InCallUI/res/drawable/btn_compound_background.xml new file mode 100644 index 000000000..6f2ef5f1d --- /dev/null +++ b/InCallUI/res/drawable/btn_compound_background.xml @@ -0,0 +1,34 @@ + + + + + + + + + + + + + + diff --git a/InCallUI/res/drawable/btn_compound_dialpad.xml b/InCallUI/res/drawable/btn_compound_dialpad.xml new file mode 100644 index 000000000..b44f2fafe --- /dev/null +++ b/InCallUI/res/drawable/btn_compound_dialpad.xml @@ -0,0 +1,30 @@ + + + + + + + + + + + + + + + diff --git a/InCallUI/res/drawable/btn_compound_hold.xml b/InCallUI/res/drawable/btn_compound_hold.xml new file mode 100644 index 000000000..50161eac8 --- /dev/null +++ b/InCallUI/res/drawable/btn_compound_hold.xml @@ -0,0 +1,30 @@ + + + + + + + + + + + + + + + diff --git a/InCallUI/res/drawable/btn_compound_mute.xml b/InCallUI/res/drawable/btn_compound_mute.xml new file mode 100644 index 000000000..4e09bd9c3 --- /dev/null +++ b/InCallUI/res/drawable/btn_compound_mute.xml @@ -0,0 +1,30 @@ + + + + + + + + + + + + + + + diff --git a/InCallUI/res/drawable/dialpad_background.xml b/InCallUI/res/drawable/dialpad_background.xml new file mode 100644 index 000000000..0e31f5eac --- /dev/null +++ b/InCallUI/res/drawable/dialpad_background.xml @@ -0,0 +1,19 @@ + + + + diff --git a/InCallUI/res/drawable/dialpad_background_opaque.xml b/InCallUI/res/drawable/dialpad_background_opaque.xml new file mode 100644 index 000000000..d8792f201 --- /dev/null +++ b/InCallUI/res/drawable/dialpad_background_opaque.xml @@ -0,0 +1,30 @@ + + + + + + + + + + + + + + + diff --git a/InCallUI/res/drawable/end_call_background.xml b/InCallUI/res/drawable/end_call_background.xml new file mode 100644 index 000000000..33ec22fa1 --- /dev/null +++ b/InCallUI/res/drawable/end_call_background.xml @@ -0,0 +1,45 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/InCallUI/res/drawable/ic_in_call_touch_handle.xml b/InCallUI/res/drawable/ic_in_call_touch_handle.xml new file mode 100644 index 000000000..e657e92ed --- /dev/null +++ b/InCallUI/res/drawable/ic_in_call_touch_handle.xml @@ -0,0 +1,33 @@ + + + + + + + + + + + + diff --git a/InCallUI/res/drawable/ic_lockscreen_answer.xml b/InCallUI/res/drawable/ic_lockscreen_answer.xml new file mode 100644 index 000000000..3184111fb --- /dev/null +++ b/InCallUI/res/drawable/ic_lockscreen_answer.xml @@ -0,0 +1,27 @@ + + + + + + + + diff --git a/InCallUI/res/drawable/ic_lockscreen_answer_activated_layer.xml b/InCallUI/res/drawable/ic_lockscreen_answer_activated_layer.xml new file mode 100644 index 000000000..6889581c7 --- /dev/null +++ b/InCallUI/res/drawable/ic_lockscreen_answer_activated_layer.xml @@ -0,0 +1,31 @@ + + + + + + + + + + + diff --git a/InCallUI/res/drawable/ic_lockscreen_answer_normal_layer.xml b/InCallUI/res/drawable/ic_lockscreen_answer_normal_layer.xml new file mode 100644 index 000000000..083fe3fbd --- /dev/null +++ b/InCallUI/res/drawable/ic_lockscreen_answer_normal_layer.xml @@ -0,0 +1,32 @@ + + + + + + + + + + + + diff --git a/InCallUI/res/drawable/ic_lockscreen_decline.xml b/InCallUI/res/drawable/ic_lockscreen_decline.xml new file mode 100644 index 000000000..6643816d9 --- /dev/null +++ b/InCallUI/res/drawable/ic_lockscreen_decline.xml @@ -0,0 +1,27 @@ + + + + + + + + diff --git a/InCallUI/res/drawable/ic_lockscreen_decline_activated_layer.xml b/InCallUI/res/drawable/ic_lockscreen_decline_activated_layer.xml new file mode 100644 index 000000000..e3606d1e7 --- /dev/null +++ b/InCallUI/res/drawable/ic_lockscreen_decline_activated_layer.xml @@ -0,0 +1,31 @@ + + + + + + + + + + + diff --git a/InCallUI/res/drawable/ic_lockscreen_decline_normal_layer.xml b/InCallUI/res/drawable/ic_lockscreen_decline_normal_layer.xml new file mode 100644 index 000000000..2896bef80 --- /dev/null +++ b/InCallUI/res/drawable/ic_lockscreen_decline_normal_layer.xml @@ -0,0 +1,32 @@ + + + + + + + + + + + + diff --git a/InCallUI/res/drawable/ic_lockscreen_text.xml b/InCallUI/res/drawable/ic_lockscreen_text.xml new file mode 100644 index 000000000..f9caac818 --- /dev/null +++ b/InCallUI/res/drawable/ic_lockscreen_text.xml @@ -0,0 +1,27 @@ + + + + + + + + diff --git a/InCallUI/res/drawable/ic_lockscreen_text_activated_layer.xml b/InCallUI/res/drawable/ic_lockscreen_text_activated_layer.xml new file mode 100644 index 000000000..95141e5ce --- /dev/null +++ b/InCallUI/res/drawable/ic_lockscreen_text_activated_layer.xml @@ -0,0 +1,31 @@ + + + + + + + + + + + diff --git a/InCallUI/res/drawable/ic_lockscreen_text_normal_layer.xml b/InCallUI/res/drawable/ic_lockscreen_text_normal_layer.xml new file mode 100644 index 000000000..42fd51de6 --- /dev/null +++ b/InCallUI/res/drawable/ic_lockscreen_text_normal_layer.xml @@ -0,0 +1,32 @@ + + + + + + + + + + + + diff --git a/InCallUI/res/drawable/list_selector_focused_and_checked.xml b/InCallUI/res/drawable/list_selector_focused_and_checked.xml new file mode 100644 index 000000000..113dae821 --- /dev/null +++ b/InCallUI/res/drawable/list_selector_focused_and_checked.xml @@ -0,0 +1,20 @@ + + + + + + + diff --git a/InCallUI/res/layout/incall_screen.xml b/InCallUI/res/layout/incall_screen.xml new file mode 100644 index 000000000..32159a688 --- /dev/null +++ b/InCallUI/res/layout/incall_screen.xml @@ -0,0 +1,55 @@ + + + + + + + + + + + + diff --git a/InCallUI/res/layout/primary_call_info.xml b/InCallUI/res/layout/primary_call_info.xml new file mode 100644 index 000000000..39c3873d0 --- /dev/null +++ b/InCallUI/res/layout/primary_call_info.xml @@ -0,0 +1,213 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/InCallUI/res/values/array.xml b/InCallUI/res/values/array.xml new file mode 100644 index 000000000..44d8d7086 --- /dev/null +++ b/InCallUI/res/values/array.xml @@ -0,0 +1,102 @@ + + + + + + + UDP + TCP + + + + @string/sip_call_options_entry_1 + @string/sip_call_options_entry_2 + @string/sip_call_options_entry_3 + + + + @string/sip_call_options_wifi_only_entry_1 + @string/sip_call_options_entry_2 + @string/sip_call_options_entry_3 + + + + @string/sip_always + @string/sip_address_only + @string/sip_ask_me_each_time + + + + @string/pstn_phone + @string/internet_phone + + + + @string/sip_system_decide + @string/sip_always_send_keepalive + + + + + + + @drawable/ic_lockscreen_answer + @drawable/ic_lockscreen_text + @drawable/ic_lockscreen_decline + @null" + + + @string/description_target_answer + @string/description_target_send_sms + @string/description_target_decline + @null" + + + @*android:string/description_direction_right + @*android:string/description_direction_up + @*android:string/description_direction_left + @null + + + + + @drawable/ic_lockscreen_answer + @null + @drawable/ic_lockscreen_decline + @null" + + + @string/description_target_answer + @null + @string/description_target_decline + @null" + + + @*android:string/description_direction_right + @null + @*android:string/description_direction_left + @null + + + diff --git a/InCallUI/res/values/attrs.xml b/InCallUI/res/values/attrs.xml new file mode 100644 index 000000000..056615d64 --- /dev/null +++ b/InCallUI/res/values/attrs.xml @@ -0,0 +1,101 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/InCallUI/res/values/colors.xml b/InCallUI/res/values/colors.xml new file mode 100644 index 000000000..4040008ad --- /dev/null +++ b/InCallUI/res/values/colors.xml @@ -0,0 +1,37 @@ + + + + + + + #99CE3F + #A0000000 + #8033b5e5 + #FFFFFF + + + #FFFFFF + + + #33B5E5 + + + #cc000000 + + + #888888 + diff --git a/InCallUI/res/values/dimens.xml b/InCallUI/res/values/dimens.xml new file mode 100644 index 000000000..c0a001cdc --- /dev/null +++ b/InCallUI/res/values/dimens.xml @@ -0,0 +1,119 @@ + + + + + + + + 80dp + + + 2dp + + + 24dp + + 16dp + + + 8dp + + + 50sp + + + 76dp + + + 74dp + + + 56dp + + + @dimen/in_call_button_height + + + 20dp + + + + 10dp + 5dp + 10dp + + + + 4dp + 2dp + 35sp + + + 0px + 3dp + 3dp + + + + 20 + 65 + 15 + + + 64dp + + + 94dp + + 28dp + + + + + 270dip + + + 135dip + + + 75dip + + + 40dip + + + 15dip + + -64dip + 0dip + + diff --git a/InCallUI/res/values/strings.xml b/InCallUI/res/values/strings.xml old mode 100644 new mode 100755 index cbf3aea3a..d92dc16e5 --- a/InCallUI/res/values/strings.xml +++ b/InCallUI/res/values/strings.xml @@ -1,21 +1,1405 @@ - + InCallUI + + + Speaker + + Handset earpiece + + Wired headset + + Bluetooth + + + + Send the following tones?\n + + Sending tones\n + + Send + + Yes + + No + + Replace wild character with + + + + Missing voicemail number + + No voicemail number is stored on the SIM card. + + Add number + + + Your SIM card has been unblocked. Your phone is unlocking\u2026 + + + SIM network unlock PIN + + Unlock + + Dismiss + + Requesting network unlock\u2026 + + Network unlock request unsuccessful. + + Network unlock successful. + + + + + GSM call settings + + CDMA call settings + + Access Point Names + + Network settings + + Voicemail + + VM: + + Network operators + + Call settings + + Additional settings + + Additional GSM only call settings + + Additional CDMA call settings + + Additional CDMA only call settings + + Network service settings + + Caller ID + + Loading settings\u2026 + + Number hidden in outgoing calls + + Number displayed in outgoing calls + + Use default operator settings to display my number in outgoing calls + + Call waiting + + During a call, notify me of incoming calls + + During a call, notify me of incoming calls + + Call forwarding settings + + Call forwarding + + + Always forward + + Always use this number + + Forwarding all calls + + Forwarding all calls to {0} + + Number is unavailable + + Disabled + + + Forward when busy + + Number when busy + + Forwarding to {0} + + Disabled + + Your operator doesn\'t support disabling call forwarding when your phone is busy. + + + Forward when unanswered + + Number when unanswered + + Forwarding to {0} + + Disabled + + Your operator doesn\'t support disabling call forwarding when your phone doesn\'t answer. + + + Forward when unreachable + + Number when unreachable + + Forwarding to {0} + + Disabled + + Your carrier doesn\'t support disabling call forwarding when your phone is unreachable. + + + Call settings + + Call settings error + + Reading settings\u2026 + + Updating settings\u2026 + + Reverting settings\u2026 + + Unexpected response from network. + + Network or SIM card error. + + Your Phone app\'s Fixed Dialing Numbers setting is turned on. As a result, some call-related features aren\'t working. + + Turn on the radio before viewing these settings. + + OK + + Enable + + Disable + + Update + + + + Network default + + Hide number + + Show number + + + + + DEFAULT + + HIDE + + SHOW + + + + + Voicemail number changed. + + Couldn\'t change the voicemail number.\nContact your carrier if this problem persists. + + Couldn\'t change the forwarding number.\nContact your carrier if this problem persists. + + Couldn\'t retrieve and save current forwarding number settings.\nSwitch to the new provider anyway? + + No changes were made. + + Choose voicemail service + + My carrier + + + + Mobile network settings + + Available networks + + Searching\u2026 + + No networks found. + + Search networks + + Error while searching for networks. + + Registering on %s\u2026 + + Your SIM card doesn\'t allow a connection to this network. + + Can\'t connect to this network right now. Try again later. + + Registered on network. + + Choose a network operator + + Search for all available networks + + Choose automatically + + Automatically choose preferred network + Automatic registration\u2026 + Network Mode + Change the network operating mode + Preferred network mode + + Preferred network mode: WCDMA preferred + + Preferred network mode: GSM only + + Preferred network mode: WCDMA only + + Preferred network mode: GSM / WCDMA + + Preferred network mode: CDMA + + Preferred network mode: CDMA / EvDo + + Preferred network mode: CDMA only + + Preferred network mode: EvDo only + + Preferred network mode: CDMA/EvDo/GSM/WCDMA + + Preferred network mode: LTE + + Preferred network mode: GSM/WCDMA/LTE + + Preferred network mode: CDMA+LTE/EVDO + + Preferred network mode: Global + + Preferred network mode: LTE / WCDMA + + + + LTE / WCDMA + LTE + Global + GSM/WCDMA/LTE + CDMA + LTE/EvDo + CDMA/EvDo/GSM/WCDMA + EvDo only + CDMA w/o EvDo + CDMA/EvDo auto + GSM/WCDMA auto + WCDMA only + GSM only + GSM/WCDMA preferred + + + "12" + "11" + "10" + "9" + "8" + "7" + "6" + "5" + "4" + "3" + "2" + "1" + "0" + + + Data enabled + + Enable data access over Mobile network + + Data roaming + + Connect to data services when roaming + + Connect to data services when roaming + + You\'ve lost data connectivity because you left your home network with data roaming turned off. + + Allow data roaming? You may incur significant roaming charges! + GSM/UMTS Options + CDMA Options + + + Data usage + + Data used in current period + + Data use period + + Data rate policy + + Learn more + + %1$s (%2$d\u066A) of %3$s period maximum\nNext period starts in %4$d days (%5$s) + + %1$s (%2$d\u066A) of %3$s period maximum + + %1$s maximum exceeded\nData rate reduced to %2$d Kb/s + + %1$d\u066A of cycle elapsed\nNext period starts in %2$d days (%3$s) + + Data rate reduced to %1$d Kb/s if data use limit is exceeded + + More information about your carrier\'s mobile network data use policy + + Cell Broadcast SMS + + Cell Broadcast SMS + Cell Broadcast SMS enabled + Cell Broadcast SMS disabled + + Cell Broadcast SMS settings + + Emergency Broadcast + Emergency Broadcast enabled + Emergency Broadcast disabled + + Administrative + Administrative enabled + Administrative disabled + + Maintenance + Maintenance enabled + Maintenance disabled + + General News + Business and Financial News + Sports News + Entertainment News + + Local + Local news enabled + Local news disabled + + Regional + Regional news enabled + Regional news disabled + + National + National news enabled + National news disabled + + International + International news enabled + International news disabled + + Language + Select the news language + + English + French + Spanish + Japanese + Korean + Chinese + Hebrew + + + "1" + "2" + "3" + "4" + "5" + "6" + "7" + + Languages + + Local Weather + Local Weather enabled + Local Weather disabled + + Area Traffic Reports + Area Traffic Reports enabled + Area Traffic Reports disabled + + Local Airport Flight Schedules + Local Airport Flight Schedules enabled + Local Airport Flight Schedules disabled + + Restaurants + Restaurants enabled + Restaurants disabled + + Lodgings + Lodgings enabled + Lodgings disabled + + Retail Directory + Retail Directory enabled + Retail Directory disabled + + Advertisements + Advertisements enabled + Advertisements disabled + + Stock Quotes + Stock Quotes enabled + Stock Quotes disabled + + Employment Opportunities + Employment Opportunities enabled + Employment Opportunities disabled + + Medical, Health, and Hospital + Medical, Health, and Hospital enabled + Medical, Health, and Hospital disabled + + Technology News + Technology News enabled + Technology News disabled + + Multi-category + Multi-category enabled + Multi-category disabled + + + Use only 2G networks + + Saves battery + + + + System select + + Change the CDMA roaming mode + + System select + + + Home only + + + + Automatic + + + + "0" + + + + "2" + + + CDMA subscription + Change between RUIM/SIM and NV + subscription + + RUIM/SIM + NV + + + "0" + "1" + + + Activate device + + Set up data service + + + + Fixed Dialing Numbers + + FDN list + + FDN activation + + Fixed Dialing Numbers are enabled + + Fixed Dialing Numbers are disabled + + Enable FDN + + Disable FDN + + Change PIN2 + + Disable FDN + + Enable FDN + + Manage Fixed Dialing Numbers + + Change PIN for FDN access + + Manage phone number list + + Voice privacy + Enable enhanced privacy mode + TTY mode + Set TTY mode + Auto-retry + Enable Auto-retry mode + + + Add contact + + Edit contact + + Delete contact + + + + Type PIN2 + + Name + + Number + + Save + + Add fixed dialing number + + Adding fixed dialing number\u2026 + + Fixed dialing number added. + + Edit fixed dialing number + + Updating fixed dialing number\u2026 + + Fixed dialing number updated. + + Delete fixed dialing number + + Deleting fixed dialing number\u2026 + + Fixed dialing number deleted. + + FDN wasn\'t updated because you typed an incorrect PIN. + + FDN wasn\'t updated because the number can\'t exceed 20 digits. + + FDN wasn\'t updated. The PIN2 was incorrect, or the phone number was rejected. + + + + Reading from SIM card\u2026 + + No contacts on your SIM card. + + Select contacts to import + + To import contacts from the SIM card, first turn off Airplane mode. + + + + Enable/disable SIM PIN + + Change SIM PIN + + SIM PIN: + + Old PIN + + New PIN + + Confirm new PIN + + The old PIN you typed isn\'t correct. Try again. + + The PINs you typed don\'t match. Try again. + + Type a PIN that is 4 to 8 numbers. + + Disable SIM PIN + + Enable SIM PIN + + Please wait\u2026 + + SIM PIN enabled. + + SIM PIN disabled. + + The PIN you typed was incorrect. + + SIM PIN changed successfully. + + Password incorrect, SIM is locked! PUK2 requested. + + + + PIN2 + + Old PIN2 + + New PIN2 + + Confirm new PIN2 + + The PUK2 you typed isn\'t correct. Try again. + + The old PIN2 you typed isn\'t correct. Try again. + + The PIN2s you typed don\'t match. Try again. + + Type a PIN2 that is 4 to 8 numbers. + + Type a PUK2 that is 8 numbers. + + PIN2 changed successfully. + + Type PUK2 code + + Password incorrect. Change PIN2 and retry. + + Password incorrect, SIM is locked. PUK2 requested. + + + Done + + + Conference call %s + + + (650) 555-1234 + + Incoming phone number + + Fake Incoming Call + + + Voicemail number + + + + Dialing + + Retrying + + Conference call + + Incoming call + + Call ended + + On hold + + Hanging up + + In call + + My number is %s + + + + Dialing + + Missed call + + Missed calls + + %s missed calls + + Missed call from %s + + Ongoing call + + On hold + + Incoming call + + New voicemail + + New voicemail (%d) + + Dial %s + + Voicemail number unknown + + No service + + Selected network (%s) unavailable + + Hang up + + Call back + + Message + + + To place a call, first turn off Airplane mode. + + Not registered on network. + + Mobile network not available. + + Call not sent, no valid number entered. + + Call not sent. + + Starting MMI sequence\u2026 + + Unsupported service. + + Unable to switch calls. + + Unable to separate call. + + Unable to transfer call. + + Unable to conference calls. + + Unable to reject call. + + Unable to release call(s). + + + Internet call + + + Emergency call + + Turning on radio\u2026 + + Out of service area, retrying\u2026 + + + + Call not sent. %s is not an emergency number! + + Call not sent. Dial an emergency number! + + + Use keyboard to dial + + + Hold + + End + + Dialpad + + Mute + + Add call + + Merge calls + + Swap + + Manage calls + + Manage conference + + Audio + + Video call + + + Import + + Import all + + Importing SIM contacts + + Import from contacts + + + Hearing aids + Turn on hearing aid compatibility + + + + TTY Off + TTY Full + TTY HCO + TTY VCO + + + + + + 0 + + 1 + + 2 + + 3 + + + + + DTMF tones + + Set the length of DTMF tones + + + Normal + Long + + + + 0 + 1 + + + + Network message + + + + Activate your phone + + 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. + + + Skip activation\? + + 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. + + Skip + + + Activate + + Phone is activated. + + Problem with activation + + Follow the spoken instructions until you hear that activation is complete. + + + Speaker + + Wait while your phone is being programmed. + + Programming unsuccessful + + Your phone is now activated. It may take up to 15 minutes for service to start. + + 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. + + EXCESS SPC FAILURES + + Back + + Try again + + Next + + + EcmExitDialog + + Entered Emergency Callback Mode + + Emergency Callback Mode + + Data connection disabled + + + No data connection for %s minute + + No data connection for %s minutes + + + + + The phone will be in Emergency Callback mode for %s minute. While in this mode no apps using a data connection can be used. Do you want to exit now? + + The phone will be in Emergency Callback mode for %s minutes. While in this mode no applications using a data connection can be used. Do you want to exit now? + + + + + The selected action isn\'t available while in the Emergency Callback mode. The phone will be in this mode for %s minute. Do you want to exit now? + + The selected action isn\'t available while in the Emergency Callback mode. The phone will be in this mode for %s minutes. Do you want to exit now? + + + The selected action isn\'t available while in an emergency call. + + Exiting Emergency Callback mode + + Yes + + No + + Dismiss + + + + ABSENT NUMBER + ABSENTNUMBER + + + + Service + + + Setup + + + <Not set> + + + Other call settings + + + Calling via %s + + + contact photo + + go private + + select contact + + + + + + Internet call settings + + Internet calling (SIP) accounts + + Accounts + + Receive incoming calls + + Reduces battery life + + Use Internet calling + + Use Internet calling (Wi-Fi only) + + + For all calls when data network is available + + Only for Internet calls + + Ask for each call + + For all calls + + + Place call + + + Use Internet calling account: + + + Always use to place Internet calls + + + You can change which Internet calling account to use by default from the Phone > Settings > Internet call settings > Accounts screen. + + + Cell phone call + + + Internet call + + + No Internet calling account + + There are no Internet calling accounts on this phone. Do you want to add one now? + + Add + + + Add account + + Remove account + + SIP accounts + + Saving the account\u2026 + + Removing the account\u2026 + + + Save + + Discard + + + Close the profile + + OK + + Close + + + Primary account. %s + + Checking status... + + Registering\u2026 + + Still trying\u2026 + + Not receiving calls. + + Account registration stopped because there is no Internet connection. + + Account registration stopped because there is no Wi-Fi connection. + + Account registration unsuccessful. + + Receiving calls. + + Account registration unsuccessful: (%s); will try later + + Account registration unsuccessful: Incorrect username or password. + + Account registration unsuccessful: Check the server name. + + This account is currently in use by the %s app. + + + + SIP account details + + SIP account details + + + Server + + Username + + Password + + Display name + + Outbound proxy address + + Port number + + Transport type + + Send keep-alive + + Set as primary account + + Used for outbound calls + + Optional settings + + Authentication username + + Username used for authentication + + + <Not set> + + <Same as username> + + <Optional> + + + 5060 + + UDP + + + + â–· Touch to show all + + â–½ Touch to hide all + + + %s is required and can\'t be left blank. + + Port number should be within 1000 and 65534. + + + No Internet connection + + No Wi-Fi connection + + To place an Internet call, check your Internet connection first. + + You need to be connected to a Wi-Fi network for Internet calls (use the Wireless & Network settings). + + Internet calling not supported + + + Automatic + + Always send + + + SIP_ALWAYS + SIP_ADDRESS_ONLY + SIP_ASK_ME_EACH_TIME + + + SipDomain + UserName + Password + DisplayName + ProxyAddress + Port + Protocol + SendKeepAlive + SetPrimary + advanced settings container + AuthUserName + + + + Voice calling not supported + + + Can\'t talk now. What\'s up? + + I\'ll call you right back. + + I\'ll call you later. + + Can\'t talk now. Call me later? + + Write your own... + + + Quick responses + + Edit quick responses + + + + Quick response + + Reset default app + + + Message sent to %s. + + + one + + + two + + + three + + + four + + + five + + + six + + + seven + + + eight + + + nine + + + star + + + zero + + + pound + + + dial + + + backspace + + + Speakerphone enabled. + + + Call muted. + + + Answer + + Send SMS + + Decline + + + Vibrate + + Vibrate + + + Sound + + + Default sound (%1$s) + + + never + + + + always + silent + never + + + + Phone ringtone + + + Vibrate when ringing + + + Dial pad touch tones + + + Dial pad autocomplete + + + Ringtone & Vibrate diff --git a/InCallUI/res/values/styles.xml b/InCallUI/res/values/styles.xml new file mode 100644 index 000000000..c86e570b8 --- /dev/null +++ b/InCallUI/res/values/styles.xml @@ -0,0 +1,144 @@ + + + + + #FF333333 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/InCallUI/src/com/android/incallui/CallMonitorService.java b/InCallUI/src/com/android/incallui/CallMonitorService.java index 7ac47785b..002441584 100644 --- a/InCallUI/src/com/android/incallui/CallMonitorService.java +++ b/InCallUI/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/InCallUI/src/com/android/incallui/InCallActivity.java b/InCallUI/src/com/android/incallui/InCallActivity.java new file mode 100644 index 000000000..ea06af8bd --- /dev/null +++ b/InCallUI/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/InCallUI/src/com/android/incallui/widget/multiwaveview/Ease.java b/InCallUI/src/com/android/incallui/widget/multiwaveview/Ease.java new file mode 100644 index 000000000..5ef689771 --- /dev/null +++ b/InCallUI/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/InCallUI/src/com/android/incallui/widget/multiwaveview/GlowPadView.java b/InCallUI/src/com/android/incallui/widget/multiwaveview/GlowPadView.java new file mode 100644 index 000000000..b577b7cc7 --- /dev/null +++ b/InCallUI/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 mTargetDrawables = new ArrayList(); + private AnimationBundle mWaveAnimations = new AnimationBundle(); + private AnimationBundle mTargetAnimations = new AnimationBundle(); + private AnimationBundle mGlowAnimations = new AnimationBundle(); + private ArrayList mTargetDescriptions; + private ArrayList 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 { + 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 loadDrawableArray(int resourceId) { + Resources res = getContext().getResources(); + TypedArray array = res.obtainTypedArray(resourceId); + final int count = array.length(); + ArrayList drawables = new ArrayList(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 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 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 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 loadDescriptions(int resourceId) { + TypedArray array = getContext().getResources().obtainTypedArray(resourceId); + final int count = array.length(); + ArrayList targetContentDescriptions = new ArrayList(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 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/InCallUI/src/com/android/incallui/widget/multiwaveview/PointCloud.java b/InCallUI/src/com/android/incallui/widget/multiwaveview/PointCloud.java new file mode 100644 index 000000000..77aac2bda --- /dev/null +++ b/InCallUI/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 mPointCloud = new ArrayList(); + 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 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/InCallUI/src/com/android/incallui/widget/multiwaveview/TargetDrawable.java b/InCallUI/src/com/android/incallui/widget/multiwaveview/TargetDrawable.java new file mode 100644 index 000000000..d83a28c11 --- /dev/null +++ b/InCallUI/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/InCallUI/src/com/android/incallui/widget/multiwaveview/Tweener.java b/InCallUI/src/com/android/incallui/widget/multiwaveview/Tweener.java new file mode 100644 index 000000000..7222442fe --- /dev/null +++ b/InCallUI/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 sTweens = new HashMap(); + + public Tweener(ObjectAnimator anim) { + animator = anim; + } + + private static void remove(Animator animator) { + Iterator> iter = sTweens.entrySet().iterator(); + while (iter.hasNext()) { + Entry 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 props = new ArrayList(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 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); + } + } + } + } +} -- cgit v1.2.3