From ccca31529c07970e89419fb85a9e8153a5396838 Mon Sep 17 00:00:00 2001 From: Eric Erfanian Date: Wed, 22 Feb 2017 16:32:36 -0800 Subject: Update dialer sources. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Test: Built package and system image. This change clobbers the old source, and is an export from an internal Google repository. The internal repository was forked form Android in March, and this change includes modifications since then, to near the v8 release. Since the fork, we've moved code from monolithic to independent modules. In addition, we've switched to Blaze/Bazel as the build sysetm. This export, however, still uses make. New dependencies have been added: - Dagger - Auto-Value - Glide - Libshortcutbadger Going forward, development will still be in Google3, and the Gerrit release will become an automated export, with the next drop happening in ~ two weeks. Android.mk includes local modifications from ToT. Abridged changelog: Bug fixes ● Not able to mute, add a call when using Phone app in multiwindow mode ● Double tap on keypad triggering multiple key and tones ● Reported spam numbers not showing as spam in the call log ● Crash when user tries to block number while Phone app is not set as default ● Crash when user picks a number from search auto-complete list Visual Voicemail (VVM) improvements ● Share Voicemail audio via standard exporting mechanisms that support file attachment (email, MMS, etc.) ● Make phone number, email and web sites in VVM transcript clickable ● Set PIN before declining VVM Terms of Service {Carrier} ● Set client type for outbound visual voicemail SMS {Carrier} New incoming call and incall UI on older devices (Android M) ● Updated Phone app icon ● New incall UI (large buttons, button labels) ● New and animated Answer/Reject gestures Accessibility ● Add custom answer/decline call buttons on answer screen for touch exploration accessibility services ● Increase size of touch target ● Add verbal feedback when a Voicemail fails to load ● Fix pressing of Phone buttons while in a phone call using Switch Access ● Fix selecting and opening contacts in talkback mode ● Split focus for ‘Learn More’ link in caller id & spam to help distinguish similar text Other ● Backup & Restore for App Preferences ● Prompt user to enable Wi-Fi calling if the call ends due to out of service and Wi-Fi is connected ● Rename “Dialpad” to “Keypad” ● Show "Private number" for restricted calls ● Delete unused items (vcard, add contact, call history) from Phone menu Change-Id: I2a7e53532a24c21bf308bf0a6d178d7ddbca4958 --- InCallUI/AndroidManifest.xml | 24 - InCallUI/build.gradle | 14 - InCallUI/proguard.flags | 14 - InCallUI/res/anim/activity_open_enter.xml | 35 - InCallUI/res/anim/activity_open_exit.xml | 26 - InCallUI/res/anim/call_status_pulse.xml | 22 - InCallUI/res/anim/decelerate_cubic.xml | 21 - InCallUI/res/anim/decelerate_quint.xml | 21 - InCallUI/res/color/ota_title_color.xml | 21 - InCallUI/res/color/selectable_icon_tint.xml | 24 - InCallUI/res/drawable-hdpi/fab_blue.png | Bin 2805 -> 0 bytes InCallUI/res/drawable-hdpi/fab_ic_call.png | Bin 875 -> 0 bytes InCallUI/res/drawable-hdpi/fab_ic_end_call.png | Bin 852 -> 0 bytes InCallUI/res/drawable-hdpi/fab_ic_message.png | Bin 617 -> 0 bytes InCallUI/res/drawable-hdpi/fab_red.png | Bin 2783 -> 0 bytes .../res/drawable-hdpi/ic_block_grey600_24dp.png | Bin 518 -> 0 bytes .../res/drawable-hdpi/ic_business_white_24dp.png | Bin 152 -> 0 bytes .../res/drawable-hdpi/ic_call_end_white_24dp.png | Bin 454 -> 0 bytes .../res/drawable-hdpi/ic_call_split_white_24dp.png | Bin 326 -> 0 bytes InCallUI/res/drawable-hdpi/ic_call_white_24dp.png | Bin 451 -> 0 bytes .../res/drawable-hdpi/ic_close_grey600_24dp.png | Bin 225 -> 0 bytes .../res/drawable-hdpi/ic_forward_white_24dp.png | Bin 139 -> 0 bytes InCallUI/res/drawable-hdpi/ic_hd_24dp.png | Bin 236 -> 0 bytes .../drawable-hdpi/ic_location_on_white_24dp.png | Bin 371 -> 0 bytes .../res/drawable-hdpi/ic_lockscreen_glowdot.png | Bin 738 -> 0 bytes .../drawable-hdpi/ic_person_add_grey600_24dp.png | Bin 300 -> 0 bytes .../drawable-hdpi/ic_phone_paused_white_24dp.png | Bin 458 -> 0 bytes InCallUI/res/drawable-hdpi/ic_question_mark.png | Bin 941 -> 0 bytes .../res/drawable-hdpi/ic_report_white_36dp.png | Bin 312 -> 0 bytes .../res/drawable-hdpi/ic_schedule_white_24dp.png | Bin 575 -> 0 bytes InCallUI/res/drawable-hdpi/ic_toolbar_add_call.png | Bin 1230 -> 0 bytes .../drawable-hdpi/ic_toolbar_arrow_whitespace.png | Bin 489 -> 0 bytes .../drawable-hdpi/ic_toolbar_audio_bluetooth.png | Bin 833 -> 0 bytes .../drawable-hdpi/ic_toolbar_audio_headphones.png | Bin 1142 -> 0 bytes .../res/drawable-hdpi/ic_toolbar_audio_phone.png | Bin 1301 -> 0 bytes InCallUI/res/drawable-hdpi/ic_toolbar_dialpad.png | Bin 624 -> 0 bytes InCallUI/res/drawable-hdpi/ic_toolbar_hold.png | Bin 511 -> 0 bytes InCallUI/res/drawable-hdpi/ic_toolbar_merge.png | Bin 772 -> 0 bytes InCallUI/res/drawable-hdpi/ic_toolbar_mic_off.png | Bin 1155 -> 0 bytes .../res/drawable-hdpi/ic_toolbar_speaker_on.png | Bin 1118 -> 0 bytes InCallUI/res/drawable-hdpi/ic_toolbar_swap.png | Bin 1110 -> 0 bytes InCallUI/res/drawable-hdpi/ic_toolbar_video.png | Bin 711 -> 0 bytes .../res/drawable-hdpi/ic_toolbar_video_off.png | Bin 932 -> 0 bytes .../res/drawable-hdpi/ic_toolbar_video_switch.png | Bin 972 -> 0 bytes InCallUI/res/drawable-hdpi/img_business.png | Bin 3311 -> 0 bytes InCallUI/res/drawable-hdpi/img_conference.png | Bin 7037 -> 0 bytes InCallUI/res/drawable-hdpi/img_no_image.png | Bin 5362 -> 0 bytes InCallUI/res/drawable-hdpi/img_phone.png | Bin 6157 -> 0 bytes .../drawable-land/rounded_call_card_background.xml | 23 - InCallUI/res/drawable-mdpi/fab_blue.png | Bin 1841 -> 0 bytes InCallUI/res/drawable-mdpi/fab_ic_call.png | Bin 698 -> 0 bytes InCallUI/res/drawable-mdpi/fab_ic_end_call.png | Bin 668 -> 0 bytes InCallUI/res/drawable-mdpi/fab_ic_message.png | Bin 561 -> 0 bytes InCallUI/res/drawable-mdpi/fab_red.png | Bin 1843 -> 0 bytes .../res/drawable-mdpi/ic_block_grey600_24dp.png | Bin 348 -> 0 bytes .../res/drawable-mdpi/ic_business_white_24dp.png | Bin 105 -> 0 bytes .../res/drawable-mdpi/ic_call_end_white_24dp.png | Bin 315 -> 0 bytes .../res/drawable-mdpi/ic_call_split_white_24dp.png | Bin 256 -> 0 bytes InCallUI/res/drawable-mdpi/ic_call_white_24dp.png | Bin 348 -> 0 bytes .../res/drawable-mdpi/ic_close_grey600_24dp.png | Bin 178 -> 0 bytes .../res/drawable-mdpi/ic_forward_white_24dp.png | Bin 117 -> 0 bytes InCallUI/res/drawable-mdpi/ic_hd_24dp.png | Bin 154 -> 0 bytes .../drawable-mdpi/ic_location_on_white_24dp.png | Bin 265 -> 0 bytes .../res/drawable-mdpi/ic_lockscreen_glowdot.png | Bin 538 -> 0 bytes .../drawable-mdpi/ic_person_add_grey600_24dp.png | Bin 211 -> 0 bytes .../drawable-mdpi/ic_phone_paused_white_24dp.png | Bin 346 -> 0 bytes InCallUI/res/drawable-mdpi/ic_question_mark.png | Bin 619 -> 0 bytes .../res/drawable-mdpi/ic_report_white_36dp.png | Bin 240 -> 0 bytes .../res/drawable-mdpi/ic_schedule_white_24dp.png | Bin 377 -> 0 bytes InCallUI/res/drawable-mdpi/ic_toolbar_add_call.png | Bin 883 -> 0 bytes .../drawable-mdpi/ic_toolbar_arrow_whitespace.png | Bin 431 -> 0 bytes .../drawable-mdpi/ic_toolbar_audio_bluetooth.png | Bin 630 -> 0 bytes .../drawable-mdpi/ic_toolbar_audio_headphones.png | Bin 885 -> 0 bytes .../res/drawable-mdpi/ic_toolbar_audio_phone.png | Bin 921 -> 0 bytes InCallUI/res/drawable-mdpi/ic_toolbar_dialpad.png | Bin 527 -> 0 bytes InCallUI/res/drawable-mdpi/ic_toolbar_hold.png | Bin 455 -> 0 bytes InCallUI/res/drawable-mdpi/ic_toolbar_merge.png | Bin 669 -> 0 bytes InCallUI/res/drawable-mdpi/ic_toolbar_mic_off.png | Bin 822 -> 0 bytes .../res/drawable-mdpi/ic_toolbar_speaker_on.png | Bin 847 -> 0 bytes InCallUI/res/drawable-mdpi/ic_toolbar_swap.png | Bin 808 -> 0 bytes InCallUI/res/drawable-mdpi/ic_toolbar_video.png | Bin 607 -> 0 bytes .../res/drawable-mdpi/ic_toolbar_video_off.png | Bin 797 -> 0 bytes .../res/drawable-mdpi/ic_toolbar_video_switch.png | Bin 776 -> 0 bytes InCallUI/res/drawable-mdpi/img_business.png | Bin 2240 -> 0 bytes InCallUI/res/drawable-mdpi/img_conference.png | Bin 4629 -> 0 bytes InCallUI/res/drawable-mdpi/img_no_image.png | Bin 3509 -> 0 bytes InCallUI/res/drawable-mdpi/img_phone.png | Bin 3798 -> 0 bytes InCallUI/res/drawable-xhdpi/fab_blue.png | Bin 4085 -> 0 bytes InCallUI/res/drawable-xhdpi/fab_ic_call.png | Bin 1266 -> 0 bytes InCallUI/res/drawable-xhdpi/fab_ic_end_call.png | Bin 1215 -> 0 bytes InCallUI/res/drawable-xhdpi/fab_ic_message.png | Bin 795 -> 0 bytes InCallUI/res/drawable-xhdpi/fab_red.png | Bin 4047 -> 0 bytes .../res/drawable-xhdpi/ic_block_grey600_24dp.png | Bin 690 -> 0 bytes .../res/drawable-xhdpi/ic_business_white_24dp.png | Bin 112 -> 0 bytes .../res/drawable-xhdpi/ic_call_end_white_24dp.png | Bin 534 -> 0 bytes .../drawable-xhdpi/ic_call_split_white_24dp.png | Bin 377 -> 0 bytes InCallUI/res/drawable-xhdpi/ic_call_white_24dp.png | Bin 535 -> 0 bytes .../res/drawable-xhdpi/ic_close_grey600_24dp.png | Bin 261 -> 0 bytes .../res/drawable-xhdpi/ic_forward_white_24dp.png | Bin 159 -> 0 bytes InCallUI/res/drawable-xhdpi/ic_hd_24dp.png | Bin 201 -> 0 bytes .../drawable-xhdpi/ic_location_on_white_24dp.png | Bin 456 -> 0 bytes .../res/drawable-xhdpi/ic_lockscreen_glowdot.png | Bin 964 -> 0 bytes .../drawable-xhdpi/ic_person_add_grey600_24dp.png | Bin 341 -> 0 bytes .../drawable-xhdpi/ic_phone_paused_white_24dp.png | Bin 584 -> 0 bytes InCallUI/res/drawable-xhdpi/ic_question_mark.png | Bin 1170 -> 0 bytes .../res/drawable-xhdpi/ic_report_white_36dp.png | Bin 340 -> 0 bytes .../res/drawable-xhdpi/ic_schedule_white_24dp.png | Bin 737 -> 0 bytes .../res/drawable-xhdpi/ic_toolbar_add_call.png | Bin 1549 -> 0 bytes .../drawable-xhdpi/ic_toolbar_arrow_whitespace.png | Bin 543 -> 0 bytes .../drawable-xhdpi/ic_toolbar_audio_bluetooth.png | Bin 882 -> 0 bytes .../drawable-xhdpi/ic_toolbar_audio_headphones.png | Bin 1479 -> 0 bytes .../res/drawable-xhdpi/ic_toolbar_audio_phone.png | Bin 1837 -> 0 bytes InCallUI/res/drawable-xhdpi/ic_toolbar_dialpad.png | Bin 709 -> 0 bytes InCallUI/res/drawable-xhdpi/ic_toolbar_hold.png | Bin 565 -> 0 bytes InCallUI/res/drawable-xhdpi/ic_toolbar_merge.png | Bin 921 -> 0 bytes InCallUI/res/drawable-xhdpi/ic_toolbar_mic_off.png | Bin 1454 -> 0 bytes .../res/drawable-xhdpi/ic_toolbar_speaker_on.png | Bin 1505 -> 0 bytes InCallUI/res/drawable-xhdpi/ic_toolbar_swap.png | Bin 1487 -> 0 bytes InCallUI/res/drawable-xhdpi/ic_toolbar_video.png | Bin 830 -> 0 bytes .../res/drawable-xhdpi/ic_toolbar_video_off.png | Bin 1160 -> 0 bytes .../res/drawable-xhdpi/ic_toolbar_video_switch.png | Bin 1120 -> 0 bytes InCallUI/res/drawable-xhdpi/img_business.png | Bin 4759 -> 0 bytes InCallUI/res/drawable-xhdpi/img_conference.png | Bin 9517 -> 0 bytes InCallUI/res/drawable-xhdpi/img_no_image.png | Bin 7369 -> 0 bytes InCallUI/res/drawable-xhdpi/img_phone.png | Bin 8189 -> 0 bytes InCallUI/res/drawable-xxhdpi/fab_blue.png | Bin 7009 -> 0 bytes InCallUI/res/drawable-xxhdpi/fab_ic_call.png | Bin 2320 -> 0 bytes InCallUI/res/drawable-xxhdpi/fab_ic_end_call.png | Bin 2227 -> 0 bytes InCallUI/res/drawable-xxhdpi/fab_ic_message.png | Bin 1556 -> 0 bytes InCallUI/res/drawable-xxhdpi/fab_red.png | Bin 6965 -> 0 bytes .../res/drawable-xxhdpi/ic_block_grey600_24dp.png | Bin 1029 -> 0 bytes .../res/drawable-xxhdpi/ic_business_white_24dp.png | Bin 119 -> 0 bytes .../res/drawable-xxhdpi/ic_call_end_white_24dp.png | Bin 736 -> 0 bytes .../drawable-xxhdpi/ic_call_split_white_24dp.png | Bin 461 -> 0 bytes .../res/drawable-xxhdpi/ic_call_white_24dp.png | Bin 750 -> 0 bytes .../res/drawable-xxhdpi/ic_close_grey600_24dp.png | Bin 353 -> 0 bytes .../res/drawable-xxhdpi/ic_forward_white_24dp.png | Bin 204 -> 0 bytes InCallUI/res/drawable-xxhdpi/ic_hd_24dp.png | Bin 290 -> 0 bytes .../drawable-xxhdpi/ic_location_on_white_24dp.png | Bin 675 -> 0 bytes .../res/drawable-xxhdpi/ic_lockscreen_glowdot.png | Bin 1907 -> 0 bytes .../drawable-xxhdpi/ic_person_add_grey600_24dp.png | Bin 485 -> 0 bytes .../drawable-xxhdpi/ic_phone_paused_white_24dp.png | Bin 842 -> 0 bytes InCallUI/res/drawable-xxhdpi/ic_question_mark.png | Bin 1774 -> 0 bytes .../res/drawable-xxhdpi/ic_report_white_36dp.png | Bin 522 -> 0 bytes .../res/drawable-xxhdpi/ic_schedule_white_24dp.png | Bin 1107 -> 0 bytes .../res/drawable-xxhdpi/ic_toolbar_add_call.png | Bin 1874 -> 0 bytes .../ic_toolbar_arrow_whitespace.png | Bin 1188 -> 0 bytes .../drawable-xxhdpi/ic_toolbar_audio_bluetooth.png | Bin 1528 -> 0 bytes .../ic_toolbar_audio_headphones.png | Bin 1858 -> 0 bytes .../res/drawable-xxhdpi/ic_toolbar_audio_phone.png | Bin 2285 -> 0 bytes .../res/drawable-xxhdpi/ic_toolbar_dialpad.png | Bin 1449 -> 0 bytes InCallUI/res/drawable-xxhdpi/ic_toolbar_hold.png | Bin 1143 -> 0 bytes InCallUI/res/drawable-xxhdpi/ic_toolbar_merge.png | Bin 1385 -> 0 bytes .../res/drawable-xxhdpi/ic_toolbar_mic_off.png | Bin 1956 -> 0 bytes .../res/drawable-xxhdpi/ic_toolbar_speaker_on.png | Bin 2065 -> 0 bytes InCallUI/res/drawable-xxhdpi/ic_toolbar_swap.png | Bin 1970 -> 0 bytes InCallUI/res/drawable-xxhdpi/ic_toolbar_video.png | Bin 1347 -> 0 bytes .../res/drawable-xxhdpi/ic_toolbar_video_off.png | Bin 1538 -> 0 bytes .../drawable-xxhdpi/ic_toolbar_video_switch.png | Bin 1534 -> 0 bytes InCallUI/res/drawable-xxhdpi/img_business.png | Bin 6499 -> 0 bytes InCallUI/res/drawable-xxhdpi/img_conference.png | Bin 16306 -> 0 bytes InCallUI/res/drawable-xxhdpi/img_no_image.png | Bin 9850 -> 0 bytes InCallUI/res/drawable-xxhdpi/img_phone.png | Bin 10848 -> 0 bytes InCallUI/res/drawable-xxxhdpi/fab_blue.png | Bin 9807 -> 0 bytes InCallUI/res/drawable-xxxhdpi/fab_ic_call.png | Bin 2921 -> 0 bytes InCallUI/res/drawable-xxxhdpi/fab_ic_end_call.png | Bin 2567 -> 0 bytes InCallUI/res/drawable-xxxhdpi/fab_ic_message.png | Bin 1850 -> 0 bytes InCallUI/res/drawable-xxxhdpi/fab_red.png | Bin 9802 -> 0 bytes .../res/drawable-xxxhdpi/ic_block_grey600_24dp.png | Bin 1353 -> 0 bytes .../drawable-xxxhdpi/ic_business_white_24dp.png | Bin 114 -> 0 bytes .../drawable-xxxhdpi/ic_call_end_white_24dp.png | Bin 929 -> 0 bytes .../drawable-xxxhdpi/ic_call_split_white_24dp.png | Bin 646 -> 0 bytes .../res/drawable-xxxhdpi/ic_close_grey600_24dp.png | Bin 444 -> 0 bytes .../res/drawable-xxxhdpi/ic_forward_white_24dp.png | Bin 236 -> 0 bytes InCallUI/res/drawable-xxxhdpi/ic_hd_24dp.png | Bin 348 -> 0 bytes .../drawable-xxxhdpi/ic_location_on_white_24dp.png | Bin 869 -> 0 bytes .../ic_person_add_grey600_24dp.png | Bin 638 -> 0 bytes InCallUI/res/drawable-xxxhdpi/ic_question_mark.png | Bin 2370 -> 0 bytes .../res/drawable-xxxhdpi/ic_report_white_36dp.png | Bin 649 -> 0 bytes .../drawable-xxxhdpi/ic_schedule_white_24dp.png | Bin 1478 -> 0 bytes .../res/drawable-xxxhdpi/ic_toolbar_add_call.png | Bin 2271 -> 0 bytes .../ic_toolbar_arrow_whitespace.png | Bin 1262 -> 0 bytes .../ic_toolbar_audio_bluetooth.png | Bin 1728 -> 0 bytes .../ic_toolbar_audio_headphones.png | Bin 2158 -> 0 bytes .../drawable-xxxhdpi/ic_toolbar_audio_phone.png | Bin 2830 -> 0 bytes .../res/drawable-xxxhdpi/ic_toolbar_dialpad.png | Bin 1651 -> 0 bytes InCallUI/res/drawable-xxxhdpi/ic_toolbar_hold.png | Bin 1179 -> 0 bytes InCallUI/res/drawable-xxxhdpi/ic_toolbar_merge.png | Bin 1444 -> 0 bytes .../res/drawable-xxxhdpi/ic_toolbar_mic_off.png | Bin 2284 -> 0 bytes .../res/drawable-xxxhdpi/ic_toolbar_speaker_on.png | Bin 2532 -> 0 bytes InCallUI/res/drawable-xxxhdpi/ic_toolbar_swap.png | Bin 2370 -> 0 bytes InCallUI/res/drawable-xxxhdpi/ic_toolbar_video.png | Bin 1394 -> 0 bytes .../res/drawable-xxxhdpi/ic_toolbar_video_off.png | Bin 1703 -> 0 bytes .../drawable-xxxhdpi/ic_toolbar_video_switch.png | Bin 1610 -> 0 bytes InCallUI/res/drawable-xxxhdpi/img_business.png | Bin 10730 -> 0 bytes InCallUI/res/drawable-xxxhdpi/img_conference.png | Bin 19584 -> 0 bytes InCallUI/res/drawable-xxxhdpi/img_no_image.png | Bin 16251 -> 0 bytes InCallUI/res/drawable-xxxhdpi/img_phone.png | Bin 18635 -> 0 bytes InCallUI/res/drawable/btn_add.xml | 30 - InCallUI/res/drawable/btn_background.xml | 33 - InCallUI/res/drawable/btn_change_to_video.xml | 31 - InCallUI/res/drawable/btn_change_to_voice.xml | 31 - InCallUI/res/drawable/btn_compound_audio.xml | 93 - InCallUI/res/drawable/btn_compound_background.xml | 35 - InCallUI/res/drawable/btn_compound_dialpad.xml | 32 - InCallUI/res/drawable/btn_compound_hold.xml | 32 - InCallUI/res/drawable/btn_compound_mute.xml | 31 - InCallUI/res/drawable/btn_compound_video_off.xml | 33 - .../res/drawable/btn_compound_video_switch.xml | 33 - InCallUI/res/drawable/btn_merge.xml | 30 - InCallUI/res/drawable/btn_overflow.xml | 30 - InCallUI/res/drawable/btn_selected.xml | 25 - InCallUI/res/drawable/btn_selected_focused.xml | 29 - InCallUI/res/drawable/btn_swap.xml | 30 - InCallUI/res/drawable/btn_unselected.xml | 25 - InCallUI/res/drawable/btn_unselected_focused.xml | 28 - InCallUI/res/drawable/conference_ripple.xml | 25 - InCallUI/res/drawable/end_call_background.xml | 25 - InCallUI/res/drawable/ic_incall_audio_handle.xml | 40 - InCallUI/res/drawable/ic_incall_video_handle.xml | 41 - InCallUI/res/drawable/ic_lockscreen_answer.xml | 27 - .../ic_lockscreen_answer_activated_layer.xml | 25 - .../drawable/ic_lockscreen_answer_normal_layer.xml | 33 - .../res/drawable/ic_lockscreen_answer_video.xml | 28 - .../ic_lockscreen_answer_video_activated_layer.xml | 26 - .../ic_lockscreen_answer_video_normal_layer.xml | 34 - InCallUI/res/drawable/ic_lockscreen_decline.xml | 27 - .../ic_lockscreen_decline_activated_layer.xml | 24 - .../ic_lockscreen_decline_normal_layer.xml | 32 - .../res/drawable/ic_lockscreen_decline_video.xml | 28 - ...ic_lockscreen_decline_video_activated_layer.xml | 26 - .../ic_lockscreen_decline_video_normal_layer.xml | 34 - InCallUI/res/drawable/ic_lockscreen_outerring.xml | 22 - InCallUI/res/drawable/ic_lockscreen_text.xml | 27 - .../ic_lockscreen_text_activated_layer.xml | 32 - .../drawable/ic_lockscreen_text_normal_layer.xml | 33 - .../res/drawable/img_conference_automirrored.xml | 21 - .../res/drawable/img_no_image_automirrored.xml | 21 - InCallUI/res/drawable/incoming_sms_background.xml | 25 - InCallUI/res/drawable/outgoing_sms_background.xml | 25 - InCallUI/res/drawable/spam_notification_icon.xml | 31 - InCallUI/res/drawable/subject_bubble.xml | 22 - .../res/drawable/unknown_notification_icon.xml | 31 - InCallUI/res/layout-h400dp/call_card_fragment.xml | 172 -- .../manage_conference_call_button.xml | 61 - .../res/layout-w500dp-land/call_card_fragment.xml | 158 -- .../manage_conference_call_button.xml | 61 - InCallUI/res/layout/accessible_answer_fragment.xml | 104 -- InCallUI/res/layout/answer_fragment.xml | 42 - .../business_contact_context_list_header.xml | 40 - .../res/layout/business_context_info_list_item.xml | 48 - InCallUI/res/layout/call_button_fragment.xml | 171 -- InCallUI/res/layout/call_card_fragment.xml | 158 -- InCallUI/res/layout/caller_in_conference.xml | 116 -- .../res/layout/conference_manager_fragment.xml | 36 - InCallUI/res/layout/incall_dialpad_fragment.xml | 24 - InCallUI/res/layout/incall_screen.xml | 23 - .../res/layout/manage_conference_call_button.xml | 72 - InCallUI/res/layout/outgoing_call_animation.xml | 22 - .../res/layout/person_context_info_list_item.xml | 40 - InCallUI/res/layout/primary_call_info.xml | 231 --- InCallUI/res/layout/secondary_call_info.xml | 105 -- InCallUI/res/layout/video_call_fragment.xml | 28 - InCallUI/res/layout/video_call_views.xml | 66 - InCallUI/res/menu/incall_audio_mode_menu.xml | 39 - InCallUI/res/values-af/strings.xml | 195 -- InCallUI/res/values-am/strings.xml | 195 -- InCallUI/res/values-ar/strings.xml | 195 -- InCallUI/res/values-az/strings.xml | 195 -- InCallUI/res/values-b+sr+Latn/strings.xml | 195 -- InCallUI/res/values-be/strings.xml | 195 -- InCallUI/res/values-bg/strings.xml | 195 -- InCallUI/res/values-bn/strings.xml | 195 -- InCallUI/res/values-bs/strings.xml | 195 -- InCallUI/res/values-ca/strings.xml | 195 -- InCallUI/res/values-cs/strings.xml | 195 -- InCallUI/res/values-da/strings.xml | 195 -- InCallUI/res/values-de/strings.xml | 195 -- InCallUI/res/values-el/strings.xml | 195 -- InCallUI/res/values-en-rAU/strings.xml | 195 -- InCallUI/res/values-en-rGB/strings.xml | 195 -- InCallUI/res/values-en-rIN/strings.xml | 195 -- InCallUI/res/values-es-rUS/strings.xml | 195 -- InCallUI/res/values-es/strings.xml | 195 -- InCallUI/res/values-et/strings.xml | 195 -- InCallUI/res/values-eu/strings.xml | 195 -- InCallUI/res/values-fa/strings.xml | 195 -- InCallUI/res/values-fi/strings.xml | 195 -- InCallUI/res/values-fr-rCA/strings.xml | 195 -- InCallUI/res/values-fr/strings.xml | 195 -- InCallUI/res/values-gl/strings.xml | 195 -- InCallUI/res/values-gu/strings.xml | 195 -- InCallUI/res/values-h400dp/dimens.xml | 31 - InCallUI/res/values-hi/strings.xml | 195 -- InCallUI/res/values-hr/strings.xml | 195 -- InCallUI/res/values-hu/strings.xml | 195 -- InCallUI/res/values-hy/strings.xml | 195 -- InCallUI/res/values-in/strings.xml | 195 -- InCallUI/res/values-is/strings.xml | 195 -- InCallUI/res/values-it/strings.xml | 195 -- InCallUI/res/values-iw/strings.xml | 195 -- InCallUI/res/values-ja/strings.xml | 195 -- InCallUI/res/values-ka/strings.xml | 195 -- InCallUI/res/values-kk/strings.xml | 195 -- InCallUI/res/values-km/strings.xml | 195 -- InCallUI/res/values-kn/strings.xml | 195 -- InCallUI/res/values-ko/strings.xml | 195 -- InCallUI/res/values-ky/strings.xml | 195 -- InCallUI/res/values-lo/strings.xml | 195 -- InCallUI/res/values-lt/strings.xml | 195 -- InCallUI/res/values-lv/strings.xml | 195 -- InCallUI/res/values-mk/strings.xml | 195 -- InCallUI/res/values-ml/strings.xml | 195 -- InCallUI/res/values-mn/strings.xml | 195 -- InCallUI/res/values-mr/strings.xml | 195 -- InCallUI/res/values-ms/strings.xml | 195 -- InCallUI/res/values-my/strings.xml | 195 -- InCallUI/res/values-nb/strings.xml | 195 -- InCallUI/res/values-ne/strings.xml | 195 -- InCallUI/res/values-nl/strings.xml | 195 -- InCallUI/res/values-pa/strings.xml | 195 -- InCallUI/res/values-pl/strings.xml | 195 -- InCallUI/res/values-pt-rBR/strings.xml | 195 -- InCallUI/res/values-pt-rPT/strings.xml | 195 -- InCallUI/res/values-pt/strings.xml | 195 -- InCallUI/res/values-ro/strings.xml | 195 -- InCallUI/res/values-ru/strings.xml | 195 -- InCallUI/res/values-si/strings.xml | 195 -- InCallUI/res/values-sk/strings.xml | 195 -- InCallUI/res/values-sl/strings.xml | 195 -- InCallUI/res/values-sq/strings.xml | 195 -- InCallUI/res/values-sr/strings.xml | 195 -- InCallUI/res/values-sv/strings.xml | 195 -- InCallUI/res/values-sw/strings.xml | 195 -- InCallUI/res/values-sw360dp/dimens.xml | 35 - InCallUI/res/values-sw410dp/config.xml | 21 - InCallUI/res/values-ta/strings.xml | 195 -- InCallUI/res/values-te/strings.xml | 195 -- InCallUI/res/values-th/strings.xml | 195 -- InCallUI/res/values-tl/strings.xml | 195 -- InCallUI/res/values-tr/strings.xml | 195 -- InCallUI/res/values-uk/strings.xml | 195 -- InCallUI/res/values-ur/strings.xml | 195 -- InCallUI/res/values-uz/strings.xml | 195 -- InCallUI/res/values-vi/strings.xml | 195 -- InCallUI/res/values-w500dp-land/colors.xml | 21 - InCallUI/res/values-w500dp-land/dimens.xml | 35 - InCallUI/res/values-zh-rCN/strings.xml | 195 -- InCallUI/res/values-zh-rHK/strings.xml | 195 -- InCallUI/res/values-zh-rTW/strings.xml | 195 -- InCallUI/res/values-zu/strings.xml | 195 -- InCallUI/res/values/animation_constants.xml | 22 - InCallUI/res/values/array.xml | 135 -- InCallUI/res/values/attrs.xml | 71 - InCallUI/res/values/colors.xml | 133 -- InCallUI/res/values/config.xml | 27 - InCallUI/res/values/dimens.xml | 150 -- InCallUI/res/values/ids.xml | 20 - InCallUI/res/values/strings.xml | 540 ------ InCallUI/res/values/styles.xml | 100 - .../android/incallui/AccelerometerListener.java | 169 -- .../android/incallui/AccessibleAnswerFragment.java | 157 -- .../src/com/android/incallui/AnswerFragment.java | 307 ---- .../src/com/android/incallui/AnswerPresenter.java | 312 ---- .../com/android/incallui/AudioModeProvider.java | 105 -- .../src/com/android/incallui/BaseFragment.java | 84 - InCallUI/src/com/android/incallui/Call.java | 1023 ----------- .../com/android/incallui/CallButtonFragment.java | 819 --------- .../com/android/incallui/CallButtonPresenter.java | 486 ----- .../src/com/android/incallui/CallCardFragment.java | 1510 --------------- .../com/android/incallui/CallCardPresenter.java | 1181 ------------ InCallUI/src/com/android/incallui/CallList.java | 695 ------- InCallUI/src/com/android/incallui/CallTimer.java | 90 - InCallUI/src/com/android/incallui/CallerInfo.java | 585 ------ .../com/android/incallui/CallerInfoAsyncQuery.java | 599 ------ .../src/com/android/incallui/CallerInfoUtils.java | 234 --- .../android/incallui/CircularRevealFragment.java | 170 -- .../incallui/ConferenceManagerFragment.java | 139 -- .../incallui/ConferenceManagerPresenter.java | 144 -- .../incallui/ConferenceParticipantListAdapter.java | 533 ------ .../src/com/android/incallui/ContactInfoCache.java | 699 ------- .../src/com/android/incallui/ContactUtils.java | 48 - .../com/android/incallui/ContactsAsyncHelper.java | 258 --- .../incallui/ContactsPreferencesFactory.java | 61 - .../src/com/android/incallui/DialpadFragment.java | 563 ------ .../src/com/android/incallui/DialpadPresenter.java | 84 - .../src/com/android/incallui/DistanceHelper.java | 37 - .../src/com/android/incallui/ExternalCallList.java | 105 -- .../com/android/incallui/ExternalCallNotifier.java | 406 ---- .../android/incallui/FragmentDisplayManager.java | 23 - .../android/incallui/GlowPadAnswerFragment.java | 155 -- .../src/com/android/incallui/GlowPadWrapper.java | 158 -- .../src/com/android/incallui/InCallActivity.java | 980 ---------- .../com/android/incallui/InCallAnimationUtils.java | 184 -- .../com/android/incallui/InCallCameraManager.java | 184 -- .../incallui/InCallContactInteractions.java | 399 ---- .../src/com/android/incallui/InCallDateUtils.java | 53 - .../incallui/InCallOrientationEventListener.java | 178 -- .../src/com/android/incallui/InCallPresenter.java | 1938 -------------------- .../com/android/incallui/InCallServiceImpl.java | 100 - .../android/incallui/InCallServiceListener.java | 41 - .../incallui/InCallUIMaterialColorMapUtils.java | 55 - .../android/incallui/InCallVideoCallCallback.java | 156 -- .../incallui/InCallVideoCallCallbackNotifier.java | 284 --- .../src/com/android/incallui/LatencyReport.java | 145 -- InCallUI/src/com/android/incallui/Log.java | 176 -- .../com/android/incallui/NeededForReflection.java | 30 - .../incallui/NotificationBroadcastReceiver.java | 82 - .../android/incallui/PostCharDialogFragment.java | 95 - InCallUI/src/com/android/incallui/Presenter.java | 59 - .../src/com/android/incallui/ProximitySensor.java | 317 ---- .../com/android/incallui/StatusBarNotifier.java | 793 -------- .../src/com/android/incallui/TelecomAdapter.java | 226 --- InCallUI/src/com/android/incallui/Ui.java | 24 - .../com/android/incallui/VideoCallFragment.java | 901 --------- .../com/android/incallui/VideoCallPresenter.java | 1306 ------------- .../com/android/incallui/VideoPauseController.java | 420 ----- InCallUI/src/com/android/incallui/VideoUtils.java | 109 -- .../android/incallui/async/PausableExecutor.java | 61 - .../incallui/async/PausableExecutorImpl.java | 42 - .../incallui/ringtone/DialerRingtoneManager.java | 140 -- .../incallui/ringtone/InCallTonePlayer.java | 168 -- .../incallui/ringtone/ToneGeneratorFactory.java | 36 - .../incallui/service/PhoneNumberService.java | 67 - .../incallui/spam/SpamCallListListener.java | 117 -- .../android/incallui/util/AccessibilityUtil.java | 30 - .../com/android/incallui/util/TelecomCallUtil.java | 53 - .../incallui/widget/multiwaveview/Ease.java | 132 -- .../incallui/widget/multiwaveview/GlowPadView.java | 1473 --------------- .../incallui/widget/multiwaveview/PointCloud.java | 235 --- .../widget/multiwaveview/TargetDrawable.java | 250 --- .../incallui/widget/multiwaveview/Tweener.java | 178 -- .../com/android/incalluibind/ObjectFactory.java | 59 - .../android/incallui/CallCardPresenterTest.java | 121 -- .../tests/src/com/android/incallui/CallTest.java | 125 -- .../com/android/incallui/CallerInfoUtilsTest.java | 31 - .../incallui/ContactsPreferencesFactoryTest.java | 51 - .../com/android/incallui/ExternalCallListTest.java | 144 -- .../android/incallui/ExternalCallNotifierTest.java | 214 --- .../incallui/InCallContactInteractionsTest.java | 325 ---- .../com/android/incallui/InCallPresenterTest.java | 198 -- .../com/android/incallui/LatencyReportTest.java | 59 - .../com/android/incallui/MockCallListWrapper.java | 80 - .../com/android/incallui/ProximitySensorTest.java | 66 - .../android/incallui/StatusBarNotifierTest.java | 98 - .../src/com/android/incallui/TestTelecomCall.java | 161 -- .../incallui/async/SingleProdThreadExecutor.java | 69 - .../ringtone/DialerRingtoneManagerTest.java | 219 --- .../incallui/ringtone/InCallTonePlayerTest.java | 148 -- .../incallui/spam/SpamCallListListenerTest.java | 206 --- 450 files changed, 47104 deletions(-) delete mode 100644 InCallUI/AndroidManifest.xml delete mode 100644 InCallUI/build.gradle delete mode 100644 InCallUI/proguard.flags delete mode 100644 InCallUI/res/anim/activity_open_enter.xml delete mode 100644 InCallUI/res/anim/activity_open_exit.xml delete mode 100644 InCallUI/res/anim/call_status_pulse.xml delete mode 100644 InCallUI/res/anim/decelerate_cubic.xml delete mode 100644 InCallUI/res/anim/decelerate_quint.xml delete mode 100644 InCallUI/res/color/ota_title_color.xml delete mode 100644 InCallUI/res/color/selectable_icon_tint.xml delete mode 100644 InCallUI/res/drawable-hdpi/fab_blue.png delete mode 100644 InCallUI/res/drawable-hdpi/fab_ic_call.png delete mode 100644 InCallUI/res/drawable-hdpi/fab_ic_end_call.png delete mode 100644 InCallUI/res/drawable-hdpi/fab_ic_message.png delete mode 100644 InCallUI/res/drawable-hdpi/fab_red.png delete mode 100644 InCallUI/res/drawable-hdpi/ic_block_grey600_24dp.png delete mode 100644 InCallUI/res/drawable-hdpi/ic_business_white_24dp.png delete mode 100644 InCallUI/res/drawable-hdpi/ic_call_end_white_24dp.png delete mode 100644 InCallUI/res/drawable-hdpi/ic_call_split_white_24dp.png delete mode 100644 InCallUI/res/drawable-hdpi/ic_call_white_24dp.png delete mode 100644 InCallUI/res/drawable-hdpi/ic_close_grey600_24dp.png delete mode 100644 InCallUI/res/drawable-hdpi/ic_forward_white_24dp.png delete mode 100644 InCallUI/res/drawable-hdpi/ic_hd_24dp.png delete mode 100644 InCallUI/res/drawable-hdpi/ic_location_on_white_24dp.png delete mode 100644 InCallUI/res/drawable-hdpi/ic_lockscreen_glowdot.png delete mode 100644 InCallUI/res/drawable-hdpi/ic_person_add_grey600_24dp.png delete mode 100644 InCallUI/res/drawable-hdpi/ic_phone_paused_white_24dp.png delete mode 100644 InCallUI/res/drawable-hdpi/ic_question_mark.png delete mode 100644 InCallUI/res/drawable-hdpi/ic_report_white_36dp.png delete mode 100644 InCallUI/res/drawable-hdpi/ic_schedule_white_24dp.png delete mode 100644 InCallUI/res/drawable-hdpi/ic_toolbar_add_call.png delete mode 100644 InCallUI/res/drawable-hdpi/ic_toolbar_arrow_whitespace.png delete mode 100644 InCallUI/res/drawable-hdpi/ic_toolbar_audio_bluetooth.png delete mode 100644 InCallUI/res/drawable-hdpi/ic_toolbar_audio_headphones.png delete mode 100644 InCallUI/res/drawable-hdpi/ic_toolbar_audio_phone.png delete mode 100644 InCallUI/res/drawable-hdpi/ic_toolbar_dialpad.png delete mode 100644 InCallUI/res/drawable-hdpi/ic_toolbar_hold.png delete mode 100644 InCallUI/res/drawable-hdpi/ic_toolbar_merge.png delete mode 100644 InCallUI/res/drawable-hdpi/ic_toolbar_mic_off.png delete mode 100644 InCallUI/res/drawable-hdpi/ic_toolbar_speaker_on.png delete mode 100644 InCallUI/res/drawable-hdpi/ic_toolbar_swap.png delete mode 100644 InCallUI/res/drawable-hdpi/ic_toolbar_video.png delete mode 100644 InCallUI/res/drawable-hdpi/ic_toolbar_video_off.png delete mode 100644 InCallUI/res/drawable-hdpi/ic_toolbar_video_switch.png delete mode 100644 InCallUI/res/drawable-hdpi/img_business.png delete mode 100644 InCallUI/res/drawable-hdpi/img_conference.png delete mode 100644 InCallUI/res/drawable-hdpi/img_no_image.png delete mode 100644 InCallUI/res/drawable-hdpi/img_phone.png delete mode 100644 InCallUI/res/drawable-land/rounded_call_card_background.xml delete mode 100644 InCallUI/res/drawable-mdpi/fab_blue.png delete mode 100644 InCallUI/res/drawable-mdpi/fab_ic_call.png delete mode 100644 InCallUI/res/drawable-mdpi/fab_ic_end_call.png delete mode 100644 InCallUI/res/drawable-mdpi/fab_ic_message.png delete mode 100644 InCallUI/res/drawable-mdpi/fab_red.png delete mode 100644 InCallUI/res/drawable-mdpi/ic_block_grey600_24dp.png delete mode 100644 InCallUI/res/drawable-mdpi/ic_business_white_24dp.png delete mode 100644 InCallUI/res/drawable-mdpi/ic_call_end_white_24dp.png delete mode 100644 InCallUI/res/drawable-mdpi/ic_call_split_white_24dp.png delete mode 100644 InCallUI/res/drawable-mdpi/ic_call_white_24dp.png delete mode 100644 InCallUI/res/drawable-mdpi/ic_close_grey600_24dp.png delete mode 100644 InCallUI/res/drawable-mdpi/ic_forward_white_24dp.png delete mode 100644 InCallUI/res/drawable-mdpi/ic_hd_24dp.png delete mode 100644 InCallUI/res/drawable-mdpi/ic_location_on_white_24dp.png delete mode 100644 InCallUI/res/drawable-mdpi/ic_lockscreen_glowdot.png delete mode 100644 InCallUI/res/drawable-mdpi/ic_person_add_grey600_24dp.png delete mode 100644 InCallUI/res/drawable-mdpi/ic_phone_paused_white_24dp.png delete mode 100644 InCallUI/res/drawable-mdpi/ic_question_mark.png delete mode 100644 InCallUI/res/drawable-mdpi/ic_report_white_36dp.png delete mode 100644 InCallUI/res/drawable-mdpi/ic_schedule_white_24dp.png delete mode 100644 InCallUI/res/drawable-mdpi/ic_toolbar_add_call.png delete mode 100644 InCallUI/res/drawable-mdpi/ic_toolbar_arrow_whitespace.png delete mode 100644 InCallUI/res/drawable-mdpi/ic_toolbar_audio_bluetooth.png delete mode 100644 InCallUI/res/drawable-mdpi/ic_toolbar_audio_headphones.png delete mode 100644 InCallUI/res/drawable-mdpi/ic_toolbar_audio_phone.png delete mode 100644 InCallUI/res/drawable-mdpi/ic_toolbar_dialpad.png delete mode 100644 InCallUI/res/drawable-mdpi/ic_toolbar_hold.png delete mode 100644 InCallUI/res/drawable-mdpi/ic_toolbar_merge.png delete mode 100644 InCallUI/res/drawable-mdpi/ic_toolbar_mic_off.png delete mode 100644 InCallUI/res/drawable-mdpi/ic_toolbar_speaker_on.png delete mode 100644 InCallUI/res/drawable-mdpi/ic_toolbar_swap.png delete mode 100644 InCallUI/res/drawable-mdpi/ic_toolbar_video.png delete mode 100644 InCallUI/res/drawable-mdpi/ic_toolbar_video_off.png delete mode 100644 InCallUI/res/drawable-mdpi/ic_toolbar_video_switch.png delete mode 100644 InCallUI/res/drawable-mdpi/img_business.png delete mode 100644 InCallUI/res/drawable-mdpi/img_conference.png delete mode 100644 InCallUI/res/drawable-mdpi/img_no_image.png delete mode 100644 InCallUI/res/drawable-mdpi/img_phone.png delete mode 100644 InCallUI/res/drawable-xhdpi/fab_blue.png delete mode 100644 InCallUI/res/drawable-xhdpi/fab_ic_call.png delete mode 100644 InCallUI/res/drawable-xhdpi/fab_ic_end_call.png delete mode 100644 InCallUI/res/drawable-xhdpi/fab_ic_message.png delete mode 100644 InCallUI/res/drawable-xhdpi/fab_red.png delete mode 100644 InCallUI/res/drawable-xhdpi/ic_block_grey600_24dp.png delete mode 100644 InCallUI/res/drawable-xhdpi/ic_business_white_24dp.png delete mode 100644 InCallUI/res/drawable-xhdpi/ic_call_end_white_24dp.png delete mode 100644 InCallUI/res/drawable-xhdpi/ic_call_split_white_24dp.png delete mode 100644 InCallUI/res/drawable-xhdpi/ic_call_white_24dp.png delete mode 100644 InCallUI/res/drawable-xhdpi/ic_close_grey600_24dp.png delete mode 100644 InCallUI/res/drawable-xhdpi/ic_forward_white_24dp.png delete mode 100644 InCallUI/res/drawable-xhdpi/ic_hd_24dp.png delete mode 100644 InCallUI/res/drawable-xhdpi/ic_location_on_white_24dp.png delete mode 100644 InCallUI/res/drawable-xhdpi/ic_lockscreen_glowdot.png delete mode 100644 InCallUI/res/drawable-xhdpi/ic_person_add_grey600_24dp.png delete mode 100644 InCallUI/res/drawable-xhdpi/ic_phone_paused_white_24dp.png delete mode 100644 InCallUI/res/drawable-xhdpi/ic_question_mark.png delete mode 100644 InCallUI/res/drawable-xhdpi/ic_report_white_36dp.png delete mode 100644 InCallUI/res/drawable-xhdpi/ic_schedule_white_24dp.png delete mode 100644 InCallUI/res/drawable-xhdpi/ic_toolbar_add_call.png delete mode 100644 InCallUI/res/drawable-xhdpi/ic_toolbar_arrow_whitespace.png delete mode 100644 InCallUI/res/drawable-xhdpi/ic_toolbar_audio_bluetooth.png delete mode 100644 InCallUI/res/drawable-xhdpi/ic_toolbar_audio_headphones.png delete mode 100644 InCallUI/res/drawable-xhdpi/ic_toolbar_audio_phone.png delete mode 100644 InCallUI/res/drawable-xhdpi/ic_toolbar_dialpad.png delete mode 100644 InCallUI/res/drawable-xhdpi/ic_toolbar_hold.png delete mode 100644 InCallUI/res/drawable-xhdpi/ic_toolbar_merge.png delete mode 100644 InCallUI/res/drawable-xhdpi/ic_toolbar_mic_off.png delete mode 100644 InCallUI/res/drawable-xhdpi/ic_toolbar_speaker_on.png delete mode 100644 InCallUI/res/drawable-xhdpi/ic_toolbar_swap.png delete mode 100644 InCallUI/res/drawable-xhdpi/ic_toolbar_video.png delete mode 100644 InCallUI/res/drawable-xhdpi/ic_toolbar_video_off.png delete mode 100644 InCallUI/res/drawable-xhdpi/ic_toolbar_video_switch.png delete mode 100644 InCallUI/res/drawable-xhdpi/img_business.png delete mode 100644 InCallUI/res/drawable-xhdpi/img_conference.png delete mode 100644 InCallUI/res/drawable-xhdpi/img_no_image.png delete mode 100644 InCallUI/res/drawable-xhdpi/img_phone.png delete mode 100644 InCallUI/res/drawable-xxhdpi/fab_blue.png delete mode 100644 InCallUI/res/drawable-xxhdpi/fab_ic_call.png delete mode 100644 InCallUI/res/drawable-xxhdpi/fab_ic_end_call.png delete mode 100644 InCallUI/res/drawable-xxhdpi/fab_ic_message.png delete mode 100644 InCallUI/res/drawable-xxhdpi/fab_red.png delete mode 100644 InCallUI/res/drawable-xxhdpi/ic_block_grey600_24dp.png delete mode 100644 InCallUI/res/drawable-xxhdpi/ic_business_white_24dp.png delete mode 100644 InCallUI/res/drawable-xxhdpi/ic_call_end_white_24dp.png delete mode 100644 InCallUI/res/drawable-xxhdpi/ic_call_split_white_24dp.png delete mode 100644 InCallUI/res/drawable-xxhdpi/ic_call_white_24dp.png delete mode 100644 InCallUI/res/drawable-xxhdpi/ic_close_grey600_24dp.png delete mode 100644 InCallUI/res/drawable-xxhdpi/ic_forward_white_24dp.png delete mode 100644 InCallUI/res/drawable-xxhdpi/ic_hd_24dp.png delete mode 100644 InCallUI/res/drawable-xxhdpi/ic_location_on_white_24dp.png delete mode 100644 InCallUI/res/drawable-xxhdpi/ic_lockscreen_glowdot.png delete mode 100644 InCallUI/res/drawable-xxhdpi/ic_person_add_grey600_24dp.png delete mode 100644 InCallUI/res/drawable-xxhdpi/ic_phone_paused_white_24dp.png delete mode 100644 InCallUI/res/drawable-xxhdpi/ic_question_mark.png delete mode 100644 InCallUI/res/drawable-xxhdpi/ic_report_white_36dp.png delete mode 100644 InCallUI/res/drawable-xxhdpi/ic_schedule_white_24dp.png delete mode 100644 InCallUI/res/drawable-xxhdpi/ic_toolbar_add_call.png delete mode 100644 InCallUI/res/drawable-xxhdpi/ic_toolbar_arrow_whitespace.png delete mode 100644 InCallUI/res/drawable-xxhdpi/ic_toolbar_audio_bluetooth.png delete mode 100644 InCallUI/res/drawable-xxhdpi/ic_toolbar_audio_headphones.png delete mode 100644 InCallUI/res/drawable-xxhdpi/ic_toolbar_audio_phone.png delete mode 100644 InCallUI/res/drawable-xxhdpi/ic_toolbar_dialpad.png delete mode 100644 InCallUI/res/drawable-xxhdpi/ic_toolbar_hold.png delete mode 100644 InCallUI/res/drawable-xxhdpi/ic_toolbar_merge.png delete mode 100644 InCallUI/res/drawable-xxhdpi/ic_toolbar_mic_off.png delete mode 100644 InCallUI/res/drawable-xxhdpi/ic_toolbar_speaker_on.png delete mode 100644 InCallUI/res/drawable-xxhdpi/ic_toolbar_swap.png delete mode 100644 InCallUI/res/drawable-xxhdpi/ic_toolbar_video.png delete mode 100644 InCallUI/res/drawable-xxhdpi/ic_toolbar_video_off.png delete mode 100644 InCallUI/res/drawable-xxhdpi/ic_toolbar_video_switch.png delete mode 100644 InCallUI/res/drawable-xxhdpi/img_business.png delete mode 100644 InCallUI/res/drawable-xxhdpi/img_conference.png delete mode 100644 InCallUI/res/drawable-xxhdpi/img_no_image.png delete mode 100644 InCallUI/res/drawable-xxhdpi/img_phone.png delete mode 100644 InCallUI/res/drawable-xxxhdpi/fab_blue.png delete mode 100644 InCallUI/res/drawable-xxxhdpi/fab_ic_call.png delete mode 100644 InCallUI/res/drawable-xxxhdpi/fab_ic_end_call.png delete mode 100644 InCallUI/res/drawable-xxxhdpi/fab_ic_message.png delete mode 100644 InCallUI/res/drawable-xxxhdpi/fab_red.png delete mode 100644 InCallUI/res/drawable-xxxhdpi/ic_block_grey600_24dp.png delete mode 100644 InCallUI/res/drawable-xxxhdpi/ic_business_white_24dp.png delete mode 100644 InCallUI/res/drawable-xxxhdpi/ic_call_end_white_24dp.png delete mode 100644 InCallUI/res/drawable-xxxhdpi/ic_call_split_white_24dp.png delete mode 100644 InCallUI/res/drawable-xxxhdpi/ic_close_grey600_24dp.png delete mode 100644 InCallUI/res/drawable-xxxhdpi/ic_forward_white_24dp.png delete mode 100644 InCallUI/res/drawable-xxxhdpi/ic_hd_24dp.png delete mode 100644 InCallUI/res/drawable-xxxhdpi/ic_location_on_white_24dp.png delete mode 100644 InCallUI/res/drawable-xxxhdpi/ic_person_add_grey600_24dp.png delete mode 100644 InCallUI/res/drawable-xxxhdpi/ic_question_mark.png delete mode 100644 InCallUI/res/drawable-xxxhdpi/ic_report_white_36dp.png delete mode 100644 InCallUI/res/drawable-xxxhdpi/ic_schedule_white_24dp.png delete mode 100644 InCallUI/res/drawable-xxxhdpi/ic_toolbar_add_call.png delete mode 100644 InCallUI/res/drawable-xxxhdpi/ic_toolbar_arrow_whitespace.png delete mode 100644 InCallUI/res/drawable-xxxhdpi/ic_toolbar_audio_bluetooth.png delete mode 100644 InCallUI/res/drawable-xxxhdpi/ic_toolbar_audio_headphones.png delete mode 100644 InCallUI/res/drawable-xxxhdpi/ic_toolbar_audio_phone.png delete mode 100644 InCallUI/res/drawable-xxxhdpi/ic_toolbar_dialpad.png delete mode 100644 InCallUI/res/drawable-xxxhdpi/ic_toolbar_hold.png delete mode 100644 InCallUI/res/drawable-xxxhdpi/ic_toolbar_merge.png delete mode 100644 InCallUI/res/drawable-xxxhdpi/ic_toolbar_mic_off.png delete mode 100644 InCallUI/res/drawable-xxxhdpi/ic_toolbar_speaker_on.png delete mode 100644 InCallUI/res/drawable-xxxhdpi/ic_toolbar_swap.png delete mode 100644 InCallUI/res/drawable-xxxhdpi/ic_toolbar_video.png delete mode 100644 InCallUI/res/drawable-xxxhdpi/ic_toolbar_video_off.png delete mode 100644 InCallUI/res/drawable-xxxhdpi/ic_toolbar_video_switch.png delete mode 100644 InCallUI/res/drawable-xxxhdpi/img_business.png delete mode 100644 InCallUI/res/drawable-xxxhdpi/img_conference.png delete mode 100644 InCallUI/res/drawable-xxxhdpi/img_no_image.png delete mode 100644 InCallUI/res/drawable-xxxhdpi/img_phone.png delete mode 100644 InCallUI/res/drawable/btn_add.xml delete mode 100644 InCallUI/res/drawable/btn_background.xml delete mode 100644 InCallUI/res/drawable/btn_change_to_video.xml delete mode 100644 InCallUI/res/drawable/btn_change_to_voice.xml delete mode 100644 InCallUI/res/drawable/btn_compound_audio.xml delete mode 100644 InCallUI/res/drawable/btn_compound_background.xml delete mode 100644 InCallUI/res/drawable/btn_compound_dialpad.xml delete mode 100644 InCallUI/res/drawable/btn_compound_hold.xml delete mode 100644 InCallUI/res/drawable/btn_compound_mute.xml delete mode 100644 InCallUI/res/drawable/btn_compound_video_off.xml delete mode 100644 InCallUI/res/drawable/btn_compound_video_switch.xml delete mode 100644 InCallUI/res/drawable/btn_merge.xml delete mode 100644 InCallUI/res/drawable/btn_overflow.xml delete mode 100644 InCallUI/res/drawable/btn_selected.xml delete mode 100644 InCallUI/res/drawable/btn_selected_focused.xml delete mode 100644 InCallUI/res/drawable/btn_swap.xml delete mode 100644 InCallUI/res/drawable/btn_unselected.xml delete mode 100644 InCallUI/res/drawable/btn_unselected_focused.xml delete mode 100644 InCallUI/res/drawable/conference_ripple.xml delete mode 100644 InCallUI/res/drawable/end_call_background.xml delete mode 100644 InCallUI/res/drawable/ic_incall_audio_handle.xml delete mode 100644 InCallUI/res/drawable/ic_incall_video_handle.xml delete mode 100644 InCallUI/res/drawable/ic_lockscreen_answer.xml delete mode 100644 InCallUI/res/drawable/ic_lockscreen_answer_activated_layer.xml delete mode 100644 InCallUI/res/drawable/ic_lockscreen_answer_normal_layer.xml delete mode 100644 InCallUI/res/drawable/ic_lockscreen_answer_video.xml delete mode 100644 InCallUI/res/drawable/ic_lockscreen_answer_video_activated_layer.xml delete mode 100644 InCallUI/res/drawable/ic_lockscreen_answer_video_normal_layer.xml delete mode 100644 InCallUI/res/drawable/ic_lockscreen_decline.xml delete mode 100644 InCallUI/res/drawable/ic_lockscreen_decline_activated_layer.xml delete mode 100644 InCallUI/res/drawable/ic_lockscreen_decline_normal_layer.xml delete mode 100644 InCallUI/res/drawable/ic_lockscreen_decline_video.xml delete mode 100644 InCallUI/res/drawable/ic_lockscreen_decline_video_activated_layer.xml delete mode 100644 InCallUI/res/drawable/ic_lockscreen_decline_video_normal_layer.xml delete mode 100644 InCallUI/res/drawable/ic_lockscreen_outerring.xml delete mode 100644 InCallUI/res/drawable/ic_lockscreen_text.xml delete mode 100644 InCallUI/res/drawable/ic_lockscreen_text_activated_layer.xml delete mode 100644 InCallUI/res/drawable/ic_lockscreen_text_normal_layer.xml delete mode 100644 InCallUI/res/drawable/img_conference_automirrored.xml delete mode 100644 InCallUI/res/drawable/img_no_image_automirrored.xml delete mode 100644 InCallUI/res/drawable/incoming_sms_background.xml delete mode 100644 InCallUI/res/drawable/outgoing_sms_background.xml delete mode 100644 InCallUI/res/drawable/spam_notification_icon.xml delete mode 100644 InCallUI/res/drawable/subject_bubble.xml delete mode 100644 InCallUI/res/drawable/unknown_notification_icon.xml delete mode 100644 InCallUI/res/layout-h400dp/call_card_fragment.xml delete mode 100644 InCallUI/res/layout-h600dp/manage_conference_call_button.xml delete mode 100644 InCallUI/res/layout-w500dp-land/call_card_fragment.xml delete mode 100644 InCallUI/res/layout-w600dp-land/manage_conference_call_button.xml delete mode 100644 InCallUI/res/layout/accessible_answer_fragment.xml delete mode 100644 InCallUI/res/layout/answer_fragment.xml delete mode 100644 InCallUI/res/layout/business_contact_context_list_header.xml delete mode 100644 InCallUI/res/layout/business_context_info_list_item.xml delete mode 100644 InCallUI/res/layout/call_button_fragment.xml delete mode 100644 InCallUI/res/layout/call_card_fragment.xml delete mode 100644 InCallUI/res/layout/caller_in_conference.xml delete mode 100644 InCallUI/res/layout/conference_manager_fragment.xml delete mode 100644 InCallUI/res/layout/incall_dialpad_fragment.xml delete mode 100644 InCallUI/res/layout/incall_screen.xml delete mode 100644 InCallUI/res/layout/manage_conference_call_button.xml delete mode 100644 InCallUI/res/layout/outgoing_call_animation.xml delete mode 100644 InCallUI/res/layout/person_context_info_list_item.xml delete mode 100644 InCallUI/res/layout/primary_call_info.xml delete mode 100644 InCallUI/res/layout/secondary_call_info.xml delete mode 100644 InCallUI/res/layout/video_call_fragment.xml delete mode 100644 InCallUI/res/layout/video_call_views.xml delete mode 100644 InCallUI/res/menu/incall_audio_mode_menu.xml delete mode 100644 InCallUI/res/values-af/strings.xml delete mode 100644 InCallUI/res/values-am/strings.xml delete mode 100644 InCallUI/res/values-ar/strings.xml delete mode 100644 InCallUI/res/values-az/strings.xml delete mode 100644 InCallUI/res/values-b+sr+Latn/strings.xml delete mode 100644 InCallUI/res/values-be/strings.xml delete mode 100644 InCallUI/res/values-bg/strings.xml delete mode 100644 InCallUI/res/values-bn/strings.xml delete mode 100644 InCallUI/res/values-bs/strings.xml delete mode 100644 InCallUI/res/values-ca/strings.xml delete mode 100644 InCallUI/res/values-cs/strings.xml delete mode 100644 InCallUI/res/values-da/strings.xml delete mode 100644 InCallUI/res/values-de/strings.xml delete mode 100644 InCallUI/res/values-el/strings.xml delete mode 100644 InCallUI/res/values-en-rAU/strings.xml delete mode 100644 InCallUI/res/values-en-rGB/strings.xml delete mode 100644 InCallUI/res/values-en-rIN/strings.xml delete mode 100644 InCallUI/res/values-es-rUS/strings.xml delete mode 100644 InCallUI/res/values-es/strings.xml delete mode 100644 InCallUI/res/values-et/strings.xml delete mode 100644 InCallUI/res/values-eu/strings.xml delete mode 100644 InCallUI/res/values-fa/strings.xml delete mode 100644 InCallUI/res/values-fi/strings.xml delete mode 100644 InCallUI/res/values-fr-rCA/strings.xml delete mode 100644 InCallUI/res/values-fr/strings.xml delete mode 100644 InCallUI/res/values-gl/strings.xml delete mode 100644 InCallUI/res/values-gu/strings.xml delete mode 100644 InCallUI/res/values-h400dp/dimens.xml delete mode 100644 InCallUI/res/values-hi/strings.xml delete mode 100644 InCallUI/res/values-hr/strings.xml delete mode 100644 InCallUI/res/values-hu/strings.xml delete mode 100644 InCallUI/res/values-hy/strings.xml delete mode 100644 InCallUI/res/values-in/strings.xml delete mode 100644 InCallUI/res/values-is/strings.xml delete mode 100644 InCallUI/res/values-it/strings.xml delete mode 100644 InCallUI/res/values-iw/strings.xml delete mode 100644 InCallUI/res/values-ja/strings.xml delete mode 100644 InCallUI/res/values-ka/strings.xml delete mode 100644 InCallUI/res/values-kk/strings.xml delete mode 100644 InCallUI/res/values-km/strings.xml delete mode 100644 InCallUI/res/values-kn/strings.xml delete mode 100644 InCallUI/res/values-ko/strings.xml delete mode 100644 InCallUI/res/values-ky/strings.xml delete mode 100644 InCallUI/res/values-lo/strings.xml delete mode 100644 InCallUI/res/values-lt/strings.xml delete mode 100644 InCallUI/res/values-lv/strings.xml delete mode 100644 InCallUI/res/values-mk/strings.xml delete mode 100644 InCallUI/res/values-ml/strings.xml delete mode 100644 InCallUI/res/values-mn/strings.xml delete mode 100644 InCallUI/res/values-mr/strings.xml delete mode 100644 InCallUI/res/values-ms/strings.xml delete mode 100644 InCallUI/res/values-my/strings.xml delete mode 100644 InCallUI/res/values-nb/strings.xml delete mode 100644 InCallUI/res/values-ne/strings.xml delete mode 100644 InCallUI/res/values-nl/strings.xml delete mode 100644 InCallUI/res/values-pa/strings.xml delete mode 100644 InCallUI/res/values-pl/strings.xml delete mode 100644 InCallUI/res/values-pt-rBR/strings.xml delete mode 100644 InCallUI/res/values-pt-rPT/strings.xml delete mode 100644 InCallUI/res/values-pt/strings.xml delete mode 100644 InCallUI/res/values-ro/strings.xml delete mode 100644 InCallUI/res/values-ru/strings.xml delete mode 100644 InCallUI/res/values-si/strings.xml delete mode 100644 InCallUI/res/values-sk/strings.xml delete mode 100644 InCallUI/res/values-sl/strings.xml delete mode 100644 InCallUI/res/values-sq/strings.xml delete mode 100644 InCallUI/res/values-sr/strings.xml delete mode 100644 InCallUI/res/values-sv/strings.xml delete mode 100644 InCallUI/res/values-sw/strings.xml delete mode 100644 InCallUI/res/values-sw360dp/dimens.xml delete mode 100644 InCallUI/res/values-sw410dp/config.xml delete mode 100644 InCallUI/res/values-ta/strings.xml delete mode 100644 InCallUI/res/values-te/strings.xml delete mode 100644 InCallUI/res/values-th/strings.xml delete mode 100644 InCallUI/res/values-tl/strings.xml delete mode 100644 InCallUI/res/values-tr/strings.xml delete mode 100644 InCallUI/res/values-uk/strings.xml delete mode 100644 InCallUI/res/values-ur/strings.xml delete mode 100644 InCallUI/res/values-uz/strings.xml delete mode 100644 InCallUI/res/values-vi/strings.xml delete mode 100644 InCallUI/res/values-w500dp-land/colors.xml delete mode 100644 InCallUI/res/values-w500dp-land/dimens.xml delete mode 100644 InCallUI/res/values-zh-rCN/strings.xml delete mode 100644 InCallUI/res/values-zh-rHK/strings.xml delete mode 100644 InCallUI/res/values-zh-rTW/strings.xml delete mode 100644 InCallUI/res/values-zu/strings.xml delete mode 100644 InCallUI/res/values/animation_constants.xml delete mode 100644 InCallUI/res/values/array.xml delete mode 100644 InCallUI/res/values/attrs.xml delete mode 100644 InCallUI/res/values/colors.xml delete mode 100644 InCallUI/res/values/config.xml delete mode 100644 InCallUI/res/values/dimens.xml delete mode 100644 InCallUI/res/values/ids.xml delete mode 100644 InCallUI/res/values/strings.xml delete mode 100644 InCallUI/res/values/styles.xml delete mode 100644 InCallUI/src/com/android/incallui/AccelerometerListener.java delete mode 100644 InCallUI/src/com/android/incallui/AccessibleAnswerFragment.java delete mode 100644 InCallUI/src/com/android/incallui/AnswerFragment.java delete mode 100644 InCallUI/src/com/android/incallui/AnswerPresenter.java delete mode 100644 InCallUI/src/com/android/incallui/AudioModeProvider.java delete mode 100644 InCallUI/src/com/android/incallui/BaseFragment.java delete mode 100644 InCallUI/src/com/android/incallui/Call.java delete mode 100644 InCallUI/src/com/android/incallui/CallButtonFragment.java delete mode 100644 InCallUI/src/com/android/incallui/CallButtonPresenter.java delete mode 100644 InCallUI/src/com/android/incallui/CallCardFragment.java delete mode 100644 InCallUI/src/com/android/incallui/CallCardPresenter.java delete mode 100644 InCallUI/src/com/android/incallui/CallList.java delete mode 100644 InCallUI/src/com/android/incallui/CallTimer.java delete mode 100644 InCallUI/src/com/android/incallui/CallerInfo.java delete mode 100644 InCallUI/src/com/android/incallui/CallerInfoAsyncQuery.java delete mode 100644 InCallUI/src/com/android/incallui/CallerInfoUtils.java delete mode 100644 InCallUI/src/com/android/incallui/CircularRevealFragment.java delete mode 100644 InCallUI/src/com/android/incallui/ConferenceManagerFragment.java delete mode 100644 InCallUI/src/com/android/incallui/ConferenceManagerPresenter.java delete mode 100644 InCallUI/src/com/android/incallui/ConferenceParticipantListAdapter.java delete mode 100644 InCallUI/src/com/android/incallui/ContactInfoCache.java delete mode 100644 InCallUI/src/com/android/incallui/ContactUtils.java delete mode 100644 InCallUI/src/com/android/incallui/ContactsAsyncHelper.java delete mode 100644 InCallUI/src/com/android/incallui/ContactsPreferencesFactory.java delete mode 100644 InCallUI/src/com/android/incallui/DialpadFragment.java delete mode 100644 InCallUI/src/com/android/incallui/DialpadPresenter.java delete mode 100644 InCallUI/src/com/android/incallui/DistanceHelper.java delete mode 100644 InCallUI/src/com/android/incallui/ExternalCallList.java delete mode 100644 InCallUI/src/com/android/incallui/ExternalCallNotifier.java delete mode 100644 InCallUI/src/com/android/incallui/FragmentDisplayManager.java delete mode 100644 InCallUI/src/com/android/incallui/GlowPadAnswerFragment.java delete mode 100644 InCallUI/src/com/android/incallui/GlowPadWrapper.java delete mode 100644 InCallUI/src/com/android/incallui/InCallActivity.java delete mode 100644 InCallUI/src/com/android/incallui/InCallAnimationUtils.java delete mode 100644 InCallUI/src/com/android/incallui/InCallCameraManager.java delete mode 100644 InCallUI/src/com/android/incallui/InCallContactInteractions.java delete mode 100644 InCallUI/src/com/android/incallui/InCallDateUtils.java delete mode 100644 InCallUI/src/com/android/incallui/InCallOrientationEventListener.java delete mode 100644 InCallUI/src/com/android/incallui/InCallPresenter.java delete mode 100644 InCallUI/src/com/android/incallui/InCallServiceImpl.java delete mode 100644 InCallUI/src/com/android/incallui/InCallServiceListener.java delete mode 100644 InCallUI/src/com/android/incallui/InCallUIMaterialColorMapUtils.java delete mode 100644 InCallUI/src/com/android/incallui/InCallVideoCallCallback.java delete mode 100644 InCallUI/src/com/android/incallui/InCallVideoCallCallbackNotifier.java delete mode 100644 InCallUI/src/com/android/incallui/LatencyReport.java delete mode 100644 InCallUI/src/com/android/incallui/Log.java delete mode 100644 InCallUI/src/com/android/incallui/NeededForReflection.java delete mode 100644 InCallUI/src/com/android/incallui/NotificationBroadcastReceiver.java delete mode 100644 InCallUI/src/com/android/incallui/PostCharDialogFragment.java delete mode 100644 InCallUI/src/com/android/incallui/Presenter.java delete mode 100644 InCallUI/src/com/android/incallui/ProximitySensor.java delete mode 100644 InCallUI/src/com/android/incallui/StatusBarNotifier.java delete mode 100644 InCallUI/src/com/android/incallui/TelecomAdapter.java delete mode 100644 InCallUI/src/com/android/incallui/Ui.java delete mode 100644 InCallUI/src/com/android/incallui/VideoCallFragment.java delete mode 100644 InCallUI/src/com/android/incallui/VideoCallPresenter.java delete mode 100644 InCallUI/src/com/android/incallui/VideoPauseController.java delete mode 100644 InCallUI/src/com/android/incallui/VideoUtils.java delete mode 100644 InCallUI/src/com/android/incallui/async/PausableExecutor.java delete mode 100644 InCallUI/src/com/android/incallui/async/PausableExecutorImpl.java delete mode 100644 InCallUI/src/com/android/incallui/ringtone/DialerRingtoneManager.java delete mode 100644 InCallUI/src/com/android/incallui/ringtone/InCallTonePlayer.java delete mode 100644 InCallUI/src/com/android/incallui/ringtone/ToneGeneratorFactory.java delete mode 100644 InCallUI/src/com/android/incallui/service/PhoneNumberService.java delete mode 100644 InCallUI/src/com/android/incallui/spam/SpamCallListListener.java delete mode 100644 InCallUI/src/com/android/incallui/util/AccessibilityUtil.java delete mode 100644 InCallUI/src/com/android/incallui/util/TelecomCallUtil.java delete mode 100644 InCallUI/src/com/android/incallui/widget/multiwaveview/Ease.java delete mode 100644 InCallUI/src/com/android/incallui/widget/multiwaveview/GlowPadView.java delete mode 100644 InCallUI/src/com/android/incallui/widget/multiwaveview/PointCloud.java delete mode 100644 InCallUI/src/com/android/incallui/widget/multiwaveview/TargetDrawable.java delete mode 100644 InCallUI/src/com/android/incallui/widget/multiwaveview/Tweener.java delete mode 100644 InCallUI/src/com/android/incalluibind/ObjectFactory.java delete mode 100644 InCallUI/tests/src/com/android/incallui/CallCardPresenterTest.java delete mode 100644 InCallUI/tests/src/com/android/incallui/CallTest.java delete mode 100644 InCallUI/tests/src/com/android/incallui/CallerInfoUtilsTest.java delete mode 100644 InCallUI/tests/src/com/android/incallui/ContactsPreferencesFactoryTest.java delete mode 100644 InCallUI/tests/src/com/android/incallui/ExternalCallListTest.java delete mode 100644 InCallUI/tests/src/com/android/incallui/ExternalCallNotifierTest.java delete mode 100644 InCallUI/tests/src/com/android/incallui/InCallContactInteractionsTest.java delete mode 100644 InCallUI/tests/src/com/android/incallui/InCallPresenterTest.java delete mode 100644 InCallUI/tests/src/com/android/incallui/LatencyReportTest.java delete mode 100644 InCallUI/tests/src/com/android/incallui/MockCallListWrapper.java delete mode 100644 InCallUI/tests/src/com/android/incallui/ProximitySensorTest.java delete mode 100644 InCallUI/tests/src/com/android/incallui/StatusBarNotifierTest.java delete mode 100644 InCallUI/tests/src/com/android/incallui/TestTelecomCall.java delete mode 100644 InCallUI/tests/src/com/android/incallui/async/SingleProdThreadExecutor.java delete mode 100644 InCallUI/tests/src/com/android/incallui/ringtone/DialerRingtoneManagerTest.java delete mode 100644 InCallUI/tests/src/com/android/incallui/ringtone/InCallTonePlayerTest.java delete mode 100644 InCallUI/tests/src/com/android/incallui/spam/SpamCallListListenerTest.java (limited to 'InCallUI') diff --git a/InCallUI/AndroidManifest.xml b/InCallUI/AndroidManifest.xml deleted file mode 100644 index 5c758edaa..000000000 --- a/InCallUI/AndroidManifest.xml +++ /dev/null @@ -1,24 +0,0 @@ - - - - - - - diff --git a/InCallUI/build.gradle b/InCallUI/build.gradle deleted file mode 100644 index de4725199..000000000 --- a/InCallUI/build.gradle +++ /dev/null @@ -1,14 +0,0 @@ -apply plugin: 'com.android.library' - -android { - sourceSets.main { - manifest.srcFile 'AndroidManifest.xml' - res.srcDirs = ['res'] - } -} - -dependencies { - compile 'com.android.support:support-v4:23.1.+' - compile project(':phonecommon') - compile project(':contactscommon') -} diff --git a/InCallUI/proguard.flags b/InCallUI/proguard.flags deleted file mode 100644 index 4e8310ca9..000000000 --- a/InCallUI/proguard.flags +++ /dev/null @@ -1,14 +0,0 @@ --keep class com.android.incallui.widget.multiwaveview.* { - *; -} - -# Keep names that are used only by animation framework. --keepclasseswithmembers class com.android.incallui.AnimationUtils$CrossFadeDrawable { - *** setCrossFadeAlpha(...); -} - -# Any class or method annotated with NeededForTesting or NeededForReflection. --keepclassmembers class * { -@com.android.contacts.common.test.NeededForTesting *; -@com.android.incallui.NeededForReflection *; -} diff --git a/InCallUI/res/anim/activity_open_enter.xml b/InCallUI/res/anim/activity_open_enter.xml deleted file mode 100644 index 303b9ddc0..000000000 --- a/InCallUI/res/anim/activity_open_enter.xml +++ /dev/null @@ -1,35 +0,0 @@ - - - - - - - \ No newline at end of file diff --git a/InCallUI/res/anim/activity_open_exit.xml b/InCallUI/res/anim/activity_open_exit.xml deleted file mode 100644 index afa7c5e72..000000000 --- a/InCallUI/res/anim/activity_open_exit.xml +++ /dev/null @@ -1,26 +0,0 @@ - - - - - - \ No newline at end of file diff --git a/InCallUI/res/anim/call_status_pulse.xml b/InCallUI/res/anim/call_status_pulse.xml deleted file mode 100644 index abda25b73..000000000 --- a/InCallUI/res/anim/call_status_pulse.xml +++ /dev/null @@ -1,22 +0,0 @@ - - - diff --git a/InCallUI/res/anim/decelerate_cubic.xml b/InCallUI/res/anim/decelerate_cubic.xml deleted file mode 100644 index f98809165..000000000 --- a/InCallUI/res/anim/decelerate_cubic.xml +++ /dev/null @@ -1,21 +0,0 @@ - - - - diff --git a/InCallUI/res/anim/decelerate_quint.xml b/InCallUI/res/anim/decelerate_quint.xml deleted file mode 100644 index ff2d5a9d0..000000000 --- a/InCallUI/res/anim/decelerate_quint.xml +++ /dev/null @@ -1,21 +0,0 @@ - - - - diff --git a/InCallUI/res/color/ota_title_color.xml b/InCallUI/res/color/ota_title_color.xml deleted file mode 100644 index 14a283a6b..000000000 --- a/InCallUI/res/color/ota_title_color.xml +++ /dev/null @@ -1,21 +0,0 @@ - - - - - - - diff --git a/InCallUI/res/color/selectable_icon_tint.xml b/InCallUI/res/color/selectable_icon_tint.xml deleted file mode 100644 index b8aad1303..000000000 --- a/InCallUI/res/color/selectable_icon_tint.xml +++ /dev/null @@ -1,24 +0,0 @@ - - - - - - - - - - diff --git a/InCallUI/res/drawable-hdpi/fab_blue.png b/InCallUI/res/drawable-hdpi/fab_blue.png deleted file mode 100644 index 8ff3d2918..000000000 Binary files a/InCallUI/res/drawable-hdpi/fab_blue.png and /dev/null differ diff --git a/InCallUI/res/drawable-hdpi/fab_ic_call.png b/InCallUI/res/drawable-hdpi/fab_ic_call.png deleted file mode 100644 index 548a391a6..000000000 Binary files a/InCallUI/res/drawable-hdpi/fab_ic_call.png and /dev/null differ diff --git a/InCallUI/res/drawable-hdpi/fab_ic_end_call.png b/InCallUI/res/drawable-hdpi/fab_ic_end_call.png deleted file mode 100644 index b7f54d3bb..000000000 Binary files a/InCallUI/res/drawable-hdpi/fab_ic_end_call.png and /dev/null differ diff --git a/InCallUI/res/drawable-hdpi/fab_ic_message.png b/InCallUI/res/drawable-hdpi/fab_ic_message.png deleted file mode 100644 index a1cf2ad82..000000000 Binary files a/InCallUI/res/drawable-hdpi/fab_ic_message.png and /dev/null differ diff --git a/InCallUI/res/drawable-hdpi/fab_red.png b/InCallUI/res/drawable-hdpi/fab_red.png deleted file mode 100644 index 497cc7916..000000000 Binary files a/InCallUI/res/drawable-hdpi/fab_red.png and /dev/null differ diff --git a/InCallUI/res/drawable-hdpi/ic_block_grey600_24dp.png b/InCallUI/res/drawable-hdpi/ic_block_grey600_24dp.png deleted file mode 100644 index 1e9294c12..000000000 Binary files a/InCallUI/res/drawable-hdpi/ic_block_grey600_24dp.png and /dev/null differ diff --git a/InCallUI/res/drawable-hdpi/ic_business_white_24dp.png b/InCallUI/res/drawable-hdpi/ic_business_white_24dp.png deleted file mode 100644 index d10ebb766..000000000 Binary files a/InCallUI/res/drawable-hdpi/ic_business_white_24dp.png and /dev/null differ diff --git a/InCallUI/res/drawable-hdpi/ic_call_end_white_24dp.png b/InCallUI/res/drawable-hdpi/ic_call_end_white_24dp.png deleted file mode 100644 index 757d339c4..000000000 Binary files a/InCallUI/res/drawable-hdpi/ic_call_end_white_24dp.png and /dev/null differ diff --git a/InCallUI/res/drawable-hdpi/ic_call_split_white_24dp.png b/InCallUI/res/drawable-hdpi/ic_call_split_white_24dp.png deleted file mode 100644 index 4e3dbf55d..000000000 Binary files a/InCallUI/res/drawable-hdpi/ic_call_split_white_24dp.png and /dev/null differ diff --git a/InCallUI/res/drawable-hdpi/ic_call_white_24dp.png b/InCallUI/res/drawable-hdpi/ic_call_white_24dp.png deleted file mode 100644 index 1902e721b..000000000 Binary files a/InCallUI/res/drawable-hdpi/ic_call_white_24dp.png and /dev/null differ diff --git a/InCallUI/res/drawable-hdpi/ic_close_grey600_24dp.png b/InCallUI/res/drawable-hdpi/ic_close_grey600_24dp.png deleted file mode 100644 index 9ab350e9a..000000000 Binary files a/InCallUI/res/drawable-hdpi/ic_close_grey600_24dp.png and /dev/null differ diff --git a/InCallUI/res/drawable-hdpi/ic_forward_white_24dp.png b/InCallUI/res/drawable-hdpi/ic_forward_white_24dp.png deleted file mode 100644 index a0711d377..000000000 Binary files a/InCallUI/res/drawable-hdpi/ic_forward_white_24dp.png and /dev/null differ diff --git a/InCallUI/res/drawable-hdpi/ic_hd_24dp.png b/InCallUI/res/drawable-hdpi/ic_hd_24dp.png deleted file mode 100644 index 35bf51a4f..000000000 Binary files a/InCallUI/res/drawable-hdpi/ic_hd_24dp.png and /dev/null differ diff --git a/InCallUI/res/drawable-hdpi/ic_location_on_white_24dp.png b/InCallUI/res/drawable-hdpi/ic_location_on_white_24dp.png deleted file mode 100644 index 7c281c3f5..000000000 Binary files a/InCallUI/res/drawable-hdpi/ic_location_on_white_24dp.png and /dev/null differ diff --git a/InCallUI/res/drawable-hdpi/ic_lockscreen_glowdot.png b/InCallUI/res/drawable-hdpi/ic_lockscreen_glowdot.png deleted file mode 100644 index 983c45e2c..000000000 Binary files a/InCallUI/res/drawable-hdpi/ic_lockscreen_glowdot.png and /dev/null differ diff --git a/InCallUI/res/drawable-hdpi/ic_person_add_grey600_24dp.png b/InCallUI/res/drawable-hdpi/ic_person_add_grey600_24dp.png deleted file mode 100644 index 185d03393..000000000 Binary files a/InCallUI/res/drawable-hdpi/ic_person_add_grey600_24dp.png and /dev/null differ diff --git a/InCallUI/res/drawable-hdpi/ic_phone_paused_white_24dp.png b/InCallUI/res/drawable-hdpi/ic_phone_paused_white_24dp.png deleted file mode 100644 index a2177f58a..000000000 Binary files a/InCallUI/res/drawable-hdpi/ic_phone_paused_white_24dp.png and /dev/null differ diff --git a/InCallUI/res/drawable-hdpi/ic_question_mark.png b/InCallUI/res/drawable-hdpi/ic_question_mark.png deleted file mode 100644 index adab6c13f..000000000 Binary files a/InCallUI/res/drawable-hdpi/ic_question_mark.png and /dev/null differ diff --git a/InCallUI/res/drawable-hdpi/ic_report_white_36dp.png b/InCallUI/res/drawable-hdpi/ic_report_white_36dp.png deleted file mode 100644 index 919a872e0..000000000 Binary files a/InCallUI/res/drawable-hdpi/ic_report_white_36dp.png and /dev/null differ diff --git a/InCallUI/res/drawable-hdpi/ic_schedule_white_24dp.png b/InCallUI/res/drawable-hdpi/ic_schedule_white_24dp.png deleted file mode 100644 index f3581d104..000000000 Binary files a/InCallUI/res/drawable-hdpi/ic_schedule_white_24dp.png and /dev/null differ diff --git a/InCallUI/res/drawable-hdpi/ic_toolbar_add_call.png b/InCallUI/res/drawable-hdpi/ic_toolbar_add_call.png deleted file mode 100644 index 06603f21c..000000000 Binary files a/InCallUI/res/drawable-hdpi/ic_toolbar_add_call.png and /dev/null differ diff --git a/InCallUI/res/drawable-hdpi/ic_toolbar_arrow_whitespace.png b/InCallUI/res/drawable-hdpi/ic_toolbar_arrow_whitespace.png deleted file mode 100644 index ea02daad2..000000000 Binary files a/InCallUI/res/drawable-hdpi/ic_toolbar_arrow_whitespace.png and /dev/null differ diff --git a/InCallUI/res/drawable-hdpi/ic_toolbar_audio_bluetooth.png b/InCallUI/res/drawable-hdpi/ic_toolbar_audio_bluetooth.png deleted file mode 100644 index 05e19bc25..000000000 Binary files a/InCallUI/res/drawable-hdpi/ic_toolbar_audio_bluetooth.png and /dev/null differ diff --git a/InCallUI/res/drawable-hdpi/ic_toolbar_audio_headphones.png b/InCallUI/res/drawable-hdpi/ic_toolbar_audio_headphones.png deleted file mode 100644 index 413fdff26..000000000 Binary files a/InCallUI/res/drawable-hdpi/ic_toolbar_audio_headphones.png and /dev/null differ diff --git a/InCallUI/res/drawable-hdpi/ic_toolbar_audio_phone.png b/InCallUI/res/drawable-hdpi/ic_toolbar_audio_phone.png deleted file mode 100644 index 90ee1fb5f..000000000 Binary files a/InCallUI/res/drawable-hdpi/ic_toolbar_audio_phone.png and /dev/null differ diff --git a/InCallUI/res/drawable-hdpi/ic_toolbar_dialpad.png b/InCallUI/res/drawable-hdpi/ic_toolbar_dialpad.png deleted file mode 100644 index 69ece11be..000000000 Binary files a/InCallUI/res/drawable-hdpi/ic_toolbar_dialpad.png and /dev/null differ diff --git a/InCallUI/res/drawable-hdpi/ic_toolbar_hold.png b/InCallUI/res/drawable-hdpi/ic_toolbar_hold.png deleted file mode 100644 index f32d6d552..000000000 Binary files a/InCallUI/res/drawable-hdpi/ic_toolbar_hold.png and /dev/null differ diff --git a/InCallUI/res/drawable-hdpi/ic_toolbar_merge.png b/InCallUI/res/drawable-hdpi/ic_toolbar_merge.png deleted file mode 100644 index 2871555e4..000000000 Binary files a/InCallUI/res/drawable-hdpi/ic_toolbar_merge.png and /dev/null differ diff --git a/InCallUI/res/drawable-hdpi/ic_toolbar_mic_off.png b/InCallUI/res/drawable-hdpi/ic_toolbar_mic_off.png deleted file mode 100644 index b142ca869..000000000 Binary files a/InCallUI/res/drawable-hdpi/ic_toolbar_mic_off.png and /dev/null differ diff --git a/InCallUI/res/drawable-hdpi/ic_toolbar_speaker_on.png b/InCallUI/res/drawable-hdpi/ic_toolbar_speaker_on.png deleted file mode 100644 index c934b1344..000000000 Binary files a/InCallUI/res/drawable-hdpi/ic_toolbar_speaker_on.png and /dev/null differ diff --git a/InCallUI/res/drawable-hdpi/ic_toolbar_swap.png b/InCallUI/res/drawable-hdpi/ic_toolbar_swap.png deleted file mode 100644 index e673f3251..000000000 Binary files a/InCallUI/res/drawable-hdpi/ic_toolbar_swap.png and /dev/null differ diff --git a/InCallUI/res/drawable-hdpi/ic_toolbar_video.png b/InCallUI/res/drawable-hdpi/ic_toolbar_video.png deleted file mode 100644 index cef47aaff..000000000 Binary files a/InCallUI/res/drawable-hdpi/ic_toolbar_video.png and /dev/null differ diff --git a/InCallUI/res/drawable-hdpi/ic_toolbar_video_off.png b/InCallUI/res/drawable-hdpi/ic_toolbar_video_off.png deleted file mode 100644 index 968ded7d8..000000000 Binary files a/InCallUI/res/drawable-hdpi/ic_toolbar_video_off.png and /dev/null differ diff --git a/InCallUI/res/drawable-hdpi/ic_toolbar_video_switch.png b/InCallUI/res/drawable-hdpi/ic_toolbar_video_switch.png deleted file mode 100644 index cdd623dc0..000000000 Binary files a/InCallUI/res/drawable-hdpi/ic_toolbar_video_switch.png and /dev/null differ diff --git a/InCallUI/res/drawable-hdpi/img_business.png b/InCallUI/res/drawable-hdpi/img_business.png deleted file mode 100644 index f70634262..000000000 Binary files a/InCallUI/res/drawable-hdpi/img_business.png and /dev/null differ diff --git a/InCallUI/res/drawable-hdpi/img_conference.png b/InCallUI/res/drawable-hdpi/img_conference.png deleted file mode 100644 index 3d9f683a5..000000000 Binary files a/InCallUI/res/drawable-hdpi/img_conference.png and /dev/null differ diff --git a/InCallUI/res/drawable-hdpi/img_no_image.png b/InCallUI/res/drawable-hdpi/img_no_image.png deleted file mode 100644 index fd0ab3211..000000000 Binary files a/InCallUI/res/drawable-hdpi/img_no_image.png and /dev/null differ diff --git a/InCallUI/res/drawable-hdpi/img_phone.png b/InCallUI/res/drawable-hdpi/img_phone.png deleted file mode 100644 index 748312e6e..000000000 Binary files a/InCallUI/res/drawable-hdpi/img_phone.png and /dev/null differ diff --git a/InCallUI/res/drawable-land/rounded_call_card_background.xml b/InCallUI/res/drawable-land/rounded_call_card_background.xml deleted file mode 100644 index f41ecda79..000000000 --- a/InCallUI/res/drawable-land/rounded_call_card_background.xml +++ /dev/null @@ -1,23 +0,0 @@ - - - - - - - - \ No newline at end of file diff --git a/InCallUI/res/drawable-mdpi/fab_blue.png b/InCallUI/res/drawable-mdpi/fab_blue.png deleted file mode 100644 index 2ca6b4bdf..000000000 Binary files a/InCallUI/res/drawable-mdpi/fab_blue.png and /dev/null differ diff --git a/InCallUI/res/drawable-mdpi/fab_ic_call.png b/InCallUI/res/drawable-mdpi/fab_ic_call.png deleted file mode 100644 index ff7b345e1..000000000 Binary files a/InCallUI/res/drawable-mdpi/fab_ic_call.png and /dev/null differ diff --git a/InCallUI/res/drawable-mdpi/fab_ic_end_call.png b/InCallUI/res/drawable-mdpi/fab_ic_end_call.png deleted file mode 100644 index 76ce3973d..000000000 Binary files a/InCallUI/res/drawable-mdpi/fab_ic_end_call.png and /dev/null differ diff --git a/InCallUI/res/drawable-mdpi/fab_ic_message.png b/InCallUI/res/drawable-mdpi/fab_ic_message.png deleted file mode 100644 index 74876fe77..000000000 Binary files a/InCallUI/res/drawable-mdpi/fab_ic_message.png and /dev/null differ diff --git a/InCallUI/res/drawable-mdpi/fab_red.png b/InCallUI/res/drawable-mdpi/fab_red.png deleted file mode 100644 index c9e76a057..000000000 Binary files a/InCallUI/res/drawable-mdpi/fab_red.png and /dev/null differ diff --git a/InCallUI/res/drawable-mdpi/ic_block_grey600_24dp.png b/InCallUI/res/drawable-mdpi/ic_block_grey600_24dp.png deleted file mode 100644 index edd666b73..000000000 Binary files a/InCallUI/res/drawable-mdpi/ic_block_grey600_24dp.png and /dev/null differ diff --git a/InCallUI/res/drawable-mdpi/ic_business_white_24dp.png b/InCallUI/res/drawable-mdpi/ic_business_white_24dp.png deleted file mode 100644 index 7b9227c06..000000000 Binary files a/InCallUI/res/drawable-mdpi/ic_business_white_24dp.png and /dev/null differ diff --git a/InCallUI/res/drawable-mdpi/ic_call_end_white_24dp.png b/InCallUI/res/drawable-mdpi/ic_call_end_white_24dp.png deleted file mode 100644 index 17eb4824e..000000000 Binary files a/InCallUI/res/drawable-mdpi/ic_call_end_white_24dp.png and /dev/null differ diff --git a/InCallUI/res/drawable-mdpi/ic_call_split_white_24dp.png b/InCallUI/res/drawable-mdpi/ic_call_split_white_24dp.png deleted file mode 100644 index cb7ee1f35..000000000 Binary files a/InCallUI/res/drawable-mdpi/ic_call_split_white_24dp.png and /dev/null differ diff --git a/InCallUI/res/drawable-mdpi/ic_call_white_24dp.png b/InCallUI/res/drawable-mdpi/ic_call_white_24dp.png deleted file mode 100644 index d4e5f5d7d..000000000 Binary files a/InCallUI/res/drawable-mdpi/ic_call_white_24dp.png and /dev/null differ diff --git a/InCallUI/res/drawable-mdpi/ic_close_grey600_24dp.png b/InCallUI/res/drawable-mdpi/ic_close_grey600_24dp.png deleted file mode 100644 index 73faf52eb..000000000 Binary files a/InCallUI/res/drawable-mdpi/ic_close_grey600_24dp.png and /dev/null differ diff --git a/InCallUI/res/drawable-mdpi/ic_forward_white_24dp.png b/InCallUI/res/drawable-mdpi/ic_forward_white_24dp.png deleted file mode 100644 index 65f73299f..000000000 Binary files a/InCallUI/res/drawable-mdpi/ic_forward_white_24dp.png and /dev/null differ diff --git a/InCallUI/res/drawable-mdpi/ic_hd_24dp.png b/InCallUI/res/drawable-mdpi/ic_hd_24dp.png deleted file mode 100644 index 30938fe4d..000000000 Binary files a/InCallUI/res/drawable-mdpi/ic_hd_24dp.png and /dev/null differ diff --git a/InCallUI/res/drawable-mdpi/ic_location_on_white_24dp.png b/InCallUI/res/drawable-mdpi/ic_location_on_white_24dp.png deleted file mode 100644 index 933eb5148..000000000 Binary files a/InCallUI/res/drawable-mdpi/ic_location_on_white_24dp.png and /dev/null differ diff --git a/InCallUI/res/drawable-mdpi/ic_lockscreen_glowdot.png b/InCallUI/res/drawable-mdpi/ic_lockscreen_glowdot.png deleted file mode 100644 index 056c3f175..000000000 Binary files a/InCallUI/res/drawable-mdpi/ic_lockscreen_glowdot.png and /dev/null differ diff --git a/InCallUI/res/drawable-mdpi/ic_person_add_grey600_24dp.png b/InCallUI/res/drawable-mdpi/ic_person_add_grey600_24dp.png deleted file mode 100644 index ec3237086..000000000 Binary files a/InCallUI/res/drawable-mdpi/ic_person_add_grey600_24dp.png and /dev/null differ diff --git a/InCallUI/res/drawable-mdpi/ic_phone_paused_white_24dp.png b/InCallUI/res/drawable-mdpi/ic_phone_paused_white_24dp.png deleted file mode 100644 index 7dc920b2b..000000000 Binary files a/InCallUI/res/drawable-mdpi/ic_phone_paused_white_24dp.png and /dev/null differ diff --git a/InCallUI/res/drawable-mdpi/ic_question_mark.png b/InCallUI/res/drawable-mdpi/ic_question_mark.png deleted file mode 100644 index cfe64f696..000000000 Binary files a/InCallUI/res/drawable-mdpi/ic_question_mark.png and /dev/null differ diff --git a/InCallUI/res/drawable-mdpi/ic_report_white_36dp.png b/InCallUI/res/drawable-mdpi/ic_report_white_36dp.png deleted file mode 100644 index dc0c995c1..000000000 Binary files a/InCallUI/res/drawable-mdpi/ic_report_white_36dp.png and /dev/null differ diff --git a/InCallUI/res/drawable-mdpi/ic_schedule_white_24dp.png b/InCallUI/res/drawable-mdpi/ic_schedule_white_24dp.png deleted file mode 100644 index 501ee842e..000000000 Binary files a/InCallUI/res/drawable-mdpi/ic_schedule_white_24dp.png and /dev/null differ diff --git a/InCallUI/res/drawable-mdpi/ic_toolbar_add_call.png b/InCallUI/res/drawable-mdpi/ic_toolbar_add_call.png deleted file mode 100644 index 1ee2fb1f5..000000000 Binary files a/InCallUI/res/drawable-mdpi/ic_toolbar_add_call.png and /dev/null differ diff --git a/InCallUI/res/drawable-mdpi/ic_toolbar_arrow_whitespace.png b/InCallUI/res/drawable-mdpi/ic_toolbar_arrow_whitespace.png deleted file mode 100644 index c39990deb..000000000 Binary files a/InCallUI/res/drawable-mdpi/ic_toolbar_arrow_whitespace.png and /dev/null differ diff --git a/InCallUI/res/drawable-mdpi/ic_toolbar_audio_bluetooth.png b/InCallUI/res/drawable-mdpi/ic_toolbar_audio_bluetooth.png deleted file mode 100644 index a6634ed66..000000000 Binary files a/InCallUI/res/drawable-mdpi/ic_toolbar_audio_bluetooth.png and /dev/null differ diff --git a/InCallUI/res/drawable-mdpi/ic_toolbar_audio_headphones.png b/InCallUI/res/drawable-mdpi/ic_toolbar_audio_headphones.png deleted file mode 100644 index b387e850a..000000000 Binary files a/InCallUI/res/drawable-mdpi/ic_toolbar_audio_headphones.png and /dev/null differ diff --git a/InCallUI/res/drawable-mdpi/ic_toolbar_audio_phone.png b/InCallUI/res/drawable-mdpi/ic_toolbar_audio_phone.png deleted file mode 100644 index b4d887cf3..000000000 Binary files a/InCallUI/res/drawable-mdpi/ic_toolbar_audio_phone.png and /dev/null differ diff --git a/InCallUI/res/drawable-mdpi/ic_toolbar_dialpad.png b/InCallUI/res/drawable-mdpi/ic_toolbar_dialpad.png deleted file mode 100644 index 9baa21b95..000000000 Binary files a/InCallUI/res/drawable-mdpi/ic_toolbar_dialpad.png and /dev/null differ diff --git a/InCallUI/res/drawable-mdpi/ic_toolbar_hold.png b/InCallUI/res/drawable-mdpi/ic_toolbar_hold.png deleted file mode 100644 index c8372738b..000000000 Binary files a/InCallUI/res/drawable-mdpi/ic_toolbar_hold.png and /dev/null differ diff --git a/InCallUI/res/drawable-mdpi/ic_toolbar_merge.png b/InCallUI/res/drawable-mdpi/ic_toolbar_merge.png deleted file mode 100644 index 2fba86514..000000000 Binary files a/InCallUI/res/drawable-mdpi/ic_toolbar_merge.png and /dev/null differ diff --git a/InCallUI/res/drawable-mdpi/ic_toolbar_mic_off.png b/InCallUI/res/drawable-mdpi/ic_toolbar_mic_off.png deleted file mode 100644 index c6b02b82c..000000000 Binary files a/InCallUI/res/drawable-mdpi/ic_toolbar_mic_off.png and /dev/null differ diff --git a/InCallUI/res/drawable-mdpi/ic_toolbar_speaker_on.png b/InCallUI/res/drawable-mdpi/ic_toolbar_speaker_on.png deleted file mode 100644 index 008e245f8..000000000 Binary files a/InCallUI/res/drawable-mdpi/ic_toolbar_speaker_on.png and /dev/null differ diff --git a/InCallUI/res/drawable-mdpi/ic_toolbar_swap.png b/InCallUI/res/drawable-mdpi/ic_toolbar_swap.png deleted file mode 100644 index acc9850d5..000000000 Binary files a/InCallUI/res/drawable-mdpi/ic_toolbar_swap.png and /dev/null differ diff --git a/InCallUI/res/drawable-mdpi/ic_toolbar_video.png b/InCallUI/res/drawable-mdpi/ic_toolbar_video.png deleted file mode 100644 index 3f13f9c31..000000000 Binary files a/InCallUI/res/drawable-mdpi/ic_toolbar_video.png and /dev/null differ diff --git a/InCallUI/res/drawable-mdpi/ic_toolbar_video_off.png b/InCallUI/res/drawable-mdpi/ic_toolbar_video_off.png deleted file mode 100644 index 64a69f2a7..000000000 Binary files a/InCallUI/res/drawable-mdpi/ic_toolbar_video_off.png and /dev/null differ diff --git a/InCallUI/res/drawable-mdpi/ic_toolbar_video_switch.png b/InCallUI/res/drawable-mdpi/ic_toolbar_video_switch.png deleted file mode 100644 index 6d097c9e7..000000000 Binary files a/InCallUI/res/drawable-mdpi/ic_toolbar_video_switch.png and /dev/null differ diff --git a/InCallUI/res/drawable-mdpi/img_business.png b/InCallUI/res/drawable-mdpi/img_business.png deleted file mode 100644 index 90738a7ee..000000000 Binary files a/InCallUI/res/drawable-mdpi/img_business.png and /dev/null differ diff --git a/InCallUI/res/drawable-mdpi/img_conference.png b/InCallUI/res/drawable-mdpi/img_conference.png deleted file mode 100644 index 0694dbd55..000000000 Binary files a/InCallUI/res/drawable-mdpi/img_conference.png and /dev/null differ diff --git a/InCallUI/res/drawable-mdpi/img_no_image.png b/InCallUI/res/drawable-mdpi/img_no_image.png deleted file mode 100644 index 014a1c414..000000000 Binary files a/InCallUI/res/drawable-mdpi/img_no_image.png and /dev/null differ diff --git a/InCallUI/res/drawable-mdpi/img_phone.png b/InCallUI/res/drawable-mdpi/img_phone.png deleted file mode 100644 index 41a1d339d..000000000 Binary files a/InCallUI/res/drawable-mdpi/img_phone.png and /dev/null differ diff --git a/InCallUI/res/drawable-xhdpi/fab_blue.png b/InCallUI/res/drawable-xhdpi/fab_blue.png deleted file mode 100644 index 300b07eb4..000000000 Binary files a/InCallUI/res/drawable-xhdpi/fab_blue.png and /dev/null differ diff --git a/InCallUI/res/drawable-xhdpi/fab_ic_call.png b/InCallUI/res/drawable-xhdpi/fab_ic_call.png deleted file mode 100644 index 2bff65e0a..000000000 Binary files a/InCallUI/res/drawable-xhdpi/fab_ic_call.png and /dev/null differ diff --git a/InCallUI/res/drawable-xhdpi/fab_ic_end_call.png b/InCallUI/res/drawable-xhdpi/fab_ic_end_call.png deleted file mode 100644 index 1c95e175a..000000000 Binary files a/InCallUI/res/drawable-xhdpi/fab_ic_end_call.png and /dev/null differ diff --git a/InCallUI/res/drawable-xhdpi/fab_ic_message.png b/InCallUI/res/drawable-xhdpi/fab_ic_message.png deleted file mode 100644 index 5e3334ae0..000000000 Binary files a/InCallUI/res/drawable-xhdpi/fab_ic_message.png and /dev/null differ diff --git a/InCallUI/res/drawable-xhdpi/fab_red.png b/InCallUI/res/drawable-xhdpi/fab_red.png deleted file mode 100644 index 373e49e8f..000000000 Binary files a/InCallUI/res/drawable-xhdpi/fab_red.png and /dev/null differ diff --git a/InCallUI/res/drawable-xhdpi/ic_block_grey600_24dp.png b/InCallUI/res/drawable-xhdpi/ic_block_grey600_24dp.png deleted file mode 100644 index 36210a8cb..000000000 Binary files a/InCallUI/res/drawable-xhdpi/ic_block_grey600_24dp.png and /dev/null differ diff --git a/InCallUI/res/drawable-xhdpi/ic_business_white_24dp.png b/InCallUI/res/drawable-xhdpi/ic_business_white_24dp.png deleted file mode 100644 index e5630455a..000000000 Binary files a/InCallUI/res/drawable-xhdpi/ic_business_white_24dp.png and /dev/null differ diff --git a/InCallUI/res/drawable-xhdpi/ic_call_end_white_24dp.png b/InCallUI/res/drawable-xhdpi/ic_call_end_white_24dp.png deleted file mode 100644 index b00d82edd..000000000 Binary files a/InCallUI/res/drawable-xhdpi/ic_call_end_white_24dp.png and /dev/null differ diff --git a/InCallUI/res/drawable-xhdpi/ic_call_split_white_24dp.png b/InCallUI/res/drawable-xhdpi/ic_call_split_white_24dp.png deleted file mode 100644 index 218cb1214..000000000 Binary files a/InCallUI/res/drawable-xhdpi/ic_call_split_white_24dp.png and /dev/null differ diff --git a/InCallUI/res/drawable-xhdpi/ic_call_white_24dp.png b/InCallUI/res/drawable-xhdpi/ic_call_white_24dp.png deleted file mode 100644 index cde9cea3a..000000000 Binary files a/InCallUI/res/drawable-xhdpi/ic_call_white_24dp.png and /dev/null differ diff --git a/InCallUI/res/drawable-xhdpi/ic_close_grey600_24dp.png b/InCallUI/res/drawable-xhdpi/ic_close_grey600_24dp.png deleted file mode 100644 index a3896c5c6..000000000 Binary files a/InCallUI/res/drawable-xhdpi/ic_close_grey600_24dp.png and /dev/null differ diff --git a/InCallUI/res/drawable-xhdpi/ic_forward_white_24dp.png b/InCallUI/res/drawable-xhdpi/ic_forward_white_24dp.png deleted file mode 100644 index 7a5df52bf..000000000 Binary files a/InCallUI/res/drawable-xhdpi/ic_forward_white_24dp.png and /dev/null differ diff --git a/InCallUI/res/drawable-xhdpi/ic_hd_24dp.png b/InCallUI/res/drawable-xhdpi/ic_hd_24dp.png deleted file mode 100644 index 4c954d86f..000000000 Binary files a/InCallUI/res/drawable-xhdpi/ic_hd_24dp.png and /dev/null differ diff --git a/InCallUI/res/drawable-xhdpi/ic_location_on_white_24dp.png b/InCallUI/res/drawable-xhdpi/ic_location_on_white_24dp.png deleted file mode 100644 index 814ca8ddc..000000000 Binary files a/InCallUI/res/drawable-xhdpi/ic_location_on_white_24dp.png and /dev/null differ diff --git a/InCallUI/res/drawable-xhdpi/ic_lockscreen_glowdot.png b/InCallUI/res/drawable-xhdpi/ic_lockscreen_glowdot.png deleted file mode 100644 index cbd039afd..000000000 Binary files a/InCallUI/res/drawable-xhdpi/ic_lockscreen_glowdot.png and /dev/null differ diff --git a/InCallUI/res/drawable-xhdpi/ic_person_add_grey600_24dp.png b/InCallUI/res/drawable-xhdpi/ic_person_add_grey600_24dp.png deleted file mode 100644 index e56481ed7..000000000 Binary files a/InCallUI/res/drawable-xhdpi/ic_person_add_grey600_24dp.png and /dev/null differ diff --git a/InCallUI/res/drawable-xhdpi/ic_phone_paused_white_24dp.png b/InCallUI/res/drawable-xhdpi/ic_phone_paused_white_24dp.png deleted file mode 100644 index a8becf485..000000000 Binary files a/InCallUI/res/drawable-xhdpi/ic_phone_paused_white_24dp.png and /dev/null differ diff --git a/InCallUI/res/drawable-xhdpi/ic_question_mark.png b/InCallUI/res/drawable-xhdpi/ic_question_mark.png deleted file mode 100644 index 8da487088..000000000 Binary files a/InCallUI/res/drawable-xhdpi/ic_question_mark.png and /dev/null differ diff --git a/InCallUI/res/drawable-xhdpi/ic_report_white_36dp.png b/InCallUI/res/drawable-xhdpi/ic_report_white_36dp.png deleted file mode 100644 index aed766804..000000000 Binary files a/InCallUI/res/drawable-xhdpi/ic_report_white_36dp.png and /dev/null differ diff --git a/InCallUI/res/drawable-xhdpi/ic_schedule_white_24dp.png b/InCallUI/res/drawable-xhdpi/ic_schedule_white_24dp.png deleted file mode 100644 index 2e27936a4..000000000 Binary files a/InCallUI/res/drawable-xhdpi/ic_schedule_white_24dp.png and /dev/null differ diff --git a/InCallUI/res/drawable-xhdpi/ic_toolbar_add_call.png b/InCallUI/res/drawable-xhdpi/ic_toolbar_add_call.png deleted file mode 100644 index b251d6bd8..000000000 Binary files a/InCallUI/res/drawable-xhdpi/ic_toolbar_add_call.png and /dev/null differ diff --git a/InCallUI/res/drawable-xhdpi/ic_toolbar_arrow_whitespace.png b/InCallUI/res/drawable-xhdpi/ic_toolbar_arrow_whitespace.png deleted file mode 100644 index cdaa79d37..000000000 Binary files a/InCallUI/res/drawable-xhdpi/ic_toolbar_arrow_whitespace.png and /dev/null differ diff --git a/InCallUI/res/drawable-xhdpi/ic_toolbar_audio_bluetooth.png b/InCallUI/res/drawable-xhdpi/ic_toolbar_audio_bluetooth.png deleted file mode 100644 index 88f6bb945..000000000 Binary files a/InCallUI/res/drawable-xhdpi/ic_toolbar_audio_bluetooth.png and /dev/null differ diff --git a/InCallUI/res/drawable-xhdpi/ic_toolbar_audio_headphones.png b/InCallUI/res/drawable-xhdpi/ic_toolbar_audio_headphones.png deleted file mode 100644 index 1acfcafbd..000000000 Binary files a/InCallUI/res/drawable-xhdpi/ic_toolbar_audio_headphones.png and /dev/null differ diff --git a/InCallUI/res/drawable-xhdpi/ic_toolbar_audio_phone.png b/InCallUI/res/drawable-xhdpi/ic_toolbar_audio_phone.png deleted file mode 100644 index 0ba8f1e3e..000000000 Binary files a/InCallUI/res/drawable-xhdpi/ic_toolbar_audio_phone.png and /dev/null differ diff --git a/InCallUI/res/drawable-xhdpi/ic_toolbar_dialpad.png b/InCallUI/res/drawable-xhdpi/ic_toolbar_dialpad.png deleted file mode 100644 index cf803d1c1..000000000 Binary files a/InCallUI/res/drawable-xhdpi/ic_toolbar_dialpad.png and /dev/null differ diff --git a/InCallUI/res/drawable-xhdpi/ic_toolbar_hold.png b/InCallUI/res/drawable-xhdpi/ic_toolbar_hold.png deleted file mode 100644 index 8fecf7514..000000000 Binary files a/InCallUI/res/drawable-xhdpi/ic_toolbar_hold.png and /dev/null differ diff --git a/InCallUI/res/drawable-xhdpi/ic_toolbar_merge.png b/InCallUI/res/drawable-xhdpi/ic_toolbar_merge.png deleted file mode 100644 index 777483eb0..000000000 Binary files a/InCallUI/res/drawable-xhdpi/ic_toolbar_merge.png and /dev/null differ diff --git a/InCallUI/res/drawable-xhdpi/ic_toolbar_mic_off.png b/InCallUI/res/drawable-xhdpi/ic_toolbar_mic_off.png deleted file mode 100644 index cf2041ad6..000000000 Binary files a/InCallUI/res/drawable-xhdpi/ic_toolbar_mic_off.png and /dev/null differ diff --git a/InCallUI/res/drawable-xhdpi/ic_toolbar_speaker_on.png b/InCallUI/res/drawable-xhdpi/ic_toolbar_speaker_on.png deleted file mode 100644 index 5b5831cc0..000000000 Binary files a/InCallUI/res/drawable-xhdpi/ic_toolbar_speaker_on.png and /dev/null differ diff --git a/InCallUI/res/drawable-xhdpi/ic_toolbar_swap.png b/InCallUI/res/drawable-xhdpi/ic_toolbar_swap.png deleted file mode 100644 index 38917cb88..000000000 Binary files a/InCallUI/res/drawable-xhdpi/ic_toolbar_swap.png and /dev/null differ diff --git a/InCallUI/res/drawable-xhdpi/ic_toolbar_video.png b/InCallUI/res/drawable-xhdpi/ic_toolbar_video.png deleted file mode 100644 index b20f50498..000000000 Binary files a/InCallUI/res/drawable-xhdpi/ic_toolbar_video.png and /dev/null differ diff --git a/InCallUI/res/drawable-xhdpi/ic_toolbar_video_off.png b/InCallUI/res/drawable-xhdpi/ic_toolbar_video_off.png deleted file mode 100644 index 1b269a6a7..000000000 Binary files a/InCallUI/res/drawable-xhdpi/ic_toolbar_video_off.png and /dev/null differ diff --git a/InCallUI/res/drawable-xhdpi/ic_toolbar_video_switch.png b/InCallUI/res/drawable-xhdpi/ic_toolbar_video_switch.png deleted file mode 100644 index fae6bfdb1..000000000 Binary files a/InCallUI/res/drawable-xhdpi/ic_toolbar_video_switch.png and /dev/null differ diff --git a/InCallUI/res/drawable-xhdpi/img_business.png b/InCallUI/res/drawable-xhdpi/img_business.png deleted file mode 100644 index 7b04d956f..000000000 Binary files a/InCallUI/res/drawable-xhdpi/img_business.png and /dev/null differ diff --git a/InCallUI/res/drawable-xhdpi/img_conference.png b/InCallUI/res/drawable-xhdpi/img_conference.png deleted file mode 100644 index b0dbcc2dc..000000000 Binary files a/InCallUI/res/drawable-xhdpi/img_conference.png and /dev/null differ diff --git a/InCallUI/res/drawable-xhdpi/img_no_image.png b/InCallUI/res/drawable-xhdpi/img_no_image.png deleted file mode 100644 index 4022207d0..000000000 Binary files a/InCallUI/res/drawable-xhdpi/img_no_image.png and /dev/null differ diff --git a/InCallUI/res/drawable-xhdpi/img_phone.png b/InCallUI/res/drawable-xhdpi/img_phone.png deleted file mode 100644 index 2e0ceec0f..000000000 Binary files a/InCallUI/res/drawable-xhdpi/img_phone.png and /dev/null differ diff --git a/InCallUI/res/drawable-xxhdpi/fab_blue.png b/InCallUI/res/drawable-xxhdpi/fab_blue.png deleted file mode 100644 index 76d68ac6a..000000000 Binary files a/InCallUI/res/drawable-xxhdpi/fab_blue.png and /dev/null differ diff --git a/InCallUI/res/drawable-xxhdpi/fab_ic_call.png b/InCallUI/res/drawable-xxhdpi/fab_ic_call.png deleted file mode 100644 index a756b95ad..000000000 Binary files a/InCallUI/res/drawable-xxhdpi/fab_ic_call.png and /dev/null differ diff --git a/InCallUI/res/drawable-xxhdpi/fab_ic_end_call.png b/InCallUI/res/drawable-xxhdpi/fab_ic_end_call.png deleted file mode 100644 index 37e826402..000000000 Binary files a/InCallUI/res/drawable-xxhdpi/fab_ic_end_call.png and /dev/null differ diff --git a/InCallUI/res/drawable-xxhdpi/fab_ic_message.png b/InCallUI/res/drawable-xxhdpi/fab_ic_message.png deleted file mode 100644 index 66984b1e3..000000000 Binary files a/InCallUI/res/drawable-xxhdpi/fab_ic_message.png and /dev/null differ diff --git a/InCallUI/res/drawable-xxhdpi/fab_red.png b/InCallUI/res/drawable-xxhdpi/fab_red.png deleted file mode 100644 index 92eb979d5..000000000 Binary files a/InCallUI/res/drawable-xxhdpi/fab_red.png and /dev/null differ diff --git a/InCallUI/res/drawable-xxhdpi/ic_block_grey600_24dp.png b/InCallUI/res/drawable-xxhdpi/ic_block_grey600_24dp.png deleted file mode 100644 index 9f5120373..000000000 Binary files a/InCallUI/res/drawable-xxhdpi/ic_block_grey600_24dp.png and /dev/null differ diff --git a/InCallUI/res/drawable-xxhdpi/ic_business_white_24dp.png b/InCallUI/res/drawable-xxhdpi/ic_business_white_24dp.png deleted file mode 100644 index 7dfc8dc52..000000000 Binary files a/InCallUI/res/drawable-xxhdpi/ic_business_white_24dp.png and /dev/null differ diff --git a/InCallUI/res/drawable-xxhdpi/ic_call_end_white_24dp.png b/InCallUI/res/drawable-xxhdpi/ic_call_end_white_24dp.png deleted file mode 100644 index aeabe4a81..000000000 Binary files a/InCallUI/res/drawable-xxhdpi/ic_call_end_white_24dp.png and /dev/null differ diff --git a/InCallUI/res/drawable-xxhdpi/ic_call_split_white_24dp.png b/InCallUI/res/drawable-xxhdpi/ic_call_split_white_24dp.png deleted file mode 100644 index 5ea577716..000000000 Binary files a/InCallUI/res/drawable-xxhdpi/ic_call_split_white_24dp.png and /dev/null differ diff --git a/InCallUI/res/drawable-xxhdpi/ic_call_white_24dp.png b/InCallUI/res/drawable-xxhdpi/ic_call_white_24dp.png deleted file mode 100644 index b761bc466..000000000 Binary files a/InCallUI/res/drawable-xxhdpi/ic_call_white_24dp.png and /dev/null differ diff --git a/InCallUI/res/drawable-xxhdpi/ic_close_grey600_24dp.png b/InCallUI/res/drawable-xxhdpi/ic_close_grey600_24dp.png deleted file mode 100644 index 22d7aa55e..000000000 Binary files a/InCallUI/res/drawable-xxhdpi/ic_close_grey600_24dp.png and /dev/null differ diff --git a/InCallUI/res/drawable-xxhdpi/ic_forward_white_24dp.png b/InCallUI/res/drawable-xxhdpi/ic_forward_white_24dp.png deleted file mode 100644 index 7bd5b1635..000000000 Binary files a/InCallUI/res/drawable-xxhdpi/ic_forward_white_24dp.png and /dev/null differ diff --git a/InCallUI/res/drawable-xxhdpi/ic_hd_24dp.png b/InCallUI/res/drawable-xxhdpi/ic_hd_24dp.png deleted file mode 100644 index dd08bbbec..000000000 Binary files a/InCallUI/res/drawable-xxhdpi/ic_hd_24dp.png and /dev/null differ diff --git a/InCallUI/res/drawable-xxhdpi/ic_location_on_white_24dp.png b/InCallUI/res/drawable-xxhdpi/ic_location_on_white_24dp.png deleted file mode 100644 index 078b10d4f..000000000 Binary files a/InCallUI/res/drawable-xxhdpi/ic_location_on_white_24dp.png and /dev/null differ diff --git a/InCallUI/res/drawable-xxhdpi/ic_lockscreen_glowdot.png b/InCallUI/res/drawable-xxhdpi/ic_lockscreen_glowdot.png deleted file mode 100644 index c0edd91c8..000000000 Binary files a/InCallUI/res/drawable-xxhdpi/ic_lockscreen_glowdot.png and /dev/null differ diff --git a/InCallUI/res/drawable-xxhdpi/ic_person_add_grey600_24dp.png b/InCallUI/res/drawable-xxhdpi/ic_person_add_grey600_24dp.png deleted file mode 100644 index c17dfe05f..000000000 Binary files a/InCallUI/res/drawable-xxhdpi/ic_person_add_grey600_24dp.png and /dev/null differ diff --git a/InCallUI/res/drawable-xxhdpi/ic_phone_paused_white_24dp.png b/InCallUI/res/drawable-xxhdpi/ic_phone_paused_white_24dp.png deleted file mode 100644 index baf0cf27f..000000000 Binary files a/InCallUI/res/drawable-xxhdpi/ic_phone_paused_white_24dp.png and /dev/null differ diff --git a/InCallUI/res/drawable-xxhdpi/ic_question_mark.png b/InCallUI/res/drawable-xxhdpi/ic_question_mark.png deleted file mode 100644 index b9b6b00e7..000000000 Binary files a/InCallUI/res/drawable-xxhdpi/ic_question_mark.png and /dev/null differ diff --git a/InCallUI/res/drawable-xxhdpi/ic_report_white_36dp.png b/InCallUI/res/drawable-xxhdpi/ic_report_white_36dp.png deleted file mode 100644 index f7cfacbd4..000000000 Binary files a/InCallUI/res/drawable-xxhdpi/ic_report_white_36dp.png and /dev/null differ diff --git a/InCallUI/res/drawable-xxhdpi/ic_schedule_white_24dp.png b/InCallUI/res/drawable-xxhdpi/ic_schedule_white_24dp.png deleted file mode 100644 index bfc72736a..000000000 Binary files a/InCallUI/res/drawable-xxhdpi/ic_schedule_white_24dp.png and /dev/null differ diff --git a/InCallUI/res/drawable-xxhdpi/ic_toolbar_add_call.png b/InCallUI/res/drawable-xxhdpi/ic_toolbar_add_call.png deleted file mode 100644 index 6e343c74e..000000000 Binary files a/InCallUI/res/drawable-xxhdpi/ic_toolbar_add_call.png and /dev/null differ diff --git a/InCallUI/res/drawable-xxhdpi/ic_toolbar_arrow_whitespace.png b/InCallUI/res/drawable-xxhdpi/ic_toolbar_arrow_whitespace.png deleted file mode 100644 index 737704018..000000000 Binary files a/InCallUI/res/drawable-xxhdpi/ic_toolbar_arrow_whitespace.png and /dev/null differ diff --git a/InCallUI/res/drawable-xxhdpi/ic_toolbar_audio_bluetooth.png b/InCallUI/res/drawable-xxhdpi/ic_toolbar_audio_bluetooth.png deleted file mode 100644 index b8a385d14..000000000 Binary files a/InCallUI/res/drawable-xxhdpi/ic_toolbar_audio_bluetooth.png and /dev/null differ diff --git a/InCallUI/res/drawable-xxhdpi/ic_toolbar_audio_headphones.png b/InCallUI/res/drawable-xxhdpi/ic_toolbar_audio_headphones.png deleted file mode 100644 index 62d0ae331..000000000 Binary files a/InCallUI/res/drawable-xxhdpi/ic_toolbar_audio_headphones.png and /dev/null differ diff --git a/InCallUI/res/drawable-xxhdpi/ic_toolbar_audio_phone.png b/InCallUI/res/drawable-xxhdpi/ic_toolbar_audio_phone.png deleted file mode 100644 index 0e88501d6..000000000 Binary files a/InCallUI/res/drawable-xxhdpi/ic_toolbar_audio_phone.png and /dev/null differ diff --git a/InCallUI/res/drawable-xxhdpi/ic_toolbar_dialpad.png b/InCallUI/res/drawable-xxhdpi/ic_toolbar_dialpad.png deleted file mode 100644 index a754f6875..000000000 Binary files a/InCallUI/res/drawable-xxhdpi/ic_toolbar_dialpad.png and /dev/null differ diff --git a/InCallUI/res/drawable-xxhdpi/ic_toolbar_hold.png b/InCallUI/res/drawable-xxhdpi/ic_toolbar_hold.png deleted file mode 100644 index f3757a8b5..000000000 Binary files a/InCallUI/res/drawable-xxhdpi/ic_toolbar_hold.png and /dev/null differ diff --git a/InCallUI/res/drawable-xxhdpi/ic_toolbar_merge.png b/InCallUI/res/drawable-xxhdpi/ic_toolbar_merge.png deleted file mode 100644 index 5d046008c..000000000 Binary files a/InCallUI/res/drawable-xxhdpi/ic_toolbar_merge.png and /dev/null differ diff --git a/InCallUI/res/drawable-xxhdpi/ic_toolbar_mic_off.png b/InCallUI/res/drawable-xxhdpi/ic_toolbar_mic_off.png deleted file mode 100644 index ae41d5c35..000000000 Binary files a/InCallUI/res/drawable-xxhdpi/ic_toolbar_mic_off.png and /dev/null differ diff --git a/InCallUI/res/drawable-xxhdpi/ic_toolbar_speaker_on.png b/InCallUI/res/drawable-xxhdpi/ic_toolbar_speaker_on.png deleted file mode 100644 index d1bbb0947..000000000 Binary files a/InCallUI/res/drawable-xxhdpi/ic_toolbar_speaker_on.png and /dev/null differ diff --git a/InCallUI/res/drawable-xxhdpi/ic_toolbar_swap.png b/InCallUI/res/drawable-xxhdpi/ic_toolbar_swap.png deleted file mode 100644 index ea9127ee2..000000000 Binary files a/InCallUI/res/drawable-xxhdpi/ic_toolbar_swap.png and /dev/null differ diff --git a/InCallUI/res/drawable-xxhdpi/ic_toolbar_video.png b/InCallUI/res/drawable-xxhdpi/ic_toolbar_video.png deleted file mode 100644 index 5c52dd6c6..000000000 Binary files a/InCallUI/res/drawable-xxhdpi/ic_toolbar_video.png and /dev/null differ diff --git a/InCallUI/res/drawable-xxhdpi/ic_toolbar_video_off.png b/InCallUI/res/drawable-xxhdpi/ic_toolbar_video_off.png deleted file mode 100644 index 898b7c04d..000000000 Binary files a/InCallUI/res/drawable-xxhdpi/ic_toolbar_video_off.png and /dev/null differ diff --git a/InCallUI/res/drawable-xxhdpi/ic_toolbar_video_switch.png b/InCallUI/res/drawable-xxhdpi/ic_toolbar_video_switch.png deleted file mode 100644 index 4380a47ca..000000000 Binary files a/InCallUI/res/drawable-xxhdpi/ic_toolbar_video_switch.png and /dev/null differ diff --git a/InCallUI/res/drawable-xxhdpi/img_business.png b/InCallUI/res/drawable-xxhdpi/img_business.png deleted file mode 100644 index c17e4c9d8..000000000 Binary files a/InCallUI/res/drawable-xxhdpi/img_business.png and /dev/null differ diff --git a/InCallUI/res/drawable-xxhdpi/img_conference.png b/InCallUI/res/drawable-xxhdpi/img_conference.png deleted file mode 100644 index a8dba5ed0..000000000 Binary files a/InCallUI/res/drawable-xxhdpi/img_conference.png and /dev/null differ diff --git a/InCallUI/res/drawable-xxhdpi/img_no_image.png b/InCallUI/res/drawable-xxhdpi/img_no_image.png deleted file mode 100644 index 2cf7f23a0..000000000 Binary files a/InCallUI/res/drawable-xxhdpi/img_no_image.png and /dev/null differ diff --git a/InCallUI/res/drawable-xxhdpi/img_phone.png b/InCallUI/res/drawable-xxhdpi/img_phone.png deleted file mode 100644 index 4eaaba509..000000000 Binary files a/InCallUI/res/drawable-xxhdpi/img_phone.png and /dev/null differ diff --git a/InCallUI/res/drawable-xxxhdpi/fab_blue.png b/InCallUI/res/drawable-xxxhdpi/fab_blue.png deleted file mode 100644 index 1dd8a9260..000000000 Binary files a/InCallUI/res/drawable-xxxhdpi/fab_blue.png and /dev/null differ diff --git a/InCallUI/res/drawable-xxxhdpi/fab_ic_call.png b/InCallUI/res/drawable-xxxhdpi/fab_ic_call.png deleted file mode 100644 index 7af3396b4..000000000 Binary files a/InCallUI/res/drawable-xxxhdpi/fab_ic_call.png and /dev/null differ diff --git a/InCallUI/res/drawable-xxxhdpi/fab_ic_end_call.png b/InCallUI/res/drawable-xxxhdpi/fab_ic_end_call.png deleted file mode 100644 index aabdadec2..000000000 Binary files a/InCallUI/res/drawable-xxxhdpi/fab_ic_end_call.png and /dev/null differ diff --git a/InCallUI/res/drawable-xxxhdpi/fab_ic_message.png b/InCallUI/res/drawable-xxxhdpi/fab_ic_message.png deleted file mode 100644 index c5a108aba..000000000 Binary files a/InCallUI/res/drawable-xxxhdpi/fab_ic_message.png and /dev/null differ diff --git a/InCallUI/res/drawable-xxxhdpi/fab_red.png b/InCallUI/res/drawable-xxxhdpi/fab_red.png deleted file mode 100644 index f1b36f70b..000000000 Binary files a/InCallUI/res/drawable-xxxhdpi/fab_red.png and /dev/null differ diff --git a/InCallUI/res/drawable-xxxhdpi/ic_block_grey600_24dp.png b/InCallUI/res/drawable-xxxhdpi/ic_block_grey600_24dp.png deleted file mode 100644 index 01df2b52b..000000000 Binary files a/InCallUI/res/drawable-xxxhdpi/ic_block_grey600_24dp.png and /dev/null differ diff --git a/InCallUI/res/drawable-xxxhdpi/ic_business_white_24dp.png b/InCallUI/res/drawable-xxxhdpi/ic_business_white_24dp.png deleted file mode 100644 index c9aea72ce..000000000 Binary files a/InCallUI/res/drawable-xxxhdpi/ic_business_white_24dp.png and /dev/null differ diff --git a/InCallUI/res/drawable-xxxhdpi/ic_call_end_white_24dp.png b/InCallUI/res/drawable-xxxhdpi/ic_call_end_white_24dp.png deleted file mode 100644 index a6e8a7bc1..000000000 Binary files a/InCallUI/res/drawable-xxxhdpi/ic_call_end_white_24dp.png and /dev/null differ diff --git a/InCallUI/res/drawable-xxxhdpi/ic_call_split_white_24dp.png b/InCallUI/res/drawable-xxxhdpi/ic_call_split_white_24dp.png deleted file mode 100644 index 600cec8e6..000000000 Binary files a/InCallUI/res/drawable-xxxhdpi/ic_call_split_white_24dp.png and /dev/null differ diff --git a/InCallUI/res/drawable-xxxhdpi/ic_close_grey600_24dp.png b/InCallUI/res/drawable-xxxhdpi/ic_close_grey600_24dp.png deleted file mode 100644 index 7d1c061f7..000000000 Binary files a/InCallUI/res/drawable-xxxhdpi/ic_close_grey600_24dp.png and /dev/null differ diff --git a/InCallUI/res/drawable-xxxhdpi/ic_forward_white_24dp.png b/InCallUI/res/drawable-xxxhdpi/ic_forward_white_24dp.png deleted file mode 100644 index 428009cfe..000000000 Binary files a/InCallUI/res/drawable-xxxhdpi/ic_forward_white_24dp.png and /dev/null differ diff --git a/InCallUI/res/drawable-xxxhdpi/ic_hd_24dp.png b/InCallUI/res/drawable-xxxhdpi/ic_hd_24dp.png deleted file mode 100644 index 3f87b882e..000000000 Binary files a/InCallUI/res/drawable-xxxhdpi/ic_hd_24dp.png and /dev/null differ diff --git a/InCallUI/res/drawable-xxxhdpi/ic_location_on_white_24dp.png b/InCallUI/res/drawable-xxxhdpi/ic_location_on_white_24dp.png deleted file mode 100644 index 8bcb6f620..000000000 Binary files a/InCallUI/res/drawable-xxxhdpi/ic_location_on_white_24dp.png and /dev/null differ diff --git a/InCallUI/res/drawable-xxxhdpi/ic_person_add_grey600_24dp.png b/InCallUI/res/drawable-xxxhdpi/ic_person_add_grey600_24dp.png deleted file mode 100644 index e24919737..000000000 Binary files a/InCallUI/res/drawable-xxxhdpi/ic_person_add_grey600_24dp.png and /dev/null differ diff --git a/InCallUI/res/drawable-xxxhdpi/ic_question_mark.png b/InCallUI/res/drawable-xxxhdpi/ic_question_mark.png deleted file mode 100644 index 7ba34242c..000000000 Binary files a/InCallUI/res/drawable-xxxhdpi/ic_question_mark.png and /dev/null differ diff --git a/InCallUI/res/drawable-xxxhdpi/ic_report_white_36dp.png b/InCallUI/res/drawable-xxxhdpi/ic_report_white_36dp.png deleted file mode 100644 index 7ef0d7afc..000000000 Binary files a/InCallUI/res/drawable-xxxhdpi/ic_report_white_36dp.png and /dev/null differ diff --git a/InCallUI/res/drawable-xxxhdpi/ic_schedule_white_24dp.png b/InCallUI/res/drawable-xxxhdpi/ic_schedule_white_24dp.png deleted file mode 100644 index b94f4dfa1..000000000 Binary files a/InCallUI/res/drawable-xxxhdpi/ic_schedule_white_24dp.png and /dev/null differ diff --git a/InCallUI/res/drawable-xxxhdpi/ic_toolbar_add_call.png b/InCallUI/res/drawable-xxxhdpi/ic_toolbar_add_call.png deleted file mode 100644 index c97e4bb15..000000000 Binary files a/InCallUI/res/drawable-xxxhdpi/ic_toolbar_add_call.png and /dev/null differ diff --git a/InCallUI/res/drawable-xxxhdpi/ic_toolbar_arrow_whitespace.png b/InCallUI/res/drawable-xxxhdpi/ic_toolbar_arrow_whitespace.png deleted file mode 100644 index 1c11c5d0f..000000000 Binary files a/InCallUI/res/drawable-xxxhdpi/ic_toolbar_arrow_whitespace.png and /dev/null differ diff --git a/InCallUI/res/drawable-xxxhdpi/ic_toolbar_audio_bluetooth.png b/InCallUI/res/drawable-xxxhdpi/ic_toolbar_audio_bluetooth.png deleted file mode 100644 index f7fa12c8b..000000000 Binary files a/InCallUI/res/drawable-xxxhdpi/ic_toolbar_audio_bluetooth.png and /dev/null differ diff --git a/InCallUI/res/drawable-xxxhdpi/ic_toolbar_audio_headphones.png b/InCallUI/res/drawable-xxxhdpi/ic_toolbar_audio_headphones.png deleted file mode 100644 index 8199701ce..000000000 Binary files a/InCallUI/res/drawable-xxxhdpi/ic_toolbar_audio_headphones.png and /dev/null differ diff --git a/InCallUI/res/drawable-xxxhdpi/ic_toolbar_audio_phone.png b/InCallUI/res/drawable-xxxhdpi/ic_toolbar_audio_phone.png deleted file mode 100644 index ee14ea67a..000000000 Binary files a/InCallUI/res/drawable-xxxhdpi/ic_toolbar_audio_phone.png and /dev/null differ diff --git a/InCallUI/res/drawable-xxxhdpi/ic_toolbar_dialpad.png b/InCallUI/res/drawable-xxxhdpi/ic_toolbar_dialpad.png deleted file mode 100644 index e537112fb..000000000 Binary files a/InCallUI/res/drawable-xxxhdpi/ic_toolbar_dialpad.png and /dev/null differ diff --git a/InCallUI/res/drawable-xxxhdpi/ic_toolbar_hold.png b/InCallUI/res/drawable-xxxhdpi/ic_toolbar_hold.png deleted file mode 100644 index 883d0d609..000000000 Binary files a/InCallUI/res/drawable-xxxhdpi/ic_toolbar_hold.png and /dev/null differ diff --git a/InCallUI/res/drawable-xxxhdpi/ic_toolbar_merge.png b/InCallUI/res/drawable-xxxhdpi/ic_toolbar_merge.png deleted file mode 100644 index 4b6437507..000000000 Binary files a/InCallUI/res/drawable-xxxhdpi/ic_toolbar_merge.png and /dev/null differ diff --git a/InCallUI/res/drawable-xxxhdpi/ic_toolbar_mic_off.png b/InCallUI/res/drawable-xxxhdpi/ic_toolbar_mic_off.png deleted file mode 100644 index 2d8f279da..000000000 Binary files a/InCallUI/res/drawable-xxxhdpi/ic_toolbar_mic_off.png and /dev/null differ diff --git a/InCallUI/res/drawable-xxxhdpi/ic_toolbar_speaker_on.png b/InCallUI/res/drawable-xxxhdpi/ic_toolbar_speaker_on.png deleted file mode 100644 index 0560bb262..000000000 Binary files a/InCallUI/res/drawable-xxxhdpi/ic_toolbar_speaker_on.png and /dev/null differ diff --git a/InCallUI/res/drawable-xxxhdpi/ic_toolbar_swap.png b/InCallUI/res/drawable-xxxhdpi/ic_toolbar_swap.png deleted file mode 100644 index 6f03b3f66..000000000 Binary files a/InCallUI/res/drawable-xxxhdpi/ic_toolbar_swap.png and /dev/null differ diff --git a/InCallUI/res/drawable-xxxhdpi/ic_toolbar_video.png b/InCallUI/res/drawable-xxxhdpi/ic_toolbar_video.png deleted file mode 100644 index 0797fd019..000000000 Binary files a/InCallUI/res/drawable-xxxhdpi/ic_toolbar_video.png and /dev/null differ diff --git a/InCallUI/res/drawable-xxxhdpi/ic_toolbar_video_off.png b/InCallUI/res/drawable-xxxhdpi/ic_toolbar_video_off.png deleted file mode 100644 index 63f742bef..000000000 Binary files a/InCallUI/res/drawable-xxxhdpi/ic_toolbar_video_off.png and /dev/null differ diff --git a/InCallUI/res/drawable-xxxhdpi/ic_toolbar_video_switch.png b/InCallUI/res/drawable-xxxhdpi/ic_toolbar_video_switch.png deleted file mode 100644 index 77ff73cdb..000000000 Binary files a/InCallUI/res/drawable-xxxhdpi/ic_toolbar_video_switch.png and /dev/null differ diff --git a/InCallUI/res/drawable-xxxhdpi/img_business.png b/InCallUI/res/drawable-xxxhdpi/img_business.png deleted file mode 100644 index 88f14e999..000000000 Binary files a/InCallUI/res/drawable-xxxhdpi/img_business.png and /dev/null differ diff --git a/InCallUI/res/drawable-xxxhdpi/img_conference.png b/InCallUI/res/drawable-xxxhdpi/img_conference.png deleted file mode 100644 index eb42b5552..000000000 Binary files a/InCallUI/res/drawable-xxxhdpi/img_conference.png and /dev/null differ diff --git a/InCallUI/res/drawable-xxxhdpi/img_no_image.png b/InCallUI/res/drawable-xxxhdpi/img_no_image.png deleted file mode 100644 index 216574222..000000000 Binary files a/InCallUI/res/drawable-xxxhdpi/img_no_image.png and /dev/null differ diff --git a/InCallUI/res/drawable-xxxhdpi/img_phone.png b/InCallUI/res/drawable-xxxhdpi/img_phone.png deleted file mode 100644 index 7cbfbd75e..000000000 Binary files a/InCallUI/res/drawable-xxxhdpi/img_phone.png and /dev/null differ diff --git a/InCallUI/res/drawable/btn_add.xml b/InCallUI/res/drawable/btn_add.xml deleted file mode 100644 index 7d5e90f71..000000000 --- a/InCallUI/res/drawable/btn_add.xml +++ /dev/null @@ -1,30 +0,0 @@ - - - - - - - - - - - - - \ No newline at end of file diff --git a/InCallUI/res/drawable/btn_background.xml b/InCallUI/res/drawable/btn_background.xml deleted file mode 100644 index 597885803..000000000 --- a/InCallUI/res/drawable/btn_background.xml +++ /dev/null @@ -1,33 +0,0 @@ - - - - - - - - - - - - - - - diff --git a/InCallUI/res/drawable/btn_change_to_video.xml b/InCallUI/res/drawable/btn_change_to_video.xml deleted file mode 100644 index a26cee3e9..000000000 --- a/InCallUI/res/drawable/btn_change_to_video.xml +++ /dev/null @@ -1,31 +0,0 @@ - - - - - - - - - - - - - \ No newline at end of file diff --git a/InCallUI/res/drawable/btn_change_to_voice.xml b/InCallUI/res/drawable/btn_change_to_voice.xml deleted file mode 100644 index 86a7f21d5..000000000 --- a/InCallUI/res/drawable/btn_change_to_voice.xml +++ /dev/null @@ -1,31 +0,0 @@ - - - - - - - - - - - - - \ No newline at end of file diff --git a/InCallUI/res/drawable/btn_compound_audio.xml b/InCallUI/res/drawable/btn_compound_audio.xml deleted file mode 100644 index 25a64a6ab..000000000 --- a/InCallUI/res/drawable/btn_compound_audio.xml +++ /dev/null @@ -1,93 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/InCallUI/res/drawable/btn_compound_background.xml b/InCallUI/res/drawable/btn_compound_background.xml deleted file mode 100644 index 20e2a3056..000000000 --- a/InCallUI/res/drawable/btn_compound_background.xml +++ /dev/null @@ -1,35 +0,0 @@ - - - - - - - - - - - - - - - - - diff --git a/InCallUI/res/drawable/btn_compound_dialpad.xml b/InCallUI/res/drawable/btn_compound_dialpad.xml deleted file mode 100644 index 1b78ead44..000000000 --- a/InCallUI/res/drawable/btn_compound_dialpad.xml +++ /dev/null @@ -1,32 +0,0 @@ - - - - - - - - - - - - - - - diff --git a/InCallUI/res/drawable/btn_compound_hold.xml b/InCallUI/res/drawable/btn_compound_hold.xml deleted file mode 100644 index 7974efae5..000000000 --- a/InCallUI/res/drawable/btn_compound_hold.xml +++ /dev/null @@ -1,32 +0,0 @@ - - - - - - - - - - - - - - - diff --git a/InCallUI/res/drawable/btn_compound_mute.xml b/InCallUI/res/drawable/btn_compound_mute.xml deleted file mode 100644 index 86708fb0c..000000000 --- a/InCallUI/res/drawable/btn_compound_mute.xml +++ /dev/null @@ -1,31 +0,0 @@ - - - - - - - - - - - - - - - diff --git a/InCallUI/res/drawable/btn_compound_video_off.xml b/InCallUI/res/drawable/btn_compound_video_off.xml deleted file mode 100644 index b942cd0c3..000000000 --- a/InCallUI/res/drawable/btn_compound_video_off.xml +++ /dev/null @@ -1,33 +0,0 @@ - - - - - - - - - - - - - - - diff --git a/InCallUI/res/drawable/btn_compound_video_switch.xml b/InCallUI/res/drawable/btn_compound_video_switch.xml deleted file mode 100644 index f8111866e..000000000 --- a/InCallUI/res/drawable/btn_compound_video_switch.xml +++ /dev/null @@ -1,33 +0,0 @@ - - - - - - - - - - - - - - - diff --git a/InCallUI/res/drawable/btn_merge.xml b/InCallUI/res/drawable/btn_merge.xml deleted file mode 100644 index 2b4818a47..000000000 --- a/InCallUI/res/drawable/btn_merge.xml +++ /dev/null @@ -1,30 +0,0 @@ - - - - - - - - - - - - - \ No newline at end of file diff --git a/InCallUI/res/drawable/btn_overflow.xml b/InCallUI/res/drawable/btn_overflow.xml deleted file mode 100644 index 2eb26cc14..000000000 --- a/InCallUI/res/drawable/btn_overflow.xml +++ /dev/null @@ -1,30 +0,0 @@ - - - - - - - - - - - - - \ No newline at end of file diff --git a/InCallUI/res/drawable/btn_selected.xml b/InCallUI/res/drawable/btn_selected.xml deleted file mode 100644 index 1446e4163..000000000 --- a/InCallUI/res/drawable/btn_selected.xml +++ /dev/null @@ -1,25 +0,0 @@ - - - - - - - - - - - \ No newline at end of file diff --git a/InCallUI/res/drawable/btn_selected_focused.xml b/InCallUI/res/drawable/btn_selected_focused.xml deleted file mode 100644 index 2eda9bf8b..000000000 --- a/InCallUI/res/drawable/btn_selected_focused.xml +++ /dev/null @@ -1,29 +0,0 @@ - - - - - - - - - - - - - \ No newline at end of file diff --git a/InCallUI/res/drawable/btn_swap.xml b/InCallUI/res/drawable/btn_swap.xml deleted file mode 100644 index 5d6c8ecaf..000000000 --- a/InCallUI/res/drawable/btn_swap.xml +++ /dev/null @@ -1,30 +0,0 @@ - - - - - - - - - - - - - \ No newline at end of file diff --git a/InCallUI/res/drawable/btn_unselected.xml b/InCallUI/res/drawable/btn_unselected.xml deleted file mode 100644 index aed995cec..000000000 --- a/InCallUI/res/drawable/btn_unselected.xml +++ /dev/null @@ -1,25 +0,0 @@ - - - - - - - - - - - \ No newline at end of file diff --git a/InCallUI/res/drawable/btn_unselected_focused.xml b/InCallUI/res/drawable/btn_unselected_focused.xml deleted file mode 100644 index 66075d427..000000000 --- a/InCallUI/res/drawable/btn_unselected_focused.xml +++ /dev/null @@ -1,28 +0,0 @@ - - - - - - - - - - - - \ No newline at end of file diff --git a/InCallUI/res/drawable/conference_ripple.xml b/InCallUI/res/drawable/conference_ripple.xml deleted file mode 100644 index 4e4a21304..000000000 --- a/InCallUI/res/drawable/conference_ripple.xml +++ /dev/null @@ -1,25 +0,0 @@ - - - - - - - - - - \ No newline at end of file diff --git a/InCallUI/res/drawable/end_call_background.xml b/InCallUI/res/drawable/end_call_background.xml deleted file mode 100644 index c43deac4f..000000000 --- a/InCallUI/res/drawable/end_call_background.xml +++ /dev/null @@ -1,25 +0,0 @@ - - - - - - - - - - - diff --git a/InCallUI/res/drawable/ic_incall_audio_handle.xml b/InCallUI/res/drawable/ic_incall_audio_handle.xml deleted file mode 100644 index 2e71a5b70..000000000 --- a/InCallUI/res/drawable/ic_incall_audio_handle.xml +++ /dev/null @@ -1,40 +0,0 @@ - - - - - - - - - - - - - - - - - - - diff --git a/InCallUI/res/drawable/ic_incall_video_handle.xml b/InCallUI/res/drawable/ic_incall_video_handle.xml deleted file mode 100644 index a24e305c4..000000000 --- a/InCallUI/res/drawable/ic_incall_video_handle.xml +++ /dev/null @@ -1,41 +0,0 @@ - - - - - - - - - - - - - - - - - - - diff --git a/InCallUI/res/drawable/ic_lockscreen_answer.xml b/InCallUI/res/drawable/ic_lockscreen_answer.xml deleted file mode 100644 index 3184111fb..000000000 --- a/InCallUI/res/drawable/ic_lockscreen_answer.xml +++ /dev/null @@ -1,27 +0,0 @@ - - - - - - - - diff --git a/InCallUI/res/drawable/ic_lockscreen_answer_activated_layer.xml b/InCallUI/res/drawable/ic_lockscreen_answer_activated_layer.xml deleted file mode 100644 index f22b87e34..000000000 --- a/InCallUI/res/drawable/ic_lockscreen_answer_activated_layer.xml +++ /dev/null @@ -1,25 +0,0 @@ - - - - - - - - diff --git a/InCallUI/res/drawable/ic_lockscreen_answer_normal_layer.xml b/InCallUI/res/drawable/ic_lockscreen_answer_normal_layer.xml deleted file mode 100644 index 31b884f99..000000000 --- a/InCallUI/res/drawable/ic_lockscreen_answer_normal_layer.xml +++ /dev/null @@ -1,33 +0,0 @@ - - - - - - - - - - - - - - diff --git a/InCallUI/res/drawable/ic_lockscreen_answer_video.xml b/InCallUI/res/drawable/ic_lockscreen_answer_video.xml deleted file mode 100644 index 05577979a..000000000 --- a/InCallUI/res/drawable/ic_lockscreen_answer_video.xml +++ /dev/null @@ -1,28 +0,0 @@ - - - - - - - - diff --git a/InCallUI/res/drawable/ic_lockscreen_answer_video_activated_layer.xml b/InCallUI/res/drawable/ic_lockscreen_answer_video_activated_layer.xml deleted file mode 100644 index 7895e1b6d..000000000 --- a/InCallUI/res/drawable/ic_lockscreen_answer_video_activated_layer.xml +++ /dev/null @@ -1,26 +0,0 @@ - - - - - - - - diff --git a/InCallUI/res/drawable/ic_lockscreen_answer_video_normal_layer.xml b/InCallUI/res/drawable/ic_lockscreen_answer_video_normal_layer.xml deleted file mode 100644 index 793a36e10..000000000 --- a/InCallUI/res/drawable/ic_lockscreen_answer_video_normal_layer.xml +++ /dev/null @@ -1,34 +0,0 @@ - - - - - - - - - - - - - - diff --git a/InCallUI/res/drawable/ic_lockscreen_decline.xml b/InCallUI/res/drawable/ic_lockscreen_decline.xml deleted file mode 100644 index 6643816d9..000000000 --- a/InCallUI/res/drawable/ic_lockscreen_decline.xml +++ /dev/null @@ -1,27 +0,0 @@ - - - - - - - - diff --git a/InCallUI/res/drawable/ic_lockscreen_decline_activated_layer.xml b/InCallUI/res/drawable/ic_lockscreen_decline_activated_layer.xml deleted file mode 100644 index 096c32b4a..000000000 --- a/InCallUI/res/drawable/ic_lockscreen_decline_activated_layer.xml +++ /dev/null @@ -1,24 +0,0 @@ - - - - - - - - diff --git a/InCallUI/res/drawable/ic_lockscreen_decline_normal_layer.xml b/InCallUI/res/drawable/ic_lockscreen_decline_normal_layer.xml deleted file mode 100644 index 4da5f8d66..000000000 --- a/InCallUI/res/drawable/ic_lockscreen_decline_normal_layer.xml +++ /dev/null @@ -1,32 +0,0 @@ - - - - - - - - - - - - - - diff --git a/InCallUI/res/drawable/ic_lockscreen_decline_video.xml b/InCallUI/res/drawable/ic_lockscreen_decline_video.xml deleted file mode 100644 index cedd49757..000000000 --- a/InCallUI/res/drawable/ic_lockscreen_decline_video.xml +++ /dev/null @@ -1,28 +0,0 @@ - - - - - - - - diff --git a/InCallUI/res/drawable/ic_lockscreen_decline_video_activated_layer.xml b/InCallUI/res/drawable/ic_lockscreen_decline_video_activated_layer.xml deleted file mode 100644 index 0790aed19..000000000 --- a/InCallUI/res/drawable/ic_lockscreen_decline_video_activated_layer.xml +++ /dev/null @@ -1,26 +0,0 @@ - - - - - - - - diff --git a/InCallUI/res/drawable/ic_lockscreen_decline_video_normal_layer.xml b/InCallUI/res/drawable/ic_lockscreen_decline_video_normal_layer.xml deleted file mode 100644 index e3b89b947..000000000 --- a/InCallUI/res/drawable/ic_lockscreen_decline_video_normal_layer.xml +++ /dev/null @@ -1,34 +0,0 @@ - - - - - - - - - - - - - - diff --git a/InCallUI/res/drawable/ic_lockscreen_outerring.xml b/InCallUI/res/drawable/ic_lockscreen_outerring.xml deleted file mode 100644 index 489515fbc..000000000 --- a/InCallUI/res/drawable/ic_lockscreen_outerring.xml +++ /dev/null @@ -1,22 +0,0 @@ - - - - - - - diff --git a/InCallUI/res/drawable/ic_lockscreen_text.xml b/InCallUI/res/drawable/ic_lockscreen_text.xml deleted file mode 100644 index f9caac818..000000000 --- a/InCallUI/res/drawable/ic_lockscreen_text.xml +++ /dev/null @@ -1,27 +0,0 @@ - - - - - - - - diff --git a/InCallUI/res/drawable/ic_lockscreen_text_activated_layer.xml b/InCallUI/res/drawable/ic_lockscreen_text_activated_layer.xml deleted file mode 100644 index a74e36b31..000000000 --- a/InCallUI/res/drawable/ic_lockscreen_text_activated_layer.xml +++ /dev/null @@ -1,32 +0,0 @@ - - - - - - - - - - - - - diff --git a/InCallUI/res/drawable/ic_lockscreen_text_normal_layer.xml b/InCallUI/res/drawable/ic_lockscreen_text_normal_layer.xml deleted file mode 100644 index be32d0baa..000000000 --- a/InCallUI/res/drawable/ic_lockscreen_text_normal_layer.xml +++ /dev/null @@ -1,33 +0,0 @@ - - - - - - - - - - - - - - diff --git a/InCallUI/res/drawable/img_conference_automirrored.xml b/InCallUI/res/drawable/img_conference_automirrored.xml deleted file mode 100644 index fa1fd4920..000000000 --- a/InCallUI/res/drawable/img_conference_automirrored.xml +++ /dev/null @@ -1,21 +0,0 @@ - - - - - \ No newline at end of file diff --git a/InCallUI/res/drawable/img_no_image_automirrored.xml b/InCallUI/res/drawable/img_no_image_automirrored.xml deleted file mode 100644 index f0cf0db31..000000000 --- a/InCallUI/res/drawable/img_no_image_automirrored.xml +++ /dev/null @@ -1,21 +0,0 @@ - - - - - \ No newline at end of file diff --git a/InCallUI/res/drawable/incoming_sms_background.xml b/InCallUI/res/drawable/incoming_sms_background.xml deleted file mode 100644 index 81ff21c61..000000000 --- a/InCallUI/res/drawable/incoming_sms_background.xml +++ /dev/null @@ -1,25 +0,0 @@ - - - - - - diff --git a/InCallUI/res/drawable/outgoing_sms_background.xml b/InCallUI/res/drawable/outgoing_sms_background.xml deleted file mode 100644 index e4f868fea..000000000 --- a/InCallUI/res/drawable/outgoing_sms_background.xml +++ /dev/null @@ -1,25 +0,0 @@ - - - - - - diff --git a/InCallUI/res/drawable/spam_notification_icon.xml b/InCallUI/res/drawable/spam_notification_icon.xml deleted file mode 100644 index c8bafe085..000000000 --- a/InCallUI/res/drawable/spam_notification_icon.xml +++ /dev/null @@ -1,31 +0,0 @@ - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/InCallUI/res/drawable/subject_bubble.xml b/InCallUI/res/drawable/subject_bubble.xml deleted file mode 100644 index adab67833..000000000 --- a/InCallUI/res/drawable/subject_bubble.xml +++ /dev/null @@ -1,22 +0,0 @@ - - - - - - - \ No newline at end of file diff --git a/InCallUI/res/drawable/unknown_notification_icon.xml b/InCallUI/res/drawable/unknown_notification_icon.xml deleted file mode 100644 index 85c50752c..000000000 --- a/InCallUI/res/drawable/unknown_notification_icon.xml +++ /dev/null @@ -1,31 +0,0 @@ - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/InCallUI/res/layout-h400dp/call_card_fragment.xml b/InCallUI/res/layout-h400dp/call_card_fragment.xml deleted file mode 100644 index 2ef6e52da..000000000 --- a/InCallUI/res/layout-h400dp/call_card_fragment.xml +++ /dev/null @@ -1,172 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/InCallUI/res/layout-h600dp/manage_conference_call_button.xml b/InCallUI/res/layout-h600dp/manage_conference_call_button.xml deleted file mode 100644 index 9a83313ac..000000000 --- a/InCallUI/res/layout-h600dp/manage_conference_call_button.xml +++ /dev/null @@ -1,61 +0,0 @@ - - - - - - - - - - - - - - - - - - diff --git a/InCallUI/res/layout-w500dp-land/call_card_fragment.xml b/InCallUI/res/layout-w500dp-land/call_card_fragment.xml deleted file mode 100644 index c71cf07a6..000000000 --- a/InCallUI/res/layout-w500dp-land/call_card_fragment.xml +++ /dev/null @@ -1,158 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/InCallUI/res/layout-w600dp-land/manage_conference_call_button.xml b/InCallUI/res/layout-w600dp-land/manage_conference_call_button.xml deleted file mode 100644 index 9a83313ac..000000000 --- a/InCallUI/res/layout-w600dp-land/manage_conference_call_button.xml +++ /dev/null @@ -1,61 +0,0 @@ - - - - - - - - - - - - - - - - - - diff --git a/InCallUI/res/layout/accessible_answer_fragment.xml b/InCallUI/res/layout/accessible_answer_fragment.xml deleted file mode 100644 index 90fe57788..000000000 --- a/InCallUI/res/layout/accessible_answer_fragment.xml +++ /dev/null @@ -1,104 +0,0 @@ - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/InCallUI/res/layout/answer_fragment.xml b/InCallUI/res/layout/answer_fragment.xml deleted file mode 100644 index ec6ef30ac..000000000 --- a/InCallUI/res/layout/answer_fragment.xml +++ /dev/null @@ -1,42 +0,0 @@ - - - - diff --git a/InCallUI/res/layout/business_contact_context_list_header.xml b/InCallUI/res/layout/business_contact_context_list_header.xml deleted file mode 100644 index 90521188e..000000000 --- a/InCallUI/res/layout/business_contact_context_list_header.xml +++ /dev/null @@ -1,40 +0,0 @@ - - - - - - \ No newline at end of file diff --git a/InCallUI/res/layout/business_context_info_list_item.xml b/InCallUI/res/layout/business_context_info_list_item.xml deleted file mode 100644 index 616d219d9..000000000 --- a/InCallUI/res/layout/business_context_info_list_item.xml +++ /dev/null @@ -1,48 +0,0 @@ - - - - - - - - - \ No newline at end of file diff --git a/InCallUI/res/layout/call_button_fragment.xml b/InCallUI/res/layout/call_button_fragment.xml deleted file mode 100644 index 802e3de62..000000000 --- a/InCallUI/res/layout/call_button_fragment.xml +++ /dev/null @@ -1,171 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/InCallUI/res/layout/call_card_fragment.xml b/InCallUI/res/layout/call_card_fragment.xml deleted file mode 100644 index fabde378a..000000000 --- a/InCallUI/res/layout/call_card_fragment.xml +++ /dev/null @@ -1,158 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/InCallUI/res/layout/caller_in_conference.xml b/InCallUI/res/layout/caller_in_conference.xml deleted file mode 100644 index ac78096f6..000000000 --- a/InCallUI/res/layout/caller_in_conference.xml +++ /dev/null @@ -1,116 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/InCallUI/res/layout/conference_manager_fragment.xml b/InCallUI/res/layout/conference_manager_fragment.xml deleted file mode 100644 index 7350bee14..000000000 --- a/InCallUI/res/layout/conference_manager_fragment.xml +++ /dev/null @@ -1,36 +0,0 @@ - - - - - - - - diff --git a/InCallUI/res/layout/incall_dialpad_fragment.xml b/InCallUI/res/layout/incall_dialpad_fragment.xml deleted file mode 100644 index b567dbbf2..000000000 --- a/InCallUI/res/layout/incall_dialpad_fragment.xml +++ /dev/null @@ -1,24 +0,0 @@ - - - - - - diff --git a/InCallUI/res/layout/incall_screen.xml b/InCallUI/res/layout/incall_screen.xml deleted file mode 100644 index 3922ea073..000000000 --- a/InCallUI/res/layout/incall_screen.xml +++ /dev/null @@ -1,23 +0,0 @@ - - - - - - diff --git a/InCallUI/res/layout/manage_conference_call_button.xml b/InCallUI/res/layout/manage_conference_call_button.xml deleted file mode 100644 index 01ca1bdc3..000000000 --- a/InCallUI/res/layout/manage_conference_call_button.xml +++ /dev/null @@ -1,72 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/InCallUI/res/layout/outgoing_call_animation.xml b/InCallUI/res/layout/outgoing_call_animation.xml deleted file mode 100644 index 69ba3d3c6..000000000 --- a/InCallUI/res/layout/outgoing_call_animation.xml +++ /dev/null @@ -1,22 +0,0 @@ - - - - \ No newline at end of file diff --git a/InCallUI/res/layout/person_context_info_list_item.xml b/InCallUI/res/layout/person_context_info_list_item.xml deleted file mode 100644 index 4f973d564..000000000 --- a/InCallUI/res/layout/person_context_info_list_item.xml +++ /dev/null @@ -1,40 +0,0 @@ - - - - - - \ No newline at end of file diff --git a/InCallUI/res/layout/primary_call_info.xml b/InCallUI/res/layout/primary_call_info.xml deleted file mode 100644 index cae915224..000000000 --- a/InCallUI/res/layout/primary_call_info.xml +++ /dev/null @@ -1,231 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/InCallUI/res/layout/secondary_call_info.xml b/InCallUI/res/layout/secondary_call_info.xml deleted file mode 100644 index e866795a6..000000000 --- a/InCallUI/res/layout/secondary_call_info.xml +++ /dev/null @@ -1,105 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/InCallUI/res/layout/video_call_fragment.xml b/InCallUI/res/layout/video_call_fragment.xml deleted file mode 100644 index d5e11ef4a..000000000 --- a/InCallUI/res/layout/video_call_fragment.xml +++ /dev/null @@ -1,28 +0,0 @@ - - - - - - - \ No newline at end of file diff --git a/InCallUI/res/layout/video_call_views.xml b/InCallUI/res/layout/video_call_views.xml deleted file mode 100644 index d514f6df1..000000000 --- a/InCallUI/res/layout/video_call_views.xml +++ /dev/null @@ -1,66 +0,0 @@ - - - - - - - - - - - - - - - - - - - - diff --git a/InCallUI/res/menu/incall_audio_mode_menu.xml b/InCallUI/res/menu/incall_audio_mode_menu.xml deleted file mode 100644 index 070c1813a..000000000 --- a/InCallUI/res/menu/incall_audio_mode_menu.xml +++ /dev/null @@ -1,39 +0,0 @@ - - - - - - - - - - - - - - - diff --git a/InCallUI/res/values-af/strings.xml b/InCallUI/res/values-af/strings.xml deleted file mode 100644 index 181ffce66..000000000 --- a/InCallUI/res/values-af/strings.xml +++ /dev/null @@ -1,195 +0,0 @@ - - - - - "Foon" - "Hou aan" - "Onbekend" - "Privaat nommer" - "Telefoonhokkie" - "Konferensie-oproep" - "Oproep is ontkoppel" - "Luidspreker" - "Selfoonoorfoon" - "Bedraade kopfoon" - "Bluetooth" - "Stuur die volgende luitone?\n" - "Stuur luitone\n" - "Stuur" - "Ja" - "Nee" - "Vervang die plekhouerkarakter met" - "Konferensie-oproep %s" - "Stemboodskapnommer" - "Bel" - "Bel tans weer" - "Konferensie-oproep" - "Inkomende oproep" - "Inkomende werkoproep" - "Oproep beëindig" - "Hou aan" - "Lui af" - "In oproep" - "My nommer is %s" - "Koppel tans video" - "Video-oproep" - "Versoek tans video" - "Kan nie video-oproep koppel nie" - "Videoversoek is verwerp" - "Jou terugbelnommer\n %1$s" - "Jou noodterugbelnommer\n %1$s" - "Bel" - "Gemiste oproep" - "Gemiste oproepe" - "%s gemiste oproepe" - "Gemiste oproep vanaf %s" - "Voortdurende oproep" - "Voortdurende werkoproep" - "Voortdurende Wi-Fi-oproep" - "Voortdurende Wi-Fi-werkoproep" - "Hou aan" - "Inkomende oproep" - "Inkomende werkoproep" - "Inkomende Wi-Fi-oproep" - "Inkomende Wi-Fi-werkoproep" - "Inkomende video-oproep" - "Inkomende verdagte strooipos-oproep" - "Inkomende videoversoek" - "Nuwe stemboodskap" - "Nuwe stemboodskap (%d)" - "Bel %s" - "Stemboodskapnommer is onbekend" - "Geen diens nie" - "Gekose netwerk (%s) is nie beskikbaar nie" - "Antwoord" - "Lui af" - "Video" - "Stem" - "Aanvaar" - "Maak toe" - "Bel terug" - "Boodskap" - "Voortgesette oproep op \'n ander toestel" - "Sit oproep deur" - "Skakel vliegtuigmodus eers af om \'n oproep te maak." - "Nie geregistreer op netwerk nie." - "Sellulêre netwerk is nie beskikbaar nie." - "Voer \'n geldige nommer in om \'n oproep te maak." - "Kan nie bel nie." - "Begin tans MMI-volgorde …" - "Diens word nie gesteun nie." - "Kan nie oproepe wissel nie." - "Kan nie oproep skei nie." - "Kan nie deurskakel nie." - "Kan nie konferensie-oproep maak nie." - "Kan nie oproep weier nie." - "Kan nie oproep(e) vrystel nie." - "SIP-oproep" - "Noodoproep" - "Skakel tans radio aan …" - "Geen sein nie. Probeer tans weer …" - "Kan nie bel nie. %s is nie \'n noodnommer nie." - "Kan nie bel nie. Bel \'n noodnommer." - "Gebruik sleutelbord om te bel" - "Hou oproep" - "Hervat oproep" - "Beëindig oproep" - "Wys belblad" - "Versteek belblad" - "Demp" - "Ontdemp" - "Voeg oproep by" - "Smelt oproepe saam" - "Ruil" - "Bestuur oproepe" - "Bestuur konferensie-oproep" - "Konferensie-oproep" - "Bestuur" - "Oudio" - "Video-oproep" - "Verander na stemoproep" - "Wissel kamera" - "Skakel kamera aan" - "Skakel kamera af" - "Nog opsies" - "Speler het begin" - "Speler het gestop" - "Kamera is nie gereed nie" - "Kamera is gereed" - "Onbekende oproepsessiegebeurtenis" - "Diens" - "Opstelling" - "<Nie gestel nie>" - "Ander oproepinstellings" - "Bel via %s" - "Inkomend via %s" - "kontakfoto" - "gaan privaat" - "kies kontak" - "Skryf jou eie …" - "Kanselleer" - "Stuur" - "Antwoord" - "Stuur SMS" - "Weier" - "Antwoord as video-oproep" - "Antwoord as oudio-oproep" - "Aanvaar videoversoek" - "Weier videoversoek" - "Aanvaar videoversendversoek" - "Weier videoversendversoek" - "Aanvaar video-ontvangversoek" - "Weier video-ontvangversoek" - "Gly op vir %s." - "Gly links vir %s." - "Gly regs vir %s." - "Gly af vir %s." - "Vibreer" - "Vibreer" - "Klank" - "Verstekklank (%1$s)" - "Foonluitoon" - "Vibreer wanneer dit lui" - "Luitoon en vibreer" - "Bestuur konferensie-oproep" - "Noodnommer" - "Profielfoto" - "Kamera is af" - "via %s" - "Nota is gestuur" - "Onlangse boodskappe" - "Besigheidinligting" - "%.1f myl ver" - "%.1f km ver" - "%1$s, %2$s" - "%1$s%2$s" - "%1$s, %2$s" - "Maak môre om %s oop" - "Maak vandag om %s oop" - "Maak om %s toe" - "Het vandag om %s toegemaak" - "Nou oop" - "Nou gesluit" - "Verdagte strooiposbeller" - "Oproep het geëindig %1$s" - "Dit is die eerste keer wat hierdie nommer jou bel." - "Ons vermoed dat hierdie oproep strooipos was." - "Blokkeer/gee strooipos aan" - "Voeg kontak by" - "Nie strooipos nie" - diff --git a/InCallUI/res/values-am/strings.xml b/InCallUI/res/values-am/strings.xml deleted file mode 100644 index 99516cfec..000000000 --- a/InCallUI/res/values-am/strings.xml +++ /dev/null @@ -1,195 +0,0 @@ - - - - - "ስልክ" - "ያዝና ቆይ" - "ያልታወቀ" - "የግል ቁጥር" - "የሕዝብ ስልክ" - "የስብሰባ ጥሪ" - "ጥሪው ተቋርጧል" - "ድምፅ ማጉያ" - "የስልክ ጆሮ ማዳመጫ" - "ባለ ገመድ የጆሮ ማዳመጫ" - "ብሉቱዝ" - "የሚከተሉትን የጥሪ ድምፆች ላክ?\n" - "የጥሪ ድምፆች በመላክ ላይ \n" - "ላክ" - "አዎ" - "አይ" - "የልቅ ምልክት ተካ በ" - "የስብሰባ ጥሪ %s" - "የድምፅ መልእክት ቁጥር" - "በመደወል ላይ" - "ዳግም በመደወል ላይ" - "የስብሰባ ጥሪ" - "ገቢ ጥሪ" - "ገቢ የሥራ ጥሪ" - "ጥሪ አብቅቷል" - "ያዝና ቆይ" - "በመዝጋት ላይ" - "ጥሪ ላይ" - "ቁጥሬ %s ነው" - "ቪድዮ በማገናኘት ላይ" - "የቪዲዮ ጥሪ" - "ቪድዮ በመጠየቅ ላይ" - "የቪዲዮ ጥሪን ማገናኘት አይቻልም" - "የቪዲዮ ጥያቄ ውድቅ ተደርጓል" - "የእርስዎ የመልሶ መደወያ ቁጥር\n%1$s" - "የእርስዎ የድንገተኛ አደጋ መልሶ መደወያ ቁጥር\n%1$s" - "በመደወል ላይ" - "ያመለጠ ጥሪ" - "ያመለጡ ጥሪዎች" - "%s ያመለጡ ጥሪዎች" - "ያልተመለሰ ጥሪ ከ%s" - "በሂደት ላይ ያለ ጥሪ" - "በሂደት ላይ ያለ የሥራ ጥሪ" - "በሂደት ላይ ያለ የWi-Fi ጥሪ" - "በሂደት ላይ ያለ የWi-Fi የሥራ ጥሪ" - "ያዝና ቆይ" - "ገቢ ጥሪ" - "ገቢ የሥራ ጥሪ" - "ገቢ የWi-Fi ጥሪ" - "ገቢ የWi-Fi የሥራ ጥሪ" - "ገቢ የቪዲዮ ጥሪ" - "መጪ የተጠረጠረ የአይፈለጌ መልዕክት ጥሪ" - "ገቢ የቪዲዮ ጥያቄ" - "አዲስ የድምፅ መልእክት" - "አዲስ የድምፅ መልእክት (%d)" - "ደውል %s" - "የማይታወቅ የድምፅ መልእክት ቁጥር" - "ምንም አገልግሎት የለም" - "የተመረጠ አውታረመረብ (%s) አይገኝም" - "መልስ" - "ዝጋ" - "ቪዲዮ" - "ድምፅ" - "ተቀበል" - "አስወግድ" - "መልሰህ ደውል" - "መልእክት" - "በሌላ መሳሪያ ጥሪ በመካሄድ ላይ ነው" - "ጥሪ አስተላልፍ" - "ለመደወል፣ መጀመሪያ የአውሮፕላኑን ሁኔታ ያጥፉ።" - "በአውታረ መረቡ ላይ አልተመዘገበም።" - "የተንቀሳቃሽ ስልክ አውታረ መረብ አይገኝም።" - "አንድ ጥሪ ለማድረግ የሚሠራ ቁጥር ያስገቡ።" - "መደወል አይቻልም።" - "የMMI ቅደመ ተከተል በማስጀመር ላይ…" - "አገልግሎት አይደገፍም።" - "ጥሪዎችን መቀያየር አይቻልም።" - "ጥሪን መለየት አይቻልም።" - "ማስተላለፍ አይቻልም።" - "የጉባዔ ጥሪ ማድረግ አይቻልም።" - "ጥሪውን መዝጋት አይቻልም።" - "ጥሪ(ዎች)ን መልቀቅ አይቻልም።" - "የSIP ጥሪ" - "የአስቸኳይ ጊዜ ጥሪ" - "ሬዲዮ በማብራት ላይ…" - "ምንም አገልግሎት የለም። ዳግም በመሞከር ላይ…" - "መደወል አይቻልም። %s የአስቸኳይ አደጋ ቁጥር አይደለም።" - "መደወል አይቻልም። ወደ የአስቸኳይ አደጋ ቁጥር ይደውሉ።" - "ለመደወል የሰሌዳ ቁልፍ ተጠቀም" - "ጥሪ አቆይ" - "ጥሪ ቀጥል" - "ጥሪ ጨርስ" - "የመደወያ ሰሌዳ አሳይ" - "የመደወያ ሰሌዳ ደብቅ" - "ድምፅ-ከል አድርግ" - "ድምፅ አታጥፋ" - "ጥሪ ያክሉ" - "ጥሪዎችን አዋህድ" - "በውዝ" - "ጥሪዎችን አደራጅ" - "የስብሰባ ስልክ ጥሪ አደራጅ" - "የስብሰባ ጥሪ" - "ያስተዳድሩ" - "ኦዲዮ" - "የቪዲዮ ጥሪ" - "ወደ ድምፅ ጥሪ ይለውጡ" - "ካሜራ ቀይር" - "ካሜራ ያብሩ" - "ካሜራ ያጥፉ" - "ተጨማሪ አማራጮች" - "አጫዋች ጀምሯል" - "አጫዋች ቆሟል" - "ካሜራ ዝግጁ አይደለም" - "ካሜራ ዝግጁ ነው" - "ያልታወቀ የጥሪ ክፍለጊዜ ክስተት" - "አገልግሎት" - "አዋቅር" - "<አልተዘጋጀም>" - "ሌሎች የጥሪ ቅንብሮች" - "በ%s በኩል በመደወል ላይ" - "በ%s በኩል የመጣ" - "የዕውቂያ ፎቶ" - "ወደ ግላዊነት ሂድ" - "ዕውቂያ ይምረጡ" - "የእራስዎን ይጻፉ..." - "ተወው" - "ላክ" - "መልስ" - "ኤስኤምኤስ ላክ" - "ውድቅ አድርግ" - "እንደ ቪድዮ ጥሪ ይመልሱ" - "እንደ ድምፅ ጥሪ ይመልሱ" - "የቪዲዮ ጥያቄ ተቀበል" - "የቪዲዮ ጥያቄ ውድቅ አድርግ" - "የቪዲዮ አስተላልፍ ጥያቄን ተቀበል" - "የቪዲዮ አስተላልፍ ጥያቄን ውድቅ አድርግ" - "የቪዲዮ ተቀበል ጥያቄን ተቀበል" - "የቪዲዮ ተቀበል ጥያቄን ውድቅ አድርግ" - "ለ%s ወደ ላይ ያንሸራትቱ።" - "ለ%s ወደ ግራ ያንሸራትቱ።" - "ለ%s ወደ ቀኝ ያንሸራትቱ።" - "ለ%s ወደ ታች ያንሸራትቱ።" - "ንዘር" - "ንዘር" - "ድምፅ" - "ነባሪ ድምፅ (%1$s)" - "የስልክ ጥሪ ቅላጼ" - "በሚደወልበት ጊዜ ንዘር" - "የጥሪ ቅላጼ እና ንዘረት" - "የስብሰባ ስልክ ጥሪ አደራጅ" - "የአደጋ ጊዜ ቁጥር" - "የመገለጫ ፎቶ" - "ካሜራ ጠፍቷል" - "በ%s በኩል" - "ማስታወሻ ተልኳል" - "የቅርብ ጊዜ መልእክቶች" - "የንግድ መረጃ" - "%.1f ማይል ርቀት ላይ" - "%.1f ኪሜ ርቀት ላይ" - "%1$s%2$s" - "%1$s - %2$s" - "%1$s%2$s" - "ነገ %s ላይ ይከፈታል" - "ዛሬ %s ላይ ይከፈታል" - "%s ላይ ይዘጋል" - "ዛሬ %s ላይ ተዘግቷል" - "አሁን ክፍት ነው" - "አሁን ዝግ ነው" - "የተጠረጠረ አይፈለጌ ጠሪ" - "ጥሪው አብቅቷል %1$s" - "ይህ ቁጥር ለእርስዎ ሲደውል ይህ የመጀመሪያው ነው።" - "ይህ ቁጥር አይፈለጌ ላኪ ነው ብለን እንገምታለን።" - "አይፈለጌ አግድ/ሪፖርት አድርግ" - "እውቂያ ያክሉ" - "አይፈለጌ አይደለም" - diff --git a/InCallUI/res/values-ar/strings.xml b/InCallUI/res/values-ar/strings.xml deleted file mode 100644 index e89f026b6..000000000 --- a/InCallUI/res/values-ar/strings.xml +++ /dev/null @@ -1,195 +0,0 @@ - - - - - "الهاتف" - "معلقة" - "غير معروف" - "رقم خاص" - "هاتف بالعملة" - "مكالمة جماعية" - "تم قطع المكالمة" - "السماعة" - "سماعة الأذن للهاتف" - "سماعة رأس سلكية" - "بلوتوث" - "هل تريد إرسال النغمات التالية؟\n" - "إرسال النغمات\n" - "إرسال" - "نعم" - "لا" - "استبدال حرف البدل بـ" - "مكالمة جماعية %s" - "رقم البريد الصوتي" - "جارٍ الطلب" - "جارٍ إعادة الطلب" - "مكالمة جماعية" - "مكالمة واردة" - "مكالمة عمل واردة" - "تم إنهاء الاتصال" - "معلقة" - "جارٍ وقف المكالمة" - "بصدد مكالمة" - "رقمي %s" - "جارٍ الاتصال بالفيديو" - "مكالمة فيديو" - "جارٍ طلب الفيديو" - "يتعذر الاتصال بمكالمة فيديو" - "تم رفض طلب الفيديو" - "رقم معاودة الاتصال\n %1$s" - "رقم معاودة اتصال الطوارئ\n %1$s" - "جارٍ الطلب" - "مكالمة فائتة" - "المكالمات الفائتة" - "%s من المكالمات الفائتة" - "مكالمة فائتة من %s" - "مكالمة حالية" - "مكالمة عمل جارية" - "‏مكالمة جارية عبر Wi-Fi" - "‏مكالمة عمل جارية عبر Wi-Fi" - "معلقة" - "مكالمة واردة" - "مكالمة عمل واردة" - "‏مكالمة واردة عبر Wi-Fi" - "‏مكالمة عمل واردة عبر اتصال Wi-Fi" - "مكالمة فيديو واردة" - "مكالمة واردة يشتبه في كونها غير مرغوب فيها" - "طلب فيديو وارد" - "بريد صوتي جديد" - "بريد صوتي جديد (%d)" - "طلب %s" - "رقم البريد الصوتي غير معروف" - "لا تتوفر خدمة" - "الشبكة المحددة (%s) غير متاحة" - "رد" - "قطع الاتصال" - "فيديو" - "صوت" - "قبول" - "تجاهل" - "معاودة الاتصال" - "رسالة" - "مكالمة جارية على جهاز آخر" - "تحويل الاتصال" - "لإجراء مكالمة، أوقف تشغيل وضع الطائرة أولاً." - "غير مسجل على الشبكة." - "شبكة الجوّال غير متاحة." - "لإجراء مكالمة، أدخل رقمًا صالحًا." - "يتعذر الاتصال." - "‏جارٍ بدء تسلسل MMI…" - "الخدمة ليست متوفرة." - "يتعذر تبديل المكالمات." - "يتعذر فصل المكالمة." - "يتعذر النقل." - "يتعذر إجراء مكالمة جماعية." - "يتعذر رفض المكالمة." - "يتعذر تحرير المكالمات." - "‏مكالمة SIP" - "مكالمة طوارئ" - "جارٍ تشغيل اللاسلكي..." - "لا تتوفر خدمة. جارٍ إعادة المحاولة…" - "يتعذر الاتصال. لا يعد %s رقم طوارئ." - "يتعذر الاتصال. يمكنك طلب رقم طوارئ" - "استخدام لوحة المفاتيح للطلب" - "تعليق المكالمة" - "استئناف المكالمة" - "إنهاء المكالمة" - "عرض لوحة الاتصال" - "إخفاء لوحة الاتصال" - "تجاهل" - "إلغاء التجاهل" - "إضافة مكالمة" - "دمج المكالمات" - "تبديل" - "إدارة المكالمات" - "إدارة مكالمة جماعية" - "مكالمة جماعية" - "إدارة" - "صوت" - "مكالمة فيديو" - "التغيير إلى مكالمة صوتية" - "تبديل الكاميرا" - "تشغيل الكاميرا" - "إيقاف الكاميرا" - "خيارات أخرى" - "تم بدء المشغّل" - "تم إيقاف المشغّل" - "الكاميرا غير جاهزة" - "الكاميرا جاهزة" - "حدث جلسة اتصال غير معروف" - "الخدمة" - "الإعداد" - "‏<لم يتم التعيين>" - "إعدادات الاتصال الأخرى" - "الاتصال عبر %s" - "واردة عبر %s" - "صورة جهة الاتصال" - "انتقال إلى مكالمة خاصة" - "تحديد جهة اتصال" - "اكتب ردك…" - "إلغاء" - "إرسال" - "الرد" - "‏إرسال رسالة قصيرة SMS" - "الرفض" - "الرد بمكالمة فيديو" - "الرد بمكالمة صوتية" - "قبول طلب الفيديو" - "رفض طلب الفيديو" - "قبول طلب بث الفيديو" - "رفض طلب بث الفيديو" - "قبول طلب استلام مكالمة الفيديو" - "رفض طلب استلام مكالمة الفيديو" - "تمرير لأعلى لـ %s." - "تمرير لليسار لـ %s." - "تمرير لليمين لـ %s." - "تمرير لأسفل لـ %s." - "اهتزاز" - "اهتزاز" - "الصوت" - "الصوت الافتراضي (%1$s)" - "نغمة رنين الهاتف" - "اهتزاز عند الرنين" - "نغمة الرنين والاهتزاز" - "إدارة مكالمة جماعية" - "رقم الطوارئ" - "صورة الملف الشخصي" - "تم إيقاف الكاميرا" - "عبر %s" - "تم إرسال الملاحظة" - "الرسائل الأخيرة" - "معلومات النشاط التجاري" - "على بُعد %.1f ميل" - "على بُعد %.1f كم" - "%1$s، %2$s" - "%1$s - %2$s" - "%1$s، %2$s" - "مفتوح غدًا في %s" - "مفتوح اليوم في %s" - "مغلق في %s" - "مغلق اليوم في %s" - "مفتوح الآن" - "مغلق الآن" - "اشتباه في متصل غير مرغوب فيه" - "‏المكالمة انتهت %1$s" - "هذه هي المرة الأولى التي تتلقى فيها اتصالاً من هذا الرقم." - "لدينا شك أن هذه المكالمة واردة من متصل غير مرغوب فيه." - "حظر/إبلاغ عن رقم غير مرغوب فيه" - "إضافة جهة اتصال" - "ليس رقمًا غير مرغوب فيه" - diff --git a/InCallUI/res/values-az/strings.xml b/InCallUI/res/values-az/strings.xml deleted file mode 100644 index 4bb9652b9..000000000 --- a/InCallUI/res/values-az/strings.xml +++ /dev/null @@ -1,195 +0,0 @@ - - - - - "Telefon" - "Gözləmə mövqeyində" - "Naməlum" - "Şəxsi nömrə" - "Taksofon" - "Konfrans zəngi" - "Zəng bitdi" - "Dinamik" - "Dəstək qulaqlığı" - "Simli qulaqlıq" - "Bluetooth" - "Aşağıdakı tonlar göndərilsin?\n" - "Tonlar göndərilir\n" - "Göndər" - "Bəli" - "Xeyr" - "Joker simvolları əvəz edin" - "Konfrans zəngi %s" - "Səsli poçt nömrəsi" - "Nömrə yığılır" - "Yenidən yığır" - "Konfrans zəngi" - "Gələn zəng" - "Daxil olan iş çağrısı" - "Zəng sona çatdı" - "Gözləmə mövqeyində" - "Dəstək asılır" - "Çağrıda" - "Mənim nömrəm %s" - "Video qoşulur" - "Video zəng" - "Video sorğusu göndərilir" - "Video zəngə qoşulmaq mümkün deyil" - "Video sorğusu rədd edildi" - "Cavab zəngi nömrəniz\n %1$s" - "Təcili cavab zəngi nömrəniz\n %1$s" - "Nömrə yığılır" - "Buraxılmış zəng" - "Buraxılmış zənglər" - "%s buraxılmış zənglər" - "%s tərəfindən zəng buraxılıb" - "Davam edən çağrı" - "Davam edən iş çağrısı" - "Davam edən Wi-Fi zəngi" - "Davam edən Wi-Fi iş çağrısı" - "Gözləmə mövqeyində" - "Gələn zəng" - "Daxil olan iş çağrısı" - "Gələn Wi-Fi zəngi" - "Daxil olan Wi-Fi iş çağrısı" - "Gələn video zəng" - "Şübhəli spam zəngi" - "Gələn video çağrı" - "Yeni səsli poçt" - "Yeni səsli poçt (%d)" - "Yığın %s" - "Səsli poçt nömrəsi naməlumdur" - "Xidmət yoxdur" - "Seçilmiş (%s) şəbəkə əlçatmazdır" - "Cavab" - "Dəstəyi qoyun" - "Videolar" - "Səs" - "Qəbul edin" - "Rədd edin" - "Geriyə zəng" - "Mesaj" - "Digər cihazda davam etməkdə olan zəng" - "Zəngi Transfer edin" - "Zəng etmək üçün ilk olaraq Uçuş Rejimini söndürün." - "Şəbəkədə qeydə alınmayıb." - "Mobil şəbəkə əlçatan deyil" - "Zəngi yerləşdirmək üçün düzgün nömrə daxil edin." - "Zəng etmək mümkün deyil." - "MMI başlanma ardıcıllığı…" - "Xidmət dəstəklənmir." - "Zəngləri keçirmək mümkün deyil." - "Zəngi ayırmaq mümkün deyil." - "Ötürmək mümkün deyil." - "Konfrans keçirmək mümkün deyil." - "Zəngi rədd etmək mümkün deyil." - "Zəngləri buraxmaq mümkün deyil." - "SIP çağrısıs" - "Təcili zəng" - "Radio yandırılır ..." - "Xidmət yoxdur. Yenidən cəhd edilir…" - "Zəng etmək mümkün deyil. %s fövqəladə nömrə deyil." - "Zəng etmək mümkün deyil. Fövqəladə nömrəni yı" - "Nömrə yığmaq üçün klaviaturadan istifadə ediin" - "Zəngi gözlədin" - "Zəngə davam edin" - "Zəngi bitirin" - "Yığım düymələrini göstərin" - "Yığım düymələrini gizlədin" - "Susdurun" - "Susdurmayın" - "Zəng əlavə edin" - "Zəngləri birləşdirin" - "Dəyişdirin" - "Zəngləri idarə edin" - "Konfrans çağrısını idarə edin" - "Konfrans zəngi" - "İdarə edin" - "Audio" - "Video zəng" - "Səsli çağrıya dəyişin" - "Kameraya keçin" - "Kameranı yandırın" - "Kameranı söndürün" - "Daha çox seçim" - "Pleyer Başladıldı" - "Pleyer Dayandırıldı" - "Kamera hazır deyil" - "Kamera hazırdır" - "Naməlum zəng sessiyası" - "Xidmət" - "Quraşdırma" - "<Təyin edilməyib>" - "Digər zəng parametrləri" - "%s vasitəsi ilə zəng edilir" - "%s vasitəsilə gələn" - "kontakt fotosu" - "şəxsi rejimə keçin" - "kontakt seçin" - "Özünüzünkünü yazın" - "Ləğv edin" - "Göndər" - "Cavab" - "SMS göndərin" - "İmtina edin" - "Video çağrı olaraq cavab verin" - "Audio çağrı olaraq cavab verin" - "Video sorğusunu qəbul edin" - "Video sorğusunu ləğv edin" - "Video ötürmə sorğusunu qəbul edin" - "Video ötürmə sorğusunu ləğv edin" - "Video qəbuletmə sorğusunu qəbul edin" - "Video qəbuletmə sorğusunu ləğv edin" - "%s üçün yuxarı sürüşdürün." - "%s üçün sola sürüşdürün." - "%s üçün sağa sürüşdürün." - "%s üçün aşağı sürüşdürün." - "Vibrasiya" - "Vibrasiya" - "Səs" - "Defolt səs (%1$s)" - "Telefon zəng səsi" - "Zəng çalanda vibrasiya olsun" - "Zəng səsi & Vibrasiya" - "Konfrans çağrısını idarə edin" - "Təcili nömrə" - "Profil fotosu" - "Kamera deaktivdir" - "%s vasitəsilə" - "Qeyd göndərildi" - "Son mesajlar" - "Biznes məlumatı" - "%.1f mil uzaqlıqda" - "%.1f km uzaqlıqda" - "%1$s, %2$s" - "%1$s - %2$s" - "%1$s, %2$s" - "Sabah saat %s açılır" - "Bu gün saat %s açılır" - "Saat %s bağlanır" - "Bu gün saat %s bağlanıb" - "İndi açın" - "İndi bağlandı" - "Şübhəli spam çağrıcısı" - "Zəng bitdi %1$s" - "Bu nömrə ilk dəfədir Sizə zəng edir." - "Bu zəngin spam olduğundan şübhələnirik." - "Spamı blok edin/bildirin" - "Kontakt əlavə edin" - "Spam deyil" - diff --git a/InCallUI/res/values-b+sr+Latn/strings.xml b/InCallUI/res/values-b+sr+Latn/strings.xml deleted file mode 100644 index 9770f90a9..000000000 --- a/InCallUI/res/values-b+sr+Latn/strings.xml +++ /dev/null @@ -1,195 +0,0 @@ - - - - - "Telefon" - "Na čekanju" - "Nepoznat" - "Privatan broj" - "Telefonska govornica" - "Konferencijski poziv" - "Poziv je prekinut" - "Zvučnik" - "Slušalica telefona" - "Žičane naglavne slušalice" - "Bluetooth" - "Želite li da pošaljete sledeće tonove?\n" - "Tonovi se šalju\n" - "Pošalji" - "Da" - "Ne" - "Zamenite džoker znak sa" - "Konferencijski poziv %s" - "Broj govorne pošte" - "Poziva se" - "Ponovo se bira" - "Konferencijski poziv" - "Dolazni poziv" - "Dolazni poziv za Work" - "Poziv je završen" - "Na čekanju" - "Veza se prekida" - "Poziv je u toku" - "Moj broj je %s" - "Povezuje se video poziv" - "Video poziv" - "Zahteva se video poziv" - "Povezivanje video poziva nije uspelo" - "Zahtev za video poziv je odbijen" - "Broj za povratni poziv\n %1$s" - "Broj za hitan povratni poziv\n %1$s" - "Poziva se" - "Propušten poziv" - "Propušteni pozivi" - "Broj propuštenih poziva: %s" - "Propušten poziv od: %s" - "Tekući poziv" - "Tekući poziv za Work" - "Tekući Wi-Fi poziv" - "Tekući poziv za Work preko Wi-Fi-ja" - "Na čekanju" - "Dolazni poziv" - "Dolazni poziv za Work" - "Dolazni Wi-Fi poziv" - "Dolazni poziv za Work preko Wi-Fi-ja" - "Dolazni video poziv" - "Sumnja na nepoželjan dolazni poziv" - "Zahtev za dolazni video poziv" - "Nova poruka govorne pošte" - "Nova poruka govorne pošte (%d)" - "Pozovi %s" - "Nepoznat broj govorne pošte" - "Mobilna mreža nije dostupna" - "Izabrana mreža (%s) nije dostupna" - "Odgovori" - "Prekini vezu" - "Video" - "Glasovni" - "Prihvatam" - "Odbaci" - "Uzvrati poziv" - "Pošalji SMS" - "Poziv je u toku na drugom uređaju" - "Prebaci poziv" - "Da biste uputili poziv, prvo isključite režim rada u avionu." - "Nije registrovano na mreži." - "Mobilna mreža nije dostupna." - "Da biste uputili poziv, unesite važeći broj." - "Poziv nije uspeo." - "Pokreće se MMI sekvenca..." - "Usluga nije podržana." - "Zamena poziva nije uspela." - "Razdvajanje poziva nije uspelo." - "Prebacivanje nije uspelo." - "Konferencijski poziv nije uspeo." - "Odbijanje poziva nije uspelo." - "Uspostavljanje poziva nije uspelo." - "SIP poziv" - "Hitni poziv" - "Uključuje se radio…" - "Mobilna mreža nije dostupna. Pokušavamo ponovo…" - "Poziv nije uspeo. %s nije broj za hitne slučajeve." - "Poziv nije uspeo. Pozovite broj za hitne slučajeve." - "Koristite tastaturu za pozivanje" - "Stavi poziv na čekanje" - "Nastavi poziv" - "Završi poziv" - "Prikaži numeričku tastaturu" - "Sakrij numeričku tastaturu" - "Isključi zvuk" - "Uključi zvuk" - "Dodaj poziv" - "Objedini pozive" - "Zameni" - "Upravljaj pozivima" - "Upravljaj konferencijskim pozivom" - "Konferencijski poziv" - "Upravljaj" - "Audio" - "Video poziv" - "Promeni u glasovni poziv" - "Promeni kameru" - "Uključi kameru" - "Isključi kameru" - "Još opcija" - "Plejer je pokrenut" - "Plejer je zaustavljen" - "Kamera nije spremna" - "Kamera je spremna" - "Nepoznat događaj sesije poziva" - "Usluga" - "Podešavanje" - "<Nije podešeno>" - "Druga podešavanja poziva" - "Poziva se preko dobavljača %s" - "Dolazni poziv preko %s" - "slika kontakta" - "idi na privatno" - "izaberite kontakt" - "Napišite sami…" - "Otkaži" - "Pošalji" - "Odgovori" - "Pošalji SMS" - "Odbij" - "Odgovori video pozivom" - "Odgovori audio-pozivom" - "Prihvati zahtev za video" - "Odbij zahtev za video" - "Prihvati zahtev za odlazni video poziv" - "Odbij zahtev za odlazni video poziv" - "Prihvati zahtev za dolazni video poziv" - "Odbij zahtev za dolazni video poziv" - "Prevucite nagore za %s." - "Prevucite ulevo za %s." - "Prevucite udesno za %s." - "Prevucite nadole za %s." - "Vibracija" - "Vibracija" - "Zvuk" - "Podrazumevani zvuk (%1$s)" - "Melodija zvona telefona" - "Vibriraj kada zvoni" - "Melodija zvona i vibracija" - "Upravljaj konferencijskim pozivom" - "Broj za hitne slučajeve" - "Slika profila" - "Kamera je isključena" - "na %s" - "Beleška je poslata" - "Nedavne poruke" - "Informacije o preduzeću" - "Udaljenost je %.1f mi" - "Udaljenost je %.1f km" - "%1$s, %2$s" - "%1$s%2$s" - "%1$s, %2$s" - "Otvara se sutra u %s" - "Otvara se danas u %s" - "Zatvara se u %s" - "Zatvorilo se danas u %s" - "Trenutno otvoreno" - "Trenutno zatvoreno" - "Nepoželjan pozivalac" - "Poziv se završio u %1$s" - "Ovo je bio prvi poziv sa ovog broja." - "Sumnjamo da je ovaj poziv nepoželjan." - "Blokiraj/prijavi" - "Dodaj kontakt" - "Nije nepoželjan" - diff --git a/InCallUI/res/values-be/strings.xml b/InCallUI/res/values-be/strings.xml deleted file mode 100644 index 70145fb7c..000000000 --- a/InCallUI/res/values-be/strings.xml +++ /dev/null @@ -1,195 +0,0 @@ - - - - - "Тэлефон" - "На ўтрыманні" - "Невядомы" - "Прыватны нумар" - "Таксафон" - "Канферэнц-выклік" - "Выклік абарваўся" - "Дынамік" - "Дынамік тэлефона" - "Правадная гарнітура" - "Bluetooth" - "Адправіць гэтыя тоны?\n" - "Адпраўка тонаў\n" - "Адправiць" - "Так" - "Не" - "Замяніце знак падстаноўкі на" - "Канферэнц-выклік у %s" - "Нумар галасавой пошты" - "Набор нумара" - "Паўторны набор" - "Канферэнц-выклік" - "Уваходны выклік" - "Уваходны выклік па працы" - "Выклік скончаны" - "На ўтрыманні" - "Завяршэнне выкліку" - "У выкліку" - "Мой нумар - %s" - "Падлучэнне відэа" - "Відэавыклік" - "Запыт на відэа" - "Немагчыма падлучыць відэавыклік" - "Запыт на відэа адхілены" - "Ваш нумар зваротнага выкліку\n %1$s" - "Ваш нумар экстраннага зваротнага выкліку\n %1$s" - "Набор нумара" - "Прапушчаны выклік" - "Прапушчаныя выклікі" - "Прапушчаных выклікаў: %s" - "Прапушчаны выклiк ад %s" - "Бягучы выклік" - "Бягучы выклік па працы" - "Бягучы выклік праз Wi-Fi" - "Бягучы выклік па працы праз Wi-Fi" - "На ўтрыманні" - "Уваходны выклік" - "Уваходны выклік па працы" - "Уваходны выклік праз Wi-Fi" - "Уваходны выклік па працы праз Wi-Fi" - "Уваходны відэавыклік" - "Уваходны выклiк ад абанента, якога падазраваюць у спаме" - "Уваходны запыт на відэавыклік" - "Новая галасавая пошта" - "Новыя паведамленнi галасавой пошты (%d)" - "Набраць %s" - "Невядомы нумар галасавой пошты" - "Не абслугоўваецца" - "Выбраная сетка (%s) недаступная" - "Адказ" - "Сконч. разм." - "Відэа" - "Галасавы" - "Прыняць" - "Адхіліць" - "Звар. выклік" - "Паведамленне" - "Бягучы выклік на іншай прыладзе" - "Перадаць выклік" - "Каб зрабіць выклік, спачатку выключыце рэжым палёту." - "Не зарэгістраваны ў сетцы." - "Мабільная сетка недаступная." - "Каб зрабіць выклік, увядзіце сапраўдны нумар." - "Выклік немагчымы." - "Пачатак паслядоўнасці MMI…" - "Служба не падтрымліваецца." - "Немагчыма пераключыць выклікі." - "Немагчыма аддзяліць выклік." - "Немагчыма перадаць выклік." - "Немагчыма зрабіць канферэнц-выклік." - "Немагчыма адхіліць выклік." - "Немагчыма скончыць выклік(і)." - "SIP-выклік" - "Экстранны выклік" - "Уключэнне радыё…" - "Не абслугоўваецца. Паўтор спробы…" - "Выклік немагчымы. %s не з\'яўляецца нумарам экстраннай службы." - "Выклік немагчымы. Набярыце нумар экстраннай службы." - "Набраць нумар з клавіятуры" - "Паставіць выклік на ўтрыманне" - "Узнавіць выклік" - "Завяршыць выклік" - "Паказаць панэль набору" - "Схаваць панэль набору" - "Адключыць мікрафон" - "Уключыць мікрафон" - "Дадаць выклік" - "Аб\'яднаць выклікі" - "Пераключыць" - "Кіраваць выклікамі" - "Кіраванне канферэнц-выклікам" - "Канферэнц-выклік" - "Кіраванне" - "Аўдыя" - "Відэавыклік" - "Змяніць на галасавы выклік" - "Пераключыць камеру" - "Уключыць камеру" - "Адключыць камеру" - "Дадатковыя параметры" - "Прайгравальнік запушчаны" - "Прайгравальнік спынены" - "Камера не гатовая" - "Камера гатовая" - "Невядомая падзея сеансу выкліку" - "Сэрвіс" - "Наладка" - "<Не зададзены>" - "Іншыя налады выклікаў" - "Выклікі праз правайдара %s" - "Уваходны выклік праз %s" - "фаіаграфія кантакту" - "перайсці да прыватнай гаворкі" - "выбраць кантакт" - "Напiшыце сваё…" - "Скасаваць" - "Адправiць" - "Адказ" - "Адправiць SMS" - "Адхіліць" - "Адказаць відэавыклікам" - "Адказаць аўдыявыклікам" - "Прыняць запыт на відэа" - "Адхіліць запыт на відэа" - "Прыняць запыт на перадачу відэа" - "Адхіліць запыт на перадачу відэа" - "Прыняць запыт на атрыманне відэа" - "Адхіліць запыт на атрыманне відэа" - "Правядзіце пальцам уверх, каб %s." - "Правядзіце пальцам улева, каб %s." - "Правядзіце пальцам управа, каб %s." - "Правядзіце пальцам уніз, каб %s." - "Вібрацыя" - "Вібрацыя" - "Гук" - "Стандартны гук (%1$s)" - "Рынгтон тэлефона" - "Вібрацыя падчас званка" - "Рынгтон і вiбрацыя" - "Кіраванне канферэнц-выклікам" - "Нумар экстраннай службы" - "Фота профілю" - "Камера адключана" - "праз %s" - "Нататка адпраўлена" - "Апошнія паведамленні" - "Бізнес-інфармацыя" - "Адлеглаць у мілях: %.1f" - "Адлегласць %.1f км" - "%1$s, %2$s" - "%1$s - %2$s" - "%1$s, %2$s" - "Адкрываецца заўтра ў %s" - "Адкрываецца сёння ў %s" - "Закрываецца ў %s" - "Закрыта сёння ў %s" - "Адкрыць зараз" - "Зараз закрыта" - "Падазраваецца ў спаме" - "Выклік завершаны %1$s" - "Вы атрымліваеце выклік з гэтага нумара ўпершыню." - "Існуе падазрэнне, што гэты выклік – спамерскі." - "Забл./павед.пра спам" - "Дадаць кантакт" - "Не спам" - diff --git a/InCallUI/res/values-bg/strings.xml b/InCallUI/res/values-bg/strings.xml deleted file mode 100644 index adf504777..000000000 --- a/InCallUI/res/values-bg/strings.xml +++ /dev/null @@ -1,195 +0,0 @@ - - - - - "Телефон" - "Задържано" - "Неизвестно лице" - "Частен номер" - "Обществен телефон" - "Конферентно обаждане" - "Обаждането бе прекъснато" - "Високоговорител" - "Телефонна слушалка" - "Слушалки с кабел" - "Bluetooth" - "Да се изпратят ли следните мелодии? \n" - "Мелодиите се изпращат\n" - "Изпращане" - "Да" - "Не" - "Замяна на заместващия символ със:" - "Конферентно обаждане – %s" - "Номер за гласова поща" - "Набира се" - "Набира се отново" - "Конферентно обаждане" - "Входящо обаждане" - "Входящо служебно обаждане" - "Обаждането завърши" - "Задържано" - "Разговорът се приключва" - "Извършва се обаждане" - "Номерът ми е %s" - "Установява се видеовръзка" - "Видеообаждане" - "Заявява се видеовръзка" - "Видеообаждането не може да се осъществи" - "Заявката за видеовръзка е отхвърлена" - "Номерът ви за обратно обаждане\n– %1$s" - "Номерът ви за спешно обратно обаждане\n– %1$s" - "Набиране" - "Пропуснато обаждане" - "Пропуснати обаждания" - "%s пропуснати обаждания" - "Пропуснато обаждане от %s" - "Текущо обаждане" - "Текущо служебно обаждане" - "Текущо обаждане през Wi-Fi" - "Текущо служебно обаждане през Wi-Fi" - "Задържано" - "Входящо обаждане" - "Входящо служебно обаждане" - "Входящо обаждане през Wi-Fi" - "Входящо служебно обаждане през Wi-Fi" - "Входящо видеообаждане" - "Входящо обаждане – възможен спам" - "Заявка за входящо видеообаждане" - "Нова гласова поща" - "Нова гласова поща (%d)" - "Набиране на %s" - "Неизвестен номер за гласова поща" - "Няма покритие" - "Избраната мрежа (%s) не е налице" - "Приемане" - "Затваряне" - "Видеообажд." - "Гл. обаждане" - "Приемане" - "Отхвърляне" - "Обр. обажд." - "Съобщение" - "Текущо обаждане на друго устройство" - "Прехвърляне на обаждането" - "За да осъществите обаждане, първо изключете самолетния режим." - "Няма регистрация в мрежата." - "Няма достъп до клетъчната мрежа." - "За да извършите обаждане, въведете валиден номер." - "Не може да се извърши обаждане." - "Стартира се последователността MMI…" - "Услугата не се поддържа." - "Обажданията не могат да се превключат." - "Обаждането не може да се отдели." - "Не може да се прехвърли." - "Не може да се извърши конферентно обаждане." - "Обаждането не може да се отхвърли." - "Обаждането или съответно обажданията не могат да се освободят." - "Обаждане чрез SIP" - "Спешно обаждане" - "Радиомодулът се включва…" - "Няма услуга. Извършва се нов опит…" - "Не може да се извърши обаждане. %s не е номер за спешни случаи." - "Не може да се извърши обаждане. Наберете номер за спешни случаи." - "Използвайте клавиатурата за набиране" - "Задържане на обаждането" - "Възобновяване на обаждането" - "Край на обаждането" - "Показване на клавиатурата за набиране" - "Скриване на клавиатурата за набиране" - "Заглушаване" - "Пускане" - "Добавяне на обаждане" - "Обединяване на обаждания" - "Размяна" - "Управление на обажданията" - "Управление на конф. обаждане" - "Конферентно обаждане" - "Управление" - "Аудио" - "Видеообажд." - "Преминаване към гласово обаждане" - "Превключване на камерата" - "Включване на камерата" - "Изключване на камерата" - "Още опции" - "Плейърът е стартиран" - "Плейърът е спрян" - "Камерата не е в готовност" - "Камерата е в готовност" - "Неизвестно събитие в сесията на обаждане" - "Услуга" - "Настройване" - "<Не е зададено>" - "Други настройки за обаждане" - "Обаждане чрез %s" - "Входящо обаждане чрез %s" - "снимка на контакта" - "превключване към частно обаждане" - "избиране на контакта" - "Напишете свой собствен..." - "Отказ" - "Изпращане" - "Приемане" - "Изпращане на SMS" - "Отхвърляне" - "Приемане като видеообаждане" - "Приемане като аудиообаждане" - "Приемане на заявката за видеовръзка" - "Отхвърляне на заявката за видеовръзка" - "Приемане на заявката за предаване на видео" - "Отхвърляне на заявката за предаване на видео" - "Приемане на заявката за получаване на видеообаждане" - "Отхвърляне на заявката за получаване на видео" - "Плъзнете нагоре за %s." - "Плъзнете наляво за %s." - "Плъзнете надясно за %s." - "Плъзнете надолу за %s." - "Вибриране" - "Вибриране" - "Звук" - "Стандартен звук (%1$s)" - "Мелодия на телефона" - "Вибриране при звънене" - "Мелодия и вибриране" - "Управление на конферентното обаждане" - "Спешен номер" - "Снимка на потребителския профил" - "Камерата е изключена" - "чрез %s" - "Бележката е изпратена" - "Скорошни съобщения" - "Бизнес информация" - "На %.1f мили" - "На %.1f км" - "%1$s, %2$s" - "%1$s%2$s" - "%1$s; %2$s" - "Отваря утре в %s" - "Отваря днес в %s" - "Затваря в %s" - "Затворено днес в %s" - "В момента работи" - "В момента не работи" - "Възможен спам" - "Обаждането завърши %1$s" - "За първи път ви се обаждат от този номер." - "Подозирахме, че това обаждане може да е от разпространител на спам." - "Блокиране/спам" - "Добавяне на контакт" - "Не е спам" - diff --git a/InCallUI/res/values-bn/strings.xml b/InCallUI/res/values-bn/strings.xml deleted file mode 100644 index 2f561ce6e..000000000 --- a/InCallUI/res/values-bn/strings.xml +++ /dev/null @@ -1,195 +0,0 @@ - - - - - "ফোন" - "হোল্ডে রয়েছে" - "অজানা" - "ব্যক্তিগত নম্বর" - "অর্থের বিনিময়ে কল করার ফোন" - "কনফারেন্স কল" - "কল সমাপ্ত হয়েছে" - "স্পিকার" - "হ্যান্ডসেট ইয়ারপিস" - "তারযুক্ত হেডসেট" - "ব্লুটুথ" - "নিম্নলিখিত টোনগুলি পাঠাবেন?\n" - "টোনগুলি পাঠানো হচ্ছে\n" - "পাঠান" - "হ্যাঁ" - "না" - "ওয়াইল্ড অক্ষরগুলিকে এর মাধ্যমে প্রতিস্থাপিত করুন" - "কনফারেন্স কল %s" - "ভয়েসমেল নম্বর" - "ডায়াল করা হচ্ছে" - "আবার ডায়াল করা হচ্ছে" - "কনফারেন্স কল" - "আগত কল" - "আগত কাজের কল" - "কল সমাপ্ত হয়েছে" - "হোল্ডে রয়েছে" - "কল নামিয়ে রাখা হচ্ছে" - "কলের সময়ে" - "আমার নম্বর হল %s" - "ভিডিও সংযুক্ত করছে" - "ভিডিও কল" - "ভিডিওর অনুরোধ করছে" - "ভিডিও কলে সংযোগ করা যাচ্ছে না" - "ভিডিওর অনুরোধ প্রত্যাখ্যান করা হয়েছে" - "আপনার কলব্যাক নম্বর\n%1$s" - "আপনার জরুরী কলব্যাক নম্বর\n%1$s" - "ডায়াল করা হচ্ছে" - "মিসড কল" - "মিসড কলগুলি" - "%sটি মিসড কল" - "%s এর থেকে মিসড কল" - "চলমান কল" - "চলমান কাজের কল" - "চলমান ওয়াই-ফাই কল" - "চলমান ওয়াই-ফাই কাজের কল" - "হোল্ডে রয়েছে" - "আগত কল" - "আগত কাজের কল" - "আগত ওয়াই-ফাই কল" - "আগত ওয়াই-ফাই কাজের কল" - "আগত ভিডিও কল" - "আগত সন্দেহভাজন স্প্যাম কল" - "আগত ভিডিও অনুরোধ" - "নতুন ভয়েসমেল" - "নতুন ভয়েসমেল (%dটি)" - "%s ডায়াল করুন" - "ভয়েসমেল নম্বর অজানা" - "কোনো পরিষেবা নেই" - "নির্বাচিত নেটওয়ার্ক (%s) অনুপলব্ধ" - "উত্তর" - "কল নামিয়ে রাখুন" - "ভিডিও" - "ভয়েস" - "স্বীকার করুন" - "খারিজ করুন" - "ঘুরিয়ে কল করুন" - "বার্তা" - "অন্য ডিভাইসে চালু থাকা কল" - "কল স্থানান্তর করুন" - "একটি কল করতে, প্রথমে বিমানমোড বন্ধ করুন৷" - "নেটওয়ার্কে নিবন্ধিত নয়৷" - "সেলুলার নেটওয়ার্ক উপলব্ধ নয়।" - "কোনো কল স্থাপন করতে, একটি বৈধ নম্বর লিখুন৷" - "কল করা যাবে না৷" - "MMI ক্রম চালু হচ্ছে…" - "পরিষেবা সমর্থিত নয়৷" - "কলগুলি স্যুইচ করা যাবে না৷" - "কল আলাদা করা যাবে না৷" - "হস্তান্তর করা যাবে না৷" - "কনফারেন্স করা যাবে না৷" - "কল প্রত্যাখ্যান কলা যাবে না৷" - "কল(গুলি) কাটা যাবে না৷" - "SIP কল" - "জরুরি কল" - "রেডিও চালু করা হচ্ছে…" - "কোন পরিষেবা নেই৷ আবার চেষ্টা করা হচ্ছে..." - "কল করা যাবে না৷ %s কোনো জরুরী নম্বর নয়৷" - "কল করা যাবে না৷ কোনো জরুরী নম্বর ডায়াল করুন৷" - "ডায়াল করতে কীবোর্ড ব্যবহার করুন" - "কল হোল্ডে রাখুন" - "কল আবার শুরু করুন" - "কল শেষ করুন" - "ডায়ালপ্যাড দেখান" - "ডায়ালপ্যাড লুকান" - "নিঃশব্দ করুন" - "সশব্দ করুন" - "কল যোগ করুন" - "কলগুলি মার্জ করুন" - "সোয়াপ করুন" - "কলগুলি পরিচালনা করুন" - "কনফারেন্স কল পরিচালনা করুন" - "কনফারেন্স কল" - "পরিচালনা করুন" - "অডিও" - "ভিডিও কল" - "ভয়েস কলে পরিবর্তন করুন" - "ক্যামেরা স্যুইচ করুন" - "ক্যামেরা চালু করুন" - "ক্যামেরা বন্ধ করুন" - "আরো বিকল্প" - "প্লেয়ার শুরু হয়েছে" - "প্লেয়ার বন্ধ হয়ে গেছে" - "ক্যামেরা রেডি নয়" - "ক্যামেরা রেডি" - "অজানা কল অধিবেশনের ইভেন্ট" - "পরিষেবা" - "সেটআপ" - "<সেট করা নেই>" - "অন্যান্য কল সেটিংস" - "%s এর মাধ্যমে কল করা হচ্ছে" - "%s এর মাধ্যমে ইনকামিং কল" - "পরিচিতির ফটো" - "ব্যক্তিগতভাবে কাজ করুন" - "পরিচিতি নির্বাচন করুন" - "আপনার নিজের পছন্দ মতো লিখুন…" - "বাতিল করুন" - "পাঠান" - "উত্তর" - "SMS পাঠান" - "অস্বীকার করুন" - "ভিডিও কল হিসেবে উত্তর দিন" - "অডিও কল হিসেবে উত্তর দিন" - "ভিডিওর অনুরোধ গ্রহণ করুন" - "ভিডিওর অনুরোধ প্রত্যাখ্যান করুন" - "ভিডিও প্রেরণ করার অনুরোধ স্বীকার করুন" - "ভিডিও প্রেরণ করার অনুরোধ প্রত্যাখ্যান করুন" - "ভিডিও গ্রহণ করার অনুরোধ স্বীকার করুন" - "ভিডিও গ্রহণ করার অনুরোধ প্রত্যাখ্যান করুন" - "%s এর জন্য উপরের দিকে স্লাইড করুন৷" - "%s এর জন্য বাঁ দিকে স্লাইড করুন৷" - "%s এর জন্য ডান দিকে স্লাইড করুন৷" - "%s এর জন্য নীচের দিকে স্লাইড করুন৷" - "কম্পন" - "কম্পন" - "শব্দ" - "ডিফল্ট শব্দ (%1$s)" - "ফোন রিংটোন" - "রিং হওয়ার সময় কম্পন হবে" - "রিংটোন ও কম্পন" - "কনফারেন্স কল পরিচালনা করুন" - "জরুরি নম্বর" - "প্রোফাইল ফটো" - "ক্যামেরা বন্ধ" - "%s এর মাধ্যমে" - "নোট পাঠানো হয়েছে" - "সাম্প্রতিক বার্তাগুলি" - "ব্যবসার তথ্য" - "%.1f মাইল দূরে" - "%.1f কিলোমিটার দূরে" - "%1$s, %2$s" - "%1$s - %2$s" - "%1$s, %2$s" - "আগামীকাল %s\'টায় খুলবে" - "আজ %s\'টায় খুলবে" - "%s\'টায় বন্ধ হয়" - "আজ %s\'টায় বন্ধ হয়েছে" - "এখন খোলা রয়েছে" - "এখন বন্ধ রয়েছে" - "সন্দেহভাজন স্প্যাম কলার" - "কল সমাপ্ত হয়েছে %1$s" - "এই প্রথমবার এই নম্বর থেকে আপনাকে কল করা হয়েছে৷" - "এটি কোনো স্প্যামারের কল হতে পারে বলে আমাদের মনে হচ্ছে৷" - "অবরুদ্ধ করুন/স্প্যাম হিসাবে অভিযোগ করুন" - "পরিচিতি যোগ করুন" - "স্প্যাম নয়" - diff --git a/InCallUI/res/values-bs/strings.xml b/InCallUI/res/values-bs/strings.xml deleted file mode 100644 index 9db727c98..000000000 --- a/InCallUI/res/values-bs/strings.xml +++ /dev/null @@ -1,195 +0,0 @@ - - - - - "Telefon" - "Na čekanju" - "Nepoznato" - "Privatni broj" - "Telefonska govornica" - "Konferencijski poziv" - "Poziv je prekinut" - "Zvučnik" - "Slušalice telefona" - "Žičane slušalice" - "Bluetooth" - "Poslati sljedeće tonove?\n" - "Slanje tonova\n" - "Pošalji" - "Da" - "Ne" - "Zamijeni zamjenski znak sa" - "Konferencijski poziv %s" - "Broj govorne pošte" - "Poziva se" - "Ponovno pozivanje" - "Konferencijski poziv" - "Dolazni poziv" - "Dolazni poslovni poziv" - "Poziv je završen" - "Na čekanju" - "Prekid veze" - "Poziv u toku" - "Moj broj je %s" - "Uspostavljanje videopoziva" - "Videopoziv" - "Zahtijevanje videopoziva" - "Nije moguće uspostaviti videopoziv" - "Zahtjev za videopoziv je odbijen" - "Vaš broj za povratni poziv\n %1$s" - "Vaš broj za hitni povratni poziv\n %1$s" - "Poziva se" - "Propušteni poziv" - "Propušteni pozivi" - "Propušteni pozivi: %s" - "Propušteni poziv od kontakta %s" - "Poziv u toku" - "Poslovni poziv u toku" - "Wi-Fi poziv u toku" - "Wi-Fi poslovni poziv u toku" - "Na čekanju" - "Dolazni poziv" - "Dolazni poslovni poziv" - "Dolazni Wi-Fi poziv" - "Dolazni Wi-Fi poslovni poziv" - "Dolazni videopoziv" - "Mogući neželjeni dolazni poziv" - "Zahtjev za dolazni videopoziv" - "Nova govorna pošta" - "Nova govorna pošta (%d)" - "Pozovi %s" - "Nepoznat broj govorne pošte" - "Nema mreže" - "Odabrana mreža (%s) je nedostupna" - "Odgovori" - "Prekini vezu" - "Videopoziv" - "Glasovni poziv" - "Prihvati" - "Odbaci" - "Povr. poziv" - "Poruka" - "Poziv u toku na drugom uređaju" - "Prenesi poziv" - "Da uputite poziv, isključite Način rada u avionu." - "Nije registrirano na mreži." - "Mobilna mreža nije dostupna." - "Da uputite poziv, upišite važeći broj." - "Nije moguće pozvati." - "Pokretanje MMI sekvence u toku…" - "Usluga nije podržana." - "Nije moguće prebacivanje poziva." - "Nije moguće odvojiti poziv." - "Prijenos nije moguć." - "Konferencijski poziv nije uspio." - "Nije moguće odbiti poziv." - "Nije moguće uputiti poziv(e)." - "SIP poziv" - "Hitni poziv" - "Uključivanje radija u toku…" - "Nema mreže. Ponovni pokušaj u toku…" - "Nije moguće pozvati. %s nije broj za htine slučajeve." - "Nije moguće pozvati. Pozovite broj za hitne slučajeve." - "Koristi tastaturu za biranje" - "Stavi poziv na čekanje" - "Nastavi poziv" - "Prekini poziv" - "Prikaži telefonsku tipkovnicu" - "Sakrij telefonsku tipkovnicu" - "Isključi zvuk" - "Uključi zvuk" - "Dodaj poziv" - "Spoji pozive" - "Zamijeni" - "Upravljaj pozivima" - "Upravljaj konf. pozivom" - "Konferencijski poziv" - "Upravljaj" - "Zvuk" - "Videopoziv" - "Promijeni na glasovni poziv" - "Promijeni kameru" - "Uključi kameru" - "Isključi kameru" - "Više opcija" - "Plejer je pokrenut" - "Plejer je zaustavljen" - "Kamera nije spremna" - "Kamera je spremna" - "Nepoznati događaj sesije poziva" - "Usluga" - "Postavljanje" - "<Nije postavljeno>" - "Ostale postavke poziva" - "Pozivanje putem %s" - "Dolazni poziv putem %s" - "fotografija kontakta" - "idi na privatno" - "odaberi kontakt" - "Napišite svoj..." - "Otkaži" - "Pošalji" - "Odgovori" - "Pošalji SMS" - "Odbij" - "Odgovori videopozivom" - "Prihvati kao audiopoziv" - "Prihvati zahtjev za videopoziv" - "Odbij zahtjev za videopoziv" - "Prihvati zahtjev za slanje videopoziva" - "Odbij zahtjev za slanje videopoziva" - "Prihvati zahtjev za primanje videopoziva" - "Odbij zahtjev za primanje videopoziva" - "Kliznite nagore za %s." - "Kliznite lijevo za %s." - "Kliznite nadesno za %s." - "Kliznite nadolje za %s." - "Vibracija" - "Vibracija" - "Zvuk" - "Zadani zvuk (%1$s)" - "Melodija zvona telefona" - "Vibriraj kada zvoni" - "Melodija zvona i vibracija" - "Upravljaj konferencijskim pozivom" - "Broj za hitne slučajeve" - "Fotografija profila" - "Kamera je isključena" - "putem %s" - "Bilješka je poslana" - "Nedavne poruke" - "Informacije o preduzeću" - "Udaljenost u miljama: %.1f" - "Udaljenost u km: %.1f" - "%1$s, %2$s" - "%1$s - %2$s" - "%1$s, %2$s" - "Otvara se sutra u %s" - "Otvara se danas u %s" - "Zatvara se u %s" - "Zatvoreno danas u %s" - "Otvori sad" - "Zatvoreno sada" - "Neželjeni pozivalac" - "Poziv je završen %1$s" - "Ovo je prvi poziv koji ste primili s ovog broja." - "Sumnjamo da je ovaj poziv neželjen sadržaj." - "Blokiraj/prijavi" - "Dodaj kontakt" - "Nije neželjeno" - diff --git a/InCallUI/res/values-ca/strings.xml b/InCallUI/res/values-ca/strings.xml deleted file mode 100644 index 103f15b63..000000000 --- a/InCallUI/res/values-ca/strings.xml +++ /dev/null @@ -1,195 +0,0 @@ - - - - - "Telèfon" - "En espera" - "Desconegut" - "Número privat" - "Telèfon públic" - "Conferència" - "La trucada s\'ha interromput" - "Altaveu" - "Auricular" - "Auricular amb cable" - "Bluetooth" - "Vols enviar els tons següents?\n" - "S\'estan enviant els tons\n" - "Envia" - "Sí" - "No" - "Substitueix el caràcter comodí per" - "Conferència, %s" - "Número del missatge de veu" - "S\'està marcant" - "S\'està tornant a marcar" - "Conferència" - "Trucada entrant" - "Trucada de feina entrant" - "Ha finalitzat la trucada" - "En espera" - "S\'està penjant" - "En una trucada" - "El meu número és %s" - "S\'està connectant el vídeo" - "Videotrucada" - "S\'està sol·licitant el vídeo" - "No es pot connectar la videotrucada" - "S\'ha rebutjat la sol·licitud de vídeo" - "Número de devolució de trucada\n %1$s" - "Número de devolució de trucada d\'emergència\n %1$s" - "S\'està marcant" - "Trucada perduda" - "Trucades perdudes" - "%s trucades perdudes" - "Trucada perduda de %s" - "Trucada en curs" - "Trucada de feina en curs" - "Trucada per Wi-Fi en curs" - "Trucada de feina per Wi-Fi en curs" - "En espera" - "Trucada entrant" - "Trucada de feina entrant" - "Trucada per Wi-Fi entrant" - "Trucada de feina per Wi-Fi entrant" - "Videotrucada entrant" - "Presumpta trucada brossa entrant" - "Sol·licitud de vídeo entrant" - "Missatge de veu nou" - "Missatges de veu nous (%d)" - "Marca %s" - "Número del missatge de veu desconegut" - "Sense servei" - "La xarxa seleccionada (%s) no està disponible" - "Respon" - "Penja" - "Vídeo" - "Veu" - "Accepta" - "Ignora" - "Torna trucada" - "Missatge" - "Trucada en curs en un altre dispositiu" - "Transfereix la trucada" - "Per fer una trucada, primer desactiva el mode d\'avió." - "No s\'ha registrat a la xarxa." - "La xarxa mòbil no està disponible." - "Introdueix un número vàlid per fer una trucada." - "No es pot trucar." - "S\'està iniciant la seqüència MMI…" - "El servei no és compatible." - "No es pot canviar de trucada." - "No es pot separar la trucada." - "No es poden transferir trucades." - "No es pot establir la conferència." - "No es pot rebutjar la trucada." - "No es poden alliberar trucades." - "Trucada de SIP" - "Trucada d\'emergència" - "S\'està activant el senyal mòbil…" - "No hi ha servei. S\'està tornant a provar…" - "No es pot trucar. %s no és un número d\'emergència." - "No es pot trucar. Marca un número d\'emergència." - "Utilitza el teclat per marcar" - "Posa la trucada en espera" - "Reprèn la trucada" - "Finalitza la trucada" - "Mostra el teclat" - "Amaga el teclat" - "Silencia" - "Activa el so" - "Afegeix una trucada" - "Combina les trucades" - "Canvia" - "Gestiona les trucades" - "Gestiona la conferència" - "conferència" - "Gestiona" - "Àudio" - "Videotrucada" - "Canvia a trucada de veu" - "Canvia la càmera" - "Activa la càmera" - "Desactiva la càmera" - "Més opcions" - "S\'ha iniciat el reproductor" - "S\'ha aturat el reproductor" - "La càmera no està preparada" - "La càmera està preparada" - "Esdeveniment de sessió de trucada desconeguda" - "Servei" - "Configura" - "<No definit>" - "Altres opcions de configuració de les trucades" - "S\'està trucant amb %s" - "Trucada entrant mitjançant %s" - "foto de contacte" - "conferència privada" - "selecciona el contacte" - "Escriu la teva…" - "Cancel·la" - "Envia" - "Respon" - "Envia SMS" - "Rebutja" - "Respon amb una videotrucada" - "Respon amb una trucada d\'àudio" - "Accepta la sol·licitud de vídeo" - "Rebutja la sol·licitud de vídeo" - "Accepta la sol·licitud per transmetre vídeo" - "Rebutja la sol·licitud per transmetre vídeo" - "Accepta la sol·licitud per rebre vídeo" - "Rebutja la sol·licitud per rebre vídeo" - "Fes lliscar el dit cap amunt per %s." - "Fes lliscar el dit cap a l\'esquerra per %s." - "Fes lliscar el dit cap a la dreta per %s." - "Fes lliscar el dit cap avall per %s." - "Vibració" - "Vibració" - "So" - "So predeterminat (%1$s)" - "So de trucada" - "Vibrar en sonar" - "So de trucada i vibració" - "Gestiona la conferència" - "Número d\'emergència" - "Foto de perfil" - "La càmera està desactivada" - "mitjançant %s" - "S\'ha enviat la nota" - "Missatges recents" - "Informació de l\'empresa" - "A %.1f mi de distància" - "A %.1f km de distància" - "%1$s, %2$s" - "%1$s - %2$s" - "%1$s, %2$s" - "Obre demà a les %s" - "Obre avui a les %s" - "Tanca a les %s" - "Avui ha tancat a les %s" - "Obert ara" - "Ara és tancat" - "Possible trucada brossa" - "La trucada amb el número %1$s ha finalitzat" - "És la primera vegada que aquest número t\'ha trucat." - "Sospitem que aquesta trucada prové d\'un emissor de contingut brossa." - "Bloqueja/marca brossa" - "Afegeix un contacte" - "No és brossa" - diff --git a/InCallUI/res/values-cs/strings.xml b/InCallUI/res/values-cs/strings.xml deleted file mode 100644 index f3e4a5ed3..000000000 --- a/InCallUI/res/values-cs/strings.xml +++ /dev/null @@ -1,195 +0,0 @@ - - - - - "Telefon" - "Přidržený hovor" - "Neznámý volající" - "Soukromé číslo" - "Telefonní automat" - "Konferenční hovor" - "Volání zrušeno" - "Reproduktor" - "Sluchátko telefonu" - "Kabelová náhlavní soupr." - "Bluetooth" - "Odeslat následující tóny?\n" - "Odesílání tónů\n" - "Odeslat" - "Ano" - "Ne" - "Nahradit zástupné znaky jinými znaky" - "Konferenční hovor %s" - "Číslo hlasové schránky" - "Vytáčení" - "Opakované vytáčení" - "Konferenční hovor" - "Příchozí hovor" - "Příchozí pracovní hovor" - "Hovor ukončen" - "Přidržený hovor" - "Ukončování hovoru" - "Probíhá hovor" - "Moje číslo je %s" - "Navazování spojení pro video" - "Videohovor" - "Požadování videa" - "Videohovor nelze zahájit" - "Žádost o video byla zamítnuta" - "Vaše číslo pro zpětné volání\n%1$s" - "Vaše číslo pro tísňové zpětné volání\n%1$s" - "Vytáčení" - "Zmeškaný hovor" - "Zmeškané hovory" - "Zmeškané hovory: %s" - "Zmeškaný hovor od volajícího %s" - "Probíhající hovor" - "Probíhající pracovní hovor" - "Probíhající hovor přes Wi-Fi" - "Probíhající pracovní hovor přes Wi-Fi" - "Přidržený hovor" - "Příchozí hovor" - "Příchozí pracovní hovor" - "Příchozí hovor přes Wi-Fi" - "Příchozí pracovní hovor přes Wi-Fi" - "Příchozí videohovor" - "U příchozího hovoru máme podezření, že se jedná o spam" - "Příchozí žádost o videohovor" - "Nová hlasová zpráva" - "Nové hlasové zprávy (%d)" - "Volat hlasovou schránku %s" - "Číslo hlasové schránky není známé" - "Žádný signál" - "Vybraná síť (%s) není k dispozici" - "Přijmout" - "Zavěsit" - "Videohovor" - "Hlas. hovor" - "Přijmout" - "Odmítnout" - "Zavolat zpět" - "Posl. zprávu" - "Probíhá hovor na jiném zařízení" - "Převést hovor sem" - "Chcete-li telefonovat, nejprve vypněte režim Letadlo." - "Přihlášení k síti nebylo úspěšné." - "Mobilní síť je nedostupná." - "Chcete-li uskutečnit hovor, zadejte platné telefonní číslo." - "Hovor nelze uskutečnit." - "Spouštění sekvence MMI..." - "Služba není podporována." - "Hovory nelze přepnout." - "Hovor nelze rozdělit." - "Hovor nelze předat." - "Konferenční hovor nelze uskutečnit." - "Hovor nelze odmítnout." - "Hovor nelze ukončit." - "Volání SIP" - "Tísňové volání" - "Zapínání bezdrátového modulu..." - "Žádný signál. Probíhá další pokus…" - "Hovor nelze uskutečnit. %s není číslo tísňového volání." - "Hovor nelze uskutečnit. Vytočte číslo tísňového volání." - "Vytočte číslo pomocí klávesnice" - "Podržet hovor" - "Obnovit hovor" - "Ukončit hovor" - "Zobrazit číselník" - "Skrýt číselník" - "Vypnout zvuk" - "Zapnout zvuk" - "Přidat hovor" - "Spojit hovory" - "Zaměnit" - "Spravovat hovory" - "Spravovat konferenční hovor" - "Konferenční hovor" - "Spravovat" - "Zvuk" - "Videohovor" - "Změnit na hlasové volání" - "Přepnout kameru" - "Zapnout kameru" - "Vypnout kameru" - "Další možnosti" - "Přehrávač spuštěn" - "Přehrávač zastaven" - "Fotoaparát není připraven" - "Fotoaparát je připraven" - "Neznámá událost relace volání" - "Služba" - "Nastavení" - "<Nenastaveno>" - "Další nastavení hovorů" - "Volání prostřednictvím poskytovatele %s" - "Příchozí hovor přes poskytovatele %s" - "fotografie kontaktu" - "přepnout na soukromé" - "vybrat kontakt" - "Napsat vlastní odpověď..." - "Zrušit" - "Odeslat" - "Přijmout" - "Odeslat SMS" - "Odmítnout" - "Přijmout jako videohovor" - "Přijmout jako hlasový hovor" - "Přijmout žádost o videhovor" - "Odmítnout žádost o videohovor" - "Přijmout žádost o odesílání videa" - "Odmítnout žádost o odesílání videa" - "Přijmout žádost o příjem videa" - "Odmítnout žádost o příjem videa" - "%s – přejeďte prstem nahoru" - "%s – přejeďte prstem doleva" - "%s – přejeďte prstem doprava" - "%s – přejeďte prstem dolů" - "Vibrace" - "Vibrace" - "Zvuk" - "Výchozí zvuk (%1$s)" - "Vyzváněcí tón telefonu" - "Vibrace při vyzvánění" - "Vyzvánění a vibrace" - "Správa konferenčního hovoru" - "Číslo tísňové linky" - "Profilová fotka" - "Fotoaparát je vypnutý" - "pomocí čísla %s" - "Poznámka byla odeslána" - "Nejnovější zprávy" - "Informace o firmě" - "Vzdálenost: %.1f mi" - "Vzdálenost: %.1f km" - "%1$s, %2$s" - "%1$s%2$s" - "%1$s, %2$s" - "Zítra otevírá v %s" - "Dnes otevírá v %s" - "Zavírá v %s" - "Dnes zavřeno od %s" - "Otevřeno" - "Nyní zavřeno" - "Podezření na spam" - "Hovor skončil v %1$s" - "Toto číslo vám volalo poprvé." - "Máme podezření, že tento hovor byl spam." - "Blok./nahlásit spam" - "Přidat kontakt" - "Nešlo o spam" - diff --git a/InCallUI/res/values-da/strings.xml b/InCallUI/res/values-da/strings.xml deleted file mode 100644 index 82d773c1c..000000000 --- a/InCallUI/res/values-da/strings.xml +++ /dev/null @@ -1,195 +0,0 @@ - - - - - "Telefon" - "Afventer" - "Ukendt" - "Privat nummer" - "Mønttelefon" - "Telefonmøde" - "Opkaldet blev afbrudt." - "Højttaler" - "Ørestykke til håndsæt" - "Headset med ledning" - "Bluetooth" - "Vil du sende følgende toner?\n" - "Sender toner\n" - "Send" - "Ja" - "Nej" - "Erstat jokertegnet med" - "Telefonmøde %s" - "Telefonsvarernummer" - "Ringer op" - "Ringer op igen" - "Telefonmøde" - "Indgående opkald" - "Indgående arbejdsopkald" - "Opkaldet er afsluttet" - "Afventer" - "Lægger på" - "Opkald i gang" - "Mit nummer er %s" - "Opretter videoforbindelse" - "Videoopkald" - "Anmoder om video" - "Kan ikke forbinde videoopkald" - "Videoanmodningen blev afvist" - "Dit tilbagekaldsnummer\n %1$s" - "Dit tilbagekaldsnummer til nødopkald\n %1$s" - "Ringer op" - "Ubesvaret opkald" - "Ubesvarede opkald" - "%s ubesvarede opkald" - "Ubesvaret opkald fra %s" - "Igangværende opkald" - "Igangværende opkald i forbindelse med arbejde" - "Igangværende opkald via Wi-Fi" - "Igangværende Wi-Fi-opkald i forbindelse med arbejde" - "Afventer" - "Indgående opkald" - "Indgående arbejdsopkald" - "Indgående Wi-Fi-opkald" - "Indgående Wi-Fi-opkald i forbindelse med arbejde" - "Indgående videoopkald" - "Indgående formodet spamopkald" - "Indgående videoanmodning" - "Ny telefonsvarerbesked" - "Nye telefonsvarerbeskeder (%d)" - "Ring til %s" - "Telefonsvarernummeret er ukendt" - "Ingen dækning" - "Det valgte netværk (%s) er ikke tilgængeligt" - "Besvar" - "Læg på" - "Video" - "Tale" - "Acceptér" - "Afvis" - "Ring tilbage" - "Besked" - "Igangværende opkald på en anden enhed" - "Overfør opkald" - "Slå Flytilstand fra først for at foretage et opkald." - "Ikke registreret på netværket." - "Mobilnetværket er ikke tilgængeligt." - "Indtast et gyldigt nummer for at foretage et opkald." - "Der kan ikke ringes op." - "Starter MMI-sekvens…" - "Tjenesten er ikke understøttet." - "Der kan ikke skiftes opkald." - "Opkaldet kan ikke adskilles." - "Der kan ikke viderestilles." - "Der kan ikke oprettes telefonmøde." - "Opkaldet kan ikke afvises." - "Et eller flere opkald kan ikke frigives." - "SIP-opkald" - "Nødopkald" - "Tænder for radio…" - "Ingen tjeneste. Prøver igen…" - "Der kan ikke ringes op. %s er ikke et alarmnummer." - "Der kan ikke ringes op. Ring til et alarmnummer." - "Brug tastaturet til at ringe op" - "Sæt opkald i venteposition" - "Genoptag opkald" - "Afslut opkald" - "Vis numerisk tastatur" - "Skjul numerisk tastatur" - "Slå lyden fra" - "Slå lyden til" - "Tilføj opkald" - "Slå opkald sammen" - "Skift" - "Administrer opkald" - "Administrer telefonmøde" - "Telefonmøde" - "Administrer" - "Lyd" - "Videoopkald" - "Skift til taleopkald" - "Skift kamera" - "Slå kameraet til" - "Slå kameraet fra" - "Flere valgmuligheder" - "Afspilleren er startet" - "Afspilleren er stoppet" - "Kameraet er ikke klar" - "Kameraet er klar" - "Ukendt opkaldsbegivenhed" - "Tjeneste" - "Konfiguration" - "<Ikke angivet>" - "Andre indstillinger for opkald" - "Opkald via %s" - "Indgående opkald via %s" - "billede af kontaktperson" - "gør privat" - "vælg kontaktperson" - "Skriv dit eget svar…" - "Annuller" - "Send" - "Besvar" - "Send sms" - "Afvis" - "Besvar som videoopkald" - "Besvar som taleopkald" - "Acceptér anmodning om video" - "Afvis videoanmodning" - "Acceptér anmodning om udgående video" - "Afvis anmodning om udgående video" - "Acceptér anmodning om indgående video" - "Afvis anmodning om indgående video" - "Skub op for at %s." - "Skub til venstre for at %s." - "Skub til højre for at %s." - "Skub ned for at %s." - "Vibration" - "Vibration" - "Lyd" - "Standardlyd (%1$s)" - "Ringetone ved opkald" - "Vibrer ved opringning" - "Ringetone og vibration" - "Administrer telefonmøde" - "Alarmnummer" - "Profilbillede" - "Kameraet er slukket" - "via %s" - "Noten er sendt" - "Seneste beskeder" - "Virksomhedsoplysninger" - "%.1f mil væk" - "%.1f km væk" - "%1$s, %2$s" - "%1$s-%2$s" - "%1$s, %2$s" - "Åbner i morgen kl. %s" - "Åbner i dag kl. %s" - "Lukker kl. %s" - "Lukkede i dag kl. %s" - "Åbent nu" - "Lukket for i dag" - "Formodet spammer" - "Opkaldet blev afsluttet %1$s" - "Dette er første gang, at dette nummer har ringet til dig." - "Vi har mistanke om, at dette er et spamopkald." - "Bloker/rap. spam" - "Tilføj kontaktperson" - "Ikke spam" - diff --git a/InCallUI/res/values-de/strings.xml b/InCallUI/res/values-de/strings.xml deleted file mode 100644 index b3ecffc4c..000000000 --- a/InCallUI/res/values-de/strings.xml +++ /dev/null @@ -1,195 +0,0 @@ - - - - - "Telefon" - "Gehaltener Anruf" - "Unbekannt" - "Private Nummer" - "Münztelefon" - "Telefonkonferenz" - "Verbindung unterbrochen" - "Lautsprecher" - "Mobilgerät-Kopfhörer" - "Kabelgebundenes Headset" - "Bluetooth" - "Folgende Töne senden?\n" - "Töne werden gesendet\n" - "Senden" - "Ja" - "Nein" - "Platzhalter ersetzen durch" - "Telefonkonferenz %s" - "Mailboxnummer" - "Rufaufbau" - "Wahlwiederholung" - "Telefonkonferenz" - "Eingehender Anruf" - "Eingeh. geschäftl. Anruf" - "Anruf beendet" - "Gehaltener Anruf" - "Auflegen" - "Im Gespräch" - "Meine Nummer lautet %s" - "Videoverbindung wird hergestellt" - "Videoanruf" - "Videoanfrage wird gesendet" - "Videoanruf kann nicht verbunden werden" - "Videoanfrage abgelehnt" - "Deine Rückrufnummer lautet:\n %1$s" - "Deine Notrufnummer lautet:\n %1$s" - "Rufaufbau" - "Verpasster Anruf" - "Entgangene Anrufe" - "%s entgangene Anrufe" - "Verpasster Anruf von %s" - "Aktiver Anruf" - "Aktiver geschäftlicher Anruf" - "Aktiver WLAN-Anruf" - "Aktiver geschäftlicher WLAN-Anruf" - "Gehaltener Anruf" - "Eingehender Anruf" - "Eingehender geschäftlicher Anruf" - "Eingehender WLAN-Anruf" - "Eingehender geschäftlicher WLAN-Anruf" - "Eingehender Videoanruf" - "Verdacht auf eingehenden Spam-Anruf" - "Eingehende Videoanfrage" - "Neue Mailbox-Nachricht" - "Neue Mailbox-Nachricht (%d)" - "%s wählen" - "Mailboxnummer unbekannt" - "Kein Service" - "Ausgewähltes Netzwerk (%s) nicht verfügbar" - "Annehmen" - "Beenden" - "Videoanruf" - "Sprachanruf" - "Akzeptieren" - "Ablehnen" - "Zurückrufen" - "Nachricht" - "Aktiver Anruf auf anderem Gerät" - "Anruf übertragen" - "Deaktiviere zunächst den Flugmodus, um einen Anruf zu tätigen." - "Nicht in Netzwerk registriert." - "Mobilfunknetz nicht verfügbar." - "Gib eine gültige Nummer ein, um einen Anruf zu tätigen." - "Anruf nicht möglich." - "MMI-Sequenz wird gestartet…" - "Dienst wird nicht unterstützt." - "Anruf kann nicht gewechselt werden." - "Anruf kann nicht getrennt werden." - "Anruf kann nicht übergeben werden." - "Konferenzschaltung nicht möglich." - "Anruf kann nicht abgelehnt werden." - "Anrufe können nicht freigegeben werden." - "SIP-Anruf" - "Notruf" - "Mobilfunkverbindung wird aktiviert…" - "Kein Service. Neuer Versuch…" - "Anruf nicht möglich. %s ist keine Notrufnummer." - "Anruf nicht möglich. Wähle eine Notrufnummer." - "Zum Wählen Tastatur verwenden" - "Anruf halten" - "Anruf fortsetzen" - "Anruf beenden" - "Wähltasten einblenden" - "Wähltasten ausblenden" - "Stummschalten" - "Stummschaltung aufheben" - "Anruf hinzufügen" - "Anrufe verbinden" - "Wechseln" - "Anrufe verwalten" - "Telefonkonferenz verwalten" - "Telefonkonferenz" - "Verwalten" - "Audio" - "Videoanruf" - "Zu Sprachanruf wechseln" - "Kamera wechseln" - "Kamera einschalten" - "Kamera ausschalten" - "Weitere Optionen" - "Videoübertragung gestartet" - "Videoübertragung gestoppt" - "Kamera nicht bereit" - "Kamera bereit" - "Unbekanntes Ereignis während eines Anrufs" - "Dienst" - "Einrichtung" - "<Nicht festgelegt>" - "Sonstige Anrufeinstellungen" - "Anruf über %s" - "Eingehender Anruf über %s" - "Kontaktbild" - "privat sprechen" - "Kontakt auswählen" - "Eigene Antwort schreiben…" - "Abbrechen" - "Senden" - "Annehmen" - "SMS senden" - "Ablehnen" - "Als Videoanruf annehmen" - "Als normalen Anruf annehmen" - "Videoanfrage akzeptieren" - "Videoanfrage ablehnen" - "Anfrage für ausgehenden Videoanruf akzeptieren" - "Anfrage für ausgehenden Videoanruf ablehnen" - "Anfrage für eingehenden Videoanruf akzeptieren" - "Anfrage für eingehenden Videoanruf ablehnen" - "Zum %s nach oben schieben." - "Zum %s nach links schieben." - "Zum %s nach rechts schieben." - "Zum %s nach unten schieben." - "Vibrieren" - "Vibrieren" - "Ton" - "Standardklingelton (%1$s)" - "Klingelton" - "Beim Klingeln vibrieren" - "Klingelton & Vibration" - "Telefonkonferenz verwalten" - "Notrufnummer" - "Profilbild" - "Kamera aus" - "über %s" - "Notiz gesendet" - "Zuletzt eingegangene Nachrichten" - "Geschäftsinformationen" - "%.1f Meilen entfernt" - "%.1f Kilometer entfernt" - "%1$s, %2$s" - "%1$s bis %2$s" - "%1$s, %2$s" - "Öffnet morgen um %s" - "Öffnet heute um %s" - "Schließt um %s" - "Hat heute um %s geschlossen" - "Jetzt geöffnet" - "Jetzt geschlossen" - "Verdacht auf Spam" - "Anruf beendet %1$s" - "Du wurdest das erste Mal von dieser Nummer angerufen." - "Dieser Anruf schien ein Spam-Anruf zu sein." - "Blockieren/Spam melden" - "Kontakt hinzufügen" - "Kein Spam" - diff --git a/InCallUI/res/values-el/strings.xml b/InCallUI/res/values-el/strings.xml deleted file mode 100644 index 993813290..000000000 --- a/InCallUI/res/values-el/strings.xml +++ /dev/null @@ -1,195 +0,0 @@ - - - - - "Τηλέφωνο" - "Σε αναμονή" - "Άγνωστος" - "Απόκρυψη αριθμού" - "Τηλέφωνο με χρέωση" - "Κλήση συνδιάσκεψης" - "Η κλήση απορρίφθηκε" - "Ηχείο" - "Ακουστικό" - "Ενσύρματο ακουστικό" - "Bluetooth" - "Αποστολή των παρακάτω ήχων;\n" - "Ήχοι αποστολής\n" - "Αποστολή" - "Ναι" - "Όχι" - "Αντικατάσταση του χαρακτήρα μπαλαντέρ με" - "Κλήση συνδιάσκεψης %s" - "Αριθμός αυτόματου τηλεφωνητή" - "Κλήση" - "Επανάκληση" - "Κλήση συνδιάσκεψης" - "Εισερχόμενη κλήση" - "Εισερχόμ. κλήση εργασίας" - "Η κλήση τερματίστηκε" - "Σε αναμονή" - "Κλείσιμο γραμμής" - "Σε κλήση" - "Ο αριθμός μου είναι %s" - "Σύνδεση βίντεο" - "Βιντεοκλήση" - "Αίτημα βίντεο" - "Δεν είναι δυνατή η σύνδεση βιντεοκλήσης" - "Το αίτημα βίντεο απορρίφθηκε" - "Αριθμός επανάκλησης\n %1$s" - "Αριθμός επανάκλησης έκτακτης ανάγκης\n %1$s" - "Κλήση" - "Αναπάντητη κλήση" - "Αναπάντητες κλήσεις" - "%s αναπάντητες κλήσεις" - "Αναπάντητη κλήση από %s" - "Κλήση σε εξέλιξη" - "Κλήση εργασίας σε εξέλιξη" - "Κλήση Wi-Fi σε εξέλιξη" - "Κλήση εργασίας μέσω Wi-Fi σε εξέλιξη" - "Σε αναμονή" - "Εισερχόμενη κλήση" - "Εισερχόμενη κλήση εργασίας" - "Εισερχόμενη κλήση μέσω Wi-Fi" - "Εισερχόμενη κλήση εργασίας μέσω Wi-Fi" - "Εισερχόμενη βιντεοκλήση" - "Πιθανώς ανεπιθύμητη εισερχόμενη κλήση" - "Αίτημα εισερχόμενου βίντεο" - "Νέο μήνυμα στον αυτόματο τηλεφωνητή" - "Νέο μήνυμα στον αυτόματο τηλεφωνητή (%d)" - "Καλέστε στο %s" - "Άγνωστος αριθμός αυτόματου τηλεφωνητή" - "Δίκτυο μη διαθέσιμο" - "Το επιλεγμένο δίκτυο (%s) δεν είναι διαθέσιμο" - "Απάντηση" - "Τερμ. κλήσης" - "Βίντεο" - "Φωνή" - "Αποδοχή" - "Παράβλεψη" - "Επανάκληση" - "Μήνυμα" - "Κλήση σε εξέλιξη σε άλλη συσκευή" - "Μεταφορά κλήσης" - "Για να πραγματοποιήσετε μια κλήση, απενεργοποιήστε πρώτα τη λειτουργία πτήσης." - "Δεν έχετε εγγραφεί στο δίκτυο." - "Το δίκτυο κινητής τηλεφωνίας δεν είναι διαθέσιμο." - "Για να πραγματοποιήσετε κλήση, εισαγάγετε έναν έγκυρο αριθμό." - "Δεν είναι δυνατή η κλήση." - "Έναρξη ακολουθίας MMI…" - "Η υπηρεσία δεν υποστηρίζεται." - "Δεν είναι δυνατή η εναλλαγή κλήσεων." - "Δεν είναι δυνατός ο διαχωρισμός της κλήσης." - "Δεν είναι δυνατή η μεταφορά." - "Δεν είναι δυνατή η συνδιάσκεψη." - "Δεν είναι δυνατή η απόρριψη της κλήσης." - "Δεν είναι δυνατή η πραγματοποίηση κλήσεων." - "Κλήση SIP" - "Κλήση έκτακτης ανάγκης" - "Ενεργοποίηση πομπού…" - "Δεν υπάρχει υπηρεσία. Νέα προσπάθεια…" - "Δεν είναι δυνατή η κλήση. Το %s δεν είναι αριθμός έκτακτης ανάγκης." - "Δεν είναι δυνατή η κλήση. Πληκτρολογήστε έναν αριθμό έκτακτης ανάγκης." - "Χρησιμοποιήστε το πληκτρολόγιο για να πραγματοποιήσετε μια κλήση" - "Αναμονή κλήσης" - "Συνέχιση κλήσης" - "Τερματισμός κλήσης" - "Εμφάνιση πληκτρολογίου κλήσης" - "Απόκρυψη πληκτρολογίου κλήσης" - "Σίγαση" - "Κατάργηση σίγασης" - "Προσθήκη κλήσης" - "Συγχώνευση κλήσεων" - "Ανταλλαγή" - "Διαχείριση κλήσεων" - "Διαχείριση κλήσης συνδιάσκεψης" - "Κλήση διάσκεψης" - "Διαχείριση" - "Ήχος" - "Βιντεοκλ." - "Αλλαγή σε φωνητική κλήση" - "Αλλαγή κάμερας" - "Ενεργοποίηση κάμερας" - "Απενεργοποίηση κάμερας" - "Περισσότερες επιλογές" - "Το πρόγραμμα αναπαραγωγής βίντεο ξεκίνησε" - "Το πρόγραμμα αναπαραγωγής βίντεο διακόπηκε" - "Η κάμερα δεν είναι έτοιμη" - "Η κάμερα είναι έτοιμη" - "Άγνωστο συμβάν περιόδου σύνδεσης κλήσης" - "Υπηρεσία" - "Ρύθμιση" - "<Δεν έχει οριστεί>" - "Άλλες ρυθμίσεις κλήσης" - "Κλήση μέσω %s" - "Εισερχόμενη κλήση μέσω %s" - "φωτογραφία επαφής" - "ιδιωτική χρήση" - "επιλογή επαφής" - "Συντάξτε τη δική σας…" - "Ακύρωση" - "Αποστολή" - "Απάντηση" - "Αποστολή SMS" - "Απόρριψη" - "Απάντηση ως βιντεοκλήση" - "Απάντηση ως κλήση ήχου" - "Αποδοχή αιτήματος βίντεο" - "Απόρριψη αιτήματος βίντεο" - "Αποδοχή αιτήματος μετάδοσης βίντεο" - "Απόρριψη αιτήματος μετάδοσης βίντεο" - "Αποδοχή αιτήματος λήψης βίντεο" - "Απόρριψη αιτήματος λήψης βίντεο" - "Κύλιση προς τα επάνω για %s." - "Κύλιση προς τα αριστερά για %s." - "Κύλιση προς τα δεξιά για %s." - "Κύλιση προς τα κάτω για %s." - "Δόνηση" - "Δόνηση" - "Ήχος" - "Προεπιλεγμένος ήχος (%1$s)" - "Ήχος κλήσης τηλεφώνου" - "Δόνηση κατά το κουδούνισμα" - "Ήχος κλήσης και δόνηση" - "Διαχείριση κλήσης συνδιάσκεψης" - "Αριθμός έκτακτης ανάγκης" - "Φωτογραφία προφίλ" - "Απενεργοποίηση κάμερας" - "μέσω %s" - "Η σημείωση εστάλη" - "Πρόσφατα μηνύματα" - "Πληροφορίες επιχείρησης" - "%.1f μίλια μακριά" - "%.1f χιλιόμετρα μακριά" - "%1$s, %2$s" - "%1$s - %2$s" - "%1$s, %2$s" - "Ανοίγει αύριο στις %s" - "Ανοίγει σήμερα στις %s" - "Κλείνει στις %s" - "Έκλεισε σήμερα στις %s" - "Ανοιχτό τώρα" - "Κλειστό τώρα" - "Πιθανώς ανεπιθύμητος" - "Η κλήση τερματίστηκε %1$s" - "Αυτή είναι η πρώτη φορά που σας καλεί αυτός ο αριθμός." - "Έχουμε υποψίες ότι αυτή κλήση είναι ανεπιθύμητη." - "Αποκλ./αναφ. ανεπιθ." - "Προσθήκη επαφής" - "Μη ανεπιθύμητος" - diff --git a/InCallUI/res/values-en-rAU/strings.xml b/InCallUI/res/values-en-rAU/strings.xml deleted file mode 100644 index 013aa9685..000000000 --- a/InCallUI/res/values-en-rAU/strings.xml +++ /dev/null @@ -1,195 +0,0 @@ - - - - - "Phone" - "On hold" - "unknown" - "Private number" - "Payphone" - "Conference call" - "Call cut off" - "Speaker" - "Handset earpiece" - "Wired headset" - "Bluetooth" - "Send the following tones?\n" - "Sending tones\n" - "Send" - "yes" - "no" - "Replace wild character with" - "Conference call %s" - "Voicemail number" - "Dialling" - "Redialling" - "Conference call" - "Incoming call" - "Incoming work call" - "Call ended" - "On hold" - "Hanging up" - "In call" - "My number is %s" - "Connecting video" - "Video call" - "Requesting video" - "Can\'t connect video call" - "Video request rejected" - "Your callback number\n %1$s" - "Your emergency callback number\n %1$s" - "Dialling" - "Missed call" - "Missed calls" - "%s missed calls" - "Missed call from %s" - "On-going call" - "Ongoing work call" - "Ongoing Wi-Fi call" - "Ongoing Wi-Fi work call" - "On hold" - "Incoming call" - "Incoming work call" - "Incoming Wi-Fi call" - "Incoming Wi-Fi work call" - "Incoming video call" - "Incoming suspected spam call" - "Incoming video request" - "New voicemail" - "New voicemail (%d)" - "Dial %s" - "Voicemail number unknown" - "No service" - "Selected network (%s) unavailable" - "Answer" - "Hang up" - "In-stream video" - "Voice" - "Accept" - "Dismiss" - "Call back" - "Message" - "Ongoing call on another device" - "Transfer call" - "To place a call, first turn off Aeroplane mode." - "Not registered on network." - "Mobile network not available." - "To place a call, enter a valid number." - "Can\'t call." - "Starting MMI sequence…" - "Service not supported." - "Can\'t switch calls." - "Can\'t separate call." - "Can\'t transfer." - "Can\'t conference." - "Can\'t reject call." - "Can\'t release call(s)." - "SIP call" - "Emergency call" - "Turning on radio…" - "No network. Trying again…" - "Can\'t call. %s is not an emergency number." - "Can\'t call. Dial an emergency number." - "Use keyboard to dial" - "Hold Call" - "Resume Call" - "End Call" - "Show dial pad" - "Hide dial pad" - "Mute" - "Unmute" - "Add call" - "Merge calls" - "Swap" - "Manage calls" - "Manage conference call" - "Conference call" - "Manage" - "Audio" - "Video call" - "Change to voice call" - "Switch camera" - "Turn on camera" - "Turn off camera" - "More options" - "Player Started" - "Player Stopped" - "Camera not ready" - "Camera ready" - "Unknown call session event" - "Service" - "Set up" - "<Not set>" - "Other call settings" - "Calling via %s" - "Incoming via %s" - "contact photo" - "go private" - "select contact" - "Write your own..." - "cancel" - "Send" - "Answer" - "Send SMS" - "Decline" - "Answer as video call" - "Answer as audio call" - "Accept video request" - "Decline video request" - "Accept video transmit request" - "Decline video transmit request" - "Accept video receive request" - "Decline video receive request" - "Slide up for %s." - "Slide left for %s." - "Slide right for %s." - "Slide down for %s." - "Vibrate" - "Vibrate" - "Sound" - "Default sound (%1$s)" - "Phone ringtone" - "Vibrate when ringing" - "Ringtone & Vibrate" - "Manage conference call" - "Emergency number" - "Profile photo" - "Camera off" - "via %s" - "Note sent" - "Recent messages" - "Business info" - "%.1f mi away" - "%.1f km away" - "%1$s, %2$s" - "%1$s%2$s" - "%1$s, %2$s" - "Opens tomorrow at %s" - "Opens today at %s" - "Closes at %s" - "Closed today at %s" - "Open now" - "Closed now" - "Suspected spam caller" - "Call ended %1$s" - "This is the first time that this number has called you." - "We suspected that this call was from a spammer." - "Block/report spam" - "Add contact" - "Not spam" - diff --git a/InCallUI/res/values-en-rGB/strings.xml b/InCallUI/res/values-en-rGB/strings.xml deleted file mode 100644 index 013aa9685..000000000 --- a/InCallUI/res/values-en-rGB/strings.xml +++ /dev/null @@ -1,195 +0,0 @@ - - - - - "Phone" - "On hold" - "unknown" - "Private number" - "Payphone" - "Conference call" - "Call cut off" - "Speaker" - "Handset earpiece" - "Wired headset" - "Bluetooth" - "Send the following tones?\n" - "Sending tones\n" - "Send" - "yes" - "no" - "Replace wild character with" - "Conference call %s" - "Voicemail number" - "Dialling" - "Redialling" - "Conference call" - "Incoming call" - "Incoming work call" - "Call ended" - "On hold" - "Hanging up" - "In call" - "My number is %s" - "Connecting video" - "Video call" - "Requesting video" - "Can\'t connect video call" - "Video request rejected" - "Your callback number\n %1$s" - "Your emergency callback number\n %1$s" - "Dialling" - "Missed call" - "Missed calls" - "%s missed calls" - "Missed call from %s" - "On-going call" - "Ongoing work call" - "Ongoing Wi-Fi call" - "Ongoing Wi-Fi work call" - "On hold" - "Incoming call" - "Incoming work call" - "Incoming Wi-Fi call" - "Incoming Wi-Fi work call" - "Incoming video call" - "Incoming suspected spam call" - "Incoming video request" - "New voicemail" - "New voicemail (%d)" - "Dial %s" - "Voicemail number unknown" - "No service" - "Selected network (%s) unavailable" - "Answer" - "Hang up" - "In-stream video" - "Voice" - "Accept" - "Dismiss" - "Call back" - "Message" - "Ongoing call on another device" - "Transfer call" - "To place a call, first turn off Aeroplane mode." - "Not registered on network." - "Mobile network not available." - "To place a call, enter a valid number." - "Can\'t call." - "Starting MMI sequence…" - "Service not supported." - "Can\'t switch calls." - "Can\'t separate call." - "Can\'t transfer." - "Can\'t conference." - "Can\'t reject call." - "Can\'t release call(s)." - "SIP call" - "Emergency call" - "Turning on radio…" - "No network. Trying again…" - "Can\'t call. %s is not an emergency number." - "Can\'t call. Dial an emergency number." - "Use keyboard to dial" - "Hold Call" - "Resume Call" - "End Call" - "Show dial pad" - "Hide dial pad" - "Mute" - "Unmute" - "Add call" - "Merge calls" - "Swap" - "Manage calls" - "Manage conference call" - "Conference call" - "Manage" - "Audio" - "Video call" - "Change to voice call" - "Switch camera" - "Turn on camera" - "Turn off camera" - "More options" - "Player Started" - "Player Stopped" - "Camera not ready" - "Camera ready" - "Unknown call session event" - "Service" - "Set up" - "<Not set>" - "Other call settings" - "Calling via %s" - "Incoming via %s" - "contact photo" - "go private" - "select contact" - "Write your own..." - "cancel" - "Send" - "Answer" - "Send SMS" - "Decline" - "Answer as video call" - "Answer as audio call" - "Accept video request" - "Decline video request" - "Accept video transmit request" - "Decline video transmit request" - "Accept video receive request" - "Decline video receive request" - "Slide up for %s." - "Slide left for %s." - "Slide right for %s." - "Slide down for %s." - "Vibrate" - "Vibrate" - "Sound" - "Default sound (%1$s)" - "Phone ringtone" - "Vibrate when ringing" - "Ringtone & Vibrate" - "Manage conference call" - "Emergency number" - "Profile photo" - "Camera off" - "via %s" - "Note sent" - "Recent messages" - "Business info" - "%.1f mi away" - "%.1f km away" - "%1$s, %2$s" - "%1$s%2$s" - "%1$s, %2$s" - "Opens tomorrow at %s" - "Opens today at %s" - "Closes at %s" - "Closed today at %s" - "Open now" - "Closed now" - "Suspected spam caller" - "Call ended %1$s" - "This is the first time that this number has called you." - "We suspected that this call was from a spammer." - "Block/report spam" - "Add contact" - "Not spam" - diff --git a/InCallUI/res/values-en-rIN/strings.xml b/InCallUI/res/values-en-rIN/strings.xml deleted file mode 100644 index 013aa9685..000000000 --- a/InCallUI/res/values-en-rIN/strings.xml +++ /dev/null @@ -1,195 +0,0 @@ - - - - - "Phone" - "On hold" - "unknown" - "Private number" - "Payphone" - "Conference call" - "Call cut off" - "Speaker" - "Handset earpiece" - "Wired headset" - "Bluetooth" - "Send the following tones?\n" - "Sending tones\n" - "Send" - "yes" - "no" - "Replace wild character with" - "Conference call %s" - "Voicemail number" - "Dialling" - "Redialling" - "Conference call" - "Incoming call" - "Incoming work call" - "Call ended" - "On hold" - "Hanging up" - "In call" - "My number is %s" - "Connecting video" - "Video call" - "Requesting video" - "Can\'t connect video call" - "Video request rejected" - "Your callback number\n %1$s" - "Your emergency callback number\n %1$s" - "Dialling" - "Missed call" - "Missed calls" - "%s missed calls" - "Missed call from %s" - "On-going call" - "Ongoing work call" - "Ongoing Wi-Fi call" - "Ongoing Wi-Fi work call" - "On hold" - "Incoming call" - "Incoming work call" - "Incoming Wi-Fi call" - "Incoming Wi-Fi work call" - "Incoming video call" - "Incoming suspected spam call" - "Incoming video request" - "New voicemail" - "New voicemail (%d)" - "Dial %s" - "Voicemail number unknown" - "No service" - "Selected network (%s) unavailable" - "Answer" - "Hang up" - "In-stream video" - "Voice" - "Accept" - "Dismiss" - "Call back" - "Message" - "Ongoing call on another device" - "Transfer call" - "To place a call, first turn off Aeroplane mode." - "Not registered on network." - "Mobile network not available." - "To place a call, enter a valid number." - "Can\'t call." - "Starting MMI sequence…" - "Service not supported." - "Can\'t switch calls." - "Can\'t separate call." - "Can\'t transfer." - "Can\'t conference." - "Can\'t reject call." - "Can\'t release call(s)." - "SIP call" - "Emergency call" - "Turning on radio…" - "No network. Trying again…" - "Can\'t call. %s is not an emergency number." - "Can\'t call. Dial an emergency number." - "Use keyboard to dial" - "Hold Call" - "Resume Call" - "End Call" - "Show dial pad" - "Hide dial pad" - "Mute" - "Unmute" - "Add call" - "Merge calls" - "Swap" - "Manage calls" - "Manage conference call" - "Conference call" - "Manage" - "Audio" - "Video call" - "Change to voice call" - "Switch camera" - "Turn on camera" - "Turn off camera" - "More options" - "Player Started" - "Player Stopped" - "Camera not ready" - "Camera ready" - "Unknown call session event" - "Service" - "Set up" - "<Not set>" - "Other call settings" - "Calling via %s" - "Incoming via %s" - "contact photo" - "go private" - "select contact" - "Write your own..." - "cancel" - "Send" - "Answer" - "Send SMS" - "Decline" - "Answer as video call" - "Answer as audio call" - "Accept video request" - "Decline video request" - "Accept video transmit request" - "Decline video transmit request" - "Accept video receive request" - "Decline video receive request" - "Slide up for %s." - "Slide left for %s." - "Slide right for %s." - "Slide down for %s." - "Vibrate" - "Vibrate" - "Sound" - "Default sound (%1$s)" - "Phone ringtone" - "Vibrate when ringing" - "Ringtone & Vibrate" - "Manage conference call" - "Emergency number" - "Profile photo" - "Camera off" - "via %s" - "Note sent" - "Recent messages" - "Business info" - "%.1f mi away" - "%.1f km away" - "%1$s, %2$s" - "%1$s%2$s" - "%1$s, %2$s" - "Opens tomorrow at %s" - "Opens today at %s" - "Closes at %s" - "Closed today at %s" - "Open now" - "Closed now" - "Suspected spam caller" - "Call ended %1$s" - "This is the first time that this number has called you." - "We suspected that this call was from a spammer." - "Block/report spam" - "Add contact" - "Not spam" - diff --git a/InCallUI/res/values-es-rUS/strings.xml b/InCallUI/res/values-es-rUS/strings.xml deleted file mode 100644 index 915c90779..000000000 --- a/InCallUI/res/values-es-rUS/strings.xml +++ /dev/null @@ -1,195 +0,0 @@ - - - - - "Teléfono" - "En espera" - "Desconocido" - "Número privado" - "Teléfono pago" - "Llamada en conferencia" - "Se interrumpió la llamada" - "Altavoz" - "Auricular del dispositivo" - "Auriculares con cable" - "Bluetooth" - "¿Deseas enviar los siguientes tonos?\n" - "Enviando tonos\n" - "Enviar" - "Sí" - "No" - "Reemplazar el carácter comodín con" - "Llamada en conferencia: %s" - "Número de buzón de voz" - "Marcando" - "Volviendo a marcar" - "Llamada en conferencia" - "Llamada entrante" - "Llamada entrante: trabajo" - "Llamada finalizada" - "En espera" - "Colgando" - "En llamada" - "Mi número es %s" - "Conectando video" - "Videollamada" - "Solicitando video" - "No se puede conectar la videollamada" - "Se rechazó la solicitud de videollamada" - "Número de devolución de llamada\n %1$s" - "Número de devolución de llamada de emergencia\n %1$s" - "Marcando" - "Llamada perdida" - "Llamadas perdidas" - "%s llamadas perdidas" - "Llamada perdida de %s" - "Llamada en curso" - "Llamada en curso: trabajo" - "Llamada Wi-Fi en curso" - "Llamada Wi-Fi en curso: trabajo" - "En espera" - "Llamada entrante" - "Llamada entrante: trabajo" - "Llamada Wi-Fi entrante" - "Llamada Wi-Fi entrante: trabajo" - "Videollamada entrante" - "Posible llamada entrante de spam" - "Solicitud de videollamada entrante" - "Nuevo mensaje de buzón de voz" - "Buzón de voz nuevo (%d)" - "Marcar %s" - "Número de buzón de voz desconocido" - "Sin servicio" - "La red seleccionada (%s) no está disponible" - "Responder" - "Colgar" - "Video" - "Voz" - "Aceptar" - "Descartar" - "Llamar" - "Mensaje" - "Llamada en curso en otro dispositivo" - "Transferir llamada" - "Para realizar una llamada, primero debes desactivar el modo de avión." - "No está registrado en la red." - "La red móvil no está disponible." - "Para realizar una llamada, ingresa un número válido." - "No se puede realizar la llamada." - "Iniciando la secuencia de MMI…" - "El servicio no es compatible." - "No se pueden cambiar las llamadas." - "No se puede desviar la llamada." - "No se puede transferir." - "No se puede realizar la conferencia." - "No se puede rechazar la llamada." - "No se pueden liberar las llamadas." - "Llamada SIP" - "Llamada de emergencia" - "Encendiendo radio…" - "No hay servicio. Vuelve a intentarlo…" - "No se puede realizar la llamada. %s no es un número de emergencia." - "No se puede realizar la llamada. Marca un número de emergencia." - "Usar teclado para marcar" - "Retener llamada" - "Reanudar llamada" - "Finalizar llamada" - "Mostrar teclado" - "Ocultar teclado" - "Silenciar" - "Dejar de silenciar" - "Agregar llamada" - "Combinar llamadas" - "Cambiar" - "Administrar llamadas" - "Administrar conferencia" - "Llamada en conferencia" - "Administrar" - "Audio" - "Video" - "Cambiar a llamada de voz" - "Cambiar cámara" - "Activar la cámara" - "Desactivar la cámara" - "Más opciones" - "Se inició el reproductor" - "Se detuvo el reproductor" - "La cámara no está lista" - "Cámara lista" - "Evento de sesión de llamada desconocido" - "Servicio" - "Configuración" - "<Sin configurar>" - "Otras opciones de llamada" - "Llamada por medio de %s" - "Entrantes por medio de %s" - "foto de contacto" - "pasar a modo privado" - "seleccionar contacto" - "Escribe tu propia respuesta…" - "Cancelar" - "Enviar" - "Responder" - "Enviar SMS" - "Rechazar" - "Responder como videollamada" - "Responder como llamada de audio" - "Aceptar solicitud de videollamada" - "Rechazar solicitud de videollamada" - "Aceptar solicitud de transmisión de videollamada" - "Rechazar solicitud de transmisión de videollamada" - "Aceptar solicitud de recepción de videollamada" - "Rechazar solicitud de recepción de videollamada" - "Desliza el dedo hacia arriba para %s." - "Desliza el dedo hacia la izquierda para %s." - "Desliza el dedo hacia la derecha para %s." - "Desliza el dedo hacia abajo para %s." - "Vibrar" - "Vibrar" - "Sonido" - "Sonido predeterminado (%1$s)" - "Tono del teléfono" - "Vibrar al sonar" - "Tono y vibración" - "Administrar llamada en conferencia" - "Número de emergencia" - "Foto de perfil" - "Cámara desactivada" - "del %s" - "Se envió la nota" - "Mensajes recientes" - "Información de la empresa" - "A %.1f mi" - "A %.1f km" - "%1$s, %2$s" - "De %1$s a %2$s" - "%1$s y %2$s" - "Abre mañana a la hora %s" - "Abre hoy a la hora %s" - "Cierra a la hora %s" - "Cerró hoy a la hora %s" - "Abierto ahora" - "Cerrado ahora" - "Posible spam" - "Llamada finalizada %1$s" - "Es la primera vez que te llaman desde este número." - "Sospechamos que esta llamada era spam." - "Bloquear/denunciar" - "Agregar contacto" - "No es spam" - diff --git a/InCallUI/res/values-es/strings.xml b/InCallUI/res/values-es/strings.xml deleted file mode 100644 index ab570d593..000000000 --- a/InCallUI/res/values-es/strings.xml +++ /dev/null @@ -1,195 +0,0 @@ - - - - - "Teléfono" - "En espera" - "Desconocida" - "Número privado" - "Teléfono público" - "Conferencia" - "Llamada perdida" - "Altavoz" - "Auricular" - "Auriculares con cable" - "Bluetooth" - "¿Quieres enviar los siguientes tonos?\n" - "Enviando tonos\n" - "Enviar" - "Sí" - "No" - "Sustituir el carácter comodín por" - "Conferencia %s" - "Número del mensaje de voz" - "Llamando" - "Llamando otra vez" - "Conferencia" - "Llamada entrante" - "Llamada trabajo entrante" - "Llamada finalizada" - "En espera" - "Colgando" - "Llamada entrante" - "Mi número es el %s" - "Conectando videollamada" - "Videollamada" - "Solicitando videollamada" - "No se puede establecer la videollamada" - "Solicitud de videollamada rechazada" - "Tu número de devolución de llamada\n %1$s" - "Tu número de devolución de llamada de emergencia\n %1$s" - "Llamando" - "Llamada perdida" - "Llamadas perdidas" - "%s llamadas perdidas" - "Llamada perdida de %s" - "Llamada en curso" - "Llamada de trabajo en curso" - "Llamada Wi-Fi en curso" - "Llamada Wi-Fi de trabajo en curso" - "En espera" - "Llamada entrante" - "Llamada de trabajo entrante" - "Llamada Wi-Fi entrante" - "Llamada Wi-Fi de trabajo entrante" - "Videollamada entrante" - "Llamada entrante sospechosa de spam" - "Solicitud de videollamada entrante" - "Nuevo mensaje de voz" - "Nuevo mensaje de voz (%d)" - "Marcar %s" - "Número del mensaje de voz desconocido" - "Sin servicio" - "La red seleccionada (%s) no está disponible" - "Responder" - "Colgar" - "Videollamada" - "Voz" - "Aceptar" - "Rechazar" - "Llamar" - "Mensaje" - "Llamada activa en otro dispositivo" - "Transferir llamada" - "Para realizar una llamada, primero debes desactivar el modo avión." - "No estás registrado en la red." - "La red móvil no está disponible." - "Para realizar una llamada, introduce un número válido." - "No se puede establecer la llamada." - "Iniciando secuencia MMI..." - "Servicio no admitido." - "No se pueden intercambiar llamadas." - "No se pueden separar llamadas." - "No se puede transferir." - "No se puede establecer la conferencia." - "No se puede rechazar la llamada." - "No se pueden hacer llamadas." - "Llamada SIP" - "Llamada de emergencia" - "Activando señal móvil…" - "Sin servicio. Reintentado…" - "No se puede establecer la llamada. %s no es un número de emergencia." - "No se puede establecer la llamada. Marca un número de emergencia." - "Usa el teclado para marcar" - "Retener llamada" - "Seguir con la llamada" - "Finalizar llamada" - "Mostrar teclado" - "Ocultar teclado" - "Silenciar" - "Activar sonido" - "Añadir llamada" - "Llamada a tres" - "Cambiar" - "Administrar llamadas" - "Administrar conferencia" - "Teleconferencia" - "Gestionar" - "Audio" - "Videollamada" - "Cambiar a llamada de voz" - "Cambiar cámara" - "Activar cámara" - "Desactivar cámara" - "Más opciones" - "Reproductor iniciado" - "Reproductor detenido" - "Cámara no preparada" - "Cámara preparada" - "Evento de sesión de llamada desconocido" - "Servicio" - "Configuración" - "<No definido>" - "Otra configuración de llamada" - "Llamada a través de %s" - "Recibidas a través de %s" - "foto de contacto" - "llamada privada" - "seleccionar contacto" - "Escribe tu propia respuesta..." - "Cancelar" - "Enviar" - "Responder" - "Enviar SMS" - "Rechazar" - "Responder como videollamada" - "Responder como llamada de audio" - "Aceptar solicitud de videollamada" - "Rechazar solicitud de videollamada" - "Aceptar solicitud de transmisión de videollamada" - "Rechazar solicitud de transmisión de videollamada" - "Aceptar solicitud de recepción de videollamada" - "Rechazar solicitud de recepción de videollamada" - "Desliza el dedo hacia arriba para %s." - "Desliza el dedo hacia la izquierda para %s." - "Desliza el dedo hacia la derecha para %s." - "Desliza el dedo hacia abajo para %s." - "Vibrar" - "Vibrar" - "Sonido" - "Sonido predeterminado (%1$s)" - "Tono de llamada del teléfono" - "Vibrar al sonar" - "Tono de llamada y vibración" - "Administrar videollamada" - "Número de emergencia" - "Foto de perfil" - "Cámara apagada" - "a través de %s" - "Nota enviada" - "Mensajes recientes" - "Información de la empresa" - "A %.1f mi" - "A %.1f km" - "%1$s, %2$s" - "%1$s - %2$s" - "%1$s, %2$s" - "Abre mañana a las %s" - "Abre hoy a las %s" - "Cierra a las %s" - "Cerrado hoy a las %s" - "Abierto ahora" - "Cerrado ahora" - "Sospechoso de spam" - "Llamada de %1$s terminada" - "Es la primera vez que recibes una llamada de este número." - "Sospechábamos que esta llamada era de spam." - "Bloquear / Marcar como spam" - "Añadir contacto" - "No es spam" - diff --git a/InCallUI/res/values-et/strings.xml b/InCallUI/res/values-et/strings.xml deleted file mode 100644 index 5d2a0d8b0..000000000 --- a/InCallUI/res/values-et/strings.xml +++ /dev/null @@ -1,195 +0,0 @@ - - - - - "Telefon" - "Ootel" - "Tundmatu" - "Eranumber" - "Telefoniautomaat" - "Konverentskõne" - "Kõne katkes" - "Kõlar" - "Käsitelefoni kuular" - "Juhtmega peakomplekt" - "Bluetooth" - "Kas saata järgmised toonid?\n" - "Toonide saatmine\n" - "Saada" - "Jah" - "Ei" - "Asenda metamärk üksusega" - "Konverentskõne %s" - "Kõneposti number" - "Valimine" - "Uuesti valimine" - "Konverentskõne" - "Sissetulev kõne" - "Sissetulev töökõne" - "Kõne lõpetati" - "Ootel" - "Lõpetamine" - "Kõne on pooleli" - "Minu number on %s" - "Video ühendamine" - "Videokõne" - "Video taotlemine" - "Videokõnet ei õnnestu ühendada" - "Videokõne taotlus lükati tagasi" - "Teie tagasihelistamise number\n%1$s" - "Teie hädaabikõne tagasihelistamise number\n%1$s" - "Valimine" - "Vastamata kõne" - "Vastamata kõned" - "%s vastamata kõnet" - "Vastamata kõne helistajalt %s" - "Käimasolev kõne" - "Käimasolev töökõne" - "Käimasolev WiFi-kõne" - "Käimasolev töökõne WiFi kaudu" - "Ootel" - "Sissetulev kõne" - "Sissetulev töökõne" - "Sissetulev WiFi-kõne" - "Sissetulev töökõne WiFi kaudu" - "Sissetulev videokõne" - "Arvatav sissetulev rämpskõne" - "Sissetulev videokõne taotlus" - "Uus kõnepostisõnum" - "Uus kõnepostisõnum (%d)" - "Valige %s" - "Kõnepostinumber on tundmatu" - "Levi puudub" - "Valitud võrk (%s) pole saadaval" - "Vasta" - "Lõpeta kõne" - "Videokõne" - "Häälkõne" - "Nõustu" - "Loobu" - "Helista tagasi" - "Saada sõnum" - "Pooleliolev kõne teise seadmes" - "Kõne ülekandmine" - "Helistamiseks lülitage esmalt lennukirežiim välja." - "Ei ole võrgus registreeritud." - "Mobiilsidevõrk pole saadaval." - "Helistamiseks sisestage kehtiv number." - "Ei saa helistada." - "MMI-jada alustamine …" - "Teenust ei toetata." - "Kõnesid ei saa vahetada." - "Kõnet ei saa eraldada." - "Ei saa üle kanda." - "Konverentskõnet ei saa pidada." - "Kõnet ei saa tagasi lükata." - "Kõnesid ei saa vabastada." - "SIP-kõne" - "Hädaabikõne" - "Raadioside sisselülitamine …" - "Levi puudub. Uuesti proovimine …" - "Ei saa helistada. %s ei ole hädaabinumber." - "Ei saa helistada. Valige hädaabinumber." - "Kasutage valimiseks klaviatuuri" - "Kõne ootele" - "Jätka kõnet" - "Lõpeta kõne" - "Kuva valimisklahvistik" - "Peida valimisklahvistik" - "Vaigista" - "Tühista vaigistus" - "Lisa kõne" - "Ühenda kõned" - "Vaheta" - "Halda kõnesid" - "Halda konverentskõnet" - "Konverentskõne" - "Halda" - "Heli" - "Videokõne" - "Mine üle häälkõnele" - "Vaheta kaamerat" - "Lülita kaamera sisse" - "Lülita kaamera välja" - "Rohkem valikuid" - "Pleier käivitati" - "Pleier peatati" - "Kaamera pole valmis" - "Kaamera on valmis" - "Tundmatu kõneseansisündmus" - "Teenus" - "Seadistamine" - "<Määramata>" - "Muud kõneseaded" - "Kõne edastab %s" - "Sissetulev kõne teenusepakkuja %s kaudu" - "kontakti foto" - "aktiveeri privaatne kõne" - "vali kontakt" - "Kirjutage ise …" - "Tühista" - "Saada" - "Vastamine" - "Saada SMS" - "Tagasilükkamine" - "Vastamine videokõnena" - "Vastamine helikõnena" - "Video taotluse aktsepteerimine" - "Video taotluse tagasilükkamine" - "Video edastamise taotluse aktsepteerimine" - "Video edastamise taotluse tagasilükkamine" - "Video vastuvõtmise taotluse aktsepteerimine" - "Video vastuvõtmise taotluse tagasilükkamine" - "Lohistage üles: %s." - "Lohistage vasakule: %s." - "Lohistage paremale: %s." - "Lohistage alla: %s." - "Vibreerimine" - "Vibreerimine" - "Heli" - "Vaikeheli (%1$s)" - "Telefonihelin" - "Vibreerimine helina ajal" - "Helin ja vibratsioon" - "Konverentskõne haldamine" - "Hädaabinumber" - "Profiilifoto" - "Kaamera on välja lülitatud" - "numbri %s kaudu" - "Märkus on saadetud" - "Hiljutised sõnumid" - "Ettevõtte teave" - "%.1f miili kaugusel" - "%.1f km kaugusel" - "%1$s, %2$s" - "%1$s kuni %2$s" - "%1$s, %2$s" - "Avatakse homme kell %s" - "Avatakse täna kell %s" - "Suletakse kell %s" - "Suleti täna kell %s" - "Praegu avatud" - "Praegu suletud" - "Arvatav rämpskõne" - "Kõne lõppes: %1$s" - "Teile helistati sellelt numbrilt esimest korda." - "Kahtlustasime, et see võis olla rämpskõne." - "Blokeeri / teavita rämpskõnest" - "Lisa kontakt" - "Pole rämpskõne" - diff --git a/InCallUI/res/values-eu/strings.xml b/InCallUI/res/values-eu/strings.xml deleted file mode 100644 index c300c47cd..000000000 --- a/InCallUI/res/values-eu/strings.xml +++ /dev/null @@ -1,195 +0,0 @@ - - - - - "Telefonoa" - "Zain" - "Ezezaguna" - "Zenbaki pribatua" - "Telefono publikoa" - "Konferentzia-deia" - "Eten egin da deia" - "Bozgorailua" - "Aurikularrak" - "Kabledun entzungailua" - "Bluetooth konexioa" - "Tonu hauek bidali nahi dituzu?\n" - "Tonuak bidaltzen\n" - "Bidali" - "Bai" - "Ez" - "Ordeztu komodina honekin:" - "Konferentzia-deiaren ordua: %s" - "Erantzungailuaren zenbakia" - "Deitzen" - "Berriro markatzen" - "Konferentzia-deia" - "Dei bat jaso duzu" - "Laneko dei bat jaso duzu" - "Amaitu da deia" - "Zain" - "Deia amaitzen" - "Deia abian" - "Nire zenbakia %s da" - "Bideoa konektatzen" - "Bideo-deia" - "Bideo-deia eskatzen" - "Ezin da konektatu bideo-deia" - "Baztertu egin da bideo-deia egiteko eskaera" - "Dei-erantzunetarako zenbakia:\n %1$s" - "Larrialdi-dei bidez erantzuteko zenbakia:\n %1$s" - "Deitzen" - "Dei bat galdu duzu" - "Dei batzuk galdu dituzu" - "%s dei galdu dituzu" - "Deitzaile honen dei bat galdu duzu: %s" - "Deia abian da" - "Laneko dei bat abian da" - "Wi-Fi bidezko deia abian da" - "Wi-Fi bidezko laneko dei bat abian da" - "Zain" - "Dei bat jaso duzu" - "Laneko dei bat jaso duzu" - "Wi-Fi bidezko dei bat jaso duzu" - "Wi-Fi bidezko laneko dei bat jaso duzu" - "Bideo-dei bat jaso duzu" - "Ustezko spam-deia jaso duzu" - "Bideo-dei bat egiteko eskaera bat jaso duzu" - "Ahots-mezu berria" - "Ahots-mezu berriak (%d)" - "Markatu %s" - "Erantzungailuaren zenbakia ezezaguna da" - "Ez dago zerbitzurik" - "Hautatutako sarea (%s) ez dago erabilgarri" - "Erantzun" - "Amaitu deia" - "Bideo-deia" - "Ahots-deia" - "Onartu" - "Baztertu" - "Itzuli deia" - "Bidali SMSa" - "Dei bat abian da beste gailu batean" - "Transferitu deia" - "Deitzeko, desaktibatu hegaldi modua." - "Ez dago sarean erregistratuta." - "Sare mugikorra ez dago erabilgarri." - "Deitzeko, idatzi balio duen zenbaki bat." - "Ezin da deitu." - "MMI sekuentzia hasten…" - "Ez da onartzen zerbitzua." - "Ezin aldatu beste dei batera." - "Ezin da bereizi deia." - "Ezin da transferitu." - "Ezin da egin konferentzia-deia." - "Ezin da baztertu deia." - "Ezin dira amaitu deiak." - "SIP deia" - "Larrialdi-deia" - "Irratia pizten…" - "Ez dago zerbitzurik. Berriro saiatzen…" - "Ezin da deitu. %s ez da larrialdietarako zenbakia." - "Ezin da deitu. Markatu larrialdietarako zenbakia." - "Erabili teklatua markatzeko" - "Utzi deia zain" - "Berrekin deiari" - "Amaitu deia" - "Erakutsi markagailua" - "Ezkutatu markagailua" - "Desaktibatu audioa" - "Aktibatu audioa" - "Gehitu deia" - "Bateratu deiak" - "Aldatu" - "Kudeatu deiak" - "Kudeatu konferentzia-deia" - "Konferentzia-deia" - "Kudeatu" - "Audioa" - "Bideo-deia" - "Aldatu ahots-deira" - "Aldatu kamera" - "Aktibatu kamera" - "Desaktibatu kamera" - "Aukera gehiago" - "Abian da erreproduzigailua" - "Gelditu da erreproduzigailua" - "Ez dago prest kamera" - "Prest dago kamera" - "Dei-saioko gertaera ezezaguna" - "Zerbitzua" - "Konfigurazioa" - "<Ezarri gabe>" - "Deien beste ezarpen batzuk" - "%s bidez deitzen" - "%s bidez jasotzen" - "kontaktuaren argazkia" - "bihurtu pribatu" - "hautatu kontaktua" - "Idatzi zeure erantzuna…" - "Utzi" - "Bidali" - "Erantzun" - "Bidali SMS mezua" - "Baztertu" - "Erantzun bideo-dei moduan" - "Erantzun audio-dei moduan" - "Onartu bideo-deia egiteko eskaera" - "Baztertu bideo-deia egiteko eskaera" - "Onartu bideoa transmititzeko eskaera" - "Baztertu bideoa transmititzeko eskaera" - "Onartu bideo-deia jasotzeko eskaera" - "Baztertu bideo-deia jasotzeko eskaera" - "Lerratu gora hau egiteko: %s." - "Lerratu ezkerrera hau egiteko: %s." - "Lerratu eskuinera hau egiteko: %s." - "Lerratu behera hau egiteko: %s." - "Dardara" - "Dardara" - "Soinua" - "Soinu lehenetsia (%1$s)" - "Telefonoaren tonua" - "Egin dar-dar tonuak jotzean" - "Tonua eta dardara" - "Kudeatu konferentzia-deia" - "Larrialdietarako zenbakia" - "Profileko argazkia" - "Desaktibatuta dago kamera" - "%s zenbakitik" - "Bidali da oharra" - "Azken mezuak" - "Enpresaren informazioa" - "Hemendik %.1f miliara" - "Hemendik %.1f km-ra" - "%1$s, %2$s" - "%1$s%2$s" - "%1$s, %2$s" - "%s da biharko irekitze-ordua" - "%s da gaurko irekitze-ordua" - "%s da ixte-ordua" - "%s da gaurko itxiera-ordua" - "Irekita dago" - "Itxita dago" - "Ustezko spam-deitzailea" - "Deiaren amaiera: %1$s" - "Zenbaki honek deitu dizun lehen aldia izan da." - "Spam-igorle baten deia izan dela susmatu dugu." - "Salatu spama dela" - "Gehitu kontaktua" - "Ez da spama" - diff --git a/InCallUI/res/values-fa/strings.xml b/InCallUI/res/values-fa/strings.xml deleted file mode 100644 index f96b8956a..000000000 --- a/InCallUI/res/values-fa/strings.xml +++ /dev/null @@ -1,195 +0,0 @@ - - - - - "تلفن" - "در انتظار" - "نامشخص" - "شماره خصوصی" - "تلفن عمومی" - "تماس کنفرانسی" - "تماس قطع شد" - "بلندگو" - "گوشی" - "هدست سیمی" - "بلوتوث" - "شماره‌های بعدی ارسال شود؟\n" - "تون‌های ارسالی\n" - "ارسال" - "بله" - "نه" - "جایگزینی نویسه عمومی با" - "تماس کنفرانسی %s" - "شماره پست صوتی" - "شماره‌گیری" - "درحال شماره‌گیری مجدد" - "تماس کنفرانسی" - "تماس ورودی" - "تماس کاری ورودی" - "تماس پایان یافت" - "در انتظار" - "قطع تماس" - "درحال تماس" - "شماره من %s است" - "درحال برقراری تماس ویدئویی" - "تماس ویدئویی" - "درحال درخواست تماس ویدئویی" - "برقراری تماس ویدئویی ممکن نیست" - "درخواست تماس ویدئویی رد شد" - "شماره پاسخ تماس شما\n %1$s" - "شماره پاسخ تماس اضطراری شما\n %1$s" - "شماره‌گیری" - "تماس بی‌پاسخ" - "تماس بی‌پاسخ" - "%s تماس بی‌پاسخ" - "تماس بی‌پاسخ از %s" - "تماس درحال انجام" - "تماس کاری درحال انجام" - "‏تماس درحال انجام ازطریق Wi-Fi" - "‏تماس کاری Wi-Fi درحال انجام" - "در انتظار" - "تماس ورودی" - "تماس کاری ورودی" - "‏تماس Wi-Fi ورودی" - "‏تماس کاری Wi-Fi ورودی" - "تماس ویدئویی ورودی" - "تماس هرزنامه احتمالی ورودی" - "درخواست تماس ویدئویی ورودی" - "پست صوتی جدید" - "پست صوتی جدید (%d)" - "شماره‌گیری %s" - "شماره پست صوتی ناشناس" - "بدون سرویس" - "شبکه انتخابی (%s) قابل دسترس نیست" - "پاسخ" - "پایان تماس" - "ویدئو" - "صدا" - "پذیرفتن" - "نپذیرفتن" - "پاسخ تماس" - "پیام" - "تماس در حال انجام در دستگاهی دیگر" - "انتقال تماس" - "برای برقراری تماس، ابتدا حالت هواپیما را خاموش کنید." - "در شبکه ثبت نشده است." - "شبکه تلفن همراه در دسترس نیست." - "برای برقراری تماس، شماره معتبری وارد کنید." - "تماس ممکن نیست." - "‏شروع ترتیب MMI…" - "سرویس پشتیبانی نمی‌شود." - "جابه‌جایی بین تماس‌ها ممکن نیست." - "جدا کردن تماس ممکن نیست." - "انتقال ممکن نیست." - "تماس کنفرانسی ممکن نیست." - "رد کردن تماس ممکن نیست." - "آزاد کردن تماس(ها) ممکن نیست." - "‏تماس SIP" - "تماس اضطراری" - "درحال روشن کردن رادیو…‏" - "سرویسی در دسترس نیست. درحال تلاش مجدد…‏" - "تماس ممکن نیست. %s شماره اضطراری نیست." - "تماس ممکن نیست. فقط شماره اضطراری." - "استفاده از صفحه‌کلید برای شماره‌گیری" - "در انتظار گذاشتن تماس" - "ازسرگیری تماس" - "پایان تماس" - "نمایش صفحه شماره‌گیری" - "پنهان کردن صفحه شماره‌گیری" - "بی‌صدا کردن" - "لغو نادیده گرفتن" - "افزودن تماس" - "ادغام تماس‌ها" - "تعویض" - "مدیریت تماس‌ها" - "مدیریت تماس کنفرانسی" - "تماس کنفرانسی" - "مدیریت" - "صوتی" - "تماس ویدئویی" - "تغییر به تماس صوتی" - "تعویض دوربین" - "روشن کردن دوربین" - "خاموش کردن دوربین" - "گزینه‌های بیشتر" - "پخش‌کننده راه‌اندازی شد" - "پخش‌کننده متوقف شد" - "دوربین آماده نیست" - "دوربین آماده است" - "رویداد جلسه تماس ناشناس" - "سرویس" - "راه‌اندازی" - "‏<تنظیم نشده>" - "سایر تنظیمات تماس" - "تماس با %s" - "تماس‌های ورودی ازطریق %s" - "عکس مخاطب" - "رفتن به حالت خصوصی" - "انتخاب مخاطب" - "پیام خودتان را بنویسید..." - "لغو" - "ارسال" - "پاسخ" - "ارسال پیامک" - "رد کردن" - "پاسخ به‌صورت تماس ویدئویی" - "پاسخ به‌صورت تماس صوتی" - "پذیرفتن درخواست تماس ویدئویی" - "نپذیرفتن درخواست تماس ویدئویی" - "پذیرفتن درخواست مخابره ویدئویی" - "نپذیرفتن درخواست مخابره ویدئویی" - "پذیرفتن درخواست دریافت ویدئویی" - "نپذیرفتن درخواست دریافت ویدئویی" - "برای %s به بالا بلغزانید." - "برای %s به چپ بلغزانید." - "برای %s به راست بلغزانید." - "برای %s به پایین بلغزانید." - "لرزش" - "لرزش" - "صدا" - "صدای پیش‌فرض (%1$s)" - "آهنگ زنگ تلفن" - "لرزش هنگام زنگ زدن" - "آهنگ‌ زنگ و لرزش" - "مدیریت تماس کنفرانسی" - "شماره اضطراری" - "عکس نمایه" - "دوربین خاموش" - "ازطریق %s" - "یادداشت ارسال شد" - "پیام‌های جدید" - "اطلاعات کسب و کار" - "%.1f مایل فاصله" - "%.1f کیلومتر فاصله" - "%1$s،‏ %2$s" - "%1$s تا %2$s" - "%1$s،‏ %2$s" - "فردا ساعت %s باز می‌شود" - "امروز ساعت %s باز می‌شود" - "ساعت %s بسته می‌شود" - "امروز ساعت %s بسته شد" - "اکنون باز است" - "اکنون بسته است" - "تماس‌گیرنده هرزنامه احتمالی" - "‏تماس به پایان رسید %1$s" - "این اولین بار است که این شماره با شما تماس گرفته است." - "ما به این تماس شک کردیم و احساس کردیم که ممکن است کلاهبردار باشد." - "مسدود کردن/گزارش دادن هرزنامه" - "افزودن مخاطب" - "هرزنامه نیست" - diff --git a/InCallUI/res/values-fi/strings.xml b/InCallUI/res/values-fi/strings.xml deleted file mode 100644 index 7553e7c25..000000000 --- a/InCallUI/res/values-fi/strings.xml +++ /dev/null @@ -1,195 +0,0 @@ - - - - - "Puhelin" - "Pidossa" - "Tuntematon" - "Yksityinen numero" - "Maksupuhelin" - "Puhelinneuvottelu" - "Puhelu katkaistiin." - "Kaiutin" - "Puhelimen kaiutin" - "Kuulokemikrofoni" - "Bluetooth" - "Lähetetäänkö seuraavat äänet?\n" - "Lähetetään ääniä\n" - "Lähetä" - "Kyllä" - "Ei" - "Muuta jokerimerkiksi" - "Puhelinneuvottelu %s" - "Puhelinvastaajan numero" - "Soitetaan" - "Soitetaan uudelleen" - "Puhelinneuvottelu" - "Saapuva puhelu" - "Saapuva työpuhelu" - "Puhelu päättyi" - "Pidossa" - "Katkaistaan" - "Puhelu käynnissä" - "Numeroni on %s" - "Avataan videoyhteys" - "Videopuhelu" - "Videota pyydetään" - "Videopuhelua ei voi soittaa" - "Videopyyntö hylättiin" - "Takaisinsoittonumero:\n %1$s" - "Hätäpuhelujen takaisinsoittonumero:\n %1$s" - "Soitetaan" - "Vastaamaton puhelu" - "Vastaamattomia puheluita" - "%s vastaamatonta puhelua" - "Vastaamaton puhelu: %s" - "Käynnissä oleva puhelu" - "Käynnissä oleva työpuhelu" - "Käynnissä oleva Wi-Fi-puhelu" - "Käynnissä oleva Wi-Fi-työpuhelu" - "Pidossa" - "Saapuva puhelu" - "Saapuva työpuhelu" - "Saapuva Wi-Fi-puhelu" - "Saapuva Wi-Fi-työpuhelu" - "Saapuva videopuhelu" - "Tämä puhelu saattaa olla häirikköpuhelu." - "Saapuva videopyyntö" - "Uusi vastaajaviesti" - "Uusia vastaajaviestejä (%d)" - "Soita: %s" - "Puhelinvastaajan numero on tuntematon." - "Ei yhteyttä" - "Valittu verkko (%s) ei ole käytettävissä." - "Vastaa" - "Katkaise" - "Videopuhelu" - "Äänipuhelu" - "Hyväksy" - "Hylkää" - "Soita" - "Viesti" - "Puhelu on kesken toisella laitteella." - "Siirrä puhelu" - "Poista lentokonetila käytöstä ennen puhelun soittamista." - "Ei rekisteröity verkkoon" - "Matkapuhelinverkko ei ole käytettävissä." - "Soita antamalla kelvollinen numero." - "Puhelua ei voi soittaa." - "Aloitetaan MMI-koodisekvenssiä…" - "Yhteyttä ei tueta." - "Puhelua ei voi vaihtaa." - "Puhelua ei voi erottaa." - "Puhelua ei voi siirtää." - "Puheluja ei voi yhdistää." - "Puhelua ei voi hylätä." - "Puheluja ei voi katkaista." - "SIP-puhelu" - "Hätäpuhelu" - "Käynnistetään radiota…" - "Ei yhteyttä. Yritetään uudelleen…" - "Puhelua ei voi soittaa. %s ei ole hätänumero." - "Puhelua ei voi soittaa. Valitse hätänumero." - "Valitse numero näppäimistöllä." - "Aseta puhelu pitoon" - "Jatka puhelua" - "Lopeta puhelu" - "Avaa näppäimistö" - "Piilota näppäimistö" - "Mykistä" - "Poista mykistys" - "Lisää puhelu" - "Yhdistä puhelut" - "Vaihda" - "Hallinnoi puheluja" - "Hallinnoi puhelinneuvottelua" - "Puhelinneuvottelu" - "Hallinnoi" - "Ääni" - "Video" - "Muuta äänipuheluksi" - "Vaihda kameraa" - "Käynnistä kamera" - "Sammuta kamera" - "Lisäasetukset" - "Soitin käynnistettiin." - "Soitin pysäytettiin." - "Kamera ei ole valmis." - "Kamera on valmis." - "Tuntematon puheluistunnon tapahtuma" - "Palveluntarjoaja" - "Määritys" - "<Ei määritetty>" - "Muut puheluasetukset" - "Käytetään operaattoria %s" - "Saapuva puhelu (%s)" - "Yhteystiedon kuva" - "Muuta yksityiseksi." - "Valitse yhteystieto." - "Kirjoita oma…" - "Peruuta" - "Lähetä" - "Vastaa." - "Lähetä tekstiviesti." - "Hylkää." - "Vastaa ja aloita videopuhelu." - "Vastaa ja aloita äänipuhelu." - "Hyväksy videopyyntö." - "Hylkää videopyyntö." - "Hyväksy videon lähetyspyyntö." - "Hylkää videon lähetyspyyntö." - "Hyväksy videon vastaanottopyyntö." - "Hylkää videon vastaanottopyyntö." - "Valitse %s liu\'uttamalla ylös." - "Valitse %s liu\'uttamalla vasemmalle." - "Valitse %s liu\'uttamalla oikealle." - "Valitse %s liu\'uttamalla alas." - "Värinä" - "Värinä" - "Ääni" - "Oletusääni (%1$s)" - "Puhelimen soittoääni" - "Käytä värinää, kun puhelin soi" - "Soittoääni ja värinä" - "Hallinnoi puhelinneuvottelua" - "Hätänumero" - "Profiilikuva" - "Kamera on pois käytöstä." - "nron %s kautta" - "Muistiinpano lähetettiin." - "Viimeisimmät viestit" - "Yrityksen tiedot" - "Etäisyys: %.1f mailia" - "Etäisyys: %.1f kilometriä" - "%1$s, %2$s" - "%1$s%2$s" - "%1$s, %2$s" - "Avataan huomenna kello %s" - "Avataan tänään kello %s" - "Suljetaan tänään kello %s" - "Suljettiin tänään kello %s" - "Avoinna nyt" - "Suljettu nyt" - "Häirikkösoittaja" - "Puhelu loppui %1$s" - "Tämä oli ensimmäinen kerta, kun tästä numerosta soitettiin sinulle." - "Epäilemme, että tämä puhelu tuli häirikkösoittajalta." - "Estä / ilmoita" - "Lisää yhteystieto" - "Ei häirikkösoittaja" - diff --git a/InCallUI/res/values-fr-rCA/strings.xml b/InCallUI/res/values-fr-rCA/strings.xml deleted file mode 100644 index 2980646e8..000000000 --- a/InCallUI/res/values-fr-rCA/strings.xml +++ /dev/null @@ -1,195 +0,0 @@ - - - - - "Téléphone" - "En attente" - "Inconnue" - "Numéro privé" - "Cabine téléphonique" - "Conférence téléphonique" - "L\'appel a été interrompu" - "Haut-parleur" - "Écouteur du combiné" - "Écouteurs à fil" - "Bluetooth" - "Envoyer les tonalités suivantes?\n" - "Envoi des tonalités\n" - "Envoyer" - "Oui" - "Non" - "Remplacer le caractère générique par" - "Conférence téléphonique %s" - "Numéro de messagerie vocale" - "Composition..." - "Recomposition en cours..." - "Conférence téléphonique" - "Appel entrant" - "Appel entrant - travail" - "Appel terminé" - "En attente" - "Fin de l\'appel" - "En cours d\'appel" - "Mon numéro est le %s" - "Connexion de la vidéo en cours…" - "Appel vidéo" - "Demande de vidéo en cours" - "Impossible de connecter l\'appel vidéo" - "Demande vidéo refusée" - "Votre numéro de rappel :\n %1$s" - "Votre numéro de rappel d\'urgence :\n %1$s" - "Composition en cours..." - "Appel manqué" - "Appels manqués" - "%s appels manqués" - "Appel manqué de %s" - "Appel en cours" - "Appel en cours - travail" - "Appel Wi-Fi en cours" - "Appel Wi-Fi en cours - travail" - "En attente" - "Appel entrant" - "Appel entrant - travail" - "Appel Wi-Fi entrant" - "Appel Wi-Fi entrant - travail" - "Appel vidéo entrant" - "L\'appel entrant est suspect" - "Demande de vidéo reçue" - "Nouveau message vocal" - "Nouveaux messages vocaux (%d)" - "Composer le %s" - "Numéro de messagerie vocale inconnu" - "Aucun service" - "Réseau sélectionné (%s) non disponible" - "Répondre" - "Raccrocher" - "Vidéo" - "Voix" - "Accepter" - "Fermer" - "Rappeler" - "Message" - "Appel en cours sur un autre appareil" - "Transférer l\'appel" - "Pour faire un appel, d\'abord désactiver le mode Avion." - "Non enregistré sur le réseau." - "Réseau cellulaire non disponible." - "Pour faire un appel, entrez un numéro valide." - "Impossible d\'appeler." - "Lancement de la séquence IHM en cours…" - "Service non pris en charge." - "Impossible de faire des appels." - "Impossible de séparer les appels." - "Impossible de transférer." - "Impossible de créer la conférence." - "Impossible de refuser l\'appel." - "Impossible de libérer l\'appel ou les appels." - "Appel SIP" - "Appel d\'urgence" - "Activation du signal radio…" - "Aucun service. Nouvel essai en cours..." - "Appel impossible. %s n\'est pas un numéro d\'urgence." - "Appel impossible. Composez un numéro d\'urgence." - "Utilisez le clavier pour composer un numéro" - "Mettre l\'appel en attente" - "Reprendre l\'appel" - "Mettre fin à l\'appel" - "Afficher le clavier numérique" - "Masquer le clavier numérique" - "Désactiver le son" - "Réactiver le son" - "Ajouter un appel" - "Fusionner les appels" - "Permuter" - "Gérer les appels" - "Gérer la conférence" - "Conférence téléphonique" - "Gérer" - "Audio" - "Appel vidéo" - "Passer à un appel vocal" - "Changer d\'appareil photo" - "Activer la caméra" - "Désactiver la caméra" - "Plus d\'options" - "Le lecteur a démarré" - "Le lecteur a arrêté" - "L\'appareil photo n\'est pas prêt" - "L\'appareil photo est prêt" - "Événement inconnu de séance d\'appel" - "Service" - "Configuration" - "<Non défini>" - "Autres paramètres d\'appel" - "Appel par %s" - "Appel entrant par %s" - "photo du contact" - "mode privé" - "sélectionner un contact" - "Réponse personnalisée..." - "Annuler" - "Envoyer" - "Répondre" - "Envoyer un texto" - "Refuser" - "Répondre comme appel vidéo" - "Répondre comme appel audio" - "Accepter la demande vidéo" - "Refuser la demande vidéo" - "Accepter la demande de transmission vidéo" - "Refuser la demande de transmission vidéo" - "Accepter la demande de réception vidéo" - "Refuser la demande de réception vidéo" - "Faites glisser votre doigt vers le haut pour %s." - "Faites glisser votre doigt vers la gauche pour %s." - "Faites glisser votre doigt vers la droite pour %s." - "Faire glisser le doigt vers le bas : %s" - "Vibration" - "Vibration" - "Son" - "Son par défaut (%1$s)" - "Sonnerie du téléphone" - "Vibrer lorsque téléphone sonne" - "Sonnerie et vibreur" - "Gérer la conférence" - "Numéro d\'urgence" - "Photo de profil" - "Appareil photo désactivé" - "au moyen du %s" - "Note envoyée" - "Messages récents" - "Renseignements sur l\'entreprise" - %.1f mi" - %.1f km" - "%1$s, %2$s" - "De %1$s à %2$s" - "%1$s, %2$s" - "Ouvre demain à %s" - "Ouvre aujourd\'hui à %s" - "Ferme à %s" - "A fermé aujourd\'hui à %s" - "Ouvert" - "Fermé" - "Appel suspect" - "Appel terminé %1$s" - "C\'est la première fois que ce numéro vous appelle." - "Cet appel nous semblait suspect." - "Sign. appel suspect" - "Ajouter un contact" - "N\'est pas suspect" - diff --git a/InCallUI/res/values-fr/strings.xml b/InCallUI/res/values-fr/strings.xml deleted file mode 100644 index 521fedb64..000000000 --- a/InCallUI/res/values-fr/strings.xml +++ /dev/null @@ -1,195 +0,0 @@ - - - - - "Téléphone" - "En attente" - "Inconnu" - "Numéro privé" - "Cabine téléphonique" - "Conférence téléphonique" - "Appel interrompu" - "Haut-parleur" - "Écouteur du combiné" - "Casque filaire" - "Bluetooth" - "Envoyer les tonalités suivantes ?\n" - "Envoi des tonalités…\n" - "Envoyer" - "Oui" - "Non" - "Remplacer le caractère générique par" - "Conférence téléphonique à %s" - "N° de la messagerie vocale" - "Appel…" - "Rappel…" - "Conférence téléphonique" - "Appel entrant" - "Appel profession. entrant" - "Appel terminé" - "En attente" - "Fin de l\'appel…" - "Appel en cours" - "Mon numéro est le %s" - "Connexion de la vidéo…" - "Appel vidéo" - "Demande de vidéo…" - "Impossible d\'établir la connexion de l\'appel vidéo." - "Demande d\'appel vidéo refusée" - "Votre numéro de rappel\n %1$s" - "Votre numéro de rappel d\'urgence\n %1$s" - "Appel…" - "Appel manqué" - "Appels manqués" - "%s appels manqués" - "Appel manqué de %s" - "Appel en cours" - "Appel professionnel en cours" - "Appel Wi-Fi en cours" - "Appel Wi-Fi professionnel en cours" - "En attente" - "Appel entrant" - "Appel professionnel entrant" - "Appel Wi-Fi entrant" - "Appel Wi-Fi professionnel entrant" - "Appel vidéo entrant" - "Appel entrant indésirable suspecté" - "Demande de vidéo reçue" - "Nouveau message vocal" - "Nouveaux messages vocaux (%d)" - "Composer le %s" - "Numéro de messagerie vocale inconnu" - "Aucun service" - "Réseau sélectionné (%s) non disponible" - "Répondre" - "Raccrocher" - "Vidéo" - "Appel vocal" - "Accepter" - "Fermer" - "Rappeler" - "Envoyer SMS" - "Appel en cours sur un autre appareil" - "Transférer l\'appel" - "Veuillez désactiver le mode Avion avant de passer un appel." - "Non enregistré sur le réseau." - "Réseau mobile indisponible." - "Pour émettre un appel, veuillez saisir un numéro valide." - "Impossible d\'émettre l\'appel." - "Lancement de la séquence IHM…" - "Service non compatible." - "Impossible de changer d\'appel." - "Impossible d\'isoler l\'appel." - "Transfert impossible." - "Impossible de lancer une conférence téléphonique." - "Impossible de refuser l\'appel." - "Impossible de lancer les appels." - "Appel SIP" - "Appel d\'urgence" - "Activation du signal radio…" - "Aucun service disponible. Nouvelle tentative…" - "Impossible d\'émettre l\'appel. %s n\'est pas un numéro d\'urgence." - "Impossible d\'émettre l\'appel. Veuillez composer un numéro d\'urgence." - "Utilisez le clavier pour composer un numéro." - "Mettre l\'appel en attente" - "Reprendre l\'appel" - "Mettre fin à l\'appel" - "Afficher le clavier" - "Masquer le clavier" - "Couper le son" - "Réactiver le son" - "Ajouter un appel" - "Fusionner les appels" - "Permuter" - "Gérer les appels" - "Gérer conférence téléphonique" - "Conférence téléphonique" - "Gérer" - "Audio" - "Appel vidéo" - "Passer à un appel vocal" - "Changer de caméra" - "Activer la caméra" - "Désactiver la caméra" - "Plus d\'options" - "Le lecteur a démarré." - "Le lecteur s\'est arrêté." - "La caméra n\'est pas prête" - "La caméra est prête" - "Événement de session d\'appel inconnu" - "Service" - "Configuration" - "<Non défini>" - "Autres paramètres d\'appel" - "Appel via %s" - "Appel entrant via %s" - "photo du contact" - "mode privé" - "sélectionner un contact" - "Réponse personnalisée…" - "Annuler" - "Envoyer" - "Répondre" - "Envoyer un SMS" - "Refuser" - "Répondre via un appel vidéo" - "Répondre via un appel audio" - "Accepter la demande d\'appel vidéo" - "Refuser la demande d\'appel vidéo" - "Accepter la demande de transmission d\'appel vidéo" - "Refuser la demande de transmission d\'appel vidéo" - "Accepter la demande de réception d\'appel vidéo" - "Refuser la demande de réception d\'appel vidéo" - "Faites glisser vers le haut pour %s" - "Faites glisser vers la gauche pour %s." - "Faites glisser vers la droite pour %s." - "Faites glisser vers le bas pour %s." - "Vibreur" - "Vibreur" - "Sonnerie" - "Sonnerie par défaut (%1$s)" - "Sonnerie du téléphone" - "Vibreur lorsque le tél. sonne" - "Sonnerie et vibreur" - "Gérer la conférence téléphonique" - "Numéro d\'urgence" - "Photo du profil" - "Caméra désactivée" - "via le %s" - "La note a bien été envoyée." - "Messages récents" - "Informations sur l\'établissement" - %.1f mi" - %.1f km" - "%1$s, %2$s" - "%1$s%2$s" - "%1$s, %2$s" - "Ouvre demain à %s" - "Ouvre aujourd\'hui à %s" - "Ferme à %s" - "Fermé aujourd\'hui à %s" - "Ouvert" - "Fermé" - "Appel indésirable suspecté" - "Appel terminé %1$s" - "C\'est la première fois que vous recevez un appel de ce numéro." - "Nous suspectons cet appel de provenir d\'un spammeur." - "Bloquer/Signaler spam" - "Ajouter un contact" - "Numéro fiable" - diff --git a/InCallUI/res/values-gl/strings.xml b/InCallUI/res/values-gl/strings.xml deleted file mode 100644 index 8968946e6..000000000 --- a/InCallUI/res/values-gl/strings.xml +++ /dev/null @@ -1,195 +0,0 @@ - - - - - "Teléfono" - "En espera" - "Descoñecido" - "Número privado" - "Teléfono público" - "Conferencia telefónica" - "Chamada interrompida" - "Altofalante" - "Auricular do teléfono" - "Auriculares con cable" - "Bluetooth" - "Queres enviar os seguintes tons?\n" - "Enviando tons\n" - "Enviar" - "Si" - "Non" - "Substituír carácter comodín por" - "Conferencia telefónica ás %s" - "Número de correo de voz" - "Marcando" - "Marcando de novo" - "Conferencia telefónica" - "Chamada entrante" - "Chamada traballo entrante" - "Chamada finalizada" - "En espera" - "Desconectando" - "Chamada entrante" - "O meu número é o %s" - "Conectando vídeo" - "Videochamada" - "Solicitando vídeo" - "Non se pode conectar a videochamada" - "Rexeitouse a solicitude de vídeo" - "O teu número de devolución de chamada\n %1$s" - "O teu número de devolución de chamada de emerxencia\n %1$s" - "Marcando" - "Chamada perdida" - "Chamadas perdidas" - "%s chamadas perdidas" - "Chamada perdida de %s" - "Chamada en curso" - "Chamada de traballo saínte" - "Chamada por wifi saínte" - "Chamada por wifi de traballo saínte" - "En espera" - "Chamada entrante" - "Chamada de traballo entrante" - "Chamada por wifi entrante" - "Chamada wifi de traballo entrante" - "Videochamada entrante" - "Chamada entrante sospeitosa de spam" - "Solicitude de vídeo entrante" - "Correo de voz novo" - "Correo de voz novo (%d)" - "Marcar o %s" - "Número de correo de voz descoñecido" - "Sen servizo" - "A rede seleccionada (%s) non está dispoñible" - "Responder" - "Colgar" - "Vídeo" - "Voz" - "Aceptar" - "Ignorar" - "Dev. chamada" - "Mensaxe" - "Chamada en curso noutro dispositivo" - "Transferir chamada" - "Para realizar unha chamada, primeiro desactiva o modo avión." - "Sen rexistro na rede." - "Rede móbil non dispoñible." - "Para realizar unha chamada, introduce un número válido." - "Non se pode realizar a chamada." - "Iniciando secuencia MMI..." - "Servizo non compatible." - "Non se poden cambiar as chamadas." - "Non se pode separar a chamada." - "Non se pode transferir." - "Non se pode realizar a conferencia." - "Non se pode rexeitar a chamada." - "Non se poden desconectar as chamadas." - "Chamada SIP" - "Chamada de emerxencia" - "Activando radio..." - "Sen servizo. Tentándoo de novo…" - "Non se pode realizar a chamada. %s non é un número de emerxencia." - "Non se pode realizar a chamada. Marca un número de emerxencia." - "Utiliza o teclado para marcar" - "Poñer a chamada en espera" - "Retomar chamada" - "Finalizar chamada" - "Mostrar teclado de marcación" - "Ocultar teclado de marcación" - "Silenciar" - "Activar o son" - "Engadir chamada" - "Combinar chamadas" - "Cambiar" - "Xestionar chamadas" - "Xestionar confer. telefónica" - "Conferencia telefónica" - "Xestionar" - "Audio" - "Videocham." - "Cambiar para chamada de voz" - "Cambiar cámara" - "Acender cámara" - "Apagar cámara" - "Máis opcións" - "Iniciouse o reprodutor" - "Detívose o reprodutor" - "A cámara non está preparada" - "A cámara está preparada" - "Evento de sesión de chamada descoñecido" - "Servizo" - "Configuración" - "<Sen configurar>" - "Outras configuracións de chamada" - "Chamando a través de %s" - "Chamadas entrantes a través de %s" - "foto do contacto" - "activar o modo privado" - "seleccionar contacto" - "Escribe a túa propia..." - "Cancelar" - "Enviar" - "Responder" - "Enviar SMS" - "Rexeitar" - "Responde como videochamada" - "Responde como chamada de audio" - "Acepta a solicitude de vídeo" - "Rexeita a solicitude de vídeo" - "Acepta a solicitude de transmisión de vídeo" - "Rexeita a solicitude de transmisión de vídeo" - "Acepta a solicitude de recepción de vídeo" - "Rexeita a solicitude de recepción de vídeo" - "Pasa o dedo cara a arriba para %s." - "Pasa o dedo cara a esquerda para %s." - "Pasa o dedo cara a dereita para %s." - "Pasa o dedo cara a abaixo para %s." - "Vibrar" - "Vibrar" - "Son" - "Son predeterminado (%1$s)" - "Ton de chamada do teléfono" - "Vibrar ao soar" - "Ton de chamada e vibración" - "Xestionar conferencia telefónica" - "Número de emerxencia" - "Foto do perfil" - "A cámara está desactivada" - "a través do %s" - "Enviouse a nota" - "Mensaxes recentes" - "Información da empresa" - "A %.1f mi de distancia" - "A %.1f km de distancia" - "%1$s, %2$s" - "%1$s - %2$s" - "%1$s, %2$s" - "Abre mañá ás %s" - "Abre hoxe ás %s" - "Pecha ás %s" - "Pechou hoxe ás %s" - "Aberto agora" - "Pechado agora" - "Chamada sospeitosa" - "Finalizouse a chamada %1$s" - "É a primeira vez que te chama este número." - "Sospeitamos que esta chamada era un xerador de spam." - "Bloquear/marcar spam" - "Engadir contacto" - "Non é spam" - diff --git a/InCallUI/res/values-gu/strings.xml b/InCallUI/res/values-gu/strings.xml deleted file mode 100644 index 017ccb691..000000000 --- a/InCallUI/res/values-gu/strings.xml +++ /dev/null @@ -1,195 +0,0 @@ - - - - - "ફોન" - "હોલ્ડ પર" - "અજાણ્યો" - "ખાનગી નંબર" - "પેફોન" - "કોન્ફરન્સ કૉલ" - "કૉલ કપાઇ ગયો" - "સ્પીકર" - "હેન્ડસેટ ઇયરપીસ" - "વાયર્ડ હેડસેટ" - "Bluetooth" - "નીચે આપેલ ટોન્સ મોકલીએ?\n" - "ટોન્સ મોકલી રહ્યાં છે\n" - "મોકલો" - "હા" - "નહીં" - "વાઇલ્ડ અક્ષરને આની સાથે બદલો" - "કોન્ફરન્સ કૉલ %s" - "વૉઇસમેઇલ નંબર" - "ડાયલ કરી રહ્યાં છે" - "ફરી ડાયલ કરી રહ્યાં છે" - "કોન્ફરન્સ કૉલ" - "ઇનકમિંગ કૉલ" - "ઇનકમિંગ કાર્ય કૉલ" - "કૉલ સમાપ્ત થયો" - "હોલ્ડ પર" - "સમાપ્ત કરી રહ્યાં છે" - "કૉલમાં" - "મારો નંબર %s છે" - "વિડિઓ કનેક્ટ કરી રહ્યાં છે" - "વિડિઓ કૉલ" - "વિડિઓની વિનંતી કરી રહ્યાં છે" - "વિડિઓ કૉલ કનેક્ટ કરી શકાતો નથી" - "વિડિઓ વિનંતી નકારી" - "તમારો કૉલબેક નંબર\n %1$s" - "તમારો કટોકટીનો કૉલબેક નંબર\n %1$s" - "ડાયલ કરી રહ્યાં છે" - "છૂટેલો કૉલ" - "છૂટેલા કૉલ્સ" - "%s છૂટેલા કૉલ" - "%s નો કૉલ ચૂકી ગયાં" - "ચાલી રહેલ કૉલ" - "ચાલી રહેલ કાર્ય કૉલ" - "ચાલી રહેલ Wi-Fi કૉલ" - "ચાલી રહેલ Wi-Fi કાર્ય કૉલ" - "હોલ્ડ પર" - "ઇનકમિંગ કૉલ" - "ઇનકમિંગ કાર્ય કૉલ" - "ઇનકમિંગ Wi-Fi કૉલ" - "ઇનકમિંગ Wi-Fi કાર્ય કૉલ" - "ઇનકમિંગ વિડિઓ કૉલ" - "ઇનકમિંગ શંકાસ્પદ સ્પામ કૉલ" - "ઇનકમિંગ વિડિઓ વિનંતી" - "નવો વૉઇસમેઇલ" - "નવો વૉઇસમેઇલ (%d)" - "%s ડાયલ કરો" - "વૉઇસમેઇલ નંબર અજાણ" - "કોઈ સેવા નથી" - "પસંદ કરેલ નેટવર્ક (%s) અનુપલબ્ધ" - "જવાબ" - "સમાપ્ત કરો" - "વિડિઓ" - "વૉઇસ" - "સ્વીકારો" - "છોડી દો" - "કૉલ બૅક કરો" - "સંદેશ" - "અન્ય ઉપકરણ પર ચાલી રહેલ કૉલ" - "કૉલ સ્થાનાંતરિત કરો" - "કૉલ કરવા માટે, પહેલા એરપ્લેન મોડને બંધ કરો." - "નેટવર્ક પર નોંધણી કરાયેલ નથી." - "સેલ્યુલર નેટવર્ક ઉપલબ્ધ નથી." - "કૉલ કરવા માટે, માન્ય નંબર દાખલ કરો." - "કૉલ કરી શકાતો નથી." - "MMI અનુક્રમ પ્રારંભ કરી રહ્યાં છે…" - "સેવા સમર્થિત નથી." - "કૉલ્સ સ્વિચ કરી શકાતાં નથી." - "અલગ કૉલ કરી શકાતો નથી." - "ટ્રાંસ્ફર કરી શકાતો નથી." - "કોન્ફરન્સ કરી શકાતી નથી." - "કૉલ નકારી શકાતો નથી." - "કૉલ(કૉલ્સ) રિલીઝ કરી શકતાં નથી." - "SIP કૉલ" - "કટોકટીનો કૉલ" - "રેડિઓ ચાલુ કરી રહ્યાં છે…" - "કોઈ સેવા નથી. ફરી પ્રયાસ કરી રહ્યાં છે…" - "કૉલ કરી શકાતો નથી. %s એ કટોકટીનો નંબર નથી." - "કૉલ કરી શકાતો નથી. કટોકટીનો નંબર ડાયલ કરો." - "ડાયલ કરવા માટે કીબોર્ડનો ઉપયોગ કરો" - "કૉલ હોલ્ડ કરો" - "કૉલ ફરી શરૂ કરો" - "કૉલ સમાપ્ત કરો" - "ડાયલપેડ બતાવો" - "ડાયલપેડ છુપાવો" - "મ્યૂટ કરો" - "અનમ્યૂટ કરો" - "કૉલ ઉમેરો" - "કૉલ્સ મર્જ કરો" - "સ્વેપ કરો" - "કૉલ્સ સંચાલિત કરો" - "કોન્ફરન્સ કૉલ સંચાલિત કરો" - "કોન્ફરન્સ કૉલ" - "સંચાલિત કરો" - "ઑડિઓ" - "વિડિઓ કૉલ" - "વૉઇસ કૉલ પર બદલો" - "કૅમેરા પર સ્વિચ કરો" - "કૅમેરો ચાલુ કરો" - "કૅમેરો બંધ કરો" - "વધુ વિકલ્પો" - "પ્લેયર પ્રારંભ કર્યું" - "પ્લેયર બંધ કર્યું" - "કૅમેરો તૈયાર નથી" - "કૅમેરો તૈયાર" - "અજાણી કૉલ સત્ર ઇવેન્ટ" - "સેવા" - "સેટઅપ" - "<સેટ કરેલ નથી>" - "અન્ય કૉલ સેટિંગ્સ" - "%s મારફતે કૉલ કરે છે" - "%s મારફતે ઇનકમિંગ" - "સંપર્ક ફોટો" - "ખાનગી થાઓ" - "સંપર્ક પસંદ કરો" - "તમારો પોતાનો લખો…" - "રદ કરો" - "મોકલો" - "જવાબ" - "SMS મોકલો" - "નકારો" - "વિડિઓ કૉલ તરીકે જવાબ આપો" - "ઑડિઓ કૉલ તરીકે જવાબ આપો" - "વિડિઓ વિનંતી સ્વીકારો" - "વિડિઓ વિનંતી નકારો" - "વિડિઓ ટ્રાંસ્મિટ વિનંતી સ્વીકારો" - "વિડિઓ ટ્રાંસ્મિટ વિનંતી નકારો" - "વિડિઓ પ્રાપ્તિ વિનંતી સ્વીકારો" - "વિડિઓ પ્રાપ્તિ વિનંતી નકારો" - "%s માટે ઉપર સ્લાઇડ કરો." - "%s માટે ડાબે સ્લાઇડ કરો." - "%s માટે જમણે સ્લાઇડ કરો." - "%s માટે નીચે સ્લાઇડ કરો." - "વાઇબ્રેટ" - "વાઇબ્રેટ" - "ધ્વનિ" - "ડિફોલ્ટ ધ્વનિ (%1$s)" - "ફોન રિંગટોન" - "જ્યારે રિંગ કરે ત્યારે વાઇબ્રેટ કરો" - "રિંગટોન અને વાઇબ્રેટ" - "કોન્ફરન્સ કૉલ સંચાલિત કરો" - "કટોકટીનો નંબર" - "પ્રોફાઇલ ફોટો" - "કૅમેરો બંધ" - "%s મારફતે" - "નોંધ મોકલી" - "તાજેતરનાં સંદેશા" - "વ્યવસાયની માહિતી" - "%.1f માઇલ દૂર" - "%.1f કિમી દૂર" - "%1$s, %2$s" - "%1$s - %2$s" - "%1$s, %2$s" - "આવતીકાલે %s વાગ્યે ખુલશે" - "આજે %s વાગ્યે ખુલશે" - "%s વાગ્યે બંધ થશે" - "આજે %s વાગ્યે બંધ થયેલું" - "હમણાં ખુલ્લું" - "હમણાં બંધ છે" - "શંકાસ્પદ સ્પામ કૉલર" - "%1$s નો કૉલ સમાપ્ત થયો" - "આ નંબરથી તમને પહેલી વાર કૉલ કરવામાં આવ્યો છે." - "આ કૉલ કોઈ સ્પામર હોવાની અમને શંકા છે." - "સ્પામની જાણ/અવરોધિત કરો" - "સંપર્ક ઉમેરો" - "સ્પામ નથી" - diff --git a/InCallUI/res/values-h400dp/dimens.xml b/InCallUI/res/values-h400dp/dimens.xml deleted file mode 100644 index dda755a3e..000000000 --- a/InCallUI/res/values-h400dp/dimens.xml +++ /dev/null @@ -1,31 +0,0 @@ - - - - - - true - - 90dp - - 15dp - - -24dp - - 2dp - - 20dp - diff --git a/InCallUI/res/values-hi/strings.xml b/InCallUI/res/values-hi/strings.xml deleted file mode 100644 index dee8f464d..000000000 --- a/InCallUI/res/values-hi/strings.xml +++ /dev/null @@ -1,195 +0,0 @@ - - - - - "फ़ोन" - "होल्ड पर" - "अज्ञात" - "निजी नंबर" - "पे-फ़ोन" - "कॉन्फ़्रेंस कॉल" - "कॉल कट गया" - "स्पीकर" - "हैंडसेट इयरपीस" - "वायर वाला हैडसेट" - "ब्लूटूथ" - "निम्न टोन भेजें?\n" - "भेजने वाली टोन\n" - "भेजें" - "हां" - "नहीं" - "वाइल्ड वर्ण को इससे बदलें:" - "कॉन्फ़्रेंस कॉल %s" - "वॉइसमेल नबंर" - "डायल किया जा रहा है" - "पुन: डायल हो रहा है" - "कॉन्फ़्रेंस कॉल" - "इनकमिंग कॉल" - "कार्यस्थल का इनकमिंग कॉल" - "कॉल समाप्त" - "होल्ड पर" - "कॉल समाप्त हो रहा है" - "कॉल में" - "मेरा नंबर %s है" - "वीडियो कनेक्ट हो रहा है" - "वीडियो कॉल" - "वीडियो का अनुरोध किया जा रहा है" - "वीडियो कॉल कनेक्ट नहीं किया जा सकता" - "वीडियो अनुरोध अस्वीकार किया गया" - "आपका कॉलबैक नंबर\n %1$s" - "आपका आपातकालीन कॉलबैक नंबर\n %1$s" - "डायल किया जा रहा है" - "छूटा कॉल" - "छूटे कॉल" - "%s छूटे कॉल" - "%s के छूटे कॉल" - "चल रहा कॉल" - "कार्यस्थल का जारी कॉल" - "चल रहा वाई-फ़ाई कॉल" - "कार्यस्थल का जारी वाई-फ़ाई कॉल" - "होल्ड पर" - "इनकमिंग कॉल" - "कार्यस्थल का इनकमिंग कॉल" - "इनकमिंग वाई-फ़ाई कॉल" - "कार्यस्थल का वाई-फ़ाई इनकमिंग कॉल" - "इनकमिंग वीडियो कॉल" - "संदिग्ध आवक स्पैम कॉल" - "इनकमिंग वीडियो अनुरोध" - "नया वॉइसमेल" - "नया वॉइसमेल (%d)" - "%s डायल करें" - "वॉइसमेल नंबर अज्ञात" - "कोई सेवा नहीं" - "चयनित नेटवर्क (%s) अनुपलब्ध" - "उत्तर दें" - "समाप्त करें" - "वीडियो" - "ध्वनि" - "स्वीकार करें" - "ख़ारिज करें" - "कॉल बैक करें" - "संदेश" - "दूसरे डिवाइस पर चल रहा कॉल" - "कॉल स्थानान्तरित करें" - "कॉल करने के लिए, पहले हवाई जहाज़ मोड बंद करें." - "नेटवर्क पर पंजीकृत नहीं." - "सेल्युलर नेटवर्क उपलब्ध नहीं." - "कॉल करने के लिए, मान्य नंबर डालें." - "कॉल नहीं किया जा सकता." - "MMI अनुक्रम प्रारंभ हो रहा है…" - "सेवा समर्थित नहीं है." - "कॉल स्विच नहीं किए जा सकते." - "कॉल अलग नहीं किया जा सकता." - "स्थानान्तरित नहीं किया जा सकता." - "कॉन्फ़्रेंस नहीं की जा सकती." - "कॉल अस्वीकार नहीं किया जा सकता." - "कॉल रिलीज़ नहीं किया जा सकता (किए जा सकते)." - "SIP कॉल" - "आपातकालीन कॉल" - "रेडियो चालू कर रहा है..." - "कोई सेवा नहीं. पुन: प्रयास किया जा रहा है…" - "कॉल नहीं किया जा सकता. %s एक आपातकालीन नंबर नहीं है." - "कॉल नहीं किया जा सकता. आपातकालीन नबर डायल करें." - "डायल करने के लिए कीबोर्ड का उपयोग करें" - "कॉल होल्ड करें" - "कॉल फिर से शुरू करें" - "कॉल समाप्त करें" - "डायलपैड दिखाएं" - "डायलपैड छिपाएं" - "म्यूट करें" - "अनम्यूट करें" - "कॉल जोड़ें" - "कॉल मर्ज करें" - "स्वैप करें" - "कॉल प्रबंधित करें" - "कॉन्फ़्रेंस कॉल प्रबंधित करें" - "कॉन्फ़्रेंस कॉल" - "प्रबंधित करें" - "ऑडियो" - "वीडियो कॉल" - "वॉइस कॉल में बदलें" - "कैमरा स्विच करें" - "कैमरा चालू करें" - "कैमरा बंद करें" - "अधिक विकल्प" - "प्लेयर प्रारंभ हो गया" - "प्लेयर रुक गया" - "कैमरा तैयार नहीं है" - "कैमरा तैयार है" - "अज्ञात कॉल सत्र इवेंट" - "सेवा" - "सेटअप" - "<सेट नहीं है>" - "अन्य कॉल सेटिंग" - "%s के माध्यम से कॉल किया जा रहा है" - "%s की ओर से इनकमिंग" - "संपर्क का फ़ोटो" - "निजी हो जाएं" - "संपर्क को चुनें" - "अपना स्वयं का लिखें..." - "अभी नहीं" - "भेजें" - "उत्तर दें" - "SMS भेजें" - "अस्वीकार करें" - "वीडियो कॉल के रूप में उत्तर दें" - "ऑडियो कॉल के रूप में उत्तर दें" - "वीडियो अनुरोध स्वीकार करें" - "वीडियो अनुरोध अस्वीकार करें" - "वीडियो प्रसारण अनुरोध स्वीकार करें" - "वीडियो प्रसारण अनुरोध अस्वीकार करें" - "वीडियो प्राप्ति अनुरोध स्वीकार करें" - "वीडियो प्राप्ति अनुरोध अस्वीकार करें" - "%s करने के लिए ऊपर स्लाइड करें." - "%s करने के लिए बाएं स्लाइड करें." - "%s करने के लिए दाएं स्लाइड करें." - "%s करने के लिए नीचे स्लाइड करें." - "कंपन" - "कंपन" - "ध्वनि" - "डिफ़ॉल्ट ध्वनि (%1$s)" - "फ़ोन रिंगटोन" - "रिंग आने पर कंपन करें" - "रिंगटोन और कंपन" - "कॉन्फ़्रेंस कॉल प्रबंधित करें" - "आपातकालीन नंबर" - "प्रोफ़ाइल फ़ोटो" - "कैमरा बंद है" - "%s के द्वारा" - "नोट भेज दिया गया है" - "हाल ही के संदेश" - "व्यवसाय जानकारी" - "%.1f मील दूर" - "%.1f किमी दूर" - "%1$s, %2$s" - "%1$s - %2$s" - "%1$s, %2$s" - "कल %s बजे खुलेगा" - "आज %s बजे खुलता है" - "%s बजे बंद होता है" - "आज %s बजे बंद हो गया" - "अभी खुला है" - "अभी बंद है" - "संदिग्ध स्पैम कॉलर" - "%1$s का कॉल समाप्त हो गया" - "इस नंबर से आपको पहली बार कॉल किया गया है." - "हमें आशंका है कि कॉल स्पैमकर्ता का हो सकता है." - "अवरुद्ध करें/स्पैम रिपोर्ट करें" - "संपर्क जोड़ें" - "स्पैम नहीं है" - diff --git a/InCallUI/res/values-hr/strings.xml b/InCallUI/res/values-hr/strings.xml deleted file mode 100644 index 9c11644c4..000000000 --- a/InCallUI/res/values-hr/strings.xml +++ /dev/null @@ -1,195 +0,0 @@ - - - - - "Telefon" - "Na čekanju" - "Nepoznato" - "Privatni broj" - "Javna telefonska govornica" - "Konferencijski poziv" - "Poziv je prekinut" - "Zvučnik" - "Slušalice" - "Žičane slušalice" - "Bluetooth" - "Poslati sljedeće tonove?\n" - "Slanje tonova\n" - "Pošalji" - "Da" - "Ne" - "Zamijeni zamjenski znak znakom" - "Konferencijski poziv %s" - "Broj govorne pošte" - "Biranje broja" - "Ponovno biranje" - "Konferencijski poziv" - "Dolazni poziv" - "Dolazni poslovni poziv" - "Poziv je završio" - "Na čekanju" - "Prekidanje veze" - "Poziv u tijeku" - "Moj je broj %s" - "Uspostavljanje videopoziva" - "Videopoziv" - "Zahtijevanje videopoziva" - "Videopoziv nije uspostavljen" - "Zahtjev za videopoziv odbijen" - "Vaš broj za povratni poziv\n %1$s" - "Vaš broj za povratni poziv za hitne službe\n %1$s" - "Biranje broja" - "Propušteni poziv" - "Propušteni pozivi" - "Propušteni pozivi (%s)" - "Propušten poziv kontakta %s" - "Poziv u tijeku" - "Poslovni poziv u tijeku" - "Wi-Fi poziv u tijeku" - "Poslovni Wi-Fi poziv u tijeku" - "Na čekanju" - "Dolazni poziv" - "Dolazni poslovni poziv" - "Dolazni Wi-Fi poziv" - "Dolazni poslovni Wi-Fi poziv" - "Dolazni videopoziv" - "Mogući neželjeni dolazni poziv" - "Dolazni zahtjev za videopoziv" - "Nova govorna pošta" - "Nova govorna pošta (%d)" - "Biraj %s" - "Nepoznat broj govorne pošte" - "Nema usluge" - "Odabrana mreža (%s) nije dostupna" - "Odgovori" - "Prekini vezu" - "Videopoziv" - "Glasovni poziv" - "Prihvati" - "Odbaci" - "Uzvrati" - "Poruka" - "Poziv u tijeku na drugom uređaju" - "Prijenos poziva" - "Da biste uspostavili poziv, isključite način rada u zrakoplovu." - "Nije registrirano na mreži." - "Mobilna mreža nije dostupna." - "Unesite važeći broj da biste uspostavili poziv." - "Pozivanje nije moguće." - "Pokretanje MMI sekvence…" - "Usluga nije podržana." - "Prebacivanje poziva nije moguće." - "Odvajanje poziva nije moguće." - "Prijenos nije moguć." - "Konferencijski poziv nije moguć." - "Odbijanje poziva nije moguće." - "Prekidanje poziva nije moguće." - "SIP poziv" - "Hitni poziv" - "Uključivanje radija…" - "Nema usluge. Pokušavamo ponovo…" - "Pozivanje nije moguće. %s nije broj hitne službe." - "Pozivanje nije moguće. Nazovite broj hitne službe." - "Upotrijebite tipkovnicu" - "Stavi poziv na čekanje" - "Nastavi poziv" - "Završi poziv" - "Prikaži površinu za biranje brojeva" - "Sakrij površinu za biranje brojeva" - "Zanemari" - "Prestani zanemarivati" - "Dodaj poziv" - "Spoji pozive" - "Zamijeni" - "Upravljaj pozivima" - "Upravljaj konf. pozivom" - "Konferencijski poziv" - "Upravljanje" - "Audio" - "Videopoziv" - "Prijeđi na glasovni poziv" - "Promijeni kameru" - "Uključivanje kamere" - "Isključivanje kamere" - "Više opcija" - "Player je pokrenut" - "Player je prekinut" - "Fotoaparat nije spreman" - "Fotoaparat je spreman" - "Nepoznati događaj sesije poziva" - "Usluga" - "Postavljanje" - "<Nije postavljeno>" - "Ostale postavke poziva" - "Pozivanje putem operatera %s" - "Dolazni pozivi putem usluge %s" - "fotografija kontakta" - "uputi na privatno" - "odabir kontakta" - "Napišite odgovor..." - "Odustani" - "Pošalji" - "Odgovori" - "Pošalji SMS" - "Odbij" - "Prihvati kao videopoziv" - "Prihvati kao audiopoziv" - "Prihvati zahtjev za videopoziv" - "Odbij zahtjev za videopoziv" - "Prihvati zahtjev za slanje videopoziva" - "Odbij zahtjev za slanje videopoziva" - "Prihvati zahtjev za primanje videopoziva" - "Odbij zahtjev za primanje videopoziva" - "Kliznite prema gore za %s." - "Kliznite lijevo za %s." - "Kliznite desno za %s." - "Kliznite prema dolje za %s." - "Vibriranje" - "Vibriranje" - "Zvuk" - "Zadani zvuk (%1$s)" - "Melodija zvona telefona" - "Vibracija tijekom zvonjenja" - "Melodija zvona i vibracija" - "Upravljaj konferencijskim pozivom" - "Broj hitne službe" - "Fotografija profila" - "Fotoaparat je isključen" - "putem broja %s" - "Bilješka je poslana" - "Nedavne poruke" - "Informacije o tvrtki" - "%.1f mi udaljenosti" - "%.1f km udaljenosti" - "%1$s, %2$s" - "%1$s%2$s" - "%1$s, %2$s" - "Otvara se sutra u %s" - "Otvara se danas u %s" - "Zatvara se u %s" - "Zatvoreno danas u %s" - "Trenutačno otvoreno" - "Trenutačno zatvoreno" - "Neželjeni pozivatelj" - "Poziv je završio %1$s" - "Prvi ste put primili poziv s tog broja." - "Sumnjamo da vas zove pošiljatelj neželjenih sadržaja." - "Blokiranje/prijava neželjenog broja" - "Dodavanje kontakta" - "Nije neželjeni broj" - diff --git a/InCallUI/res/values-hu/strings.xml b/InCallUI/res/values-hu/strings.xml deleted file mode 100644 index 816942601..000000000 --- a/InCallUI/res/values-hu/strings.xml +++ /dev/null @@ -1,195 +0,0 @@ - - - - - "Telefon" - "Tartásban" - "Ismeretlen" - "Magántelefonszám" - "Nyilvános telefon" - "Konferenciahívás" - "A hívás megszakadt" - "Hangszóró" - "Kézibeszélő fülhallgatója" - "Vezetékes fülhallgató" - "Bluetooth" - "Elküldi a következő hangjelzéseket?\n" - "Hangjelzések küldése\n" - "Küldés" - "Igen" - "Nem" - "Helyettesítő karakter lecserélése a következőre:" - "Konferenciahívás – %s" - "Hangposta száma" - "Tárcsázás" - "Újratárcsázás" - "Konferenciahívás" - "Bejövő hívás" - "Bejövő munkahelyi hívás" - "A hívás befejeződött" - "Tartásban" - "Megszakítás" - "Hívásban" - "A számom: %s" - "Videókapcsolat létrehozása" - "Videóhívás" - "Videóhívást kér" - "A videóhívás létesítése sikertelen" - "Videókérelem elutasítva" - "Visszahívható telefonszáma:\n %1$s" - "Vészhelyzet esetén visszahívható telefonszáma:\n %1$s" - "Tárcsázás" - "Nem fogadott hívás" - "Nem fogadott hívások" - "%s nem fogadott hívás" - "Nem fogadott hívás: %s" - "Hívás folyamatban" - "Folyamatban lévő munkahelyi hívás" - "Folyamatban lévő Wi-Fi-hívás" - "Folyamatban lévő munkahelyi hívás Wi-Fi-hálózaton keresztül" - "Tartásban" - "Bejövő hívás" - "Bejövő munkahelyi hívás" - "Bejövő Wi-Fi-hívás" - "Bejövő munkahelyi hívás Wi-Fi-hálózaton keresztül" - "Bejövő videóhívás" - "Bejövő gyanús spamhívás" - "Bejövő videókérés" - "Új hangpostaüzenet" - "Új hangpostaüzenet (%d)" - "%s tárcsázása" - "A hangposta száma ismeretlen" - "Nincs szolgáltatás" - "A kiválasztott hálózat (%s) nem áll rendelkezésre" - "Fogadás" - "Hívás bontása" - "Videó" - "Hang" - "Elfogadás" - "Elvetés" - "Visszahívás" - "Üzenet" - "Folyamatban lévő hívás egy másik eszközön" - "Hívásátirányítás" - "Hívásindításhoz kapcsolja ki a Repülős üzemmódot." - "Nincs regisztrálva a hálózaton." - "A mobilhálózat nem áll rendelkezésre." - "Hívásindításhoz adjon meg egy érvényes számot." - "A hívás sikertelen." - "MMI-sorozat indítása…" - "A szolgáltatás nem támogatott." - "A hívások közötti váltás sikertelen." - "A híváselkülönítés sikertelen." - "Az átirányítás sikertelen." - "A konferenciahívás sikertelen." - "A híváselutasítás sikertelen." - "A tartásban lévő hívás(ok) folytatása sikertelen." - "SIP-hívás" - "Segélyhívás" - "Rádió bekapcsolása…" - "Nincs szolgáltatás. Újrapróbálkozás folyamatban…" - "A hívás sikertelen. A(z) %s szám nem segélyhívószám." - "A hívás sikertelen. Tárcsázzon segélyhívószámot." - "A tárcsázáshoz használja a billentyűzetet" - "Hívás tartása" - "Hívás folytatása" - "Hívás befejezése" - "Tárcsázó megjelenítése" - "Tárcsázó elrejtése" - "Némítás" - "Némítás feloldása" - "Hívás hozzáadása" - "Hívások egyesítése" - "Csere" - "Hívások kezelése" - "Konferenciahívás kezelése" - "Konferenciahívás" - "Kezelés" - "Hang" - "Videóhívás" - "Váltás hanghívásra" - "Váltás a kamerák között" - "Kamera bekapcsolása" - "Kamera kikapcsolása" - "További lehetőségek" - "A lejátszó elindult" - "A lejátszó leállt" - "A kamera nem áll készen" - "A kamera készen áll" - "Ismeretlen hívási esemény" - "Szolgáltatás" - "Beállítás" - "<Nincs megadva>" - "Egyéb hívásbeállítások" - "Hívás a(z) %s szolgáltatón keresztül" - "Bejövő hívás a következőn keresztül: %s" - "fotó a névjegyhez" - "magánbeszélgetés" - "névjegy kiválasztása" - "Saját válasz írása…" - "Mégse" - "Küldés" - "Fogadás" - "SMS küldése" - "Elutasítás" - "Fogadás videóhívásként" - "Fogadás hanghívásként" - "Videó kérésének elfogadása" - "Videó kérésének elutasítása" - "Videóküldési kérés elfogadása" - "Videóküldési kérés elutasítása" - "Videófogadási kérés elfogadása" - "Videófogadási kérés elutasítása" - "A(z) %s művelethez csúsztassa felfelé." - "A(z) %s művelethez csúsztassa balra." - "A(z) %s művelethez csúsztassa jobbra." - "A(z) %s művelethez csúsztassa lefelé." - "Rezgés" - "Rezgés" - "Hang" - "Alapértelmezett hang (%1$s)" - "Telefon csengőhangja" - "Csörgéskor rezegjen" - "Csengőhang és rezgés" - "Konferenciahívás kezelése" - "Segélyhívó szám" - "Profilfotó" - "Kamera ki" - "a következő számon keresztül: %s" - "Üzenet elküldve" - "Legutóbbi üzenetek" - "Cég adatai" - "%.1f mérföldre" - "%.1f kilométerre" - "%2$s, %1$s" - "%1$s%2$s" - "%1$s, %2$s" - "Holnap ekkor nyit: %s" - "Ma ekkor nyit: %s" - "Ekkor zár: %s" - "Ma ekkor zárt: %s" - "Jelenleg nyitva van" - "Jelenleg zárva van" - "Gyanús spamhívó" - "Hívás befejezve: %1$s" - "Ez az első alkalom, hogy erről a számról hívása érkezett." - "Azt gyanítjuk, hogy ez egy spamhívás." - "Letiltás/spam bejel." - "Névjegy hozzáadása" - "Nem spam" - diff --git a/InCallUI/res/values-hy/strings.xml b/InCallUI/res/values-hy/strings.xml deleted file mode 100644 index 899262432..000000000 --- a/InCallUI/res/values-hy/strings.xml +++ /dev/null @@ -1,195 +0,0 @@ - - - - - "Հեռախոս" - "Սպասում" - "Անհայտ" - "Գաղտնի համար" - "Հանրային հեռախոս" - "Կոնֆերանս զանգ" - "Զանգն ընդհատվեց" - "Բարձրախոս" - "Հեռախոսի ականջակալ" - "Լարային ականջակալ" - "Bluetooth" - "Ուղարկե՞լ հետևյալ ձայներանգները:\n" - "Ձայներանգների ուղարկում\n" - "Ուղարկել" - "Այո" - "Ոչ" - "Փոխարինել կոպիտ գրանշանը" - "Կոնֆերանս զանգ %s" - "Ձայնային փոստի համարը" - "Համարը հավաքվում է" - "Վերահամարարկում" - "Կոնֆերանս զանգ" - "Մուտքային զանգ" - "Մուտքային աշխատանքային զանգ" - "Զանգն ավարտվեց" - "Սպասում" - "Անջատում" - "Զանգը միացված է" - "Իմ համարը՝ %s" - "Տեսակապը միանում է" - "Տեսազանգ" - "Տեսակապի հայցում" - "Հնարավոր չէ միացնել տեսազանգը" - "Տեսազանգի հարցումը մերժվել է" - "Հետադարձ զանգի համարը՝\n%1$s" - "Արտակարգ իրավիճակների հետադարձ զանգի համարը՝\n%1$s" - "Համարը հավաքվում է" - "Բաց թողնված զանգ" - "Բաց թողնված զանգեր" - "%s բաց թողնված զանգ" - "Բաց թողնված զանգ %s-ից" - "Ընթացիկ զանգ" - "Ընթացիկ աշխատանքային զանգ" - "Ընթացիկ Wi-Fi զանգ" - "Ընթացիկ աշխատանքային Wi-Fi զանգ" - "Սպասում" - "Մուտքային զանգ" - "Մուտքային աշխատանքային զանգ" - "Մուտքային Wi-Fi զանգ" - "Մուտքային աշխատանքային Wi-Fi զանգ" - "Մուտքային տեսազանգ" - "Մուտքային զանգը հավանաբար լցոն է" - "Մուտքային տեսազանգի հայցում" - "Նոր ձայնային հաղորդագրություն" - "Նոր ձայնային հաղորդագրություն (%d)" - "Զանգել %s համարին" - "Ձայնային փոստի համարն անհայտ է" - "Ծառայություն չկա" - "Ընտրված ցանցը (%s) անհասանելի է" - "Պատասխանել" - "Անջատել" - "Տեսազանգ" - "Ձայնային" - "Ընդունել" - "Մերժել" - "Հետ զանգել" - "Հաղորդագրություն" - "Ընթացիկ զանգ այլ սարքում" - "Փոխանցել զանգը" - "Զանգ կատարելու համար նախ անջատեք Ինքնաթիռի ռեժիմը:" - "Ցանցում գրանցված չէ:" - "Բջջային ցանցն անհասանելի է:" - "Զանգ կատարելու համար մուտքագրեք ճիշտ համար:" - "Հնարավոր չէ զանգել:" - "Մեկնարկում է MMI հաջորդականությունը…" - "Ծառայությունը չի աջակցվում:" - "Հնարավոր չէ փոխարկել զանգերը:" - "Հնարավոր չէ առանձնացնել զանգը:" - "Հնարավոր չէ փոխանցել:" - "Հնարավոր չէ կոնֆերանս զանգ կատարել:" - "Հնարավոր չէ մերժել զանգը:" - "Հնարավոր չէ անջատել զանգ(եր)ը:" - "SIP զանգ" - "Շտապ կանչ" - "Ռադիոն միացվում է…" - "Ծառայությունը մատչելի չէ: Փորձը կրկնվում է…" - "Հնարավոր չէ զանգել: %s համարը արտակարգ իրավիճակի համար չէ:" - "Հնարավոր չէ զանգել: Հավաքեք արտակարգ իրավիճակի որևէ համար:" - "Օգտագործել ստեղնաշարը համար հավաքելու համար" - "Հետաձգել զանգը" - "Վերսկսել զանգը" - "Ավարտել զանգը" - "Ցուցադրել թվաշարը" - "Թաքցնել թվաշարը" - "Անջատել ձայնը" - "Չանտեսել" - "Ավելացնել զանգ" - "Միացնել զանգերը" - "Փոխանակել" - "Կառավարել զանգերը" - "Կառավարել կոնֆերանս զանգը" - "Կոնֆերանս զանգ" - "Կառավարել" - "Ձայնային" - "Տեսազանգ" - "Փոխարկել ձայնային կանչի" - "Փոխարկել խցիկը" - "Միացնել տեսախցիկը" - "Անջատել տեսախցիկը" - "Այլ ընտրանքներ" - "Նվագարկիչը մեկնարկել է" - "Նվագարկիչը դադարեցվել է" - "Տեսախցիկը պատրաստ չէ" - "Տեսախցիկը պատրաստ է" - "Զանգի աշխատաշրջանի անհայտ իրադարձություն" - "Ծառայություն" - "Կարգավորում" - "<Կարգավորված չէ>" - "Զանգերի այլ կարգավորումներ" - "Զանգում է %s-ի միջոցով" - "Մուտքային զանգ %s-ի միջոցով" - "կոնտակտի լուսանկարը" - "անցնել անձնականի" - "ընտրել կոնտակտ" - "Գրեք ձեր սեփականը…" - "Չեղարկել" - "Ուղարկել" - "Պատասխանել" - "Ուղարկել SMS" - "Մերժել" - "Պատասխանել տեսազանգով" - "Պատասխանել ձայնային զանգով" - "Ընդունել տեսազանգի հարցումը" - "Մերժել տեսազանգի հարցումը" - "Ընդունել տեսափոխանցման հարցումը" - "Մերժել տեսափոխանցման հարցումը" - "Ընդունել տեսազանգ ստանալու հարցումը" - "Մերժել տեսազանգ ստանալու հարցումը" - "Սահեցրեք վերև` %s գործառույթի համար:" - "Սահեցրեք ձախ` %s գործառույթի համար:" - "Սահեցրեք աջ` %s գործառույթի համար:" - "Սահեցրեք ցած՝ %s գործառույթի համար:" - "Թրթռոց" - "Թրթռոց" - "Ձայն" - "Կանխադրված ձայնը (%1$s)" - "Հեռախոսի զանգերանգ" - "Թրթռալ զանգի ժամանակ" - "Ձայներանգ և թրթռոց" - "Կառավարել կոնֆերանս զանգը" - "Արտակարգ իրավիճակի համար" - "Պրոֆիլի լուսանկար" - "Տեսախցիկն անջատված" - "%s-ի միջոցով" - "Գրառումն ուղարկվեց" - "Վերջին հաղորդագրությունները" - "Բիզնես տեղեկատվություն" - "%.1f մղոն հեռու" - "%.1f կմ հեռու" - "%1$s, %2$s" - "%1$s%2$s" - "%1$s, %2$s" - "Բացվում է վաղը ժամը %s-ին" - "Բացվում է այսօր ժամը %s-ին" - "Փակվում է ժամը %s-ին" - "Փակվել է այսօր ժամը %s-ին" - "Հիմա բաց է" - "Հիմա փակ է" - "Հավանաբար լցոն է" - "Զանգն ավարտվեց %1$s" - "Այս համարից առաջին անգամ եք զանգ ստանում:" - "Կասկածներ կային, որ այս զանգը լցոնողից է:" - "Արգելափակել/Նշել լցոն" - "Ավելացնել կոնտակտ" - "Լցոն չէ" - diff --git a/InCallUI/res/values-in/strings.xml b/InCallUI/res/values-in/strings.xml deleted file mode 100644 index a2cd31dc7..000000000 --- a/InCallUI/res/values-in/strings.xml +++ /dev/null @@ -1,195 +0,0 @@ - - - - - "Telepon" - "Ditahan" - "Tidak dikenal" - "Nomor pribadi" - "Telepon Umum" - "Telewicara" - "Panggilan terputus" - "Pengeras suara" - "Earpiece handset" - "Headset berkabel" - "Bluetooth" - "Kirim nada berikut?\n" - "Mengirim nada\n" - "Kirim" - "Ya" - "Tidak" - "Ganti karakter acak dengan" - "Telewicara %s" - "Nomor pesan suara" - "Memanggil" - "Memanggil ulang" - "Telewicara" - "Panggilan masuk" - "Panggilan masuk di telepon kerja" - "Panggilan diakhiri" - "Ditahan" - "Menutup panggilan" - "Sedang dalam panggilan" - "Nomor saya %s" - "Menyambungkan video" - "Video call" - "Meminta video" - "Tidak dapat menyambungkan video call" - "Permintaan video ditolak" - "Nomor panggilan balik Anda\n %1$s" - "Nomor panggilan balik darurat Anda\n %1$s" - "Memanggil" - "Panggilan tak terjawab" - "Panggilan tak terjawab" - "%s panggilan tak terjawab" - "Panggilan tak terjawab dari %s" - "Panggilan yang berlangsung" - "Panggilan telepon kerja yang sedang berlangsung" - "Panggilan Wi-Fi keluar" - "Panggilan Wi-Fi kerja yang sedang berlangsung" - "Ditahan" - "Panggilan masuk" - "Panggilan masuk di telepon kerja" - "Panggilan Wi-Fi masuk" - "Panggilan Wi-Fi masuk di telepon kerja" - "Video call masuk" - "Panggilan masuk yang diduga spam" - "Permintaan video masuk" - "Pesan suara baru" - "Pesan suara baru (%d)" - "Telepon %s" - "Nomor pesan suara tidak dikenal" - "Tidak ada layanan" - "Jaringan yang dipilih (%s) tidak tersedia" - "Jawab" - "Akhiri" - "Video" - "Suara" - "Terima" - "Tutup" - "Telepon balik" - "Pesan" - "Panggilan yang berlangsung di perangkat lain" - "Transfer Panggilan" - "Untuk melakukan panggilan, terlebih dahulu nonaktifkan mode Pesawat." - "Tidak terdaftar pada jaringan." - "Jaringan seluler tidak tersedia." - "Untuk melakukan panggilan telepon, masukkan nomor yang valid." - "Tidak dapat menelepon." - "Memulai urutan MMI..." - "Layanan tidak didukung." - "Tidak dapat beralih panggilan." - "Tidak dapat memisahkan panggilan." - "Tidak dapat mentransfer." - "Tidak dapat melakukan telewicara." - "Tidak dapat menolak panggilan." - "Tidak dapat melepas panggilan." - "Panggilan SIP" - "Panggilan darurat" - "Menghidupkan radio..." - "Tidak ada layanan. Mencoba lagi…" - "Tidak dapat menelepon. %s bukan nomor darurat." - "Tidak dapat menelepon. Panggil nomor darurat." - "Gunakan keyboard untuk memanggil" - "Tahan Panggilan" - "Mulai Kembali Panggilan" - "Akhiri Panggilan" - "Tampilkan tombol nomor" - "Sembunyikan tombol nomor" - "Bisukan" - "Suarakan" - "Tambahkan panggilan" - "Gabungkan panggilan" - "Tukar" - "Kelola panggilan" - "Kelola telewicara" - "Konferensi telepon" - "Kelola" - "Audio" - "Video call" - "Ubah ke panggilan suara" - "Beralih kamera" - "Nyalakan kamera" - "Matikan kamera" - "Opsi lainnya" - "Pemutar Dimulai" - "Pemutar Dihentikan" - "Kamera tidak siap" - "Kamera siap" - "Sesi panggilan tidak dikenal" - "Layanan" - "Siapkan" - "<Tidak disetel>" - "Setelan panggilan lainnya" - "Memanggil via %s" - "Masuk melalui %s" - "foto kontak" - "aktifkan pribadi" - "pilih kontak" - "Tulis respons Anda sendiri…" - "Batal" - "Kirim" - "Jawab" - "Kirim SMS" - "Tolak" - "Jawab sebagai video call" - "Jawab sebagai panggilan audio" - "Terima permintaan video" - "Tolak permintaan video" - "Terima permintaan transmisi video" - "Tolak permintaan transmisi video" - "Terima permintaan menerima video" - "Tolak permintaan menerima video" - "Geser ke atas untuk %s." - "Geser ke kiri untuk %s." - "Geser ke kanan untuk %s." - "Geser ke bawah untuk %s." - "Getar" - "Getar" - "Suara" - "Suara default (%1$s)" - "Nada dering ponsel" - "Bergetar saat berdering" - "Nada dering & Getar" - "Kelola telewicara" - "Nomor darurat" - "Foto profil" - "Kamera tidak aktif" - "melalui %s" - "Catatan telah dikirim" - "Pesan terbaru" - "Info bisnis" - "%.1f mil" - "%.1f km" - "%1$s, %2$s" - "%1$s - %2$s" - "%1$s, %2$s" - "Buka jam %s" - "Hari ini buka jam %s" - "Tutup pukul %s" - "Hari ini tutup pukul %s" - "Buka sekarang" - "Sekarang tutup" - "Diduga telepon spam" - "Panggilan diakhiri %1$s" - "Nomor ini baru pertama kali menghubungi Anda." - "Kami menduga panggilan ini dari pelaku spam." - "Blokir/laporkan spam" - "Tambahkan kontak" - "Bukan spam" - diff --git a/InCallUI/res/values-is/strings.xml b/InCallUI/res/values-is/strings.xml deleted file mode 100644 index 480fd6eaa..000000000 --- a/InCallUI/res/values-is/strings.xml +++ /dev/null @@ -1,195 +0,0 @@ - - - - - "Sími" - "Í bið" - "Óþekkt" - "Óþekkt númer" - "Símasjálfsali" - "Símafundur" - "Símtali slitið" - "Hátalari" - "Símahátalari" - "Höfuðtól með snúru" - "Bluetooth" - "Senda eftirfarandi tóna?\n" - "Sendir tóna\n" - "Senda" - "Já" - "Nei" - "Skipta algildisstaf út fyrir" - "Símafundur %s" - "Talhólfsnúmer" - "Hringir" - "Hringir aftur" - "Símafundur" - "Móttekið símtal" - "Vinnusímtal berst" - "Lagt á" - "Í bið" - "Leggur" - "Í símtali" - "Númerið mitt er %s" - "Tengir myndskeið" - "Myndsímtal" - "Biður um myndskeið" - "Ekki tókst að tengja myndsímtal" - "Myndsímtalsbeiðni hafnað" - "Svarhringingarnúmer þitt\n %1$s" - "Svarhringingarnúmer þitt í neyðartilvikum\n %1$s" - "Hringir" - "Ósvarað símtal" - "Ósvöruð símtöl" - "%s ósvöruð símtöl" - "Ósvarað símtal frá %s" - "Samtal í gangi" - "Vinnusímtal í gangi" - "Wi-Fi símtal stendur yfir" - "Vinnusímtal í gangi um Wi-Fi" - "Í bið" - "Móttekið símtal" - "Vinnusímtal berst" - "Wi-Fi símtal berst" - "Vinnusímtal berst um Wi-Fi" - "Myndsímtal berst" - "Símtal sem berst er hugsanlega úr ruslnúmeri" - "Myndbeiðni berst" - "Ný skilaboð í talhólfinu" - "Ný skilaboð í talhólfinu (%d)" - "Hringja í %s" - "Talhólfsnúmer ekki þekkt" - "Ekkert símasamband" - "Valið símkerfi (%s) er ekki tiltækt" - "Svara" - "Leggja á" - "Myndskeið" - "Tal" - "Samþykkja" - "Hunsa" - "Hringja til baka" - "Skilaboð" - "Símtal í gangi í öðru tæki" - "Flytja símtal" - "Til að hringja símtal þarftu fyrst að slökkva á flugstillingu." - "Ekki skráð á símkerfi." - "Farsímakerfi ekki til staðar." - "Sláðu inn gilt númer til að hringja símtal." - "Ekki hægt að hringja." - "Ræsir MMI-runu…" - "Þjónustan er ekki studd." - "Ekki hægt að skipta milli símtala." - "Ekki hægt að aðskilja símtal." - "Ekki hægt að flytja." - "Ekki hægt að halda símafund." - "Ekki hægt að hafna símtali." - "Ekki hægt að leggja á." - "SIP-símtal" - "Neyðarsímtal" - "Kveikir á loftneti…" - "Ekkert samband. Reynir aftur…" - "Getur ekki hringt. %s er ekki neyðarsímanúmer." - "Ekki hægt að hringja. Hringdu í neyðarnúmer" - "Notaðu lyklaborðið til að hringja" - "Setja símtal í bið" - "Halda símtali áfram" - "Leggja á" - "Sýna símatakkaborð" - "Fela símatakkaborð" - "Slökkva á hljóði" - "Kveikja á hljóði" - "Bæta við símtali" - "Sameina símtöl" - "Skipta milli" - "Stjórna símtölum" - "Stjórna símafundi" - "Símafundur" - "Stjórna" - "Hljóð" - "Myndsímtal" - "Breyta í símtal" - "Skipta um myndavél" - "Kveikja á myndavél" - "Slökkva á myndavél" - "Fleiri valkostir" - "Spilari ræstur" - "Spilari stöðvaður" - "Myndavél ekki tilbúin" - "Myndavél tilbúin" - "Óþekkt atvik símtalslotu" - "Þjónusta" - "Uppsetning" - "<Ekki valið>" - "Aðrar símtalsstillingar" - "Hringt í gegnum %s" - "Berst í gegnum %s" - "mynd tengiliðar" - "tala í einrúmi" - "velja tengilið" - "Skrifaðu eigið svar…" - "Hætta við" - "Senda" - "Svara" - "Senda SMS-skilaboð" - "Hafna" - "Svara sem myndsímtali" - "Svara sem símtali" - "Samþykkja beiðni um myndsímtal" - "Hafna beiðni um myndsímtal" - "Samþykkja beiðni um sendingu myndsímtals" - "Hafna beiðni um sendingu myndsímtals" - "Samþykkja beiðni um móttöku myndsímtals" - "Hafna beiðni um móttöku myndsímtals" - "Strjúktu upp til að %s." - "Strjúktu til vinstri til að %s." - "Strjúktu til hægri til að %s." - "Strjúktu niður til að %s." - "Titra" - "Titra" - "Hljóð" - "Sjálfgefið hljóð (%1$s)" - "Hringitónn síma" - "Titra við hringingu" - "Hringitónn og titringur" - "Stjórna símafundi" - "Neyðarnúmer" - "Prófílmynd" - "Slökkt á myndavél" - "úr %s" - "Glósa send" - "Nýleg skilaboð" - "Fyrirtækjaupplýsingar" - %.1f míl. fjarlægð" - %.1f km fjarlægð" - "%1$s, %2$s" - "%1$s%2$s" - "%1$s, %2$s" - "Opið á morgun frá kl. %s" - "Opið í dag frá kl. %s" - "Lokað kl. %s" - "Var lokað í dag kl. %s" - "Opið núna" - "Lokað núna" - "Grunur um svikasímtal" - "Símtali lokið %1$s" - "Þetta er í fyrsta sinn sem hringt er í þig úr þessu númeri." - "Okkur grunaði að þetta símtal væri úr ruslnúmeri." - "Bannlisti/tilkynna" - "Bæta tengilið við" - "Ekki ruslnúmer" - diff --git a/InCallUI/res/values-it/strings.xml b/InCallUI/res/values-it/strings.xml deleted file mode 100644 index c9b49501b..000000000 --- a/InCallUI/res/values-it/strings.xml +++ /dev/null @@ -1,195 +0,0 @@ - - - - - "Telefono" - "In attesa" - "Sconosciuto" - "Numero privato" - "Telefono pubblico" - "Audioconferenza" - "Chiamata persa" - "Altoparlante" - "Auricolare telefono" - "Auricolare con cavo" - "Bluetooth" - "Inviare i numeri successivi?\n" - "Invio toni\n" - "Invia" - "Sì" - "No" - "Sostituisci carattere jolly con" - "Audioconferenza: %s" - "Numero segreteria" - "Chiamata in corso" - "Ricomposizione" - "Audioconferenza" - "Chiamata in arrivo" - "Chiamata lavoro in arrivo" - "Chiamata terminata" - "In attesa" - "In fase di chiusura" - "Chiamata in corso" - "Il mio numero è: %s" - "Collegamento video" - "Videochiamata" - "Richiesta video in corso" - "Impossibile effettuare una videochiamata" - "Richiesta video rifiutata" - "Numero da richiamare:\n %1$s" - "Numero da richiamare in caso di emergenza:\n %1$s" - "Composizione in corso" - "Chiamata persa" - "Chiamate perse" - "%s chiamate perse" - "Chiamata senza risposta da %s" - "Chiamata in corso" - "Chiamata di lavoro in corso" - "Chiamata Wi-Fi in corso" - "Chiamata di lavoro tramite Wi-Fi in corso" - "In attesa" - "Chiamata in arrivo" - "Chiamata di lavoro in arrivo" - "Chiamata Wi-Fi in arrivo" - "Chiamata di lavoro in arrivo tramite Wi-Fi" - "Videochiamata in arrivo" - "Chiamata di presunto spam in arrivo" - "Richiesta video in arrivo" - "Nuovo messaggio vocale" - "Nuovo messaggio vocale (%d)" - "Componi %s" - "Numero segreteria sconosciuto" - "Nessun servizio" - "Rete selezionata (%s) non disponibile" - "Rispondi" - "Riaggancia" - "Video" - "Voce" - "Accetta" - "Ignora" - "Richiama" - "Messaggio" - "Chiamata in corso su un altro dispositivo" - "Trasferisci chiamata" - "Per fare una chiamata, disattiva la modalità aereo." - "Non registrato sulla rete." - "Rete dati non disponibile." - "Per fare una chiamata, inserisci un numero valido." - "Impossibile chiamare." - "Avvio sequenza MMI..." - "Servizio non supportato." - "Impossibile cambiare chiamata." - "Impossibile separare la chiamata." - "Impossibile trasferire." - "Impossibile fare una chiamata in conferenza." - "Impossibile rifiutare la chiamata." - "Impossibile riagganciare." - "Chiamata SIP" - "Chiamata di emergenza" - "Attivazione segnale cellulare..." - "Nessun servizio. Nuovo tentativo…" - "Impossibile chiamare. %s non è un numero di emergenza." - "Impossibile chiamare. Componi un numero di emergenza." - "Usa tastiera" - "Metti in attesa la chiamata" - "Riprendi chiamata" - "Termina chiamata" - "Mostra tastierino" - "Nascondi tastierino" - "Disattiva audio" - "Riattiva audio" - "Aggiungi chiamata" - "Unisci chiamate" - "Scambia" - "Gestisci chiamate" - "Gestisci audioconferenza" - "Audioconferenza" - "Gestisci" - "Audio" - "Videochiam" - "Passa a chiamata vocale" - "Cambia fotocamera" - "Attiva fotocamera" - "Disattiva fotocamera" - "Altre opzioni" - "Player avviato" - "Player interrotto" - "La fotocamera non è pronta" - "Fotocamera pronta" - "Evento sessione chiamata sconosciuto" - "Servizio" - "Configura" - "<Non impostato>" - "Altre impostazioni di chiamata" - "Chiamate tramite %s" - "In arrivo tramite %s" - "foto contatto" - "Privato" - "seleziona contatto" - "Scrivi risposta personale..." - "Annulla" - "Invia" - "Rispondi" - "Invia SMS" - "Rifiuta" - "Rispondi con videochiamata" - "Rispondi con chiamata audio" - "Accetta richiesta video" - "Rifiuta richiesta video" - "Accetta richiesta di trasmissione video" - "Rifiuta richiesta di trasmissione video" - "Accetta richiesta di ricevimento video" - "Rifiuta richiesta di ricevimento video" - "Scorri verso l\'alto per %s." - "Scorri verso sinistra per %s." - "Scorri verso destra per %s." - "Scorri verso il basso per %s." - "Vibrazione" - "Vibrazione" - "Suono" - "Suono predefinito (%1$s)" - "Suoneria telefono" - "Vibrazione quando squilla" - "Suoneria e vibrazione" - "Gestisci audioconferenza" - "Numero di emergenza" - "Foto del profilo" - "Fotocamera disattivata" - "tramite %s" - "Nota inviata" - "Messaggi recenti" - "Informazioni sull\'attività" - "Distante %.1f mi" - "Distante %.1f km" - "%1$s, %2$s" - "%1$s - %2$s" - "%1$s, %2$s" - "Apre domani alle ore %s" - "Apre oggi alle ore %s" - "Chiude alle ore %s" - "Ha chiuso oggi alle ore %s" - "Aperto ora" - "Ora chiuso" - "Presunto spammer" - "Chiamata terminata %1$s" - "È la prima volta che questo numero ti chiama." - "Sospettavamo che questa chiamata provenisse da uno spammer." - "Blocca/Segnala spam" - "Aggiungi contatto" - "Non spam" - diff --git a/InCallUI/res/values-iw/strings.xml b/InCallUI/res/values-iw/strings.xml deleted file mode 100644 index c75c8da0d..000000000 --- a/InCallUI/res/values-iw/strings.xml +++ /dev/null @@ -1,195 +0,0 @@ - - - - - "טלפון" - "בהמתנה" - "לא ידוע" - "מספר פרטי" - "טלפון ציבורי" - "שיחת ועידה" - "השיחה נותקה" - "רמקול" - "אוזנייה" - "אוזניות עם חיבור חוטי" - "Bluetooth" - "האם לשלוח את הצלילים הבאים?\n" - "שולח צלילים\n" - "שלח" - "כן" - "לא" - "החלף את התו הכללי ב" - "שיחת ועידה %s" - "המספר של הדואר הקולי" - "מחייג" - "מחייג שוב" - "שיחת ועידה" - "שיחה נכנסת" - "שיחת עבודה נכנסת" - "השיחה הסתיימה" - "בהמתנה" - "מנתק" - "בשיחה" - "המספר שלי הוא %s" - "מחבר וידאו" - "שיחת וידאו" - "מבקש וידאו" - "לא ניתן לחבר שיחת וידאו" - "בקשת וידאו נדחתה" - "המספר שלך להתקשרות חזרה\n %1$s" - "המספר שלך להתקשרות חזרה במצב חירום\n %1$s" - "מחייג" - "שיחה שלא נענתה" - "שיחות שלא נענו" - "%s שיחות שלא נענו" - "שיחה שלא נענתה מאת %s" - "שיחה פעילה" - "שיחת עבודה פעילה" - "‏שיחת Wi-Fi פעילה" - "‏שיחת עבודה פעילה ברשת WiFi" - "בהמתנה" - "שיחה נכנסת" - "שיחת עבודה נכנסת" - "‏שיחת Wi-Fi נכנסת" - "‏שיחת עבודה נכנסת ברשת WiFi" - "שיחת וידאו נכנסת" - "השיחה הנכנסת חשודה כספאם" - "בקשת וידאו נכנסת" - "דואר קולי חדש" - "דואר קולי חדש (%d)" - "‏חייג ‎%s‎" - "המספר של הדואר הקולי אינו ידוע" - "אין שירות" - "הרשת שנבחרה (%s) לא זמינה" - "ענה" - "נתק" - "וידאו" - "קול" - "אשר" - "בטל" - "התקשר חזרה" - "שלח הודעה" - "באחד מהמכשירים האחרים מתבצעת שיחה" - "העבר את השיחה" - "כדי להתקשר, כבה תחילה את מצב טיסה." - "לא רשום ברשת." - "רשת סלולרית אינה זמינה." - "כדי להתקשר, הזן מספר טלפון חוקי." - "לא ניתן להתקשר." - "‏מתחיל רצף MMI…" - "שירות לא נתמך." - "לא ניתן לעבור בין שיחות." - "לא ניתן להפריד שיחה." - "לא ניתן להעביר." - "לא ניתן לבצע שיחת ועידה." - "לא ניתן לדחות שיחה." - "לא ניתן להתקשר." - "‏שיחת SIP" - "שיחת חירום" - "מפעיל את הרדיו…" - "אין שירות. מנסה שוב..." - "לא ניתן להתקשר. %s אינו מספר חירום." - "לא ניתן להתקשר. חייג למספר חירום." - "השתמש במקלדת כדי לחייג" - "החזק שיחה" - "המשך בשיחה" - "סיים שיחה" - "הצגת לוח החיוג" - "הסתרת לוח החיוג" - "השתקה" - "ביטול ההשתקה" - "הוסף שיחה" - "מזג שיחות" - "החלף" - "נהל שיחות" - "נהל שיחת ועידה" - "שיחת ועידה" - "ניהול" - "אודיו" - "שיחת וידאו" - "שנה לשיחה קולית" - "החלף מצלמה" - "הפעל את המצלמה" - "כבה את המצלמה" - "אפשרויות נוספות" - "הנגן הופעל" - "הנגן הפסיק" - "המצלמה לא מוכנה" - "המצלמה מוכנה" - "אירוע הפעלת שיחה לא ידוע" - "שירות" - "הגדרות" - "<לא הוגדר>" - "הגדרות אחרות של שיחה" - "שיחה באמצעות %s" - "שיחה נכנסת באמצעות %s" - "תמונה של איש קשר" - "עבור לשיחה פרטית" - "בחר איש קשר" - "כתוב תגובה משלך..." - "בטל" - "שלח" - "ענה" - "‏שלח SMS" - "דחה" - "ענה כשיחת וידאו" - "ענה כשיחת אודיו" - "קבל בקשת וידאו" - "דחה בקשת וידאו" - "אשר את הבקשה לשידור וידאו" - "דחה את הבקשה לשידור וידאו" - "אשר את הבקשה לקבלת וידאו" - "דחה את הבקשה לקבלת וידאו" - "הסט למעלה כדי %s." - "הסט שמאלה כדי %s." - "הסט ימינה כדי %s." - "הסט למטה כדי %s." - "רטט" - "רטט" - "צליל" - "צליל ברירת מחדל (%1$s)" - "רינגטון של טלפון" - "רטט בעת צלצול" - "רינגטון ורטט" - "נהל שיחת ועידה" - "מספר חירום" - "תמונת פרופיל" - "המצלמה כבויה" - "באמצעות %s" - "ההערה נשלחה" - "הודעות אחרונות" - "פרטי עסק" - "במרחק %.1f מייל" - "במרחק %.1f ק\"מ" - "%1$s, %2$s" - "%1$s - %2$s" - "%1$s, %2$s" - "ייפתח מחר ב-%s" - "נפתח היום ב-%s" - "נסגר ב-%s" - "נסגר היום ב-%s" - "פתוח עכשיו" - "סגור עכשיו" - "חשד לשיחת ספאם" - "‏השיחה הסתיימה %1$s" - "זוהי הפעם הראשונה שמתקשרים אליך מהמספר הזה." - "אנו חושדים שהמספר הזה הוא של שולח ספאם." - "חסימה/דיווח על ספאם" - "הוספת איש קשר" - "לא ספאם" - diff --git a/InCallUI/res/values-ja/strings.xml b/InCallUI/res/values-ja/strings.xml deleted file mode 100644 index 551d896b5..000000000 --- a/InCallUI/res/values-ja/strings.xml +++ /dev/null @@ -1,195 +0,0 @@ - - - - - "電話" - "保留中" - "不明" - "非通知" - "公衆電話" - "グループ通話" - "通話が遮断されました" - "スピーカー" - "モバイル端末のイヤホン" - "有線ヘッドセット" - "Bluetooth" - "次の番号を送信しますか?\n" - "番号を送信中\n" - "送信" - "はい" - "いいえ" - "ワイルド文字を置換:" - "グループ通話 %s" - "ボイスメールの番号" - "発信中" - "リダイヤル中" - "グループ通話" - "着信中" - "仕事の通話が着信中" - "通話終了" - "保留中" - "通話終了" - "通話中" - "この電話の番号: %s" - "ビデオハングアウトに接続中" - "ビデオハングアウト" - "ビデオハングアウトをリクエスト中" - "ビデオハングアウトの接続エラー" - "ビデオハングアウトのリクエスト不承認" - "コールバック先\n %1$s" - "緊急通報コールバック先\n %1$s" - "発信中" - "不在着信" - "不在着信" - "不在着信 %s 件" - "%s さんからの不在着信" - "通話中" - "仕事の通話中" - "Wi-Fi 通話中" - "仕事の Wi-Fi 通話中" - "保留中" - "着信中" - "仕事の通話が着信中" - "Wi-Fi 通話が着信中" - "仕事の Wi-Fi 通話が着信中" - "ビデオハングアウトが着信中" - "迷惑電話の疑いがある通話を着信しています" - "ビデオハングアウト リクエストが着信中" - "新着のボイスメール" - "新着のボイスメール(%d 件)" - "%s に発信" - "ボイスメールの番号が不明です" - "通信サービスはありません" - "選択したネットワーク(%s)が利用できません" - "電話に出る" - "通話終了" - "ビデオ" - "音声" - "受ける" - "拒否する" - "コールバック" - "メッセージ" - "別の端末で通話中" - "通話を転送" - "機内モードを OFF にしてから発信してください。" - "ご加入の通信サービスがありません。" - "モバイル ネットワークが利用できません。" - "発信するには、有効な番号を入力してください。" - "発信できません。" - "MMI シーケンスを開始しています..." - "サービスはサポートされていません。" - "通話を切り替えられません。" - "通話を分割できません。" - "転送できません。" - "グループ通話できません。" - "着信を拒否できません。" - "通話を解放できません。" - "SIP 通話" - "緊急通報" - "無線通信を ON にしています..." - "通信サービスはありません。もう一度お試しください…" - "発信できません。%s は緊急通報番号ではありません。" - "発信できません。緊急通報番号におかけください。" - "キーボードで番号を入力してください" - "通話を保留" - "通話を再開" - "通話を終了" - "ダイヤルパッドを表示" - "ダイヤルパッドを非表示" - "ミュート" - "ミュートを解除" - "通話を追加" - "グループ通話" - "切り替え" - "通話を管理" - "グループ通話オプション" - "グループ通話" - "管理" - "音声" - "ビデオ" - "音声通話に変更" - "カメラを切り替え" - "カメラを ON にする" - "カメラを OFF にする" - "その他のオプション" - "プレーヤーを開始しました" - "プレーヤーを停止しました" - "カメラが準備できていません" - "カメラが準備できました" - "不明な通話セッション イベントです" - "サービス" - "セットアップ" - "<未設定>" - "その他の通話設定" - "%s で発信中" - "%s で着信中" - "連絡先の写真" - "個別通話に切り替え" - "連絡先を選択" - "カスタム返信を作成..." - "キャンセル" - "送信" - "電話に出る" - "SMS を送信する" - "拒否" - "ビデオハングアウトで電話に出る" - "音声通話で電話に出る" - "ビデオハングアウト リクエストを承認する" - "ビデオハングアウト リクエストを拒否する" - "ビデオハングアウト送信リクエストを承認する" - "ビデオハングアウト送信リクエストを拒否する" - "ビデオハングアウト受信リクエストを承認する" - "ビデオハングアウト受信リクエストを拒否する" - "上にスライドして%sを行います。" - "左にスライドして%sを行います。" - "右にスライドして%sを行います。" - "下にスライドして%sを行います。" - "バイブレーション" - "バイブレーション" - "着信音" - "デフォルトの通知音(%1$s)" - "着信音" - "着信時のバイブレーション" - "着信音とバイブレーション" - "グループ通話オプション" - "緊急通報番号" - "プロフィール写真" - "カメラ OFF" - "%s に着信" - "メモを送信しました" - "最近のメッセージ" - "ビジネス情報" - "%.1f マイル内" - "%.1f km 内" - "%1$s%2$s" - "%1$s%2$s" - "%1$s%2$s" - "明日 %sに営業開始" - "本日 %sに営業開始" - "%sに営業終了" - "本日 %sに営業終了" - "現在営業中" - "営業終了" - "迷惑電話の疑いあり" - "通話が終了しました %1$s" - "この番号からの通話を受信したのはこれが初めてです。" - "この通話は迷惑電話の可能性があります。" - "ブロック / 報告" - "連絡先に追加" - "迷惑電話ではない" - diff --git a/InCallUI/res/values-ka/strings.xml b/InCallUI/res/values-ka/strings.xml deleted file mode 100644 index b01006561..000000000 --- a/InCallUI/res/values-ka/strings.xml +++ /dev/null @@ -1,195 +0,0 @@ - - - - - "ტელეფონი" - "მოცდის რეჟიმში" - "უცნობი" - "დაფარული ნომერი" - "ტელეფონ-ავტომატი" - "საკონფერენციო ზარი" - "ზარი შეწყდა" - "დინამიკი" - "ყურსაცვამის საყურისი" - "სადენიანი ყურსაცვამი" - "Bluetooth" - "გსურთ შემდეგი ტონების გაგზავნა?\n" - "ტონების გაგზავნა\n" - "გაგზავნა" - "დიახ" - "არა" - "ჩანაცვლების სიმბოლო ჩანაცვლდეს შემდეგით:" - "საკონფერენციო ზარი: %s" - "ხმოვანი ფოსტის ნომერი" - "მიმდინარეობს აკრეფა" - "იკრიფება ხელახლა" - "საკონფერენციო ზარი" - "შემომავალი ზარი" - "შემომავალი ზარი (სამსახური)" - "ზარი დასრულდა" - "მოცდის რეჟიმში" - "მიმდინარეობს გათიშვა" - "საუბრის რეჟიმში" - "ჩემი ნომერია %s" - "მიმდინარეობს ვიდეოს დაკავშირება" - "ვიდეო ზარი" - "მიმდინარეობს ვიდეოს მოთხოვნა" - "ვიდეო ზარის დაკავშირება ვერ მოხერხდა" - "ვიდეოს მოთხოვნა უარყოფილია" - "თქვენი ნომერი გადმორეკვისთვის\n %1$s" - "თქვენი ნომერი გადაუდებელი გადმორეკვისთვის\n %1$s" - "მიმდინარეობს აკრეფა" - "გამოტოვებული ზარი" - "გამოტოვებული ზარები" - "%s გამოტოვებული ზარი" - "გამოტოვებული ზარი %s-ისგან" - "მიმდინარე ზარი" - "მიმდინარე ზარი (სამსახური)" - "მიმდინარე Wi-Fi ზარი" - "მიმდინარე Wi-Fi ზარი (სამსახური)" - "მოცდის რეჟიმში" - "შემომავალი ზარი" - "შემომავალი ზარი (სამსახური)" - "შემომავალი Wi-Fi ზარი" - "შემომავალი Wi-Fi ზარი (სამსახური)" - "შემომავალი ვიდეო ზარი" - "შემომავალი ზარი - სავარაუდოდ სპამი" - "შემომავალი ვიდეოს მოთხოვნა" - "ახალი ხმოვანი შეტყობინება" - "ახალი ხმოვანი შეტყობინება (%d)" - "%s-ზე დარეკვა" - "ხმოვანი ფოსტის ნომერი უცნობია" - "სერვისი არ არის" - "არჩეული ქსელი (%s) მიუწვდომელია" - "პასუხი" - "გათიშვა" - "ვიდეო" - "ხმოვანი" - "მიღება" - "დახურვა" - "გადარეკვა" - "შეტყობინება" - "სხვა მოწყობილობაზე მიმდინარე ზარი" - "ზარის ტრანსფერი" - "ზარის განსახორციელებლად, ჯერ გამორთეთ თვითმფრინავის რეჟიმი." - "არ არის რეგისტრირებული ქსელში." - "ფიჭური ქსელი მიუწვდომელია." - "ზარის განსახორციელებლად, შეიყვანეთ სწორი ნომერი." - "დარეკვა ვერ ხერხდება." - "MMI თანმიმდევრობის დაწყება…" - "სერვისი არ არის მხარდაჭერილი." - "ზარების გადართვა ვერ ხერხდება." - "ზარის განცალკევება ვერ ხერხდება." - "გადამისამართება ვერ ხერხდება." - "საკონფერენციო ზარის განხორციელება ვერ ხერხდება." - "ზარის უარყოფა ვერ ხერხდება." - "ზარ(ებ)ის გათიშვა ვერ ხერხდება." - "SIP ზარი" - "გადაუდებელი ზარი" - "მიმდინარეობს რადიოს ჩართვა…" - "სერვისი არ არის. მიმდინარეობს ხელახლა ცდა…" - "დარეკვა ვერ ხერხდება. %s არ არის გადაუდებელი დახმარების ნომერი." - "დარეკვა ვერ ხერხდება. აკრიფეთ გადაუდებელი დახმარების ნომერი." - "ნომრის ასაკრეფად გამოიყენეთ კლავიატურა" - "მოცდის რეჟიმზე გადაყვანა" - "ზარის განახლება" - "ზარის დასრულება" - "ციფერბლატის ჩვენება" - "ციფერბლატის დამალვა" - "დადუმება" - "დადუმების გაუქმება" - "ზარის დამატება" - "ზარების გაერთიანება" - "ჩანაცვლება" - "ზარების მართვა" - "საკონფერენციო ზარის მართვა" - "საკონფერენციო ზარი" - "მართვა" - "აუდიო" - "ვიდეო ზარი" - "ხმოვან ზარზე გადართვა" - "კამერის გადართვა" - "კამერის ჩართვა" - "კამერის გამორთვა" - "სხვა ვარიანტები" - "დამკვრელი ჩაირთო" - "დამკვრელი გამოირთო" - "კამერა არ არის მზად" - "კამერა მზადაა" - "ზარის სესიის უცნობი მოვლენა" - "სერვისი" - "დაყენება" - "<არ არის დაყენებული>" - "ზარის სხვა პარამეტრები" - "მიმდინარეობს დარეკვა %s-ის მეშვეობით" - "შემომავალი ზარი %s-დან" - "კონტაქტის ფოტო" - "პირადი რეჟიმი" - "კონტაქტის არჩევა" - "საკუთარის შექმნა..." - "გაუქმება" - "გაგზავნა" - "პასუხი" - "SMS-ის გაგზავნა" - "უარყოფა" - "პასუხი ვიდეო ზარის სახით" - "პასუხი ხმოვანი ზარის სახით" - "ვიდეოს მოთხოვნის მიღება" - "ვიდეოს მოთხოვნის უარყოფა" - "ვიდეოს გადაცემის მოთხოვნის მიღება" - "ვიდეოს გადაცემის მოთხოვნის უარყოფა" - "ვიდეოს მიღების მოთხოვნაზე დათანხმება" - "ვიდეოს მიღების მოთხოვნის უარყოფა" - "გაასრიალეთ ზემოთ, რათა შესრულდეს %s." - "გაასრიალეთ მარცხნივ, რათა შესრულდეს %s." - "გაასრიალეთ მარჯვნივ, რათა შესრულდეს %s." - "გაასრიალეთ ქვემოთ, რათა შესრულდეს %s." - "ვიბრაცია" - "ვიბრაცია" - "ხმა" - "ნაგულისხმები ხმა (%1$s)" - "ტელეფონის ზარი" - "ვიბრაცია დარეკვისას" - "ზარის მელოდია და ვიბრაცია" - "საკონფერენციო ზარის მართვა" - "გადაუდებელი დახმარების ნომერი" - "პროფილის ფოტო" - "კამერა გამორთულია" - "%s-დან" - "შენიშვნა გაიგზავნა" - "ბოლო შეტყობინებები" - "ბიზნეს-ინფორმაცია" - "%.1f მილში" - "%.1f კმ-ში" - "%1$s, %2$s" - "%1$s%2$s" - "%1$s, %2$s" - "იხსნება ხვალ %s-ზე" - "იხსნება დღეს %s-ზე" - "იკეტება %s-ზე" - "დაიკეტა დღეს %s-ზე" - "ახლა ღიაა" - "ახლა დაკეტილია" - "სავარაუდ.სპამ.აბონ." - "ზარი დასრულდა %1$s" - "ამ ნომრიდან პირველად დაგირეკეს." - "ეჭვი გვაქვს, რომ ეს ზარი სპამია." - "დაბლოკ./სპამ.შეტყობ." - "კონტაქტის დამატება" - "არ არის სპამი" - diff --git a/InCallUI/res/values-kk/strings.xml b/InCallUI/res/values-kk/strings.xml deleted file mode 100644 index 07ea6fb78..000000000 --- a/InCallUI/res/values-kk/strings.xml +++ /dev/null @@ -1,195 +0,0 @@ - - - - - "Телефон" - "Күтуде" - "Белгісіз" - "Жеке нөмір" - "Автомат-телефон" - "Конференциялық қоңырау" - "Қоңырау үзілді" - "Динамик" - "Телефон құлаққабы" - "Сымды құлақаспап жинағы" - "Bluetooth" - "Келесі әуендер жіберілсін бе?\n" - "Жіберу әуендері\n" - "Жіберу" - "Иә" - "Жоқ" - "Қойылмалы таңбаны келесі таңбамен алмастыру" - "%s конференциялық қоңырауы" - "Дауыстық пошта нөмірі" - "Терілуде" - "Қайта терілуде" - "Конференциялық қоңырау" - "Кіріс қоңырау" - "Кіріс жұмыс қоңырауы" - "Қоңырау аяқталды" - "Күтуде" - "Қоңырау аяқталуда" - "Қоңырауда" - "Mенің нөмірім — %s" - "Бейне қосылуда" - "Бейне қоңырау" - "Бейне сұралуда" - "Бейне қоңырауға қосылу мүмкін емес" - "Бейне сұрауы қабылданбады" - "Кері қоңырау шалу нөміріңіз\n %1$s" - "Төтенше кері қоңырау шалу нөміріңіз\n %1$s" - "Терілуде" - "Өткізіп алған қоңырау" - "Өткізіп алған қоңыраулар" - "%s өткізіп алған қоңырау" - "%s қоңырауы өткізіп алынған" - "Ағымдағы қоңырау" - "Ағымдағы жұмыс қоңырауы" - "Ағымдағы Wi-Fi қоңырауы" - "Ағымдағы Wi-Fi жұмыс қоңырауы" - "Күтуде" - "Кіріс қоңырау" - "Кіріс жұмыс қоңырауы" - "Кіріс Wi-Fi қоңырауы" - "Кіріс Wi-Fi жұмыс қоңырауы" - "Кіріс бейне қоңырау" - "Кіріс қоңырауы спам болуы мүмкін" - "Кіріс бейне сұрау" - "Жаңа дауыстық хабар" - "Жаңа дауыстық хабар (%d)" - "%s нөмірін теру" - "Дауыстық пошта нөмірі белгісіз" - "Қызмет жоқ" - "Таңдалған (%s) желісі қол жетімді емес" - "Жауап" - "Қоңырауды аяқтау" - "Бейне" - "Дауыс" - "Қабылдау" - "Қабылдамау" - "Кері қоңырау шалу" - "Хабар" - "Қоңырау басқа құрылғыдан шалынуда" - "Қоңырауды басқа құрылғыға бағыттау" - "Қоңырау шалу үшін алдымен ұшақ режимін өшіріңіз." - "Желіде тіркелмеген." - "Ұялы желі қол жетімді емес." - "Қоңырау шалу үшін жарамды нөмірді енгізіңіз." - "Қоңырау шалу мүмкін емес." - "MMI қатарын бастау…" - "Қызметке қолдау көрсетілмейді." - "Қоңырауларды ауыстыру мүмкін емес." - "Қоңырауды бөлу мүмкін емес." - "Тасымалдау мүмкін емес." - "Конференция мүмкін емес." - "Қоңырауды қабылдамау мүмкін емес." - "Қоңырау(лар)ды босату мүмкін емес." - "SIP қоңырауы" - "Төтенше қоңырау" - "Радио қосылуда…" - "Қызмет жоқ. Әрекет қайталануда…" - "Қоңырау шалу мүмкін емес. %s төтенше нөмір емес." - "Қоңырау шалу мүмкін емес. Төтенше нөмірді теріңіз." - "Теру үшін пернетақтаны пайдалану" - "Қоңырауды ұстап тұру" - "Қоңырауды жалғастыру" - "Қоңырауды аяқтау" - "Теру тақтасын көрсету" - "Теру тақтасын жасыру" - "Дыбысты өшіру" - "Дыбысын қосу" - "Қоңырау қосу" - "Қоңырауларды біріктіру" - "Алмастыру" - "Қоңырауларды басқару" - "Конференциялық қоңырауды басқару" - "Конференциялық қоңырау" - "Басқару" - "Aудио" - "Бейне қоңырау" - "Дауыстық қоңырауға өзгерту" - "Камераны ауыстыру" - "Камераны қосу" - "Камераны өшіру" - "Қосымша опциялар" - "Ойнатқыш іске қосылды" - "Ойнатқыш тоқтатылды" - "Камера дайын емес" - "Камера дайын" - "Белгісіз қоңырау сеансы оқиғасы" - "Қызмет" - "Реттеу" - "<Орнатылмаған>" - "Басқа қоңырау параметрлері" - "%s арқылы қоңырау шалу" - "%s арқылы кіріс" - "контакт фотосуреті" - "жеке қоңырауға ауысу" - "контакт таңдау" - "Өзіңіздікін жазыңыз..." - "Бас тарту" - "Жіберу" - "Жауап" - "SMS жіберу" - "Қабылдамау" - "Бейне қоңырауға жауап беру" - "Аудио қоңырауға жауап беру" - "Бейне сұрауды қабылдау" - "Бейне сұрауды қабылдамау" - "Бейне тасымалдау сұрауын қабылдау" - "Бейне тасымалдау сұрауын қабылдамау" - "Бейне алу сұрауын қабылдау" - "Бейне алу сұрауын қабылдамау" - "%s үшін жоғары сырғытыңыз." - "%s үшін сол жаққа сырғытыңыз." - "%s үшін оң жаққа сырғытыңыз." - "%s үшін төмен сырғытыңыз." - "Діріл" - "Діріл" - "Дыбыс" - "Әдепкі дыбыс (%1$s)" - "Телефонның қоңырау әуені" - "Шылдырлағанда дірілдеу" - "Қоңырау әуені және діріл" - "Конференциялық қоңырауды басқару" - "Төтенше нөмір" - "Профиль фотосуреті" - "Камераны өшіру" - "%s арқылы" - "Ескертпе жіберілді" - "Жақындағы хабарлар" - "Іскери ақпарат" - "%.1f миля қашықтықта" - "%.1f км қашықтықта" - "%1$s, %2$s" - "%1$s - %2$s" - "%1$s, %2$s" - "Ертең %s уақытында ашылады" - "Бүгін %s уақытында ашылады" - "%s уақытында жабылады" - "Бүгін %s уақытында жабық" - "Қазір ашық" - "Қазір жабық" - "Спам қоңырау шалушы болуы мүмкін" - "Қоңырау аяқталды (%1$s)" - "Бұл нөмірдің сізге алғашқы қоңырау шалуы." - "Бұл қоңырау спамер деп күдіктенеміз." - "Бөгеу/спамға жіберу" - "Контакт қосу" - "Спам емес" - diff --git a/InCallUI/res/values-km/strings.xml b/InCallUI/res/values-km/strings.xml deleted file mode 100644 index 7a31d8933..000000000 --- a/InCallUI/res/values-km/strings.xml +++ /dev/null @@ -1,195 +0,0 @@ - - - - - "ទូរស័ព្ទ" - "រង់ចាំ" - "មិនស្គាល់" - "លេខ​ឯកជន" - "ទូរស័ព្ទសាធារណៈ" - "ការហៅជាក្រុម" - "ការហៅទូរស័ព្ទបានដាក់ចុះ" - "ឧបករណ៍បំពងសម្លេង" - "អូប៉ាល័រសំឡេងទូរស័ព្ទ" - "កាសមានខ្សែ" - "ប៊្លូធូស" - "ផ្ញើសំឡេងដូចខាងក្រោមឬ?\n" - "ផ្ញើ​សំឡេង \n" - "ផ្ញើ" - "បាទ/ចាស" - "ទេ" - "ជំនួស​តួ​អក្សរ​ជំនួស​ដោយ" - "ការហៅជាក្រុម %s" - "លេខ​សារ​ជា​សំឡេង" - "កំពុងហៅ" - "ការចុចហៅឡើងវិញ" - "ការហៅជាក្រុម" - "ការហៅចូល" - "កំពុងហៅចូលពីកន្លែងការងារ" - "បាន​បញ្ចប់​ការ​ហៅ" - "រង់ចាំ" - "បញ្ចប់​ការ​សន្ទនា" - "កំពុង​ហៅ" - "លេខ​របស់​ខ្ញុំ​គឺ %s" - "ភ្ជាប់​វីដេអូ" - "ហៅជាវីដេអូ" - "ស្នើ​វីដេអូ" - "មិនអាចភ្ជាប់ការហៅជាវីដេអូបានទេ" - "បានបដិសេធសំណើហៅជាវីដេអូ" - "លេខហៅទៅវិញរបស់អ្នក\n%1$s" - "លេខហៅទៅវិញពេលអាសន្នរបស់អ្នក\n %1$s" - "កំពុង​ហៅ" - "ខកខាន​ទទួល" - "ខកខាន​ទទួល" - "ខកខានទទួល %s ដង" - "ខកខាន​ទទួល​ពី %s" - "កំពុង​បន្ត​ការ​ហៅ" - "ការហៅពីកន្លែងការងារកំពុងដំណើរការ" - "ការហៅតាម Wi-Fi កំពុងបន្ត" - "ការហៅតាម Wi-Fi ពីកន្លែងការងារកំពុងដំណើរការ" - "រង់ចាំ" - "ការហៅចូល" - "កំពុងហៅចូលពីកន្លែងការងារ" - "មានការហៅចូលតាម Wi-Fi" - "កំពុងហៅចូលពីកន្លែងការងារតាម Wi-Fi" - "ការ​ហៅចូលជា​វីដេអូ​" - "ការ​ហៅ​បន្លំ​​ចូល​​​ដែល​សង្ស័យ" - "សំណើ​ការ​ហៅ​ជា​វីដេអូ​ចូល" - "សារ​ជា​សំឡេង​ថ្មី" - "សារ​ជា​សំឡេង​ថ្មី (%d)" - "ហៅ %s" - "លេខសារជាសំឡេងមិនស្គាល់" - "គ្មានសេវាទេ" - "បណ្ដាញ​ដែល​បាន​ជ្រើស ( %s ) មិន​អាច​ប្រើ​បាន​ទេ" - "ឆ្លើយតប" - "បញ្ចប់​ការ​សន្ទនា" - "វីដេអូ" - "សំឡេង" - "ព្រម​ទទួល" - "បដិសេធ" - "ហៅ​ទៅ​វិញ" - "សារ" - "ការ​ហៅ​កំពុង​ដំណើរការ​លើ​ឧបករណ៍​ផ្សេង" - "ផ្ទេរ​ការហៅ" - "ដើម្បីកំណត់ការហៅ សូមបិទរបៀបពេលជិះយន្តហោះជាមុនសិន" - "មិនបានចុះឈ្មោះនៅលើបណ្ដាញទេ" - "បណ្ដាញចល័តមិនអាចប្រើបានទេ" - "ដើម្បីធ្វើការហៅ សូមបញ្ចូលលេខដែលត្រឹមត្រូវ" - "មិនអាចហៅបានទេ" - "កំពុងចាប់ផ្តើមលំដាប់ MMI…" - "សេវាកម្មមិនត្រូវបានគាំទ្រទេ" - "មិនអាចប្តូរការហៅបានទេ" - "មិនអាចបំបែកការហៅបានទេ" - "មិនអាចផ្ទេរបានទេ" - "មិនអាចធ្វើការហៅជាក្រុមបានទេ" - "មិនអាចបដិសេធការហៅបានទេ" - "មិនអាចធ្វើការហៅបានទេ" - "ការ​ហៅ SIP" - "ការ​ហៅ​ពេល​អាសន្ន" - "កំពុងបើកវិទ្យុ…" - "គ្មានសេវាទេ សូមព្យាយាមម្តង…" - "មិនអាចហៅបានទេ។ %s មិនមែនជាលេខអាសន្នទេ" - "មិនអាចហៅបានទេ សូមចុចហៅលេខអាសន្ន" - "ប្រើ​ក្ដារ​ចុច ​ដើម្បី​ចុច​លេខ" - "រង់ចាំការហៅ" - "បន្តការហៅ" - "បញ្ចប់ការហៅ" - "បង្ហាញ​បន្ទះ​លេខ" - "លាក់​បន្ទះ​លេខ" - "បិទ" - "បើក​សំឡេង" - "បន្ថែម​ការ​ហៅ" - "បញ្ចូល​ការ​ហៅ​ចូល​គ្នា" - "ប្ដូរ" - "គ្រប់គ្រង​ការ​ហៅ" - "គ្រប់គ្រងការហៅជាក្រុម" - "ការហៅជា​សន្និសិទ" - "គ្រប់គ្រង" - "សំឡេង" - "ហៅជាវីដេអូ" - "ប្ដូរ​ទៅ​ការ​ហៅ​ជា​សំឡេង" - "ប្ដូរកាមេរ៉ា" - "បើកកាមេរ៉ា" - "បិទកាមេរ៉ា" - "ជម្រើសច្រើនទៀត" - "អ្នកលេងបានចាប់ផ្តើម" - "អ្នកលេងបានឈប់" - "កាមេរ៉ាមិនទាន់ត្រៀមរួចរាល់ទេ" - "កាមេរ៉ាត្រៀមរួចរាល់ហើយ" - "ព្រឹត្តិការណ៍វេននៃការហៅមិនស្គាល់" - "សេវាកម្ម" - "ដំឡើង" - "<មិន​បាន​កំណត់>" - "​កំណត់​ការ​​ហៅ​ផ្សេងទៀត" - "ហៅតាមរយៈ %s" - "ចូល​តាមរយៈ %s" - "រូបថត​ទំនាក់ទំនង" - "ចូលជាលក្ខណៈឯកជន" - "ជ្រើសទំនាក់ទំនង" - "សរសេរដោយខ្លួនអ្នកផ្ទាល់..." - "បោះបង់" - "ផ្ញើ" - "ឆ្លើយតប" - "ផ្ញើសារ SMS" - "បដិសេធ" - "ឆ្លើយតប​ជា​ការ​ហៅ​ជា​​វីដេអូ" - "ឆ្លើយតប​ជា​ការ​ហៅ​ជា​សំឡេង" - "ទទួលយក​សំណើ​វីដេអូ" - "ទទួលយក​សំណើ​វីដេអូ" - "ទទួលយកសំណើបញ្ជូនជាវីដេអូ" - "បដិសេធសំណើបញ្ជូនជាវីដេអូ" - "ទទួលយកសំណើទទួលជាវីដេអូ" - "បដិសេធសំណើទទួលជាវីដេអូ" - "រុញឡើងលើដើម្បី %s" - "រុញទៅឆ្វេងដើម្បី %s" - "រុញទៅស្ដាំដើម្បី %s" - "រុញចុះក្រោមដើម្បី %s" - "ញ័រ" - "ញ័រ" - "សំឡេង" - "សំឡេង​លំនាំដើម (%1$s)" - "សំឡេងរោទ៍ទូរស័ព្ទ" - "ញ័រពេលរោទ៍" - "សំឡេងរោទ៍ និងញ័រ" - "គ្រប់គ្រងការហៅជាក្រុម" - "លេខអាសន្ន" - "រូបថត​ប្រវត្តិរូប" - "បិទកាមេរ៉ា" - "តាមរយៈ %s" - "បានផ្ញើចំណាំ" - "សារថ្មីៗ" - "ព័ត៌មានធុរកិច្ច" - "ចម្ងាយ %.1f ម៉ាយល៍" - "ចម្ងាយ %.1f គម" - "%1$s, %2$s" - "%1$s - %2$s" - "%1$s, %2$s" - "បើកថ្ងៃស្អែកនៅម៉ោង %s" - "បើកថ្ងៃនេះនៅម៉ោង %s" - "បិទនៅម៉ោង %s" - "បានបិទថ្ងៃនេះនៅម៉ោង %s" - "បើកឥឡូវនេះ" - "បិទឥឡូវនេះ" - "អ្នក​ហៅ​​បន្លំ​ដែល​សង្ស័យ" - "ការ​ហៅ​បាន​បញ្ចប់ %1$s" - "នេះ​គឺ​ជា​លើក​ដំបូង​ដែល​លេខ​នេះ​បាន​ហៅ​មក​អ្នក។" - "យើង​បាន​សង្ស័យ​ថា​​ការ​ហៅ​នេះ​ជា​សារ​ឥត​បាន​ការ។" - "រារាំង/រាយការណ៍សារឥតបានការ" - "បញ្ចូល​​ទំនាក់ទំនង" - "មិនមែន​សារ​ឥតបានការ" - diff --git a/InCallUI/res/values-kn/strings.xml b/InCallUI/res/values-kn/strings.xml deleted file mode 100644 index 441f6e189..000000000 --- a/InCallUI/res/values-kn/strings.xml +++ /dev/null @@ -1,195 +0,0 @@ - - - - - "ಫೋನ್" - "ತಡೆಹಿಡಿಯಲಾಗಿದೆ" - "ಅಪರಿಚಿತ" - "ಖಾಸಗಿ ಸಂಖ್ಯೆ" - "ಪೇಫೋನ್" - "ಕಾನ್ಫರೆನ್ಸ್ ಕರೆ" - "ಕರೆಯನ್ನು ಬಿಡಲಾಗಿದೆ" - "ಸ್ಪೀಕರ್‌" - "ಹ್ಯಾಂಡ್‌ಸೆಟ್ ಇಯರ್‌ಪೀಸ್" - "ವೈರ್ಡ್ ಹೆಡ್‌ಸೆಟ್‌" - "ಬ್ಲೂಟೂತ್" - "ಕೆಳಗಿನ ಟೋನ್‌ಗಳನ್ನು ಕಳುಹಿಸುವುದೇ?\n" - "ಟೋನ್‌ಗಳನ್ನು ಕಳುಹಿಸಲಾಗುತ್ತಿದೆ\n" - "ಕಳುಹಿಸು" - "ಹೌದು" - "ಇಲ್ಲ" - "ಇದರೊಂದಿಗೆ ವಿಶೇಷ ಅಕ್ಷರಗಳನ್ನು ಸ್ಥಳಾಂತರಿಸು" - "ಕಾನ್ಫರೆನ್ಸ್ ಕರೆ %s" - "ಧ್ವನಿಮೇಲ್‌ ಸಂಖ್ಯೆ" - "ಡಯಲ್‌ ಮಾಡಲಾಗುತ್ತಿದೆ" - "ಮರು ಡಯಲ್ ಮಾಡಲಾಗುತ್ತಿದೆ" - "ಕಾನ್ಫರೆನ್ಸ್ ಕರೆ" - "ಒಳಬರುವ ಕರೆ" - "ಒಳಬರುವ ಕೆಲಸದ ಕರೆ" - "ಕರೆ ಅಂತ್ಯಗೊಂಡಿದೆ" - "ತಡೆಹಿಡಿಯಲಾಗಿದೆ" - "ಹ್ಯಾಂಗ್ ಮಾಡಲಾಗುತ್ತಿದೆ" - "ಕರೆಯಲ್ಲಿ" - "ನನ್ನ ಸಂಖ್ಯೆ %s" - "ವೀಡಿಯೊ ಸಂಪರ್ಕಪಡಿಸಲಾಗುತ್ತಿದೆ" - "ವೀಡಿಯೊ ಕರೆ" - "ವೀಡಿಯೊ ವಿನಂತಿಸಲಾಗುತ್ತಿದೆ" - "ವೀಡಿಯೊ ಕರೆಯನ್ನು ಸಂಪರ್ಕಪಡಿಸಲಾಗುವುದಿಲ್ಲ" - "ವೀಡಿಯೊ ವಿನಂತಿಯನ್ನು ತಿರಸ್ಕರಿಸಲಾಗಿದೆ" - "ನಿಮ್ಮ ಮರಳಿಕರೆ ಮಾಡುವ ಸಂಖ್ಯೆ\n %1$s" - "ನಿಮ್ಮ ತುರ್ತು ಮರಳಿಕರೆ ಮಾಡುವ ಸಂಖ್ಯೆ\n %1$s" - "ಡಯಲ್‌ ಮಾಡಲಾಗುತ್ತಿದೆ" - "ಮಿಸ್ಡ್‌ ಕಾಲ್‌" - "ಮಿಸ್ಡ್ ಕಾಲ್‌ಗಳು" - "%s ಮಿಸ್ಡ್ ಕಾಲ್‌ಗಳು" - "%s ಅವರಿಂದ ಮಿಸ್ಡ್ ಕಾಲ್" - "ಚಾಲ್ತಿಯಲ್ಲಿರುವ ಕರೆ" - "ಚಾಲ್ತಿಯಲ್ಲಿರುವ ಕೆಲಸದ ಕರೆ" - "ಚಾಲ್ತಿಯಲ್ಲಿರುವ ವೈ-ಫೈ ಕರೆ" - "ಚಾಲ್ತಿಯಲ್ಲಿರುವ ವೈ-ಫೈ ಕೆಲಸದ ಕರೆ" - "ತಡೆಹಿಡಿಯಲಾಗಿದೆ" - "ಒಳಬರುವ ಕರೆ" - "ಒಳಬರುವ ಕೆಲಸದ ಕರೆ" - "ಒಳಬರುವ ವೈ-ಫೈ ಕರೆ" - "ಒಳಬರುವ ವೈ-ಫೈ ಕೆಲಸದ ಕರೆ" - "ಒಳಬರುವ ವೀಡಿಯೊ ಕರೆ" - "ಒಳಬರುವ ಶಂಕಿತ ಸ್ಪ್ಯಾಮ್ ಕರೆ" - "ಒಳಬರುವ ವೀಡಿಯೊ ವಿನಂತಿ" - "ಹೊಸ ಧ್ವನಿಮೇಲ್‌" - "ಹೊಸ ಧ್ವನಿಮೇಲ್‌‌ (%d)" - "%s ಗೆ ಡಯಲ್‌‌ ಮಾಡು" - "ಅಪರಿಚಿತ ಧ್ವನಿಮೇಲ್‌ ಸಂಖ್ಯೆ" - "ಸೇವೆ ಇಲ್ಲ" - "ಆಯ್ಕೆಮಾಡಿದ (%s) ನೆಟ್‌ವರ್ಕ್‌ ಲಭ್ಯವಿಲ್ಲ" - "ಉತ್ತರ" - "ಹ್ಯಾಂಗ್ ಅಪ್" - "ವೀಡಿಯೊ" - "ಧ್ವನಿ" - "ಸಮ್ಮತಿಸು" - "ವಜಾಗೊಳಿಸಿ" - "ಮರಳಿ ಕರೆ" - "ಸಂದೇಶ" - "ಮತ್ತೊಂದು ಸಾಧನದಲ್ಲಿ ಚಾಲ್ತಿಯಲ್ಲಿರುವ ಕರೆ" - "ಕರೆ ವರ್ಗಾಯಿಸಿ" - "ಕರೆ ಮಾಡಲು, ಮೊದಲು ಏರ್‌ಪ್ಲೇನ್‌‌ ಮೋಡ್‌‌ ಆಫ್‌ ಮಾಡಿ." - "ನೆಟ್‌ವರ್ಕ್‌ನಲ್ಲಿ ಇನ್ನೂ ನೋಂದಣಿಯಾಗಿಲ್ಲ." - "ಸೆಲ್ಯುಲಾರ್ ನೆಟ್‌ವರ್ಕ್‌ ಲಭ್ಯವಿಲ್ಲ." - "ಕರೆಯನ್ನು ಮಾಡಲು, ಮಾನ್ಯವಾದ ಸಂಖ್ಯೆಯನ್ನು ನಮೂದಿಸಿ." - "ಕರೆ ಮಾಡಲು ಸಾಧ್ಯವಿಲ್ಲ." - "MMI ಅನುಕ್ರಮ ಪ್ರಾರಂಭವಾಗುತ್ತಿದೆ…" - "ಸೇವೆ ಬೆಂಬಲಿತವಾಗಿಲ್ಲ." - "ಕರೆಗಳನ್ನು ಬದಲಾಯಿಸಲು ಸಾಧ್ಯವಿಲ್ಲ." - "ಕರೆಯನ್ನು ಪ್ರತ್ಯೇಕಿಸಲು ಸಾಧ್ಯವಿಲ್ಲ." - "ವರ್ಗಾಯಿಸಲು ಸಾಧ್ಯವಿಲ್ಲ." - "ಕಾನ್ಫರೆನ್ಸ್ ಮಾಡಲು ಸಾಧ್ಯವಿಲ್ಲ." - "ಕರೆ ತಿರಸ್ಕರಿಸಲಾಗುವುದಿಲ್ಲ." - "ಕರೆ(ಗಳು) ಬಿಡುಗಡೆ ಮಾಡಲು ಸಾಧ್ಯವಿಲ್ಲ." - "SIP ಕರೆ" - "ತುರ್ತು ಕರೆ" - "ರೇಡಿಯೋ ಆನ್‌ ಮಾಡಲಾಗುತ್ತಿದೆ…" - "ಯಾವುದೇ ಸೇವೆ ಇಲ್ಲ. ಮತ್ತೆ ಪ್ರಯತ್ನಿಸಲಾಗುತ್ತಿದೆ..." - "ಕರೆ ಮಾಡಲು ಸಾಧ್ಯವಿಲ್ಲ. %s ತುರ್ತು ಸಂಖ್ಯೆಯಲ್ಲ." - "ಕರೆ ಮಾಡಲು ಸಾಧ್ಯವಿಲ್ಲ. ತುರ್ತು ಸಂಖ್ಯೆಯನ್ನು ಡಯಲ್ ಮಾಡಿ." - "ಡಯಲ್‌ ಮಾಡಲು ಕೀಬೋರ್ಡ್‌ ಬಳಸಿ" - "ಕರೆಯನ್ನು ಹೋಲ್ಡ್‌‌ ಮಾಡು" - "ಕರೆಯನ್ನು ಮುಂದುವರಿಸಿ" - "ಕರೆ ಅಂತ್ಯಗೊಳಿಸಿ" - "ಡಯಲ್‌ಪ್ಯಾಡ್ ತೋರಿಸು" - "ಡಯಲ್‌ಪ್ಯಾಡ್ ಮರೆಮಾಡು" - "ಮ್ಯೂಟ್" - "ಅನ್‌ಮ್ಯೂಟ್" - "ಕರೆಯನ್ನು ಸೇರಿಸು" - "ಕರೆಗಳನ್ನು ವಿಲೀನಗೊಳಿಸು" - "ಸ್ವ್ಯಾಪ್‌ ಮಾಡು" - "ಕರೆಗಳನ್ನು ನಿರ್ವಹಿಸಿ" - "ಕಾನ್ಫರೆನ್ಸ್ ಕರೆಯನ್ನು ನಿರ್ವಹಿಸಿ" - "ಕಾನ್ಫರೆನ್ಸ್ ಕರೆ" - "ನಿರ್ವಹಿಸು" - "ಆಡಿಯೊ" - "ವೀಡಿಯೊ ಕರೆ" - "ಧ್ವನಿ ಕರೆಗೆ ಬದಲಾಯಿಸಿ" - "ಕ್ಯಾಮರಾ ಬದಲಿಸಿ" - "ಕ್ಯಾಮರಾ ಆನ್ ಮಾಡಿ" - "ಕ್ಯಾಮರಾ ಆಫ್ ಮಾಡಿ" - "ಇನ್ನಷ್ಟು ಆಯ್ಕೆಗಳು" - "ಪ್ಲೇಯರ್‌ ಪ್ರಾರಂಭವಾಗಿದೆ" - "ಪ್ಲೇಯರ್‌ ನಿಲ್ಲಿಸಲಾಗಿದೆ" - "ಕ್ಯಾಮರಾ ಸಿದ್ಧವಾಗಿಲ್ಲ" - "ಕ್ಯಾಮರಾ ಸಿದ್ಧವಾಗಿದೆ" - "ಅಪರಿಚಿತ ಕರೆಯ ಸೆಶನ್‌ ಈವೆಂಟ್‌" - "ಸೇವೆ" - "ಸೆಟಪ್" - "<ಹೊಂದಿಸಿಲ್ಲ>" - "ಇತರ ಕರೆ ಸೆಟ್ಟಿಂಗ್‌ಗಳು" - "%s ಮೂಲಕ ಕರೆ ಮಾಡಲಾಗುತ್ತಿದೆ" - "%s ಮೂಲಕ ಒಳಬರುತ್ತಿರುವ ಕರೆ" - "ಸಂಪರ್ಕ ಫೋಟೋ" - "ಖಾಸಗಿಯಾಗಿ ಹೋಗಿ" - "ಸಂಪರ್ಕವನ್ನು ಆಯ್ಕೆಮಾಡಿ" - "ನಿಮ್ಮ ಸ್ವಂತದ್ದನ್ನು ಬರೆಯಿರಿ..." - "ರದ್ದುಮಾಡಿ" - "ಕಳುಹಿಸು" - "ಉತ್ತರ" - "SMS ಕಳುಹಿಸಿ" - "ನಿರಾಕರಿಸು" - "ವೀಡಿಯೊ ಕರೆ ರೂಪದಲ್ಲಿ ಉತ್ತರಿಸಿ" - "ಆಡಿಯೊ ಕರೆಯಂತೆ ಉತ್ತರಿಸಿ" - "ವೀಡಿಯೊ ವಿನಂತಿ ಒಪ್ಪಿಕೊಳ್ಳು" - "ವೀಡಿಯೊ ವಿನಂತಿ ತಿರಸ್ಕರಿಸು" - "ವೀಡಿಯೊ ಪ್ರಸಾರ ವಿನಂತಿ ಸಮ್ಮತಿಸಿ" - "ವೀಡಿಯೊ ಪ್ರಸಾರ ವಿನಂತಿ ತಿರಸ್ಕರಿಸಿ" - "ವೀಡಿಯೊ ಸ್ವೀಕರಿಸುವಿಕೆ ವಿನಂತಿ ಸಮ್ಮತಿಸಿ" - "ವೀಡಿಯೊ ಸ್ವೀಕರಿಸುವಿಕೆ ವಿನಂತಿ ತಿರಸ್ಕರಿಸಿ" - "%s ಗೆ ಮೇಲಕ್ಕೆ ಸ್ಲೈಡ್ ಮಾಡಿ." - "%s ಗೆ ಎಡಕ್ಕೆ ಸ್ಲೈಡ್ ಮಾಡಿ." - "%s ಗೆ ಬಲಕ್ಕೆ ಸ್ಲೈಡ್ ಮಾಡಿ." - "%s ಗೆ ಕೆಳಕ್ಕೆ ಸ್ಲೈಡ್ ಮಾಡಿ." - "ವೈಬ್ರೇಟ್‌" - "ವೈಬ್ರೇಟ್‌" - "ಶಬ್ದ" - "ಡಿಫಾಲ್ಟ್‌ ಧ್ವನಿ (%1$s)" - "ಫೋನ್ ರಿಂಗ್‌ಟೋನ್" - "ರಿಂಗ್ ಆಗುವಾಗ ವೈಬ್ರೇಟ್‌ ಆಗು" - "ರಿಂಗ್‌ಟೋನ್‌‌ ಮತ್ತು ವೈಬ್ರೇಟ್‌" - "ಕಾನ್ಫರೆನ್ಸ್ ಕರೆಯನ್ನು ನಿರ್ವಹಿಸಿ" - "ತುರ್ತು ಸಂಖ್ಯೆ" - "ಪ್ರೊಫೈಲ್ ಫೋಟೋ" - "ಕ್ಯಾಮರಾ ಆಫ್‌" - "%s ಮೂಲಕ" - "ಟಿಪ್ಪಣಿ ಕಳುಹಿಸಲಾಗಿದೆ" - "ಇತ್ತೀಚಿನ ಸಂದೇಶಗಳು" - "ವ್ಯಾಪಾರ ಮಾಹಿತಿ" - "%.1f ಮೈಲು ದೂರ" - "%.1f ಕಿಮೀ ದೂರ" - "%1$s, %2$s" - "%1$s - %2$s" - "%1$s, %2$s" - "ನಾಳೆ %s ಗಂಟೆಗೆ ತೆರೆಯುತ್ತದೆ" - "ಇಂದು %s ಗಂಟೆಗೆ ತೆರೆಯುತ್ತದೆ" - "%s ಗಂಟೆಗೆ ಮುಚ್ಚಲಾಗಿದೆ" - "ಇಂದು %s ಗಂಟೆಗೆ ಮುಚ್ಚಲಾಗಿದೆ" - "ಇದೀಗ ತೆರೆಯಲಾಗಿದೆ" - "ಇದೀಗ ಮುಚ್ಚಲಾಗಿದೆ" - "ಶಂಕಿತ ಸ್ಪ್ಯಾಮ್ ಕರೆದಾರರು" - "ಕರೆ ಮುಕ್ತಾಯಗೊಂಡಿದೆ %1$s" - "ಇದೇ ಮೊದಲ ಬಾರಿಗೆ ಈ ಸಂಖ್ಯೆಯಿಂದ ನಿಮಗೆ ಕರೆ ಮಾಡಲಾಗಿದೆ." - "ನಾವು ಈ ಕರೆಯನ್ನು ಸ್ಪ್ಯಾಮರ್‌ ಎಂದು ಶಂಕಿಸಿದ್ದೇವೆ." - "ಸ್ಪ್ಯಾಮ್ ನಿರ್ಬಂಧಿಸು/ವರದಿ ಮಾಡು" - "ಸಂಪರ್ಕ ಸೇರಿಸಿ" - "ಸ್ಪ್ಯಾಮ್‌ ಅಲ್ಲ" - diff --git a/InCallUI/res/values-ko/strings.xml b/InCallUI/res/values-ko/strings.xml deleted file mode 100644 index 973dc4637..000000000 --- a/InCallUI/res/values-ko/strings.xml +++ /dev/null @@ -1,195 +0,0 @@ - - - - - "전화" - "대기 중" - "알 수 없음" - "비공개 번호" - "공중전화" - "다자간 통화" - "연락되지 않음" - "스피커" - "핸드셋 수화부" - "유선 헤드셋" - "블루투스" - "다음 톤을 보내시겠습니까?\n" - "신호음 보내기\n" - "전송" - "예" - "아니요" - "와일드 문자를 다음으로 바꿈:" - "다자간 통화 %s" - "음성사서함 번호" - "전화 거는 중" - "재다이얼 중" - "다자간 통화" - "수신 전화" - "수신 업무 전화" - "통화 종료됨" - "대기 중" - "전화 끊는 중" - "통화 중" - "내 전화번호는 %s입니다." - "화상 통화 연결 중" - "화상 통화" - "화상 통화 요청 중" - "화상 통화를 연결할 수 없습니다." - "화상 통화 요청이 거부되었습니다." - "콜백 번호\n %1$s" - "긴급 콜백 번호\n%1$s" - "전화 거는 중" - "부재중 전화" - "부재중 전화" - "부재중 전화 %s통" - "%s의 부재중 전화" - "발신 전화" - "발신 업무 전화" - "발신 Wi-Fi 전화" - "발신 Wi-Fi 업무 전화" - "대기 중" - "수신 전화" - "수신 업무 전화" - "Wi-Fi 수신 전화" - "수신 Wi-Fi 업무 전화" - "수신 화상 통화" - "의심스러운 스팸 발신자로부터 온 전화" - "수신 화상 통화 요청" - "새로운 음성사서함" - "새 음성사서함(%d개)" - "%s(으)로 전화 걸기" - "알 수 없는 음성사서함 번호" - "서비스 불가" - "선택한 네트워크(%s)를 사용할 수 없음" - "전화 받기" - "전화 끊기" - "화상" - "음성" - "수락" - "해제" - "전화 걸기" - "메시지" - "다른 기기에서 진행 중인 통화" - "통화 전환" - "전화를 걸려면 먼저 비행기 모드를 해제하세요." - "네트워크에서 등록되지 않았습니다." - "사용 가능한 이동통신망이 없습니다." - "전화를 걸려면 올바른 번호를 입력하세요." - "전화를 걸 수 없습니다." - "MMI 시퀀스 시작 중..." - "서비스가 지원되지 않습니다." - "통화를 전환할 수 없습니다." - "통화를 분리할 수 없습니다." - "통화를 전환할 수 없습니다." - "다자간 통화를 이용할 수 없습니다." - "통화를 거부할 수 없습니다." - "통화를 끊을 수 없습니다." - "SIP 통화" - "긴급 전화" - "무선을 켜는 중..." - "서비스를 사용할 수 없습니다. 다시 시도 중..." - "전화를 걸 수 없습니다. %s은(는) 긴급 번호가 아닙니다." - "전화를 걸 수 없습니다. 긴급 번호를 사용하세요." - "키보드를 사용하여 전화 걸기" - "통화 대기" - "통화 재개" - "통화 종료" - "다이얼패드 표시" - "다이얼패드 숨기기" - "음소거" - "음소거 해제" - "통화 추가" - "통화 병합" - "전환" - "통화 관리" - "다자간 통화 관리" - "다자간 통화" - "관리" - "오디오" - "화상 통화" - "음성 통화로 변경" - "카메라 전환" - "카메라 켜기" - "카메라 끄기" - "옵션 더보기" - "플레이어가 시작되었습니다." - "플레이어가 중지되었습니다." - "카메라가 준비되지 않았습니다." - "카메라가 준비되었습니다." - "알 수 없는 통화 세션 이벤트" - "서비스" - "설정" - "<설정 안됨>" - "기타 통화 설정" - "%s을(를) 통해 걸려온 전화" - "%s을(를) 통해 걸려온 전화" - "연락처 사진" - "비공개로 실행" - "연락처 선택" - "나만의 응답 작성…" - "취소" - "전송" - "전화 받기" - "SMS 보내기" - "거부" - "화상 통화로 받기" - "음성 통화로 받기" - "화상 통화 요청 수락" - "화상 통화 요청 거부" - "화상 통화 전송 요청 허용" - "화상 통화 전송 요청 거부" - "화상 통화 수신 요청 허용" - "화상 통화 수신 요청 거부" - "%s하려면 위로 슬라이드합니다." - "%s하려면 왼쪽으로 슬라이드합니다." - "%s하려면 오른쪽으로 슬라이드합니다." - "%s하려면 아래로 슬라이드합니다." - "진동" - "진동" - "소리" - "기본 알림음(%1$s)" - "전화 벨소리" - "전화 수신 시 진동" - "벨소리 및 진동" - "다자간 통화 관리" - "비상 전화번호" - "프로필 사진" - "카메라 꺼짐" - "수신 번호: %s" - "메모가 전송되었습니다." - "최근 메시지" - "비즈니스 정보" - "%.1fmi 거리" - "%.1fkm 거리" - "%1$s, %2$s" - "%1$s~%2$s" - "%1$s, %2$s" - "내일 %s에 영업 시작" - "오늘 %s에 영업 시작" - "%s에 영업 종료" - "오늘 %s에 영업 종료됨" - "영업 중" - "영업 종료" - "의심스러운 스팸 발신자" - "%1$s번으로 끝나는 번호에서 걸려온 전화" - "이 번호에서 처음으로 걸려온 전화입니다." - "스팸 전화로 의심됩니다." - "스팸 차단/신고" - "연락처 추가" - "스팸 해제" - diff --git a/InCallUI/res/values-ky/strings.xml b/InCallUI/res/values-ky/strings.xml deleted file mode 100644 index bebdcfde8..000000000 --- a/InCallUI/res/values-ky/strings.xml +++ /dev/null @@ -1,195 +0,0 @@ - - - - - "Телефон" - "Күтүлүүдө" - "Белгисиз" - "Купуя номер" - "Таксофон" - "Конференц-чалуу" - "Чалуу үзүлдү" - "Катуу сүйлөткүч" - "Гарнитура" - "Зымдуу гарнитура" - "Bluetooth" - "Төмөнкү номер жөнөтүлсүнбү?\n" - "Обондор жөнөтүлүүдө\n" - "Жөнөтүү" - "Ооба" - "Жок" - "Атайын белгини төмөнкүгө алмаштыруу" - "Конференц-чалуу %s" - "Үн почтасынын номери" - "Терилүүдө" - "Кайра терилүүдө" - "Конференц-чалуу" - "Кирүүчү чалуу" - "Жумуш боюнча чалуу" - "Чалуу аяктады" - "Күтүлүүдө" - "Чалуу аяктоодо" - "Чалууда" - "Менин номерим %s" - "Видео туташтырылууда" - "Видео чалуу" - "Видео суралууда" - "Видео чалууга туташуу мүмкүн болбой жатат" - "Видео сурам четке кагылды" - "Кайра чалына турган номер\n %1$s" - "Өзгөчө кырдаалда кайра чалына турган номер\n %1$s" - "Терилүүдө" - "Кабыл алынбаган чалуу" - "Кабыл алынбаган чалуулар" - "%s кабыл алынбаган чалуу" - "%s дегенден кабыл алынбаган чалуу" - "Учурдагы чалуу" - "Учурдагы чалуу (жумуш боюнча)" - "Учурдагы Wi-Fi чалуу" - "Учурдагы Wi-Fi чалуу (жумуш боюнча)" - "Күтүлүүдө" - "Кирүүчү чалуу" - "Жумуш боюнча чалуу" - "Кирүүчү Wi-Fi чалуу" - "Жумуш боюнча келип жаткан Wi-Fi чалуу" - "Кирүүчү видео чалуу" - "Келип жаткан чалуу спам окшойт" - "Кирүүчү видео сурамы" - "Жаңы үн почтасы" - "Жаңы үн почтасы (%d)" - "%s номерин терүү" - "Үн почтасынын номери белгисиз" - "Байланыш жок" - "Тандалган тармак (%s) жеткиликсиз" - "Жооп берүү" - "Чалууну бүтүрүү" - "Видео" - "Үн" - "Кабыл алуу" - "Этибарга албоо" - "Кайра чалуу" - "Билдирүү" - "Башка түзмөктө сүйлөшүп жатасыз" - "Чалууну бул түзмөккө өткөрүү" - "Учак режимин өчүрүп туруп чалыңыз." - "Тармакта катталган эмес." - "Мобилдик тармак жеткиликтүү эмес." - "Чалуу үчүн, жарактуу номер киргизиңиз." - "Чалынбай жатат." - "MMI кезеги башталууда…" - "Кызмат колдоого алынбайт." - "Чалуулар которуштурулбай жатат." - "Чалуу бөлүнбөй жатат." - "Өткөрүлбөй жатат." - "Конференц-чалуу түзүлбөй жатат." - "Чалуу четке кагылбай жатат." - "Чалуу (-лар) ажыратылбай жатат." - "SIP чалуу" - "Өзгөчө кырдаалда чалуу" - "Радио күйгүзүлүүдө…" - "Кызмат жок. Кайра аракет кылууда…" - "Чалынбай жатат. %s өзгөчө кырдаал номери эмес." - "Чалынбай жатат. Өзгөчө кырдаал номерин териңиз." - "Баскычтоп менен териңиз" - "Чалууну кармап туруу" - "Чалууну улантуу" - "Чалууну бүтүрүү" - "Номер тергичти көрсөтүү" - "Номер тергичти жашыруу" - "Үнсүз" - "Үндү чыгаруу" - "Чалуу кошуу" - "Чалууларды бириктирүү" - "Алмаштыруу" - "Чалууларды башкаруу" - "Конференц-чалууну башкаруу" - "Конференц чалуу" - "Башкаруу" - "Аудио" - "Видео чалуу" - "Үн чалууга өзгөртүү" - "Камераны которуштуруу" - "Камераны күйгүзүү" - "Камераны өчүрүү" - "Дагы параметрлер" - "Ойноткуч башталды" - "Ойноткуч токтотулду" - "Камера даяр эмес" - "Камера даяр" - "Чалуу сеансынын окуясы белгисиз" - "Кызмат" - "Орнотуу" - "<Коюлган эмес>" - "Башка чалуу жөндөөлөрү" - "%s аркылуу чалуу" - "%s аркылуу келүүдө" - "байланыштын сүрөтү" - "купуя режимине өтүү" - "байланыш тандоо" - "Сиздин жообуңуз…" - "Жокко чыгаруу" - "Жөнөтүү" - "Жооп берүү" - "SMS жөнөтүү" - "Четке кагуу" - "Видео чалуу түрүндө жооп берүү" - "Аудио чалуу түрүндө жооп берүү" - "Видео сурамын кабыл алуу" - "Видео сурамын четке кагуу" - "Видео өткөрүү сурамын кабыл алуу" - "Видео өткөрүү сурамын четке кагуу" - "Видео алуу сурамын кабыл алуу" - "Видео алуу сурамын четке кагуу" - "%s үчүн жогору жылмыштырыңыз." - "%s үчүн солго жылмыштырыңыз." - "%s үчүн оңго жылмыштырыңыз." - "%s үчүн төмөн жылмыштырыңыз." - "Дирилдөө" - "Дирилдөө" - "Үн" - "Демейки үнү (%1$s)" - "Телефондун рингтону" - "Дирилдеп шыңгырасын" - "Шыңгыр жана дирилдөө" - "Конференц-чалууну башкаруу" - "Өзгөчө кырдаал номери" - "Профилдин сүрөтү" - "Камера өчүк" - "%s аркылуу" - "Билдирүү жөнөтүлдү" - "Акыркы билдирүүлөр" - "Компания тууралуу маалымат" - "%.1f миля алыста" - "%.1f км алыста" - "%1$s, %2$s" - "%1$s%2$s" - "%1$s, %2$s" - "Эртең саат %s ачылат" - "Бүгүн саат %s ачылат" - "Саат %s жабылат" - "Бүгүн саат %s жабылды" - "Азыр ачык" - "Эми жабылды" - "Спам окшойт" - "Чалуу %1$s бүттү" - "Бул номер сизге биринчи жолу чалып жатат." - "Бул чалуу спам окшойт." - "Бөгөттөө/спам катары кабарлоо" - "Байланыш кошуу" - "Спам эмес" - diff --git a/InCallUI/res/values-lo/strings.xml b/InCallUI/res/values-lo/strings.xml deleted file mode 100644 index 3e7e81520..000000000 --- a/InCallUI/res/values-lo/strings.xml +++ /dev/null @@ -1,195 +0,0 @@ - - - - - "ໂທລະສັບ" - "ຖືສາຍລໍຖ້າ" - "ບໍ່ຮູ້ຈັກ" - "ເບີສ່ວນຕົວ" - "ຕູ້​ໂທ​ລະ​ສັບ​ສາ​ທາ​ລະ​ນະ" - "ການປະຊຸມທາງໂທລະສັບ" - "ສາຍ​ຫຼຸດ​ແລ້ວ" - "ລຳໂພງ" - "ຊຸດຫູຟັງ" - "ຊຸດຫູຟັງແບບມີສາຍ" - "Bluetooth" - "ສົ່ງໂທນສຽງຕໍ່ໄປນີ້ບໍ?\n" - "ກຳລັງສົ່ງໂທນສຽງ\n" - "ສົ່ງ" - "ແມ່ນ" - "ບໍ່" - "ປ່ຽນແທນ \"ອັກຂະລະຕົວແທນ\" ດ້ວຍ" - "ການປະຊຸມທາງໂທລະສັບ %s" - "ເບີຂໍ້ຄວາມສຽງ" - "ກຳລັງໂທ" - "ກຳ​ລັງ​ໂທ​ຄືນ" - "ການປະຊຸມທາງໂທລະສັບ" - "​ສາຍ​ໂທ​ເຂົ້າ" - "ສາຍໂທເຂົ້າຈາກບ່ອນເຮັດວຽກ" - "ວາງສາຍແລ້ວ" - "ຖືສາຍລໍຖ້າ" - "ກຳລັງວາງສາຍ" - "ຢູ່ໃນສາຍ" - "ເບີໂທຂອງຂ້ອຍແມ່ນ %s" - "​ກຳ​ລັງ​ເຊື່ອມ​ຕໍ່​ວິ​ດີ​ໂອ" - "​ການໂທ​​ວິ​ດີ​ໂອ" - "​ກຳ​ລັງ​ຮ້ອງ​ຂໍການໂທ​ວິ​ດີ​ໂອ" - "ບໍ່​ສາ​ມາດ​ເຊື່ອມ​ຕໍ່​ການ​ໂທວິດີໂອ​ໄດ້" - "ປະ​ຕິ​ເສດ​ການຮ້ອງ​ຂໍການ​ໂທວິ​ດີ​ໂອ​ແລ້ວ" - "ເບີໂທກັບຂອງທ່ານ\n %1$s" - "ເບີ​ໂທ​ກັບ​ສຸກ​ເສີນ​ຂອງ​ທ່ານ\n %1$s" - "ກຳລັງໂທ" - "ສາຍບໍ່ໄດ້ຮັບ" - "ສາຍບໍ່ໄດ້ຮັບ" - "%s ສາຍບໍ່ໄດ້ຮັບ" - "ສາຍບໍ່ໄດ້ຮັບຈາກ %s" - "ສາຍກຳລັງໂທ" - "ສາຍກຳລັງໂທຈາກບ່ອນເຮັດວຽກ" - "ສາຍກຳລັງໂທຜ່ານ Wi​-Fi" - "ສາຍກຳລັງໂທຜ່ານ Wi-Fi ຈາກບ່ອນເຮັດວຽກ" - "ຖືສາຍລໍຖ້າ" - "​ສາຍ​ໂທ​ເຂົ້າ" - "ສາຍໂທເຂົ້າຈາກບ່ອນເຮັດວຽກ" - "ສາຍໂທເຂົ້າຜ່ານ Wi-Fi" - "ສາຍໂທເຂົ້າຜ່ານ Wi-Fi ຈາກບ່ອນເຮັດວຽກ" - "ສາຍໂທ​ວິດີໂອ​ເຂົ້າ" - "ມີການໂທທີ່ຄາດວ່າເປັນສະແປມໂທເຂົ້າມາ" - "​ຄຳ​ຮ້ອງ​ຂໍ​ວິ​ດີ​ໂອທີ່​ເຂົ້າ​ມາ" - "ຂໍ້ຄວາມສຽງໃໝ່" - "ຂໍ້ຄວາມສຽງໃໝ່ (%d)" - "ໂທຫາ %s" - "ເບີຂໍ້ຄວາມສຽງບໍ່ຮູ້ຈັກ" - "ບໍ່ມີການບໍລິການ" - "ເຄືອຂ່າຍທີ່ເລືອກ (%s) ບໍ່ສາມາດໃຊ້ໄດ້" - "ຮັບສາຍ" - "ວາງສາຍ" - "ວິດີໂອ" - "ສຽງ" - "ຍອມຮັບ" - "ປິດໄວ້" - "ໂທກັບ" - "ຂໍ້ຄວາມ" - "ສາຍທີ່ກຳລັງໂທອອກໃນອຸປະກອນອື່ນ" - "ໂອນສາຍ" - "ເພື່ອເຮັດການໂທ, ໃຫ້ປິດໂໝດເຮືອບິນກ່ອນ" - "ບໍ່ໄດ້ລົງທະບຽນໃນເຄືອຂ່າຍ." - "ບໍ່​ມີ​ເຄືອ​ຂ່າຍ​ມື​ຖື​ທີ່​​ໃຊ້​ໄດ້." - "ເພື່ອເຮັດການ​ໂທ, ປ້ອນ​ເບີ​ໂທ​ທີ່​ໃຊ້​ໄດ້​." - "ບໍ່​ສາ​ມາດ​ໂທ​ໄດ້." - "ກຳລັງເລີ່ມຕົ້ນລຳດັບ MMI..." - "ບໍ່ຮອງຮັບການ​ບໍ​ລິ​ການ." - "ບໍ່​ສາ​ມາດ​ສະ​ຫຼັບ​ສາ​ຍ​ໂທ​ໄດ້." - "ບໍ່​ສາ​ມາດ​ແຍກ​ສາຍ​ໂທ​ໄດ້." - "ບໍ່​ສາ​ມາດ​ໂອນສາຍ​ໄດ້." - "ບໍ່​ສາ​ມາດ​ປະ​ຊຸມ​ໄດ້." - "ບໍ່​ສາ​ມາດ​ປະ​ຕິ​ເສດ​ສາຍ​ໂທ​ໄດ້." - "ບໍ່​ສາ​ມາດ​ປ່ອຍ​ສາຍ​ໂທ​ໄດ້." - "ການໂທ SIP" - "ການໂທສຸກເສີນ" - "ກຳລັງເປີດວິທະຍຸ" - "ບໍ່​ມີ​ການ​ບໍ​ລິ​ການ. ກຳ​ລັງ​ລອງ​ໃໝ່​ອີກ…" - "ບໍ່ສາມາດໂທໄດ້. %s ບໍ່ແມ່ນເບີໂທສຸກເສີນ." - "ບໍ່​ສາ​ມາດ​ໂທ​ໄດ້. ກົດ​ເບີ​ໂທ​ສຸກ​ເສີນ." - "ໃຊ້ແປ້ນພິມເພື່ອກົດໂທ" - "ຖືສາຍ" - "​ສືບ​ຕໍ່​ສາຍ" - "ວາງສາຍ" - "ສະແດງປຸ່ມກົດ" - "ເຊື່ອງປຸ່ມກົດ" - "ປິດສຽງ" - "ເຊົາປິດສຽງ" - "ເພີ່ມການໂທ" - "ລວມສາຍ" - "ສະຫຼັບ" - "ຈັດການການໂທ" - "ຈັດ​ການ​ການ​ປະ​ຊຸມ​ທາງໂທລະສັບ" - "ການປະຊຸມທາງໂທລະສັບ" - "ຈັດການ" - "ສຽງ" - "​ການໂທ​​ວິ​ດີ​ໂອ" - "ປ່ຽນ​ເປັນ​ການ​ໂທ​ດ້ວຍ​ສຽງ" - "ສັບປ່ຽນກ້ອງ" - "ເປີດກ້ອງ" - "ປິດກ້ອງ" - "ຕົວເລືອກ​ເພີ່ມ​ເຕີມ" - "ເຄື່ອງ​ຫຼິ້ນ​ເລີ່ມ​ຕົ້ນ​ແລ້ວ" - "ເຄື່ອງ​ຫຼິ້ນ​ຢຸດ​ແລ້ວ" - "ກ້ອງ​ຖ່າຍ​ຮູບ​ບໍ່​ພ້ອມ" - "ກ້ອງ​ຖ່າຍ​ຮູບ​ພ້ອມ​ແລ້ວ" - "ເຫດ​ການ​ເຊ​ສ​ຊັນ​ການ​ໂທ​ບໍ່​ຮູ້​ຈັກ" - "ການບໍລິການ" - "ຕັ້ງຄ່າ" - "<ບໍ່ໄດ້ຕັ້ງ>" - "ການຕັ້ງຄ່າການໂທອື່ນ" - "ກຳລັງໂທຜ່ານ %s" - "ສາຍໂທເຂົ້າ​ຈາກ %s" - "ຮູບລາຍຊື່ຜູ້ຕິດຕໍ່" - "ໃຊ້ແບບສ່ວນຕົວ" - "ເລືອກລາຍຊື່ຜູ້ຕິດຕໍ່" - "ຂຽນ...ຂອງທ່ານເອງ" - "ຍົກເລີກ" - "ສົ່ງ" - "ຮັບສາຍ" - "ສົ່ງ SMS" - "ປະຕິເສດ" - "ຮັບສາຍໂທວິດີໂອ" - "ຮັບສາຍໂທແບບສຽງ" - "ຍອມຮັບການຂໍວິດີໂອ" - "ປະຕິເສດການຂໍວິດີໂອ" - "ຍອມ​ຮັບ​ການ​ຂໍ​ສົ່ງ​ວິ​ດີ​ໂອ" - "ປະ​ຕິ​ເສດ​ການ​ຂໍ​ສົ່ງ​ວິ​ດີ​ໂອ" - "ຍອມ​ຮັບ​ການ​ຂໍ​ຮັບ​ວິ​ດີ​ໂອ" - "ປະ​ຕິ​ເສດ​ການ​ຂໍ​ຮັບ​ວິ​ດີ​ໂອ" - "ເລື່ອນຂຶ້ນເພື່ອ %s." - "ເລື່ອນໄປຊ້າຍເພື່ອ %s." - "ເລື່ອນໄປຂວາເພື່ອ %s." - "ເລື່ອນລົງເພື່ອ %s." - "ສັ່ນເຕືອນ" - "ສັ່ນເຕືອນ" - "ສຽງ" - "ສຽງເລີ່ມຕົ້ນ (%1$s)" - "ຣິງໂທນໂທລະສັບ" - "ສັ່ນເຕືອນເມື່ອດັງ" - "ຣິງໂທນ ແລະ ການສັ່ນເຕືອນ" - "ຈັດ​ການ​ການ​ປະ​ຊຸມ​ທາງໂທລະສັບ" - "ເບີໂທສຸກເສີນ" - "ຮູບໂປຣໄຟລ໌" - "ກ້ອງ​ຖ່າຍ​ຮູບ​ປິດຢູ່" - "ຜ່ານ %s" - "ສົ່ງ​ບັນ​ທຶກ​ແລ້ວ" - "ຂໍ້​ຄວາມ​ບໍ່​ດົນ​ມາ​ນີ້" - "ຂໍ້​ມູນ​ທຸ​ລະ​ກິດ" - "ຫ່າງອອກໄປ %.1f ໄມ​ລ໌​" - "ຫ່າງອອກໄປ %.1f ກມ" - "%1$s, %2$s" - "%1$s - %2$s" - "%1$s, %2$s" - "ເປີດມື້ອື່ນເວລາ %s" - "ເປີດມື້ນີ້ເວລາ %s" - "ປິດເວລາ %s" - "ປິດແລ້ວມື້ນີ້ເວລາ %s" - "ດຽວ​ນີ້​ເປີດ" - "​ປິດ​ແລ້ວດຽວນີ້" - "ຄາດວ່າເປັນການໂທສະແປມ" - "ການໂທສິ້ນສຸດແລ້ວ %1$s" - "ນີ້ເປັນເທື່ອທຳອິດທີ່ເບີນີ້ໂທຫາທ່ານ." - "ພວກເຮົາສົງໄສວ່າເບີໂທນີ້ເປັນສະແປມ." - "ບລັອກ/ລາຍງານສະແປມ" - "ເພີ່ມລາຍຊື່ຜູ້ຕິດຕໍ່" - "ບໍ່ແມ່ນສະແປມ" - diff --git a/InCallUI/res/values-lt/strings.xml b/InCallUI/res/values-lt/strings.xml deleted file mode 100644 index 2d2a70146..000000000 --- a/InCallUI/res/values-lt/strings.xml +++ /dev/null @@ -1,195 +0,0 @@ - - - - - "Telefonas" - "Sulaikyta" - "Nežinoma" - "Privatus numeris" - "Taksofonas" - "Konferencinis skambutis" - "Skambutis atmestas" - "Garsiakalbis" - "Tel. su gars. prie ausies" - "Laidinės ausinės" - "Bluetooth" - "Siųsti šiuo tonus?\n" - "Siunčiami tonai\n" - "Siųsti" - "Taip" - "Ne" - "Pakaitos simbolį pakeisti" - "Konferencinis skambutis %s" - "Balso pašto numeris" - "Renkamas numeris" - "Numeris renkamas pakartotinai" - "Konferencinis skambutis" - "Gaunamasis skambutis" - "Gaunamasis darbo skambutis" - "Skambutis baigtas" - "Sulaikyta" - "Baigiamas pokalbis" - "Dalyvauju skambutyje" - "Mano numeris: %s" - "Prisijungiama prie vaizdo skambučio" - "Vaizdo skambutis" - "Pateikiama vaizdo skambučio užklausa" - "Nepavyko prijungti vaizdo įrašo skambučio" - "Vaizdo įrašo užklausa atmesta" - "Atskambinimo numeris\n%1$s" - "Atskambinimo numeris, kuriuos skambina pagalbos tarnyba\n%1$s" - "Renkamas numeris" - "Praleistas skambutis" - "Praleisti skambučiai" - "Praleistų skambučių: %s" - "Praleistas skambutis nuo %s" - "Vykstantis pokalbis" - "Vykstantis darbo skambutis" - "Vykstantis „Wi-Fi“ skambutis" - "Vykstantis „Wi-Fi“ darbo skambutis" - "Sulaikyta" - "Gaunamasis skambutis" - "Gaunamasis darbo skambutis" - "Gaunamasis „Wi-Fi“ skambutis" - "Gaunamasis „Wi-Fi“ darbo skambutis" - "Gaunamas vaizdo skambutis" - "Gaunamasis įtartinas šlamšto skambutis" - "Gaunama vaizdo skambučio užklausa" - "Naujas balso pašto pranešimas" - "Naujas balso pašto pranešimas (%d)" - "Rinkti %s" - "Nežinomas balso pašto numeris" - "Nėra paslaugos" - "Pasirinktas tinklas (%s) negalimas" - "Atsiliepti" - "Padėti ragelį" - "Vaizdo įrašas" - "Balsas" - "Priimti" - "Atsisakyti" - "Perskambinti" - "Siųsti pranešimą" - "Kitame įrenginyje vykstantis skambutis" - "Perkelti skambutį" - "Jei norite skambinti, išjunkite lėktuvo režimą." - "Neregistruota tinkle." - "Korinis tinklas nepasiekiamas" - "Kad galėtumėte paskambinti, įveskite tinkamą numerį." - "Nepavyko paskambinti." - "Paleidžiama MMI seka..." - "Paslauga nepalaikoma." - "Nepavyko perjungti skambučių." - "Nepavyko atskirti skambučio." - "Nepavyko peradresuoti." - "Nepavyko sukurti konferencijos." - "Nepavyko atmesti skambučio." - "Nepavyko atjungti skamb." - "SIP skambutis" - "Skambutis pagalbos numeriu" - "Įjungiamas radijas…" - "Nėra ryšio. Bandoma dar kartą…" - "Nepavyko paskambinti. %s nėra pagalbos numeris." - "Nepavyko paskambinti. Surinkite pagalbos tarnybos numerį." - "Naudokite klaviatūrą ir rinkite numerius" - "Sulaikyti skambutį" - "Tęsti skambutį" - "Baigti skambutį" - "Rodyti skambinimo skydelį" - "Slėpti skambinimo skydelį" - "Nutildyti" - "Įjungti garsą" - "Pridėti skambutį" - "Sujungti skambučius" - "Apkeisti" - "Valdyti skambučius" - "Tvarkyti konferencinį skambutį" - "Konferencinis skambutis" - "Tvarkyti" - "Garsas" - "Vaizdo skambutis" - "Pakeisti į balso skambutį" - "Perjungti fotoaparatą" - "Įjungti fotoaparatą" - "Išjungti fotoaparatą" - "Daugiau parinkčių" - "Leistuvė paleista" - "Leistuvė sustabdyta" - "Fotoaparatas neparuoštas" - "Fotoaparatas paruoštas" - "Nežinomas skambučio sesijos įvykis" - "Paslaugos teikėjas" - "Sąranka" - "<Nenustatyta>" - "Kiti skambučio nustatymai" - "Skambinama naudojantis „%s“ paslaugomis" - "Gaunama per „%s“" - "kontakto nuotrauka" - "naudoti privatų režimą" - "pasirinkti kontaktą" - "Sukurkite patys..." - "Atšaukti" - "Siųsti" - "Atsiliepti" - "Siųsti SMS" - "Atmesti" - "Atsiliepti kaip į vaizdo skambutį" - "Atsiliepti kaip į garso skambutį" - "Priimti vaizdo įrašo užkl" - "Atmesti vaizdo įrašo užklausą" - "Priimti vaizdo įrašo perdavimo užklausą" - "Atmesti vaizdo įrašo perdavimo užklausą" - "Priimti vaizdo įrašo gavimo užklausą" - "Atmesti vaizdo įrašo gavimo užklausą" - "Slyskite aukštyn link parinkties „%s“." - "Slyskite į kairę link parinkties „%s“." - "Slyskite į dešinę link parinkties „%s“." - "Slyskite žemyn link %s." - "Vibruoti" - "Vibruoti" - "Garsas" - "Numatytasis garsas (%1$s)" - "Telefono skambėjimo tonas" - "Vibruoti, kai skambina" - "Skambėjimo tonas ir vibracija" - "Tvarkyti konferencinį skambutį" - "Pagalbos numeris" - "Profilio nuotrauka" - "Fotoaparatas išjungtas" - "naudojant %s" - "Užrašas išsiųstas" - "Naujausi pranešimai" - "Įmonės informacija" - "Už %.1f myl." - "Už %.1f km" - "%1$s, %2$s" - "%1$s%2$s" - "%1$s, %2$s" - "Rytoj atidaroma %s" - "Šiandien atidaroma %s" - "Uždaroma %s" - "Šiandien uždaryta %s" - "Dabar atidaryta" - "Dabar uždaryta" - "Įt. skamb. dėl šl." - "Skambutis baigtas (%1$s)" - "Tai pirmas kartas, kai jums buvo skambinama iš šio numerio." - "Įtarėme, kad šis skambutis yra šlamštas." - "Bl. / pran. apie šl." - "Pridėti kontaktą" - "Ne šlamštas" - diff --git a/InCallUI/res/values-lv/strings.xml b/InCallUI/res/values-lv/strings.xml deleted file mode 100644 index 685ba8b0c..000000000 --- a/InCallUI/res/values-lv/strings.xml +++ /dev/null @@ -1,195 +0,0 @@ - - - - - "Tālrunis" - "Aizturēts" - "Nezināms" - "Privāts numurs" - "Maksas tālrunis" - "Konferences zvans" - "Zvans tika pārtraukts." - "Skaļrunis" - "Auss skaļrunis" - "Austiņas ar vadu" - "Bluetooth" - "Vai sūtīt tālāk norādītos signālus?\n" - "Sūtīšanas signāli\n" - "Sūtīt" - "Jā" - "Nē" - "Aizstāt aizstājējzīmi ar:" - "Konferences zvans: %s" - "Balss pasta numurs" - "Notiek numura sastādīšana" - "Notiek atkārtota zvanīšana" - "Konferences zvans" - "Ienākošs zvans" - "Ienākošs darba zvans" - "Zvans ir pabeigts" - "Aizturēts" - "Notiek klausules nolikšana" - "Notiek zvans" - "Mans tālruņa numurs: %s" - "Notiek video savienojuma izveide" - "Videozvans" - "Notiek video pieprasīšana" - "Nevar veikt videozvanu" - "Video pieprasījums noraidīts" - "Jūsu atzvana numurs\n %1$s" - "Jūsu ārkārtas atzvana numurs\n %1$s" - "Notiek numura sastādīšana" - "Neatbildēts zvans" - "Neatbildēti zvani" - "%s neatbildēti zvani" - "Neatbildēts zvans no: %s" - "Notiekošs zvans" - "Notiekošs darba zvans" - "Notiekošs Wi-Fi zvans" - "Notiekošs darba Wi-Fi zvans" - "Aizturēts" - "Ienākošs zvans" - "Ienākošs darba zvans" - "Ienākošs Wi-Fi zvans" - "Ienākošs darba Wi-Fi zvans" - "Ienākošs videozvans" - "Ienākošs, iespējams, nevēlams zvans" - "Ienākošs video pieprasījums" - "Jauns balss pasta ziņojums" - "Jauns balss pasts (%d)" - "Sastādiet šādu numuru: %s" - "Balss pasta numurs nav zināms." - "Nav pakalpojuma" - "Atlasītais tīkls (%s) nav pieejams." - "Atbildēt" - "Beigt zvanu" - "Video" - "Balss" - "Pieņemt" - "Noraidīt" - "Atzvanīt" - "Sūtīt īsziņu" - "Notiekošs zvans citā ierīcē" - "Pāradresēt zvanu" - "Lai veiktu zvanu, vispirms izslēdziet lidojuma režīmu." - "Nav reģistrēts tīklā." - "Mobilais tīkls nav pieejams." - "Lai veiktu zvanu, ievadiet derīgu numuru." - "Nevar veikt zvanu." - "Notiek MMI secības startēšana…" - "Pakalpojums netiek atbalstīts." - "Nevar pārslēgt zvanus." - "Nevar nošķirt zvanu." - "Nevar pārsūtīt." - "Nevar veikt konferences zvanu." - "Nevar noraidīt zvanu." - "Nevar pārtraukt zvanu(-us)." - "SIP zvans" - "Ārkārtas izsaukums" - "Notiek radio ieslēgšana…" - "Nav pakalpojuma. Notiek atkārtots mēģinājums…" - "Nevar veikt zvanu. %s nav ārkārtas numurs." - "Nevar veikt zvanu. Zvaniet ārkārtas numuram." - "Izmantojiet tastatūru, lai sastādītu numuru" - "Aizturēt zvanu" - "Atsākt zvanu" - "Beigt zvanu" - "Rādīt numura sastādīšanas tastatūru" - "Slēpt numura sastādīšanas tastatūru" - "Izslēgt skaņu" - "Ieslēgt skaņu" - "Pievienot zvanu" - "Apvienot zvanus" - "Mainīt" - "Pārvaldīt zvanus" - "Pārvaldīt konferences zvanu" - "Konferences zvans" - "Pārvaldīt" - "Audio" - "Videozvans" - "Mainīt uz balss zvanu" - "Pārslēgt kameru" - "Ieslēgt kameru" - "Izslēgt kameru" - "Citas iespējas" - "Atskaņošana sākta" - "Atskaņošana apturēta" - "Kamera nav gatava" - "Kamera ir gatava" - "Nezināms zvana sesijas notikums" - "Pakalpojums" - "Iestatīšana" - "<Nav iestatīts>" - "Citi zvanu iestatījumi" - "Zvans, ko nodrošina %s" - "Ienākošie zvani, ko nodrošina %s" - "kontaktpersonas fotoattēls" - "pārslēgt uz privāto režīmu" - "atlasīt kontaktpersonu" - "Rakstīt savu…" - "Atcelt" - "Sūtīt" - "Atbildēt" - "Sūtīt īsziņu" - "Noraidīt" - "Atbildēt videozvanā" - "Atbildēt audiozvanā" - "Apstiprināt video pieprasījumu" - "Noraidīt video pieprasījumu" - "Apstiprināt video pārsūtīšanas pieprasījumu" - "Noraidīt video pārsūtīšanas pieprasījumu" - "Apstiprināt video saņemšanas pieprasījumu" - "Noraidīt video saņemšanas pieprasījumu" - "Velciet uz augšu, lai veiktu šādu darbību: %s." - "Velciet pa kreisi, lai veiktu šādu darbību: %s." - "Velciet pa labi, lai veiktu šādu darbību: %s." - "Velciet uz leju, lai veiktu šādu darbību: %s." - "Vibrācija" - "Vibrācija" - "Signāls" - "Noklusējuma signāls (%1$s)" - "Tālruņa zvana signāls" - "Vibrācija zvana laikā" - "Zvana signāls un vibrācija" - "Konferences zvana pārvaldība" - "Ārkārtas numurs" - "Profila fotoattēls" - "Kamera ir izslēgta" - "no numura %s" - "Piezīme nosūtīta" - "Pēdējie ziņojumi" - "Informācija par uzņēmumu" - "%.1f jūdzes(-džu) attālumā" - "%.1f km attālumā" - "%1$s, %2$s" - "%1$s%2$s" - "%1$s, %2$s" - "Tiks atvērts rīt plkst. %s" - "Tiks atvērts šodien plkst. %s" - "Tiks slēgts plkst. %s" - "Tika slēgts šodien plkst. %s" - "Atvērts" - "Slēgts" - "Nevēlams zvanītājs" - "Zvans beidzās: %1$s" - "Šis jums ir pirmais zvans no šī numura." - "Iespējams, šis zvans bija no nevēlama zvanītāja." - "Bloķēt numuru/ziņot" - "Pievienot personu" - "Nav nevēlams numurs" - diff --git a/InCallUI/res/values-mk/strings.xml b/InCallUI/res/values-mk/strings.xml deleted file mode 100644 index 3161c5475..000000000 --- a/InCallUI/res/values-mk/strings.xml +++ /dev/null @@ -1,195 +0,0 @@ - - - - - "Телефон" - "На чекање" - "Непознат" - "Приватен број" - "Говорница" - "Конференциски повик" - "Повикот е прекинат" - "Звучник" - "Слушалка" - "Жичени слушалки" - "Bluetooth" - "Испратете ги следниве тонови?\n" - "Се испраќаат тонови\n" - "Испрати" - "Да" - "Не" - "Заменете го резервниот знак со" - "Конференциски повик %s" - "Број на говорна пошта" - "Бирање" - "Повторно бирање" - "Конференциски повик" - "Дојдовен повик" - "Дојдовен работен повик" - "Повикот заврши" - "На чекање" - "Повикот се прекинува" - "Повик во тек" - "Мојот број е %s" - "Се поврзува видео" - "Видеоповик" - "Се бара видео" - "Не може да се поврзе видеоповик" - "Барањето за видео е одбиено" - "Вашиот број за повратен повик\n %1$s" - "Вашиот број за итен повик\n %1$s" - "Бирање" - "Пропуштен повик" - "Пропуштени повици" - "%s пропуштени повици" - "Пропуштен повик од %s" - "Тековен повик" - "Тековен работен повик" - "Појдовен повик преку Wi-Fi" - "Тековен работен повик преку Wi-Fi" - "На чекање" - "Дојдовен повик" - "Дојдовен работен повик" - "Дојдовен повик преку Wi-Fi" - "Дојдовен работен повик преку Wi-Fi" - "Дојдовен видеоповик" - "Дојдовниот повик може да е спам" - "Дојдовно барање за видео" - "Нова говорна пошта" - "Нова говорна пошта (%d)" - "Бирај %s" - "Непознат број на говорна пошта" - "Нема услуга" - "Избраната мрежа (%s) е недостапна" - "Одговори" - "Спушти" - "Видео" - "Гласовен" - "Прифати" - "Отфрли" - "Врати повик" - "Порака" - "Повик во тек на друг уред" - "Префрлање повик" - "За да остварите повик, прво исклучете го авионскиот режим." - "Не е регистриран на мрежа." - "Не е достапна мобилна мрежа." - "За да остварите повик, внесете важечки број." - "Не може да се повика." - "Започнува ММИ низа..." - "Услугата не е поддржана." - "Не може да се префрлат повици." - "Не може да се оддели повик." - "Не може да се пренесе." - "Не може да се оствари конференциски повик." - "Не може да се отфрли повик." - "Не може да се оствари повик." - "Повик преку SIP" - "Повик за итни случаи" - "Се вклучува радиото..." - "Нема услуга. Се обидува повторно…" - "Не може да се повика. %s не е број за итни повици." - "Не може да се повика. Бирајте го бројот за итни повици." - "Користете ја тастатурата за бирање" - "Стави на чекање" - "Продолжи го повикот" - "Заврши го повикот" - "Прикажи копчиња за бирање" - "Сокриј копчиња за бирање" - "Исклучи звук" - "Вклучи звук" - "Додај повик" - "Спои повици" - "Замени" - "Управувај со повици" - "Управувај со конференциски повик" - "Конференциски повик" - "Управувај" - "Аудио" - "Видеоповик" - "Промени во гласовен повик" - "Промени ја камерата" - "Вклучете ја камерата" - "Исклучете ја камерата" - "Повеќе опции" - "Плеерот се вклучи" - "Плеерот запре" - "Камерата не е подготвена" - "Камерата е подготвена" - "Непознат настан при сесија повици" - "Услуга" - "Поставување" - "<Нема поставка>" - "Други поставки за повик" - "Повикување преку %s" - "Дојдовни повици преку %s" - "фотографија на контакт" - "префли на приватно" - "избери контакт" - "Напиши сопствена..." - "Откажи" - "Испрати" - "Одговори" - "Испрати SMS" - "Одбиј" - "Одговори со видеоповик" - "Одговори со аудиоповик" - "Прифати барање за видео" - "Одбиј барање за видео" - "Прифати барање за пренос на видео" - "Одбиј барање за пренос на видео" - "Прифати барање за прием на видео" - "Одбиј барање за прием на видео" - "Лизгај нагоре за %s." - "Лизгај налево за %s." - "Лизгај надесно за %s." - "Лизгај надолу за %s." - "Вибрации" - "Вибрации" - "Звук" - "Стандарден звук (%1$s)" - "Мелодија на телефонот" - "Вибрации при ѕвонење" - "Мелодија и вибрации" - "Управувај со конференциски повик" - "Број за итни случаи" - "Фотографија на профилот" - "Камерата е исклучена" - "преку %s" - "Испратена е белешка" - "Неодамнешни пораки" - "Деловни информации" - "Оддалечено %.1f милји" - "Оддалечено %.1f км" - "%1$s, %2$s" - "%1$s - %2$s" - "%1$s, %2$s" - "Отвора утре во %s" - "Отвора денес во %s" - "Затвора во %s" - "Денес затвори во %s" - "Сега е отворено" - "Сега е затворено" - "Повикот е можен спам" - "Повикот заврши %1$s" - "За првпат добивте повик од бројов." - "Постоеше сомнеж дека повиков е спам." - "Блок./пријави спам" - "Додајте го контактот" - "Не е спам" - diff --git a/InCallUI/res/values-ml/strings.xml b/InCallUI/res/values-ml/strings.xml deleted file mode 100644 index 5c313ad31..000000000 --- a/InCallUI/res/values-ml/strings.xml +++ /dev/null @@ -1,195 +0,0 @@ - - - - - "ഫോൺ" - "ഹോൾഡിലാണ്" - "അജ്ഞാതം" - "സ്വകാര്യ നമ്പർ" - "പണം നൽകി ഉപയോഗിക്കുന്ന ഫോൺ" - "കോൺഫറൻസ് കോൾ" - "കോൾ വിട്ടു" - "സ്പീക്കർ" - "ഹാൻഡ്‌സെറ്റ് ഇയർപീസ്" - "വയേർഡ് ഹെഡ്സെറ്റ്" - "Bluetooth" - "ഇനിപ്പറയുന്ന ടോണുകൾ അയയ്‌ക്കണോ?\n" - "ടോണുകൾ അയയ്‌ക്കുന്നു\n" - "അയയ്‌ക്കുക" - "ഉവ്വ്" - "ഇല്ല" - "വൈൽഡ് പ്രതീകം ഇതുപയോഗിച്ച് മാറ്റിസ്ഥാപിക്കുക" - "കോൺഫറൻസ് കോൾ %s" - "വോയ്‌സ്‌മെയിൽ നമ്പർ" - "ഡയൽ ചെയ്യുന്നു" - "വീണ്ടും ഡയൽചെയ്യുന്നു" - "കോൺഫറൻസ് കോൾ" - "ഇൻകമിംഗ് കോൾ" - "ഇൻകമിംഗ് ഔദ്യോഗിക കോൾ" - "കോൾ അവസാനിച്ചു" - "ഹോൾഡിലാണ്" - "ഹാംഗ് അപ്പ് ചെയ്യുന്നു" - "കോളിലാണ്" - "എന്റെ നമ്പർ %s ആണ്" - "വീഡിയോ കണക്‌റ്റുചെയ്യുന്നു" - "വീഡിയോ കോൾ" - "വീഡിയോ അഭ്യർത്ഥിക്കുന്നു" - "വീഡിയോ കോളുമായി കണക്‌റ്റുചെയ്യാനാവില്ല" - "വീഡിയോ അഭ്യർത്ഥന നിരസിച്ചു" - "നിങ്ങൾ തിരിച്ചുവിളിക്കേണ്ട നമ്പർ\n %1$s" - "അടിയന്തിരമായി നിങ്ങൾ തിരിച്ചുവിളിക്കേണ്ട നമ്പർ\n %1$s" - "ഡയൽ ചെയ്യുന്നു" - "മിസ്‌ഡ് കോൾ" - "മിസ്‌ഡ് കോളുകൾ" - "%s മിസ്‌ഡ് കോളുകൾ" - "%s എന്നതിൽ നിന്നുള്ള മിസ്‌ഡ് കോൾ" - "കോൾ സജീവമാണ്" - "ഓൺഗോയിംഗ് ഔദ്യോഗിക കോൾ" - "ഓൺഗോയിംഗ് വൈഫൈ കോൾ" - "ഓൺഗോയിംഗ് വൈഫൈ ഔദ്യോഗിക കോൾ" - "ഹോൾഡിലാണ്" - "ഇൻകമിംഗ് കോൾ" - "ഇൻകമിംഗ് ഔദ്യോഗിക കോൾ" - "ഇൻകമിംഗ് വൈഫൈ കോൾ" - "ഇൻകമിംഗ് വൈഫൈ ഔദ്യോഗിക കോൾ" - "ഇൻകമിംഗ് വീഡിയോ കോൾ" - "സംശയാസ്‌പദമായ ഇൻകമിംഗ് സ്‌പാം കോൾ" - "ഇൻകമിംഗ് വീഡിയോ അഭ്യർത്ഥന" - "പുതിയ വോയ്‌സ്‌മെയിൽ" - "പുതിയ വോയ്‌സ്‌മെയിൽ (%d)" - "%s ഡയൽ ചെയ്യുക" - "വോയ്‌സ്‌മെയിൽ നമ്പർ അജ്ഞാതമാണ്" - "സേവനമില്ല" - "തിരഞ്ഞെടുത്ത നെറ്റ്‌വർക്ക് (%s) ലഭ്യമല്ല" - "മറുപടി" - "ഹാംഗ് അപ്പുചെയ്യുക" - "വീഡിയോ" - "വോയ്‌സ്" - "അംഗീകരിക്കുക" - "ഡിസ്മിസ്" - "തിരിച്ചുവിളിക്കുക" - "സന്ദേശം" - "മറ്റൊരു ഉപകരണത്തിൽ നടന്നുകൊണ്ടിരിക്കുന്ന കോൾ" - "കോൾ കൈമാറുക" - "ഒരു കോൾ ചെയ്യാൻ, ആദ്യം ഫ്ലൈറ്റ് മോഡ് ഓഫുചെയ്യുക." - "നെറ്റ്‌വർക്കിൽ രജിസ്റ്റർ ചെയ്‌തിട്ടില്ല." - "സെല്ലുലാർ നെറ്റ്‌വർക്ക് ലഭ്യമല്ല." - "ഒരു കോൾ ചെയ്യുന്നതിന്, സാധുതയുള്ള നമ്പർ നൽകുക." - "കോൾ ചെയ്യാനായില്ല." - "MMI സീക്വൻസ് ആരംഭിക്കുന്നു…" - "സേവനം പിന്തുണയ്‌ക്കുന്നില്ല." - "കോളുകൾ മാറാനാവില്ല." - "കോൾ വേർതിരിക്കാനാവില്ല." - "കൈമാറ്റം ചെയ്യാനാവില്ല." - "കോൺഫറൻസ് കോൾ ചെയ്യാനാവില്ല." - "കോൾ നിരസിക്കാനാവില്ല." - "കോൾ (കോളുകൾ) വിളിക്കാനാവില്ല." - "SIP കോൾ" - "എമർജൻസി കോൾ" - "റേഡിയോ ഓൺ ചെയ്യുന്നു…" - "സേവനമൊന്നുമില്ല. വീണ്ടും ശ്രമിക്കുന്നു…" - "കോൾ ചെയ്യാനാവില്ല. %s എന്നത് ഒരു അടിയന്തിര നമ്പറല്ല." - "കോൾ ചെയ്യാനാവില്ല. ഒരു അടിയന്തിര കോൾ നമ്പർ ഡയൽചെയ്യുക." - "ഡയൽ ചെയ്യാൻ കീബോർഡ് ഉപയോഗിക്കുക" - "കോൾ ഹോൾഡുചെയ്യുക" - "കോൾ പുനരാരംഭിക്കുക" - "കോൾ അവസാനിപ്പിക്കുക" - "ഡയൽപാഡ് കാണിക്കുക" - "ഡയൽപാഡ് മറയ്‌ക്കുക" - "മ്യൂട്ടുചെയ്യുക" - "അൺമ്യൂട്ടുചെയ്യുക" - "കോൾ ചേർക്കുക" - "കോളുകൾ ലയിപ്പിക്കുക" - "സ്വാപ്പുചെയ്യുക" - "കോളുകൾ നിയന്ത്രിക്കുക" - "കോൺഫറൻസ് കോൾ നിയന്ത്രിക്കുക" - "കോൺഫറൻസ് കോൾ" - "മാനേജുചെയ്യുക" - "ഓഡിയോ" - "വീഡിയോ കോൾ" - "വോയ്‌സ്‌ കോളിലേക്ക് മാറ്റുക" - "ക്യാമറ സ്വിച്ചുചെയ്യുക" - "ക്യാമറ ഓണാക്കുക" - "ക്യാമറ ഓഫാക്കുക" - "കൂടുതൽ ഓ‌പ്‌ഷനുകൾ" - "പ്ലെയർ ആരംഭിച്ചു" - "പ്ലേയർ നിർത്തി" - "ക്യാമറ തയ്യാറായില്ല" - "ക്യാമറ തയ്യാറായി" - "അജ്ഞാത കോൾ സെഷൻ ഇവന്റ്" - "സേവനം" - "സജ്ജമാക്കുക" - "<ക്രമീകരിച്ചിട്ടില്ല>" - "മറ്റ് കോൾ ക്രമീകരണം" - "%s മുഖേന വിളിക്കുന്നു" - "%s മുഖേനയുള്ള ഇൻകമിംഗ്" - "കോൺടാക്റ്റ് ഫോട്ടോ" - "സ്വകാര്യം എന്നതിലേക്ക് പോകുക" - "കോൺടാക്റ്റ് തിരഞ്ഞെടുക്കുക" - "നിങ്ങളുടെ സ്വന്തം സന്ദേശമെഴുതുക..." - "റദ്ദാക്കുക" - "അയയ്‌ക്കുക" - "മറുപടി" - "SMS അയയ്ക്കുക" - "നിരസിക്കുക" - "വീഡിയോ കോളായി മറുപടി നൽകുക" - "ഓഡിയോ കോളായി മറുപടി നൽകുക" - "വീഡിയോ കോളിനുള്ള അഭ്യർത്ഥന അംഗീകരിക്കുക" - "വീഡിയോ കോൾ അഭ്യർത്ഥന നിരസിക്കുക" - "വീഡിയോ പ്രക്ഷേപണ അഭ്യർത്ഥന അംഗീകരിക്കുക" - "വീഡിയോ പ്രക്ഷേപണ അഭ്യർത്ഥന നിരസിക്കുക" - "വീഡിയോ കോൾ സ്വീകരിക്കാനുള്ള അഭ്യർത്ഥന അംഗീകരിക്കുക" - "വീഡിയോ കോൾ സ്വീകരിക്കാനുള്ള അഭ്യർത്ഥന നിരസിക്കുക" - "%s എന്നതിനായി മുകളിലേയ്‌ക്ക് സ്ലൈഡുചെയ്യുക." - "%s എന്നതിനായി ഇടത്തേയ്‌ക്ക് സ്ലൈഡുചെയ്യുക." - "%s എന്നതിനായി വലത്തേയ്‌ക്ക് സ്ലൈഡുചെയ്യുക." - "%s എന്നതിനായി താഴേക്ക് സ്ലൈഡുചെയ്യുക." - "വൈബ്രേറ്റുചെയ്യുക" - "വൈബ്രേറ്റുചെയ്യുക" - "ശബ്‌ദം" - "സ്ഥിര ശബ്‌ദം (%1$s)" - "ഫോൺ റിംഗ്ടോൺ" - "റിംഗുചെയ്യുമ്പോൾ വൈബ്രേറ്റുചെയ്യുക" - "റിംഗ്ടോണും വൈബ്രേറ്റുചെയ്യലും" - "കോൺഫറൻസ് കോൾ നിയന്ത്രിക്കുക" - "അടിയന്തര നമ്പർ" - "പ്രൊഫൈൽ ഫോട്ടോ" - "ക്യാമറ ഓഫാക്കുക" - "%s വഴി" - "കുറിപ്പ് അയച്ചു" - "ഏറ്റവും പുതിയ സന്ദേശങ്ങൾ" - "ബിസിനസ്സ് വിവരം" - "%.1f മൈൽ അകലെ" - "%.1f കിലോമീറ്റർ അകലെ" - "%1$s, %2$s" - "%1$s - %2$s" - "%1$s, %2$s" - "നാളെ %s-ന് തുറക്കുന്നു" - "ഇന്ന് %s-ന് തുറക്കുന്നു" - "%s-ന് അടയ്ക്കുന്നു" - "ഇന്ന് %s-ന് അടച്ചു" - "ഇപ്പോൾ തുറന്നിരിക്കുന്നു" - "ഇപ്പോൾ അടച്ചിരിക്കുന്നു" - "സംശയാസ്‌പദമായ സ്‌പാം കോളർ" - "കോൾ അവസാനിച്ചു, %1$s" - "ഈ നമ്പറിൽ നിന്ന് ആദ്യമായാണ് നിങ്ങൾക്ക് കോൾ വരുന്നത്." - "ഈ കോൾ ഒരു സ്‌പാമർ ആണെന്ന് ഞങ്ങൾക്ക് സംശയമുണ്ടായിരുന്നു." - "ബ്ലോക്കുചെയ്യുക/സ്പാമാണെന്ന് റിപ്പോർട്ടുചെയ്യുക" - "കോൺടാക്റ്റ് ചേർക്കുക" - "സ്പാം അല്ല" - diff --git a/InCallUI/res/values-mn/strings.xml b/InCallUI/res/values-mn/strings.xml deleted file mode 100644 index 972f914a4..000000000 --- a/InCallUI/res/values-mn/strings.xml +++ /dev/null @@ -1,195 +0,0 @@ - - - - - "Утас" - "Хүлээлгэнд байгаа" - "Тодорхойгүй" - "Нууцалсан дугаар" - "Төлбөртэй утас" - "Хурлын дуудлага" - "Дуудлага таслагдсан" - "Чанга яригч" - "Утасны чихэвч" - "Утастай чихэвч" - "Bluetooth" - "Дараах аяыг илгээх үү?\n" - "Ая илгээж байна\n" - "Илгээх" - "Тийм" - "Үгүй" - "Тэмдэгтийг дараахаар солих" - "Хурлын дуудлага %s" - "Дуут шуудангийн дугаар" - "Залгаж байна" - "Дахин залгаж байна" - "Хурлын дуудлага" - "Орох дуудлага" - "Орох ажлын дуудлага" - "Дуудлага дууссан" - "Хүлээлгэнд" - "Тасалж байна" - "Дуудлагатай" - "Миний дугаар %s" - "Видеог холбож байна" - "Видео дуудлага" - "Видео хүлээж байна" - "Видео дуудлагад холбогдож чадсангүй" - "Бичлэг хийх хүсэлтийг зөвшөөрсөнгүй" - "Таны буцаан залгах дугаар\n %1$s" - "Таны яаралтай хулээн авах дугаар\n %1$s" - "Залгаж байна" - "Аваагүй дуудлага" - "Аваагүй дуудлага" - "%s аваагүй дуудлага" - "%s-н аваагүй дуудлага" - "Залгаж буй дуудлага" - "Холбогдсон албаны дуудлага" - "Холбогдсон Wi-Fi дуудлага" - "Залгаж буй Wi-Fi албаны дуудлага" - "Хүлээгдэж байна" - "Орох дуудлага" - "Орох ажлын дуудлага" - "Орох Wi-Fi дуудлага" - "Орох Wi-Fi албаны дуудлага" - "Орох видео дуудлага" - "Орж ирсэн сэжигтэй спам дуудлага" - "Орох видео хүсэлт" - "Шинэ дуут шуудан" - "Шинэ дуут шуудан (%d)" - "%s руу залгах" - "Дуут шуудангийн дугаар тодорхойгүй" - "Үйлчилгээ байхгүй" - "Сонгосон сүлжээг (%s) ашиглах боломжгүй" - "Хариулт" - "Таслах" - "Видео" - "Дуу хоолой" - "Зөвшөөрөх" - "Алгасах" - "Буцааж залгах" - "Зурвас" - "Өөр төхөөрөмж дээр хийгдэж буй дуудлага" - "Дуудлага шилжүүлэх" - "Залгахын тулд эхлээд Нислэгийн горимоос гарна уу." - "Сүлжээнд бүртгэгдээгүй байна." - "Үүрэн сүлжээ байхгүй." - "Залгахын тулд хүчин төгөлдөр дугаар оруулна уу." - "Залгах боломжгүй байна." - "MMI дарааллыг эхлүүлж байна…" - "Дэмжигдээгүй үйлчилгээ байна." - "Дуудлагыг солих боломжгүй байна." - "Дуудлагыг салгаж чадахгүй байна." - "Шилжүүлэх боломжгүй байна." - "Хурлын дуудлага хийх боломжгүй байна." - "Дуудлагыг цуцлах боломжгүй байна." - "Дуудлага чөлөөлөх боломжгүй байна." - "SIP дуудлага" - "яаралтай" - "Радиог асааж байна..." - "Ажиллагаагүй байна. Дахин оролдоно уу..." - "Залгах боломжгүй. %s нь яаралтай дугаар биш байна." - "Залгах боломжгүй. Яаралтай дугаар луу залгана уу." - "Залгахдаа гар ашиглана уу" - "Дуудлага хүлээлгэх" - "Дуудлагыг үргэлжлүүлэх" - "Дуудлагыг дуусгах" - "Залгах товчлуурыг харуулах" - "Залгах товчлуурыг нуух" - "Дуу хаах" - "Дууг нээх" - "Дуудлага нэмэх" - "Дуудлага нэгтгэх" - "Солих" - "Дуудлага удирдах" - "Хурлын дуудлага удирдах" - "Хурлын дуудлага" - "Удирдах" - "Аудио" - "Видео дуудлага" - "Дуут дуудлага руу өөрчлөх" - "Камер солих" - "Камераа асаана уу" - "Камер унтраах" - "Нэмэлт сонголт" - "Тоглуулагчийг эхлүүлсэн" - "Тоглуулагчийг зогсоосон" - "Камер бэлэн бус байна" - "Камер бэлэн байна" - "Үл мэдэгдэх дуудлагын үе" - "Үйлчилгээ" - "Тохируулга" - "Тохируулаагүй" - "Бусад дуудлагын тохиргоо" - "%s-р залгаж байна" - "%s-р ирж байна" - "харилцагчийн зураг" - "хувийн яриа" - "харилцагч сонгох" - "Өөрийн ...-г бичээрэй" - "Цуцлах" - "Илгээх" - "Хариулт" - "SMS илгээх" - "Татгалзах" - "Видео дуудлагаар хариулах" - "Аудио дуудлагаар хариулах" - "Видео хүсэлтийг хүлээн зөвшөөрөх" - "Видео хүсэлтээс татгалзах" - "Видео дамжуулах хүсэлтийг хүлээн зөвшөөрөх" - "Видео дамжуулах хүсэлтээс татгалзах" - "Видео хүлээж авах хүсэлтийг зөвшөөрөх" - "Видео хүлээн авах хүсэлтээс татгалзах" - "%s хийх бол дээш гулсуулна уу." - "%s-г харахын тулд зүүн тийш гулсуулна уу." - "%s харахын тулд баруун тийш гулсуулна уу." - "%s-г харахын тулд доош гулсуулна уу." - "Чичиргээ" - "Чичиргээ" - "Дуу" - "Үндсэн дуу (%1$s)" - "Утасны хонхны ая" - "Хонх дуугарах үед чичрэх" - "Хонхны ая, Чичиргээ" - "Хурлын дуудлагыг удирдах" - "Яаралтай дугаар" - "Профайл зураг" - "Камер унтраалттай байна" - "%s-р" - "Тэмдэглэлийг илгээсэн" - "Саяхны зурвас" - "Бизнес мэдээлэл" - "%.1f милийн зайтай" - "%.1f км-н зайтай" - "%1$s, %2$s" - "%1$s - %2$s" - "%1$s, %2$s" - "Маргааш %s-с нээгдэнэ" - "Өнөөдөр %s-с нээгдэнэ" - "%s-с хаадаг" - "Өнөөдөр %s-с хаасан" - "Одоо нээлттэй" - "Одоо хаалттай" - "Сэжигтэй спам дуудлага хийгч" - "Дуудлага дууссан %1$s" - "Энэ дугаараас танд анх удаа дуудлага ирсэн." - "Бид үүнийг спам дуудлага гэж үзсэн." - "Спам гэж мэдээлэх/хориглох" - "Харилцагч нэмэх" - "Спам биш" - diff --git a/InCallUI/res/values-mr/strings.xml b/InCallUI/res/values-mr/strings.xml deleted file mode 100644 index 15b3dfc32..000000000 --- a/InCallUI/res/values-mr/strings.xml +++ /dev/null @@ -1,195 +0,0 @@ - - - - - "फोन" - "होल्ड वर" - "अज्ञात" - "खाजगी नंबर" - "सार्वजनिक फोन" - "परिषद कॉल" - "कॉल सोडला" - "स्पीकर" - "हँडसेट इअरपीस" - "वायर्ड हेडसेट" - "ब्लूटुथ" - "खालील टोन पाठवायचे?\n" - "टोन पाठवित आहे\n" - "पाठवा" - "होय" - "नाही" - "खराब वर्णास यासह पुनर्स्थित करा" - "परिषद कॉल %s" - "व्हॉइसमेल नंबर" - "डायल करीत आहे" - "रीडायल करत आहे" - "परिषद कॉल" - "येणारा कॉल" - "येणारा कार्य कॉल" - "कॉल संपला" - "होल्ड वर" - "हँग अप करणेे" - "कॉल मधील" - "माझा नंबर %s आहे" - "व्हिडिओ कनेक्ट करत आहे" - "व्हिडिओ कॉल" - "व्हिडिओ विनंती करत आहे" - "व्हिडिओ कॉल कनेक्ट करू शकत नाही" - "व्हिडिओ विनंती नाकारली" - "आपला कॉलबॅक नंबर\n %1$s" - "आपला आणीबाणी कॉलबॅक नंबर\n %1$s" - "डायल करीत आहे" - "सुटलेला कॉल" - "सुटलेले कॉल" - "%s सुटलेले कॉल" - "%s कडील सुटलेला कॉल" - "सुरू असलेला कॉल" - "सुरु असलेला कार्य कॉल" - "सुरु असलेला वाय-फाय कॉल" - "सुरु असलेला वाय-फाय कार्य कॉल" - "होल्ड वर" - "येणारा कॉल" - "येणारा कार्य कॉल" - "येणारा वाय-फाय कॉल" - "येणारा वाय-फाय कार्य कॉल" - "येणारा व्हिडिओ कॉल" - "येणारा संशयित स्पॅम कॉल" - "येणारी व्हिडिओ विनंती" - "नवीन व्हॉइसमेल" - "नवीन व्हॉइसमेल (%d)" - "%s डायल करा" - "व्हॉइसमेल नंबर अज्ञात" - "सेवा नाही" - "निवडलेले नेटवर्क (%s) अनुपलब्ध" - "उत्तर" - "हँग अप" - "व्हिडिओ" - "व्हॉइस" - "स्वीकार करा" - "डिसमिस करा" - "पुन्हा कॉल करा" - "संदेश" - "दुसऱ्या डिव्हाइसवर सुरु असलेला कॉल" - "कॉल स्थानांतरित करा" - "कॉल करण्यासाठी, प्रथम विमान मोड बंद करा." - "नेटवर्कवर नोंदणीकृत नाही." - "मोबाईल नेटवर्क उपलब्ध नाही." - "कॉल करण्यासाठी, एक वैध नंबर प्रविष्ट करा." - "कॉल करू शकत नाही." - "MMI क्रम प्रारंभ करीत आहे..." - "सेवा समर्थित नाही." - "कॉल स्विच करू शकत नाही." - "कॉल विभक्त करू शकत नाही." - "हस्तांतर करू शकत नाही." - "परिषद घेऊ शकत नाही." - "कॉल नाकारू शकत नाही." - "कॉल रिलीज करू शकत नाही." - "SIP कॉल" - "आणीबाणी कॉल" - "रेडिओ चालू करीत आहे..." - "सेवा नाही. पुन्हा प्रयत्न करत आहे…" - "कॉल करू शकत नाही. %s हा आणीबाणी नंबर नाही." - "कॉल करू शकत नाही. आणीबाणी नंबर डायल करा." - "डायल करण्यासाठी कीबोर्डचा वापर करा" - "कॉल होल्ड करा" - "कॉल पुनः सुरु करा" - "कॉल समाप्त करा" - "डायलपॅड दर्शवा" - "डायलपॅड लपवा" - "नि:शब्द करा" - "सशब्द करा" - "कॉल जोडा" - "कॉल विलीन करा" - "अदलाबदल करा" - "कॉल व्यवस्थापित करा" - "परिषद कॉल व्यवस्थापित करा" - "परिषद कॉल" - "व्यवस्थापित करा" - "ऑडिओ" - "व्हिडिओ कॉल" - "व्हॉइस कॉल वर बदला" - "कॅमेरा स्विच करा" - "कॅमेरा चालू करा" - "कॅमेरा बंद करा" - "अधिक पर्याय" - "प्लेअर सुरु झाले" - "प्लेअर थांबले" - "कॅमेरा तयार नाही" - "कॅमेरा तयार" - "अज्ञात कॉल सत्र इव्हेंट" - "सेवा" - "सेटअप" - "<सेट नाही>" - "इतर कॉल सेटिंग्ज" - "%s द्वारे कॉल करीत आहे" - "%s द्वारे येणारे" - "संपर्क फोटो" - "खाजगी व्हा" - "संपर्क निवडा" - "आपण स्वतः लिहा…" - "रद्द करा" - "पाठवा" - "उत्तर" - "SMS पाठवा" - "नकार द्या" - "व्हिडिओ कॉल म्हणून उत्तर द्या" - "ऑडिओ कॉल म्हणून उत्तर द्या" - "व्हिडिओ विनंती स्वीकारा" - "व्हिडिओ विनंतीस नकार द्या" - "व्हिडिओ प्रसारण विनंती स्वीकार करा" - "व्हिडिओ प्रसारण विनंतीस नकार द्या" - "व्हिडिओ प्राप्त करा विनंती स्वीकार करा" - "व्हिडिओ प्राप्त करा विनंतीस नकार द्या" - "%s साठी वर स्लाइड करा." - "%s साठी डावीकडे स्लाइड करा." - "%s साठी उजवीकडे स्लाइड करा." - "%s साठी खाली स्लाइड करा." - "कंपन करा" - "कंपन करा" - "ध्वनी" - "डीफॉल्ट आवाज (%1$s)" - "फोन रिंगटोन" - "रिंग करताना कंपन करा" - "रिंगटोन आणि कंपन" - "परिषद कॉल व्यवस्थापित करा" - "आणीबाणी नंबर" - "प्रोफाइल फोटो" - "कॅमेरा बंद" - "%s द्वारा" - "टीप पाठविली" - "अलीकडील संदेश" - "व्यवसाय माहिती" - "%.1f मैल दूर" - "%.1f किमी दूर" - "%1$s, %2$s" - "%1$s - %2$s" - "%1$s, %2$s" - "उद्या %s वाजता उघडेल" - "आज %s उघडेल" - "आज %s वाजता बंद होईल" - "आज %s वाजता बंद केले" - "आता उघडा" - "आता बंद केले आहे" - "संशयित स्पॅम कॉलर" - "कॉल समाप्त झाला %1$s" - "या नंबरने अापल्याला कॉल केल्याची ही पहिलीच वेळ आहे." - "अाम्हाला संशय अाहे की हा कॉल एक स्पॅमर असू शकतो." - "अवरोधित करा/स्पॅमचा अहवाल द्या" - "संपर्क जोडा" - "स्पॅम नाही" - diff --git a/InCallUI/res/values-ms/strings.xml b/InCallUI/res/values-ms/strings.xml deleted file mode 100644 index 4c7be3805..000000000 --- a/InCallUI/res/values-ms/strings.xml +++ /dev/null @@ -1,195 +0,0 @@ - - - - - "Telefon" - "Ditunda" - "Tidak diketahui" - "Nombor peribadi" - "Telefon Awam" - "Panggilan sidang" - "Panggilan diputuskan" - "Pembesar suara" - "Alat dengar tel bimbit" - "Set kepala berwayar" - "Bluetooth" - "Hantar nada berikut?\n" - "Menghantar nada\n" - "Hantar" - "Ya" - "Tidak" - "Gantikan aksara bebas dengan" - "Panggilan sidang %s" - "Nombor mel suara" - "Mendail" - "Mendail semula" - "Panggilan sidang" - "Panggilan masuk" - "Pgln masuk tempat kerja" - "Panggilan tamat" - "Ditunda" - "Menamatkan panggilan" - "Dalam panggilan" - "Nombor saya ialah %s" - "Menyambungkan video" - "Panggilan video" - "Meminta video" - "Tidak dapat menyambungkan panggilan video" - "Permintaan video ditolak" - "Nombor panggilan balik anda%1$s\n" - "Nombor panggilan balik kecemasan anda\n%1$s" - "Mendail" - "Panggilan terlepas" - "Panggilan terlepas" - "%s panggilan terlepas" - "Panggilan tidak dijawab daripada %s" - "Panggilan sedang berlangsung" - "Panggilan sedang berlangsung daripada tempat kerja" - "Panggilan Wi-Fi sedang berlangsung" - "Panggian Wi-Fi sedang berlangsung daripada tempat kerja" - "Ditunda" - "Panggilan masuk" - "Panggilan masuk daripada tempat kerja" - "Panggilan masuk melalui Wi-Fi" - "Panggilan masuk melalui Wi-Fi daripada tempat kerja" - "Panggilan video masuk" - "Disyaki panggilan spam masuk" - "Permintaan video masuk" - "Mel suara baharu" - "Mel suara baharu (%d)" - "Dail %s" - "Nombor mel suara tidak dikenali" - "Tiada perkhidmatan" - "Rangkaian pilihan (%s) tidak tersedia" - "Jawab" - "Letakkan gagang" - "Video" - "Suara" - "Terima" - "Ketepikan" - "Panggil balik" - "Mesej" - "Panggilan sedang berlangsung pada peranti lain" - "Pindahkan Panggilan" - "Untuk membuat panggilan, matikan mod Pesawat terlebih dahulu." - "Tidak didaftarkan pada rangkaian." - "Rangkaian selular tidak tersedia." - "Untuk membuat panggilan, masukkan nombor yang sah." - "Tidak dapat memanggil." - "Memulakan jujukan MMI..." - "Perkhidmatan tidak disokong." - "Tidak dapat menukar panggilan." - "Tidak dapat mengasingkan panggilan." - "Tidak dapat memindahkan." - "Tidak dapat membuat panggilan persidangan." - "Tidak dapat menolak panggilan." - "Tidak dapat melepaskan panggilan." - "Panggilan SIP" - "Panggilan kecemasan" - "Menghidupkan radio..." - "Tiada perkhidmatan. Mencuba lagi..." - "Tidak dapat memanggil. %s bukan nombor kecemasan." - "Tidak dapat memanggil. Dail nombor kecemasan." - "Gunakan papan kekunci untuk mendail" - "Tahan Panggilan" - "Sambung Semula Panggilan" - "Tamatkan Panggilan" - "Tunjukkan Pad Pendail" - "Sembunyikan Pad Pendail" - "Redam" - "Nyahredam" - "Tambah panggilan" - "Gabung panggilan" - "Silih" - "Urus panggilan" - "Urus panggilan sidang" - "Panggilan sidang" - "Urus" - "Audio" - "Panggilan video" - "Tukar ke panggilan suara" - "Tukar kamera" - "Hidupkan kamera" - "Matikan kamera" - "Lagi pilihan" - "Pemain Dimulakan" - "Pemain Dihentikan" - "Kamera tidak bersedia" - "Kamera bersedia" - "Acara sesi panggilan tidak diketahui" - "Perkhidmatan" - "Persediaan" - "<Tidak ditetapkan>" - "Tetapan panggilan lain" - "Memanggil melalui %s" - "Panggilan masuk melalui %s" - "foto kenalan" - "jadi peribadi" - "pilih kenalan" - "Tulis sendiri…" - "Batal" - "Hantar" - "Jawab" - "Hantar SMS" - "Tolak" - "Jawab sebagai panggilan video" - "Jawab sebagai panggilan audio" - "Terima permintaan video" - "Tolak permintaan video" - "Terima permintaan hantar video" - "Tolak permintaan hantar video" - "Terima permintaan terima video" - "Tolak permintaan terima video" - "Luncurkan ke atas untuk %s." - "Luncurkan ke kiri untuk %s." - "Luncurkan ke kanan untuk %s." - "Luncurkan ke bawah untuk %s." - "Bergetar" - "Bergetar" - "Bunyi" - "Bunyi lalai (%1$s)" - "Nada dering telefon" - "Bergetar apabila berdering" - "Nada dering & Bergetar" - "Urus panggilan sidang" - "Nombor kecemasan" - "Foto profil" - "Kamera dimatikan" - "melalui %s" - "Nota dihantar" - "Mesej terbaharu" - "Maklumat perniagaan" - "%.1f batu dari sini" - "%.1f km dari sini" - "%1$s, %2$s" - "%1$s - %2$s" - "%1$s, %2$s" - "Dibuka esok pada pukul %s" - "Dibuka hari ini pada pukul %s" - "Tutup pada pukul %s" - "Ditutup hari ini pada pukul %s" - "Dibuka sekarang" - "Ditutup sekarang" - "Disyaki pmggil spam" - "Panggilan tamat %1$s" - "Ini kali pertama nombor ini memanggil anda." - "Kami mengesyaki panggilan ini adalah spam." - "Sekat/laporkan spam" - "Tambahkan kenalan" - "Bukan spam" - diff --git a/InCallUI/res/values-my/strings.xml b/InCallUI/res/values-my/strings.xml deleted file mode 100644 index efe91436f..000000000 --- a/InCallUI/res/values-my/strings.xml +++ /dev/null @@ -1,195 +0,0 @@ - - - - - "ဖုန်း" - "ခဏ ကိုင်ထားစဉ်" - "အမျိုးအမည်မသိ" - "ကိုယ်ပိုင်ဖုန်းနံပါတ်" - "အများသုံးဖုန်း" - "အစည်းအဝေးခေါ်ဆိုမှု" - "ဖုန်းလိုင်းကျသွားခဲ့သည်" - "စပီကာ" - "လက်ကိုင်တယ်လီဖုန်းနားခွက်" - "ကြိုးတပ် မိုက်ခွက်ပါနားကြပ်" - "ဘလူးတုသ်" - "အောက်ပါ တီးလုံးများကို ပို့မလား။\n" - "အသံများ ပို့နေသည်\n" - "ပို့ပါ" - "Yes" - "No" - "အစားထိုး အထူးအက္ခရာတွင် အစားထိုးရန်" - "အစည်းအဝေးခေါ်ဆိုမှု %s" - "အသံစာနံပါတ်" - "ခေါ်ဆိုနေသည်" - "ပြန်ခေါ်နေသည်" - "အစည်းအဝေးခေါ်ဆိုမှု" - "အဝင် ခေါ်ဆိုမှု" - "အလုပ်ဆိုင်ရာ အဝင် ခေါ်ဆိုမှု" - "ဖုန်းခေါ်ဆိုမှု ပြီးဆုံးပါပြီ" - "ခဏ ကိုင်ထားစဉ်" - "ဖုန်းချနေပါသည်" - "ဖုန်းခေါ်ဆိုနေဆဲ" - "ကျွန်ုပ်၏ နံပါတ်မှာ %s ဖြစ်ပါသည်" - "ဗီဒီယို ချိတ်ဆက်နေသည်" - "ဗီဒီယို ခေါ်ဆိုမှု" - "ဗီဒီယိုခေါ်ဆိုနေသည်" - "ဗွီဒီယို ခေါ်ဆိုမှု ချိတ်ဆက်၍မရပါ။" - "ဗီဒီယို ခေါ်ဆိုမှုကို ပယ်ချလိုက်ပါပြီ" - "သင့်ကိုပြန်လည်ခေါ်ဆိုရန် နံပါတ်\n %1$s" - "သင့်ကိုအရေးပေါ် ပြန်လည်ခေါ်ဆိုရန် နံပါတ်\n %1$s" - "ဖုန်းခေါ်နေသည်" - "လွတ်သွားသော ခေါ်ဆိုမှု" - "လွတ်သွားသော ခေါ်ဆိုမှုများ" - "လွတ်သွားသော ခေါ်ဆိုမှု %s" - "%s မှလွတ်သွားသော ခေါ်ဆိုမှု" - "လက်ရှိခေါ်ဆိုမှု" - "လက်ရှိအလုပ်ခေါ်ဆိုမှု" - "လက်ရှိ Wi-Fi ခေါ်ဆိုမှု" - "လက်ရှိအလုပ် Wi-Fi ခေါ်ဆိုမှု" - "ခဏ ကိုင်ထားစဉ်" - "အဝင် ခေါ်ဆိုမှု" - "အလုပ်ဆိုင်ရာ အဝင်ခေါ်ဆိုမှု" - "အဝင် Wi-Fi ခေါ်ဆိုမှု" - "အလုပ်ဆိုင်ရာ အဝင် Wi-Fi ခေါ်ဆိုမှု" - "အဝင်ဗီဒီယိုခေါ်ဆိုမှု" - "ခေါ်နေသော မသင်္ကာဖွယ်ရာ စပမ်းခေါ်ဆိုမှု" - "ဗီဒီယိုအဝင် ခေါ်ဆိုမှု" - "အသံစာအသစ်" - "အသံစာ အသစ် (%d) ခု" - "%s ကိုခေါ်ပါ" - "အသံစာ၏နံပါတ်ကို မသိပါ" - "ဆက်သွယ်မှု ဧရိယာပြင်ပသို့ ရောက်ရှိနေသည်" - "ရွေးချယ်ထားသော ကွန်ရက် (%s) မရရှိနိုင်ပါ" - "ဖြေကြားပါ" - "ဖုန်းချပါ" - "ဗီဒီယို" - "အသံ" - "လက်ခံပါ" - "ပယ်ပါ" - "ပြန်ခေါ်ပါ" - "မက်ဆေ့ဂျ်" - "အခြားကိရိယာတွင် လက်ရှိခေါ်ဆိုနေမှု" - "ခေါ်ဆိုမှုကို လွှဲပြောင်းပါ" - "ခေါ်ဆိုမှု ပြုလုပ်ရန်အတွက် လေယာဉ်ပျံမုဒ်ကို ဦးစွာပိတ်ပါ။" - "ကွန်ယက်ပေါ်တွင် မှတ်ပုံတင်ထားခြင်း မရှိပါ။" - "ဆဲလ်လူလာ ကွန်ရက် မရှိပါ။" - "ခေါ်ဆိုမှု ပြုလုပ်ရန်အတွက် မှန်ကန်သည့်နံပါတ်တစ်ခုကို ထည့်ပါ။" - "ခေါ်ဆို၍မရပါ။" - "MMI အစီအစဉ် စတင်နေသည်..." - "ဝန်ဆောင်မှုအား ပံ့ပိုးမထားပါ။" - "ခေါ်ဆိုမှုများကို လှည့်ပြောင်း၍မရပါ။" - "ခေါ်ဆိုမှုကို ခွဲခြား၍မရပါ။" - "မလွှဲပြောင်းနိုင်ပါ။" - "အစည်းအဝေးခေါ်ဆိုမှု ပြုလုပ်၍မရပါ။" - "ခေါ်ဆိုမှုကို ငြင်းဆို၍မရပါ။" - "ခေါ်ဆိုမှု(များ) ကို လွှတ်၍မရပါ။" - "SIP ခေါ်ဆိုမှု" - "အရေးပေါ် ခေါ်ဆိုမှု" - "ရေဒီယို ဖွင့်နေသည်…" - "ချိတ်ဆက်မှု ဧရိယာပြင်ပရောက်နေပါသည်။ ထပ်စမ်းကြည့်ပါ..." - "ခေါ်ဆို၍မရနိုင်ပါ။ %s သည်အရေးပေါ်နံပါတ်တစ်ခု မဟုတ်ပါ။" - "ခေါ်ဆို၍မရနိုင်ပါ။ အရေးပေါ်နံပါတ်တစ်ခုကို ခေါ်ဆိုပါ။" - "ခေါ်ဆိုရန် ကီးဘုတ်ကိုအသုံးပြုပါ" - "ခေါ်ဆိုမှု ခေတ္တရပ်ထားပါ" - "ခေါ်ဆိုမှုကို ဆက်လုပ်ပါ" - "ခေါ်ဆိုမှု အပြီးသတ်ပါ" - "နံပါတ်အကွက် ပြပါ" - "နံပါတ်အကွက် ဝှက်ထားပါ" - "အသံပိတ်ပါ" - "အသံပြန်ဖွင့်ပါ" - "ခေါ်ဆိုမှုထည့်ပါ" - "ခေါ်ဆိုမှုများကို ပေါင်းစည်းပါ" - "ဖလှယ်ပါ" - "ခေါ်ဆိုမှုများကို စီမံခန့်ခွဲပါ" - "အစည်းအဝေးခေါ်ဆိုမှုကို စီမံခန့်ခွဲပါ" - "မျက်နှာစုံညီစည်းဝေး ဖုန်းခေါ်ဆိုမှု" - "စီမံခန့်ခွဲပါ" - "အသံ" - "ဗီဒီယို ခေါ်ဆိုမှု" - "အသံခေါ်ဆိုမှုသို့ ပြောင်းပါ" - "ကင်မရာပြောင်းပါ" - "ကင်မရာဖွင့်ပါ" - "ကင်မရာပိတ်ပါ" - "နောက်ထပ် ရွေးစရာများ" - "ပလေယာ စပါပြီ" - "ပလေယာ ရပ်တန့်သွားပါပြီ" - "ကင်မရာအဆင်သင့် မဖြစ်သေးပါ" - "ကင်မရာအဆင်သင့်ဖြစ်ပါပြီ" - "အမျိုးအမည်မသိ ခေါ်ဆိုမှုအချိန်ကာလ" - "ဝန်ဆောင်မှု" - "စနစ်ထည့်သွင်းမှုပြုလုပ်ပါ" - "<မသတ်မှတ်ထားပါ>" - "အခြားခေါ်ဆိုမှုဆက်တင်များ" - "%s မှတစ်ဆင့် ခေါ်ဆိုခြင်း" - "%s မှတစ်ဆင့်အဝင်ခေါ်ဆိုမှု" - "အဆက်အသွယ်ဓာတ်ပုံ" - "တသီးတသန့်ချိတ်ဆက်ရန်" - "လိပ်စာရွေးပါ" - "သင့်ကိုယ်ပိုင် စာသား ရေးပါ..." - "မလုပ်တော့" - "ပို့ပါ" - "ဖြေကြားပါ" - "SMS ပို့ပါ" - "ငြင်းပယ်ပါ" - "ဗီဒီယိုခေါ်ဆိုမှုအဖြစ် ဖြေကြားပါ" - "အသံခေါ်ဆိုမှုအဖြစ် ဖြေကြားပါ" - "ဗီဒီယိုခေါ်ဆိုမှုကို လက်ခံပါ" - "ဗီဒီယိုခေါ်ဆိုမှုကို ငြင်းပယ်ပါ" - "ဗီဒီယိုထုတ်လွှင့်ခြင်းတောင်းဆိုမှုကို လက်ခံပါ" - "ဗီဒီယိုထုတ်လွှင့်ခြင်းတောင်းဆိုမှုကို ငြင်းပယ်ပါ" - "ဗီဒီယိုလက်ခံရရှိမှုတောင်းဆိုချက်ကို လက်ခံပါ" - "ဗီဒီယိုလက်ခံရရှိကြောင်းတောင်းဆိုမှုကို ငြင်းပယ်ပါ" - "%s အတွက် အပေါ်ကို ပွတ်ဆွဲပါ" - "%s အတွက် ဘယ်ဖက်ကို ပွတ်ဆွဲပါ" - "%s အတွက် ညာဖက်ကို ပွတ်ဆွဲပါ" - "%s အတွက် အောက်ကို ပွတ်ဆွဲပါ" - "တုန်ခါပါ" - "တုန်ခါပါ" - "အသံ" - "မူရင်း အသံ (%1$s)" - "ဖုန်းမြည်သံ" - "ဖုန်းမြည်စဉ် တုန်ခါပါ" - "ဖုန်းမြည်သံ & တုန်ခါသံ" - "အစည်းအဝေးခေါ်ဆိုမှုကို စီမံခန့်ခွဲပါ" - "အရေးပေါ်နံပါတ်" - "ပရိုဖိုင် ဓာတ်ပုံ" - "ကင်မရာ ပိတ်ပါ" - "%s မှတစ်ဆင့်" - "မှတ်ချက်ကို ပို့လိုက်ပါပြီ" - "မကြာသေးမီက မက်ဆေ့ဂျ်များ" - "စီးပွားရေး အချက်အလက်" - "%.1f မိုင်အကွာ" - "%.1f ကီလိုမီတာအကွာ" - "%1$s%2$s" - "%1$s - %2$s" - "%1$s%2$s" - "မနက်ဖြန် %s ၌ဖွင့်မည်" - "ယနေ့ %s ၌ဖွင့်မည်" - "%s ၌ပိတ်ပါမည်" - "ယနေ့ %s ၌ပိတ်ခဲ့သည်" - "ယခုဖွင့်ပါ" - "ယခုပိတ်ပါ" - "မသင်္ကာဖွယ်ရာ စပမ်းခေါ်ဆိုသူ" - "ဖုန်းခေါ်ဆိုမှု ပြီးဆုံးပါပြီ %1$s" - "ဤနံပါတ်သည် သင့်ထံ ပထမဆုံးခေါ်ဆိုသော နံပါတ်ဖြစ်သည်။" - "ယခုဖုန်းခေါ်ဆိုမှုသည် စပမ်းပို့သူဆီမှ ဖြစ်နိုင်သည်ဟု ထင်ပါသည်။" - "စပမ်းကို ပိတ်ဆို့ပါ/သတင်းပေးပို့ပါ" - "အဆက်အသွယ် ထည့်ပါ" - "စပမ်း မဟုတ်ပါ" - diff --git a/InCallUI/res/values-nb/strings.xml b/InCallUI/res/values-nb/strings.xml deleted file mode 100644 index d39e4d441..000000000 --- a/InCallUI/res/values-nb/strings.xml +++ /dev/null @@ -1,195 +0,0 @@ - - - - - "Telefon" - "På vent" - "Ukjent" - "Skjult nummer" - "Telefonkiosk" - "Konferansesamtale" - "Anropet ble avbrutt" - "Høyttaler" - "Telefonhøyttaler" - "Hodetelefoner med kabel" - "Bluetooth" - "Vil du sende disse lydene?\n" - "Sender lydene\n" - "Send" - "Ja" - "Nei" - "Erstatt jokertegn med" - "Konferansesamtale %s" - "Nummeret til talepostkassen" - "Ringer" - "Ringer på nytt" - "Konferansesamtale" - "Innkommende anrop" - "Innkommende jobbanrop" - "Anropet er avsluttet" - "På vent" - "Legger på" - "Anrop pågår" - "Nummeret mitt er %s" - "Kobler til video" - "Videoanrop" - "Ber om video" - "Kan ikke koble til videoanropet" - "Videoforespørselen er avvist" - "Tilbakeringingsnummeret ditt\n %1$s" - "Tilbakeringingsnummeret ditt for nødstilfeller\n %1$s" - "Ringer" - "Tapt anrop" - "Tapte anrop" - "%s tapte anrop" - "Tapt anrop fra %s" - "Pågående anrop" - "Pågående jobbanrop" - "Pågående Wi-Fi-anrop" - "Pågående jobbanrop via Wi-Fi" - "På vent" - "Innkommende anrop" - "Innkommende jobbanrop" - "Innkommende Wi-Fi-anrop" - "Innkommende jobbanrop via Wi-Fi" - "Innkommende videoanrop" - "Innkommende anrop fra en mulig useriøs oppringer" - "Innkommende videoforespørsel" - "Ny talepost" - "Ny talepost (%d)" - "Ring %s" - "Nummeret til talepostkassen er ukjent" - "Ingen tjeneste" - "Det valgte nettverket (%s) er ikke tilgjengelig" - "Svar" - "Legg på" - "Video" - "Uten video" - "Godta" - "Avvis" - "Ring tilbake" - "Melding" - "Samtale pågår på en annen enhet" - "Overfør samtalen" - "For å ringe, slå av flymodus først." - "Ikke registrert på nettverket." - "Mobilnettverket er ikke tilgjengelig." - "For å ringe, skriv inn et gyldig nummer." - "Kan ikke ringe." - "Starter MMI-sekvens …" - "Tjenesten støttes ikke." - "Kan ikke bytte samtaler." - "Kan ikke splitte opp anropet." - "Kan ikke overføre." - "Kan ikke opprette konferanse." - "Kan ikke avvise anropet." - "Kan ikke frigjøre samtale(r)." - "SIP-anrop" - "Nødanrop" - "Slår på radioen …" - "Ingen tjeneste. Prøver på nytt …" - "Kan ikke ringe. %s er ikke et nødnummer." - "Kan ikke ringe. Ring et nødnummer." - "Bruk tastaturet for å ringe" - "Sett anropet på vent" - "Gjenoppta anropet" - "Avslutt anropet" - "Vis tastaturet" - "Skjul tastaturet" - "Slå av lyden" - "Slå på lyden" - "Legg til anrop" - "Slå sammen anrop" - "Bytt" - "Administrer anrop" - "Administrer konferansesamtale" - "Konferansesamtale" - "Administrer" - "Lyd" - "Videoanrop" - "Bytt til taleanrop" - "Bytt kamera" - "Slå på kameraet" - "Slå av kameraet" - "Flere alternativer" - "Avspilleren har startet" - "Avspilleren har stoppet" - "Kameraet er ikke klart" - "Kameraet er klart" - "Ukjent anrop" - "Tjeneste" - "Konfigurering" - "<Ikke angitt>" - "Andre anropsinnstillinger" - "Ringer via %s" - "Innkommende via %s" - "kontaktbilde" - "aktivér privat samtale" - "velg kontakt" - "Skriv ditt eget" - "Avbryt" - "Send" - "Svar" - "Send SMS" - "Avslå" - "Svar med video" - "Svar uten video" - "Godta videoforespørselen" - "Avslå videoforespørselen" - "Godta forespørselen om å sende video" - "Avslå forespørselen om å sende video" - "Godta forespørselen om å motta video" - "Avslå forespørselen om å motta video" - "Dra opp for %s." - "Dra til venstre for å %s." - "Dra til høyre for å %s." - "Dra ned for å %s." - "Vibrering" - "Vibrering" - "Lyd" - "Standardlyd (%1$s)" - "Telefonringelyd" - "Vibrer når telefonen ringer" - "Ringelyd og vibrering" - "Administrer konferansesamtale" - "Nødnummer" - "Profilbilde" - "Kameraet er slått av" - "via %s" - "Notatet er sendt" - "Nylige meldinger" - "Informasjon om bedriften" - "%.1f mile unna" - "%.1f km unna" - "%1$s, %2$s" - "%1$s%2$s" - "%1$s, %2$s" - "Åpner i morgen kl. %s" - "Åpner i dag kl. %s" - "Stenger kl. %s" - "Stengte i dag kl. %s" - "Åpen nå" - "Stengt nå" - "Mulig useriøst anrop" - "Samtalen ble avsluttet %1$s" - "Dette er første gang du blir oppringt fra dette nummeret." - "Vi har mistanke om at dette anropet kommer fra en useriøs oppringer." - "Blokkér/rapportér" - "Legg til som kontakt" - "Ikke useriøs" - diff --git a/InCallUI/res/values-ne/strings.xml b/InCallUI/res/values-ne/strings.xml deleted file mode 100644 index 71c1ccae9..000000000 --- a/InCallUI/res/values-ne/strings.xml +++ /dev/null @@ -1,195 +0,0 @@ - - - - - "फोन" - "होल्डमा" - "अज्ञात" - "निजी नम्बर" - "पेफोन" - "सम्मेलन कल" - "कल ड्रप भयो" - "स्पिकर" - "हेन्डसेट इयरपिस" - "तारसहितको हेडसेट" - "ब्लुटुथ" - "निम्न टोनहरू पठाउने हो?\n" - "टोनहरू\n पठाउँदै" - "पठाउनुहोस्" - "हो" - "होइन" - "यसलाई वाइल्ड क्यारेक्टर राखेर बदल्नुहोस्" - "सम्मेलन कल %s" - "भ्वाइस मेल नम्बर" - "डायल गर्दै" - "पुन: डायल गर्दै" - "सम्मेलन कल" - "आगमन कल" - "कार्यालयबाट आएको कल" - "कल अन्त्य भयो" - "होल्डमा छ" - "फोन काट्दै" - "कलमा" - "मेरो नम्बर %s हो" - "भिडियो जडान गरिँदै" - "भिडियो कल" - "भिडियोका लागि अनुरोध गर्दै" - "भिडियो कलमा जडान गर्न सक्दैन" - "भिडियो अनुरोध अस्वीकार गरियो" - "तपाईंको कलब्याक नम्बर\n %1$s" - "तपाईंको आपतकालीन कलब्याक नम्बर\n %1$s" - "डायल गर्दै" - "छुटेको कल" - "छुटेका कलहरू" - "%s छुटेका कलहरू" - "%s बाट आएको छुटेको कल" - "चलिरहेको कल" - "चालु रहेको कार्यालयको कल" - "चालु रहेको WI-Fi कल" - "Wi-Fi मार्फत चालु रहेको कार्यालयको कल" - "होल्डमा" - "आगमन कल" - "कार्यालयबाट आएको कल" - "आगमन Wi-Fi कल" - "Wi-Fi मार्फत कार्यालयबाट आएको कल" - "आगमन भिडियो कल" - "शंकास्पद आगमन स्प्याम कल" - "आगमन भिडियो अनुरोध" - "नयाँ भ्वाइस मेल" - "नयाँ भ्वाइसमेल (%d)" - "%s मा डायल गर्नुहोस्" - "भ्वाइस मेल नम्बर अज्ञात छ" - "कुनै सेवा छैन" - "चयन गरिएको नेटवर्क (%s) अनुपलब्ध छ" - "जवाफ दिनुहोस्" - "राख्नुहोस्" - "भिडियो" - "आवाज" - "स्वीकार गर्नुहोस्" - "खारेज गर्नुहोस्" - "कल फर्काउने" - "सन्देश" - "अर्को यन्त्रमा चलिरहेको कल" - "कल स्थानान्तरण गर्नुहोस्" - "कल गर्नका लागि, पहिले हवाइजहाज मोड बन्द गर्नुहोस्।" - "नेटवर्कमा दर्ता भएको छैन।" - "सेलुलर नेटवर्क उपलब्ध छैन।" - "एक कल गर्नको लागि, मान्य नम्बर प्रविष्ट गर्नुहोस्।" - "कल गर्न सकिंदैन।" - "MMI अनुक्रम सुरु गर्दै..." - "सेवा समर्थित छैन।" - "कल स्विच गर्न सक्दैन।" - "कल अलग गर्न सक्दैन।" - "ट्रान्सफर गर्न सक्दैन।" - "सम्मेलन गर्न सक्दैन।" - "कल अस्वीकार गर्न सक्दैन।" - "कल (हरू) जारी गर्न सकिंदैन।" - "SIP कल" - "आपतकालीन कल" - "रेडियो खोल्दै..." - "कुनै सेवा छैन। फेरि प्रयास गर्दै..." - "कल गर्न सकिंदैन। %s आपतकालीन नम्बर होइन।" - "कल गर्न सकिंदैन। आपतकालीन नम्बर डायल गर्नुहोस्।" - "डायल गर्न किबोर्ड प्रयोग गर्नुहोस्" - "कललाई होल्ड गर्नुहोस्" - "कललाई पुन: निरन्तरता दिनुहोस्" - "कल अन्त्य गर्नुहोस्" - "डायलप्याड देखाउनुहोस्" - "डायलप्याड लुकाउनुहोस्" - "मौन" - "अनम्यूट गर्नुहोस्" - "कल थप्नुहोस्" - "कलहरू मर्ज गर्नुहोस्" - "स्वाप" - "कलहरूको प्रबन्ध मिलाउनुहोस्" - "सम्मेलन कलको प्रबन्ध मिलाउनहोस्" - "सम्मेलन कल" - "व्यवस्थापन गर्नुहोस्" - "अडियो" - "भिडियो कल" - "आवाज कलमा परिवर्तन गर्नुहोस्" - "क्यामेरा स्विच गर्नुहोस्" - "क्यामेरालाई सक्रिय गर्नुहोस्" - "क्यामेरालाई निष्क्रिय पार्नुहोस्" - "थप विकल्पहरू" - "प्लेयर सुरु भयो" - "प्लेयर रोकियो" - "क्यामेरा तयार छैन" - "क्यामेरा तयार छ" - "अज्ञात कल सत्र घटना" - "सेवा" - "सेटअप" - "<सेट गरिएको छैन>" - "अन्य कल सेटिङहरू" - "%s मार्फत कल गर्दै" - "%s मार्फत आगमन" - "सम्पर्क तस्बिर" - "निजी कलमा जानुहोस्" - "सम्पर्क चयन गर्नुहोस्" - "तपाईंको आफ्नै लेख्नुहोस्..." - "रद्द गर्नुहोस्" - "पठाउनुहोस्" - "जवाफ दिनुहोस्" - "SMS पठाउनुहोस्" - "अस्वीकार गर्नुहोस्" - "भिडियो कलको रूपमा जवाफ दिनुहोस्" - "अडियो कलको रूपमा जवाफ दिनुहोस्" - "भिडियो अनुरोध स्वीकार गर्नुहोस्" - "भिडियो अनुरोध अस्वीकार गर्नुहोस्" - "भिडियो प्रसारण गर्ने अनुरोध स्वीकार गर्नुहोस्" - "भिडियो प्रसारण गर्ने अनुरोध अस्वीकार गर्नुहोस्" - "भिडियो प्राप्त गर्ने अनुरोधलाई स्वीकार गर्नुहोस्" - "भिडियो प्राप्त गर्ने अनुरोध अस्वीकार गर्नुहोस्" - "%s को लागि माथि स्लाइड गर्नुहोस्।" - "%s को लागि बायाँ स्लाइड गर्नुहोस्।" - "%s को लागि दायाँ स्लाइड गर्नुहोस्।" - "%s को लागि तल स्लाइड गर्नुहोस्।" - "कम्पन हुने" - "कम्पन हुने" - "आवाज" - "पूर्वनिर्धारित ध्वनि (%1$s)" - "फोनको रिङटोन" - "घन्टी बज्दा कम्पन गराउनुहोस्" - "रिङटोन & कम्पन" - "सम्मेलन कलको प्रबन्ध मिलाउनुहोस्" - "आपतकालीन नम्बर" - "प्रोफाइल तस्बिर" - "क्यामेरा बन्द छ" - "%s बाट" - "नोट पठाइयो" - "भर्खरैका सन्देशहरू" - "व्यवसाय बारे जानकारी" - "%.1f माइल टाढा" - "%.1f किलोमिटर टाढा" - "%1$s, %2$s" - "%1$s - %2$s" - "%1$s, %2$s" - "भोलि %s मा खुल्छ" - "आज %s मा खुल्छ" - "%s मा बन्द हुन्छ" - "आज %s मा बन्द भयो" - "अहिले खुला छ" - "अब बन्द भयो" - "शंकास्पद स्प्याम कलर" - "कल समाप्त भयो %1$s" - "यो नम्बरबाट तपाईँलाई फोन आएको यो पहिलो पटक हो।" - "हामीले यो कल स्प्यामर हुन सक्ने आशङ्का गर्‍यौँ।" - "स्प्याम रोक्नु्/रिपोर्ट गर्ने" - "सम्पर्क थप्नुहोस्" - "स्प्याम होइन" - diff --git a/InCallUI/res/values-nl/strings.xml b/InCallUI/res/values-nl/strings.xml deleted file mode 100644 index 9eaf556c0..000000000 --- a/InCallUI/res/values-nl/strings.xml +++ /dev/null @@ -1,195 +0,0 @@ - - - - - "Telefoon" - "In de wacht" - "Onbekend" - "Privénummer" - "Betaaltelefoon" - "Telefonische vergadering" - "Oproep beëindigd" - "Luidspreker" - "Oortelefoon van handset" - "Bedrade headset" - "Bluetooth" - "De volgende tonen verzenden?\n" - "Nummers verzenden\n" - "Verzenden" - "Ja" - "Nee" - "Jokerteken vervangen door" - "Telefonische vergadering %s" - "Voicemailnummer" - "Kiezen" - "Opnieuw bellen" - "Telefonische vergadering" - "Inkomende oproep" - "Inkom. zakelijke oproep" - "Oproep beëindigd" - "In de wacht" - "Ophangen" - "In gesprek" - "Mijn nummer is %s" - "Verbinding maken met video" - "Videogesprek" - "Video aanvragen" - "Kan geen videogesprek starten" - "Videoverzoek geweigerd" - "Je terugbelnummer\n %1$s" - "Je terugbelnummer bij alarm\n %1$s" - "Kiezen" - "Gemiste oproep" - "Gemiste oproepen" - "%s gemiste oproepen" - "Gemiste oproep van %s" - "Actieve oproep" - "Actieve zakelijke oproep" - "Actieve wifi-oproep" - "Actieve zakelijke oproep via wifi" - "In de wacht" - "Inkomende oproep" - "Inkomende zakelijke oproep" - "Inkomende wifi-oproep" - "Inkomende zakelijke oproep via wifi" - "Inkomend videogesprek" - "Inkomende vermoedelijke spamoproep" - "Inkomend videoverzoek" - "Nieuwe voicemail" - "Nieuwe voicemail (%d)" - "%s bellen" - "Voicemailnummer onbekend" - "Geen service" - "Geselecteerd netwerk (%s) niet beschikbaar" - "Beantwoorden" - "Ophangen" - "Video" - "Spraak" - "Accepteren" - "Sluiten" - "Terugbellen" - "Bericht" - "Actief gesprek op een ander apparaat" - "Gesprek doorschakelen" - "Als je wilt bellen, moet je eerst de vliegtuigmodus uitschakelen." - "Niet geregistreerd op netwerk." - "Mobiel netwerk niet beschikbaar." - "Als je wilt bellen, moet je een geldig nummer invoeren." - "Kan niet bellen." - "MMI-reeks starten..." - "Service wordt niet ondersteund." - "Kan niet schakelen tussen oproepen." - "Kan oproep niet scheiden." - "Kan niet doorschakelen." - "Telefonische vergadering niet mogelijk." - "Kan oproep niet weigeren." - "Kan oproep(en) niet vrijgeven." - "SIP-oproep" - "Noodoproep" - "Radio inschakelen…" - "Geen bereik. Opnieuw proberen…" - "Kan niet bellen. %s is geen alarmnummer." - "Kan niet bellen. Bel een alarmnummer." - "Toetsen gebruiken om te bellen" - "Oproep in de wacht zetten" - "Oproep hervatten" - "Oproep beëindigen" - "Toetsenblok weergeven" - "Toetsenblok verbergen" - "Dempen" - "Dempen opheffen" - "Oproep toevoegen" - "Samenvoegen" - "Wisselen" - "Oproepen beheren" - "Telef. vergadering beheren" - "Telefonische vergadering" - "Beheren" - "Audio" - "Vid.gespr." - "Wijzigen in spraakoproep" - "Van camera wisselen" - "Camera inschakelen" - "Camera uitschakelen" - "Meer opties" - "Speler gestart" - "Speler gestopt" - "Camera niet gereed" - "Camera gereed" - "Onbekende oproepsessiegebeurtenis" - "Service" - "Configuratie" - "<Niet ingesteld>" - "Andere instellingen voor bellen" - "Bellen via %s" - "Inkomend via %s" - "contactfoto" - "privé" - "contact selecteren" - "Eigen reactie opstellen..." - "Annuleren" - "Verzenden" - "Beantwoorden" - "Sms verzenden" - "Weigeren" - "Beantwoorden als videogesprek" - "Beantwoorden als audiogesprek" - "Videoverzoek accepteren" - "Videoverzoek weigeren" - "Verzoek voor video-overdracht accepteren" - "Verzoek voor video-overdracht weigeren" - "Verzoek voor video-ontvangst accepteren" - "Verzoek voor video-ontvangst weigeren" - "Veeg omhoog voor %s." - "Veeg naar links voor %s." - "Veeg naar rechts voor %s." - "Veeg omlaag voor %s." - "Trillen" - "Trillen" - "Geluid" - "Standaardgeluid (%1$s)" - "Beltoon telefoon" - "Trillen bij bellen" - "Beltoon en trillen" - "Telefonische vergadering beheren" - "Alarmnummer" - "Profielfoto" - "Camera uit" - "via %s" - "Notitie verzonden" - "Recente berichten" - "Bedrijfsinformatie" - "%.1f mijl hiervandaan" - "%.1f km hiervandaan" - "%1$s, %2$s" - "%1$s - %2$s" - "%1$s, %2$s" - "Gaat morgen open om %s" - "Gaat vandaag open om %s" - "Sluit om %s" - "Vandaag gesloten vanaf %s" - "Nu geopend" - "Nu gesloten" - "Vermoedelijke spambeller" - "Oproep beëindigd %1$s" - "Dit is de eerste keer dat je bent gebeld door dit nummer." - "We vermoedden dat deze oproep afkomstig was van een spammer." - "Blokk./spam melden" - "Contact toevoegen" - "Geen spam" - diff --git a/InCallUI/res/values-pa/strings.xml b/InCallUI/res/values-pa/strings.xml deleted file mode 100644 index 318fc4cdc..000000000 --- a/InCallUI/res/values-pa/strings.xml +++ /dev/null @@ -1,195 +0,0 @@ - - - - - "ਫੋਨ" - "ਰੋਕੀ ਗਈ" - "ਅਗਿਆਤ" - "ਨਿੱਜੀ ਨੰਬਰ" - "ਪੇ-ਫੋਨ" - "ਕਾਨਫਰੰਸ ਕਾਲ" - "ਕਾਲ ਡ੍ਰੌਪ ਹੋਈ" - "ਸਪੀਕਰ" - "ਹੈੱਡਸੈੱਟ ਈਯਰਪੀਸ" - "ਵਾਇਰ ਵਾਲਾ ਹੈੱਡਸੈੱਟ" - "ਬਲੂਟੁੱਥ" - "ਕੀ ਅੱਗੇ ਦਿੱਤੀਆਂ ਗਈਆਂ ਧੁਨੀਆਂ ਭੇਜਣੀਆਂ ਹਨ?\n" - "ਧੁਨੀਆਂ ਭੇਜੀਆਂ ਜਾ ਰਹੀਆਂ ਹਨ\n" - "ਭੇਜੋ" - "ਹਾਂ" - "ਨਹੀਂ" - "ਵਾਈਲਡ ਅੱਖਰ ਨੂੰ ਇਸ ਨਾਲ ਬਦਲੋ" - "ਕਾਨਫਰੰਸ ਕਾਲ %s" - "ਵੌਇਸਮੇਲ ਨੰਬਰ" - "ਡਾਇਲ ਕੀਤਾ ਜਾ ਰਿਹਾ ਹੈ" - "ਦੁਬਾਰਾ ਡਾਇਲ ਕੀਤਾ ਜਾ ਰਿਹਾ ਹੈ" - "ਕਾਨਫਰੰਸ ਕਾਲ" - "ਆ ਰਹੀ ਕਾਲ" - "ਕੰਮ ਸੰਬੰਧਿਤ ਆ ਰਹੀ ਕਾਲ" - "ਕਾਲ ਸਮਾਪਤ ਹੋਈ" - "ਰੋਕੀ ਗਈ" - "ਰੋਕੀ ਜਾ ਰਹੀ ਹੈ" - "ਚਾਲੂ ਕਾਲ" - "ਮੇਰਾ ਨੰਬਰ %s ਹੈ" - "ਵੀਡੀਓ ਨੂੰ ਕਨੈਕਟ ਕੀਤਾ ਜਾ ਰਿਹਾ ਹੈ" - "ਵੀਡੀਓ ਕਾਲ" - "ਵੀਡੀਓ ਲਈ ਬੇਨਤੀ ਕੀਤੀ ਜਾ ਰਹੀ ਹੈ" - "ਵੀਡੀਓ ਕਾਲ ਕਨੈਕਟ ਨਹੀਂ ਕੀਤੀ ਜਾ ਸਕਦੀ" - "ਵੀਡੀਓ ਬੇਨਤੀ ਅਸਵੀਕਾਰ ਕੀਤੀ ਗਈ" - "ਤੁਹਾਡਾ ਕਾਲਬੈਕ ਨੰਬਰ \n %1$s" - "ਤੁਹਾਡਾ ਐਮਰਜੈਂਸੀ ਕਾਲਬੈਕ ਨੰਬਰ\n %1$s" - "ਡਾਇਲ ਕੀਤਾ ਜਾ ਰਿਹਾ ਹੈ" - "ਖੁੰਝੀ ਹੋਈ ਕਾਲ" - "ਖੁੰਝੀਆਂ ਹੋਈਆਂ ਕਾਲਾਂ" - "%s ਖੁੰਝੀਆਂ ਹੋਈਆਂ ਕਾਲਾਂ" - "%s ਤੋਂ ਖੁੰਝੀ ਹੋਈ ਕਾਲ" - "ਜਾਰੀ ਕਾਲ" - "ਕੰਮ ਸੰਬੰਧਿਤ ਜਾਰੀ ਕਾਲ" - "ਜਾਰੀ Wi-Fi ਕਾਲ" - "ਕੰਮ ਸੰਬੰਧਿਤ ਜਾਰੀ Wi-Fi ਕਾਲ" - "ਰੋਕੀ ਗਈ" - "ਆ ਰਹੀ ਕਾਲ" - "ਕੰਮ ਸੰਬੰਧਿਤ ਆ ਰਹੀ ਕਾਲ" - "ਆ ਰਹੀ Wi-Fi ਕਾਲ" - "ਕੰਮ ਸੰਬੰਧਿਤ ਆ ਰਹੀ Wi-Fi ਕਾਲ" - "ਆ ਰਹੀ ਵੀਡੀਓ ਕਾਲ" - "ਸ਼ੱਕੀ ਸਪੈਮ ਕਾਲ ਆ ਰਹੀ ਹੈ" - "ਆ ਰਹੀ ਵੀਡੀਓ ਬੇਨਤੀ" - "ਨਵੀਂ ਵੌਇਸਮੇਲ" - "ਨਵੀਂ ਵੌਇਸਮੇਲ (%d)" - "%s ਡਾਇਲ ਕਰੋ" - "ਵੌਇਸਮੇਲ ਨੰਬਰ ਅਗਿਆਤ" - "ਕੋਈ ਸੇਵਾ ਨਹੀਂ" - "ਚੁਣਿਆ ਗਿਆ ਨੈੱਟਵਰਕ (%s) ਉਪਲਬਧ ਨਹੀਂ ਹੈ" - "ਜਵਾਬ ਦਿਓ" - "ਰੋਕੋ" - "ਵੀਡੀਓ" - "ਵੌਇਸ" - "ਸਵੀਕਾਰ ਕਰੋ" - "ਰੱਦ ਕਰੋ" - "ਵਾਪਸ ਕਾਲ ਕਰੋ" - "ਸੁਨੇਹਾ" - "ਕਿਸੇ ਹੋਰ ਡੀਵਾਈਸ \'ਤੇ ਜਾਰੀ ਕਾਲ" - "ਕਾਲ ਟ੍ਰਾਂਸਫਰ ਕਰੋ" - "ਇੱਕ ਕਾਲ ਕਰਨ ਲਈ, ਪਹਿਲਾਂ ਜਹਾਜ਼ ਮੋਡ ਬੰਦ ਕਰੋ।" - "ਨੈੱਟਵਰਕ \'ਤੇ ਰਜਿਸਟਰ ਨਹੀਂ।" - "ਸੈਲਿਊਲਰ ਨੈੱਟਵਰਕ ਉਪਲਬਧ ਨਹੀਂ ਹੈ।" - "ਇੱਕ ਕਾਲ ਕਰਨ ਲਈ, ਇੱਕ ਵੈਧ ਨੰਬਰ ਦਾਖਲ ਕਰੋ।" - "ਕਾਲ ਨਹੀਂ ਕੀਤੀ ਜਾ ਸਕਦੀ।" - "MMI ਕੜੀ ਨੂੰ ਸ਼ੁਰੂ ਕੀਤਾ ਜਾ ਰਿਹਾ ਹੈ…" - "ਸੇਵਾ ਸਮਰਥਿਤ ਨਹੀਂ ਹੈ।" - "ਕਾਲਾਂ ਸਵਿੱਚ ਨਹੀਂ ਕੀਤੀਆਂ ਜਾ ਸਕਦੀਆਂ।" - "ਵੱਖਰੇ ਤੌਰ \'ਤੇ ਕਾਲ ਨਹੀਂ ਕੀਤੀ ਜਾ ਸਕਦੀ।" - "ਕਾਲ ਟ੍ਰਾਂਸਫਰ ਨਹੀਂ ਕੀਤੀ ਜਾ ਸਕਦੀ।" - "ਕਾਨਫਰੰਸ ਕਾਲ ਨਹੀਂ ਕੀਤੀ ਜਾ ਸਕਦੀ।" - "ਕਾਲ ਰੱਦ ਨਹੀਂ ਕੀਤੀ ਜਾ ਸਕਦੀ।" - "ਕਾਲ(ਲਾਂ) ਰੀਲੀਜ਼ ਨਹੀਂ ਕੀਤੀਆਂ ਜਾ ਸਕਦੀਆਂ।" - "SIP ਕਾਲ" - "ਐਮਰਜੈਂਸੀ ਕਾਲ" - "ਰੇਡੀਓ ਚਾਲੂ ਕੀਤਾ ਜਾ ਰਿਹਾ ਹੈ…" - "ਕੋਈ ਸੇਵਾ ਨਹੀਂ। ਦੁਬਾਰਾ ਕੋਸ਼ਿਸ਼ ਕੀਤੀ ਜਾ ਰਹੀ ਹੈ…" - "ਕਾਲ ਨਹੀਂ ਕੀਤੀ ਜਾ ਸਕਦੀ। %s ਇੱਕ ਐਮਰਜੈਂਸੀ ਨੰਬਰ ਨਹੀਂ ਹੈ।" - "ਕਾਲ ਨਹੀਂ ਕੀਤੀ ਜਾ ਸਕਦੀ। ਇੱਕ ਐਮਰਜੈਂਸੀ ਨੰਬਰ ਡਾਇਲ ਕਰੋ।" - "ਡਾਇਲ ਕਰਨ ਲਈ ਕੀ-ਬੋਰਡ ਵਰਤੋ" - "ਕਾਲ ਰੋਕੋ" - "ਕਾਲ ਮੁੜ-ਸ਼ੁਰੂ ਕਰੋ" - "ਕਾਲ ਸਮਾਪਤ ਕਰੋ" - "ਡਾਇਲਪੈਡ ਵਿਖਾਓ" - "ਡਾਇਲਪੈਡ ਲੁਕਾਓ" - "ਮਿਊਟ ਕਰੋ" - "ਅਣਮਿਊਟ ਕਰੋ" - "ਕਾਲ ਸ਼ਾਮਲ ਕਰੋ" - "ਕਾਲਾਂ ਸ਼ਾਮਲ ਕਰੋ" - "ਅਦਲਾ-ਬਦਲੀ ਕਰੋ" - "ਕਾਲਾਂ ਦਾ ਪ੍ਰਬੰਧਨ ਕਰੋ" - "ਕਾਨਫਰੰਸ ਕਾਲ ਦਾ ਪ੍ਰਬੰਧਨ ਕਰੋ" - "ਕਾਨਫਰੰਸ ਕਾਲ" - "ਪ੍ਰਬੰਧਨ ਕਰੋ" - "ਔਡੀਓ" - "ਵੀਡੀਓ ਕਾਲ" - "ਵੌਇਸ ਕਾਲ ਵਿੱਚ ਬਦਲੋ" - "ਕੈਮਰੇ \'ਤੇ ਬਦਲੋ" - "ਕੈਮਰਾ ਚਾਲੂ ਕਰੋ" - "ਕੈਮਰਾ ਬੰਦ ਕਰੋ" - "ਹੋਰ ਚੋਣਾਂ" - "ਪਲੇਅਰ ਸ਼ੁਰੂ ਹੋ ਗਿਆ" - "ਪਲੇਅਰ ਰੁਕ ਗਿਆ" - "ਕੈਮਰਾ ਤਿਆਰ ਨਹੀਂ ਹੈ" - "ਕੈਮਰਾ ਤਿਆਰ ਹੈ" - "ਅਗਿਆਤ ਕਾਲ ਸੈਸ਼ਨ ਵਰਤਾਰਾ" - "ਸੇਵਾ" - "ਸਥਾਪਨਾ" - "<ਸੈੱਟ ਨਹੀਂ>" - "ਹੋਰ ਕਾਲ ਸੈਟਿੰਗਾਂ" - "%s ਰਾਹੀਂ ਕਾਲ ਕੀਤੀ ਜਾ ਰਹੀ ਹੈ" - "%s ਰਾਹੀਂ ਆ ਰਹੀਆਂ ਕਾਲਾਂ" - "ਸੰਪਰਕ ਫ਼ੋਟੋ" - "ਨਿੱਜੀ ਵਿੱਚ ਬਦਲੋ" - "ਸੰਪਰਕ ਚੁਣੋ" - "ਆਪਣੇ ਆਪ ਲਿਖੋ..." - "ਰੱਦ ਕਰੋ" - "ਭੇਜੋ" - "ਜਵਾਬ ਦਿਓ" - "SMS ਭੇਜੋ" - "ਅਸਵੀਕਾਰ ਕਰੋ" - "ਵੀਡੀਓ ਕਾਲ ਵਜੋਂ ਜਵਾਬ ਦਿਓ" - "ਔਡੀਓ ਕਾਲ ਵਜੋਂ ਜਵਾਬ ਦਿਓ" - "ਵੀਡੀਓ ਬੇਨਤੀ ਸਵੀਕਾਰ ਕਰੋ" - "ਵੀਡੀਓ ਬੇਨਤੀ ਨੂੰ ਅਸਵੀਕਾਰ ਕਰੋ" - "ਵੀਡੀਓ ਟ੍ਰਾਂਸਮਿਟ ਬੇਨਤੀ ਨੂੰ ਸਵੀਕਾਰ ਕਰੋ" - "ਵੀਡੀਓ ਟ੍ਰਾਂਸਮਿਟ ਬੇਨਤੀ ਨੂੰ ਅਸਵੀਕਾਰ ਕਰੋ" - "ਵੀਡੀਓ ਪ੍ਰਾਪਤ ਕਰਨ ਦੀ ਬੇਨਤੀ ਨੂੰ ਸਵੀਕਾਰ ਕਰੋ" - "ਵੀਡੀਓ ਪ੍ਰਾਪਤ ਕਰਨ ਦੀ ਬੇਨਤੀ ਨੂੰ ਅਸਵੀਕਾਰ ਕਰੋ" - "%s ਲਈ ਉੱਤੇ ਸਲਾਈਡ ਕਰੋ।" - "%s ਲਈ ਖੱਬੇ ਪਾਸੇ ਸਲਾਈਡ ਕਰੋ।" - "%s ਲਈ ਸੱਜੇ ਪਾਸੇ ਸਲਾਈਡ ਕਰੋ।" - "%s ਲਈ ਹੇਠਾਂ ਸਲਾਈਡ ਕਰੋ।" - "ਥਰਥਰਾਹਟ ਕਰੋ" - "ਥਰਥਰਾਹਟ ਕਰੋ" - "ਧੁਨੀ" - "ਪੂਰਵ-ਨਿਰਧਾਰਤ ਧੁਨੀ (%1$s)" - "ਫੋਨ ਰਿੰਗਟੋਨ" - "ਘੰਟੀ ਵੱਜਣ \'ਤੇ ਥਰਥਰਾਹਟ ਕਰੋ" - "ਰਿੰਗਟੋਨ ਅਤੇ ਥਰਥਰਾਹਟ" - "ਕਾਨਫਰੰਸ ਕਾਲ ਦਾ ਪ੍ਰਬੰਧਨ ਕਰੋ" - "ਐਮਰਜੈਂਸੀ ਨੰਬਰ" - "ਪ੍ਰੋਫਾਈਲ ਫ਼ੋਟੋ" - "ਕੈਮਰਾ ਬੰਦ ਹੈ" - "%s ਰਾਹੀਂ" - "ਨੋਟ-ਕਥਨ ਭੇਜਿਆ ਗਿਆ" - "ਹਾਲੀਆ ਸੁਨੇਹੇ" - "ਵਪਾਰ ਜਾਣਕਾਰੀ" - "%.1f ਮੀਲ ਦੂਰ" - "%.1f ਕਿ.ਮੀ. ਦੂਰ" - "%1$s, %2$s" - "%1$s - %2$s" - "%1$s, %2$s" - "ਕੱਲ੍ਹ %s ਵਜੇ ਖੁੱਲ੍ਹੇਗਾ" - "ਅੱਜ %s ਵਜੇ ਖੁੱਲ੍ਹੇਗਾ" - "%s ਵਜੇ ਬੰਦ ਹੋਵੇਗਾ" - "ਅੱਜ %s ਵਜੇ ਬੰਦ ਹੋਇਆ" - "ਹੁਣ ਖੁੱਲ੍ਹਾ ਹੈ" - "ਹੁਣ ਬੰਦ ਹੈ" - "ਸ਼ੱਕੀ ਸਪੈਮ ਕਾਲਰ" - "%1$s ਦੀ ਕਾਲ ਸਮਾਪਤ ਹੋਈ" - "ਇਸ ਨੰਬਰ ਤੋਂ ਤੁਹਾਨੂੰ ਪਹਿਲੀ ਵਾਰ ਕਾਲ ਪ੍ਰਾਪਤ ਹੋਈ ਹੈ।" - "ਸਾਨੂੰ ਇਹ ਕਾਲ ਇੱਕ ਸਪੈਮਰ ਜਾਪਦੀ ਸੀ।" - "ਸਪੈਮ ਨੂੰ ਬਲੌਕ ਕਰੋ/ਰਿਪੋਰਟ ਕਰੋ" - "ਸੰਪਰਕ ਸ਼ਾਮਲ ਕਰੋ" - "ਸਪੈਮ ਨਹੀਂ" - diff --git a/InCallUI/res/values-pl/strings.xml b/InCallUI/res/values-pl/strings.xml deleted file mode 100644 index f9f78ec79..000000000 --- a/InCallUI/res/values-pl/strings.xml +++ /dev/null @@ -1,195 +0,0 @@ - - - - - "Telefon" - "Wstrzymane" - "Nieznany" - "Numer prywatny" - "Automat telefoniczny" - "Połączenie konferencyjne" - "Połączenie przerwane" - "Głośnik" - "Słuchawka telefonu" - "Przewodowy zestaw słuchawkowy" - "Bluetooth" - "Wysłać te tony?\n" - "Wysyłanie tonów\n" - "Wyślij" - "Tak" - "Nie" - "Zastąp symbol wieloznaczny" - "Połączenie konferencyjne: %s" - "Numer poczty głosowej" - "Wybieranie" - "Ponowne wybieranie numeru" - "Połączenie konferencyjne" - "Połączenie przychodzące" - "Przychodzące połączenie służbowe" - "Połączenie zakończone" - "Wstrzymane" - "Rozłączanie" - "Trwa połączenie" - "Mój numer to %s" - "Rozpoczynanie rozmowy wideo" - "Rozmowa wideo" - "Wysyłanie żądania wideo" - "Nie można nawiązać połączenia wideo" - "Żądanie wideo zostało odrzucone" - "Twój numer oddzwaniania\n %1$s" - "Twój numer oddzwaniania dla połączeń alarmowych\n %1$s" - "Wybieranie" - "Nieodebrane połączenie" - "Nieodebrane połączenia" - "Nieodebrane połączenia: %s" - "Nieodebrane połączenie od: %s" - "Trwa połączenie" - "Trwa połączenie służbowe" - "Trwa połączenie przez Wi-Fi" - "Trwa połączenie służbowe przez Wi-Fi" - "Wstrzymane" - "Połączenie przychodzące" - "Przychodzące połączenie służbowe" - "Przychodzące połączenie przez Wi-Fi" - "Przychodzące połączenie służbowe przez Wi-Fi" - "Przychodząca rozmowa wideo" - "Przychodzące połączenie podejrzanie o spam" - "Przychodzące żądanie wideo" - "Nowa poczta głosowa" - "Nowa poczta głosowa (%d)" - "Wybierz numer %s" - "Nieznany numer poczty głosowej" - "Brak usługi" - "Wybrana sieć (%s) jest niedostępna" - "Odbierz" - "Rozłącz" - "Wideo" - "Głos" - "Zaakceptuj" - "Odrzuć" - "Oddzwoń" - "Wyślij SMS-a" - "Trwająca rozmowa na innym urządzeniu" - "Przełącz rozmowę" - "Aby rozpocząć połączenie, wyłącz najpierw tryb samolotowy." - "Nie zarejestrowano w sieci." - "Sieć komórkowa jest niedostępna." - "Aby zadzwonić, wybierz prawidłowy numer." - "Nie można dzwonić." - "Rozpoczynam sekwencję MMI…" - "Usługa nie jest obsługiwana." - "Nie można przełączyć połączeń." - "Nie można rozdzielić połączenia." - "Nie można przekazać." - "Nie można nawiązać połączenia konferencyjnego." - "Nie można odrzucić połączenia." - "Nie można zwolnić połączeń." - "Połączenie SIP" - "Połączenie alarmowe" - "Włączam radio…" - "Brak sieci. Próbuję ponownie…" - "Nie można dzwonić. %s nie jest numerem alarmowym." - "Nie można dzwonić. Wybierz numer alarmowy." - "Aby zadzwonić, użyj klawiatury" - "Wstrzymaj połączenie" - "Wznów połączenie" - "Zakończ połączenie" - "Pokaż klawiaturę" - "Ukryj klawiaturę" - "Wycisz" - "Wyłącz wyciszenie" - "Dodaj połączenie" - "Scal połączenia" - "Przełącz" - "Zarządzaj połączeniami" - "Zarządzaj połączeniem konferencyjnym" - "Połączenie konferencyjne" - "Zarządzaj" - "Dźwięk" - "Rozmowa wideo" - "Zmień na połączenie głosowe" - "Przełącz kamerę" - "Włącz kamerę" - "Wyłącz kamerę" - "Więcej opcji" - "Odtwarzacz włączony" - "Odtwarzacz zatrzymany" - "Kamera niegotowa" - "Kamera gotowa" - "Nieznane zdarzenie sesji połączenia" - "Usługa" - "Konfiguracja" - "<Nie ustawiono>" - "Inne ustawienia połączeń" - "Nawiązywanie połączenia przez %s" - "Przychodzące z sieci %s" - "zdjęcie kontaktu" - "przejdź do rozmowy prywatnej" - "wybierz kontakt" - "Napisz własną..." - "Anuluj" - "Wyślij" - "Odbierz" - "Wyślij SMS-a" - "Odrzuć" - "Odbierz jako rozmowę wideo" - "Odbierz jako rozmowę audio" - "Zaakceptuj żądanie wideo" - "Odrzuć żądanie wideo" - "Zaakceptuj wysyłanie obrazu wideo" - "Odrzuć wysyłanie obrazu wideo" - "Zaakceptuj odbieranie obrazu wideo" - "Odrzuć odbieranie obrazu wideo" - "Przesuń w górę: %s." - "Przesuń w lewo: %s." - "Przesuń w prawo: %s." - "Przesuń w dół: %s." - "Wibracje" - "Wibracje" - "Dźwięk" - "Domyślny dźwięk (%1$s)" - "Dzwonek telefonu" - "Wibracje z dzwonkiem" - "Dzwonek i wibracje" - "Zarządzaj połączeniem konferencyjnym" - "Numer alarmowy" - "Zdjęcie profilowe" - "Kamera wyłączona" - "z %s" - "Notatka wysłana" - "Ostatnie wiadomości" - "Informacje o firmie" - "%.1f mil(e) stąd" - "%.1f km stąd" - "%1$s, %2$s" - "%1$s-%2$s" - "%1$s, %2$s" - "Otwarte jutro od %s" - "Otwarte dzisiaj od %s" - "Zamknięte od %s" - "Zamknięte dzisiaj od %s" - "Teraz otwarte" - "Teraz zamknięte" - "Podejrzenie spamu" - "Połączenie zakończone (%1$s)" - "To pierwsze połączenie z tego numeru." - "Podejrzewamy, że to połączenie to spam." - "Zablokuj/zgłoś spam" - "Dodaj kontakt" - "To nie spam" - diff --git a/InCallUI/res/values-pt-rBR/strings.xml b/InCallUI/res/values-pt-rBR/strings.xml deleted file mode 100644 index 5271f54cc..000000000 --- a/InCallUI/res/values-pt-rBR/strings.xml +++ /dev/null @@ -1,195 +0,0 @@ - - - - - "Telefone" - "Em espera" - "Desconhecido" - "Número privado" - "Chamada a cobrar" - "Teleconferência" - "A chamada caiu." - "Alto-falante" - "Minifone do aparelho" - "Fone de ouvido com fio" - "Bluetooth" - "Enviar os seguintes tons?\n" - "Enviando tons\n" - "Enviar" - "Sim" - "Não" - "Substituir caractere curinga por" - "Teleconferência %s" - "Número do correio de voz" - "Discando" - "Rediscando" - "Teleconferência" - "Chamada recebida" - "Chamada trabalho recebida" - "Chamada encerrada" - "Em espera" - "Desligando" - "Em chamada" - "Meu número é %s" - "Conectando vídeo" - "Videochamada" - "Solicitando vídeo" - "Não é possível conectar a videochamada" - "Solicitação de vídeo rejeitada" - "Seu número de retorno de chamada\n %1$s" - "Seu número de retorno de chamada de emergência\n %1$s" - "Discando" - "Chamada perdida" - "Chamadas perdidas" - "%s chamadas perdidas" - "Chamada perdida de %s" - "Chamanda em andamento" - "Chamada de trabalho em andamento" - "Chamada por Wi-Fi em andamento" - "Chamada de trabalho por Wi-Fi em andamento" - "Em espera" - "Chamada recebida" - "Chamada de trabalho recebida" - "Chamada por Wi-Fi recebida" - "Chamada de trabalho recebida por Wi-Fi" - "Videochamada recebida" - "Chamada recebida suspeita (spam)" - "Solicitação de vídeo recebida" - "Novo correio de voz" - "Novo correio de voz (%d)" - "Discar %s" - "Número correio de voz desconhecido" - "Sem serviço" - "A rede selecionada (%s) está indisponível" - "Atender" - "Desligar" - "Vídeo" - "Voz" - "Aceitar" - "Dispensar" - "Retor. cham." - "Mensagem" - "Chamada em andamento em outro dispositivo" - "Transferir chamada" - "Para fazer uma chamada, primeiro desative o modo avião." - "Não registrado na rede." - "Rede celular não disponível." - "Para realizar uma chamada, digite um número válido." - "Não é possível realizar chamadas." - "Iniciando sequência MMI…" - "Serviço não compatível." - "Não é possível alternar as chamadas." - "Não é possível separar a chamada." - "Não é possível transferir a chamada." - "Não é possível fazer uma conferência." - "Não é possível rejeitar a chamada." - "Não é possível liberar chamadas." - "Chamada SIP" - "Chamada de emergência" - "Ativando o rádio…" - "Sem serviço. Tentando novamente..." - "Não é possível realizar chamadas. %s não é um número de emergência." - "Não é possível realizar chamadas. Disque um número de emergência." - "Use o teclado para discar" - "Colocar chamada em espera" - "Retomar chamada" - "Encerrar chamada" - "Mostrar teclado" - "Ocultar teclado" - "Desativar som" - "Ativar som" - "Adicionar chamada" - "Juntar chamadas" - "Trocar" - "Gerenciar chamadas" - "Gerenciar teleconferência" - "Teleconferência" - "Gerenciar" - "Áudio" - "Videocham." - "Alterar para chamada de voz" - "Alternar câmera" - "Ativar câmera" - "Desativar câmera" - "Mais opções" - "Player iniciado" - "Player interrompido" - "A câmera não está pronta" - "Câmera pronta" - "Evento de sessão de chamada desconhecido" - "Serviço" - "Configuração" - "<Não definido>" - "Outras configurações de chamada" - "Chamando via %s" - "Chamada de %s" - "foto do contato" - "conversar em particular" - "selecionar contato" - "Escreva sua resposta..." - "Cancelar" - "Enviar" - "Atender" - "Enviar SMS" - "Recusar" - "Atender como videochamada" - "Atender como chamada de áudio" - "Aceitar solicitação de vídeo" - "Recusar solicitação de vídeo" - "Aceitar solicitação de transmissão de vídeo" - "Recusar solicitação de transmissão de vídeo" - "Aceitar solicitação de recebimento de vídeo" - "Recusar solicitação de recebimento de vídeo" - "Para %s, deslize para cima." - "Para %s, deslize para a esquerda." - "Para %s, deslize para a direita." - "Para %s, deslize para baixo." - "Vibrar" - "Vibrar" - "Som" - "Som padrão (%1$s)" - "Toque do telefone" - "Vibrar ao tocar" - "Toque e vibração" - "Gerenciar teleconferência" - "Número de emergência" - "Foto do perfil" - "Câmera desligada" - "via %s" - "Nota enviada" - "Mensagens recentes" - "Informações sobre a empresa" - "%.1f milhas de distância" - "%.1f km de distância" - "%1$s, %2$s" - "%1$s - %2$s" - "%1$s, %2$s" - "Abre amanhã às %s" - "Abre hoje às %s" - "Fecha às %s" - "Fechou hoje às %s" - "Aberto agora" - "Fechado agora" - "Autor suspeito (spam)" - "Chamada encerra %1$s" - "Esta é a primeira vez que este número ligou para você." - "Suspeitamos que esta chamada seja de um criador de spams." - "Bloq./denunciar spam" - "Adicionar contato" - "Não é spam" - diff --git a/InCallUI/res/values-pt-rPT/strings.xml b/InCallUI/res/values-pt-rPT/strings.xml deleted file mode 100644 index 2a04556fe..000000000 --- a/InCallUI/res/values-pt-rPT/strings.xml +++ /dev/null @@ -1,195 +0,0 @@ - - - - - "Telefone" - "Em espera" - "Desconhecido" - "Número privado" - "Telefone público" - "Conferência" - "A chamada caiu" - "Altifalante" - "Auricular do telefone" - "Auscultadores com fios" - "Bluetooth" - "Pretende enviar os seguintes tons?\n" - "A enviar tons\n" - "Enviar" - "Sim" - "Não" - "Substituir o caráter universal por" - "Conferência %s" - "Número do correio de voz" - "A marcar" - "A remarcar" - "Conferência" - "Chamada recebida" - "Chamada de trab. recebida" - "Chamada terminada" - "Em espera" - "A desligar" - "Numa chamada" - "O meu número é %s" - "A ligar vídeo" - "Videochamada" - "A solicitar vídeo" - "Não é possível ligar a videochamada" - "Pedido de vídeo rejeitado" - "O seu número de retorno de chamadas\n %1$s" - "O seu número de retorno de chamadas de emergência\n %1$s" - "A marcar" - "Chamada não atendida" - "Chamadas não atendidas" - "%s chamadas não atendidas" - "Chamada não atendida de %s" - "Chamada em curso" - "Chamada de trabalho em curso" - "Chamada Wi-Fi em curso" - "Chamada de trabalho via Wi-Fi em curso" - "Em espera" - "Chamada recebida" - "Chamada de trab. recebida" - "Chamada Wi-Fi recebida" - "Chamada de trabalho recebida via Wi-Fi" - "Videochamada recebida" - "A receber chamada spam suspeita" - "Pedido de vídeo recebido" - "Nova mensagem de correio de voz" - "Nova mensagem de correio de voz (%d)" - "Marcar %s" - "Número do correio de voz desconhecido" - "Sem serviço" - "Rede selecionada (%s) indisponível" - "Atender" - "Desligar" - "Vídeo" - "Voz" - "Aceitar" - "Ignorar" - "Ligar de volta" - "Mensagem" - "Chamada em curso noutro dispositivo" - "Transferir chamada" - "Para efetuar uma chamada, desative primeiro o Modo de avião." - "Sem registo na rede." - "Rede móvel não disponível." - "Para efetuar uma chamada, introduza um número válido." - "Não é possível telefonar." - "A iniciar sequência de MMI..." - "Serviço não suportado." - "Não é possível alternar entre chamadas." - "Não é possível separar a chamada." - "Não é possível transferir." - "Não é possível efetuar uma conferência." - "Não é possível rejeitar a chamada." - "Não é possível libertar as chamadas." - "Chamada SIP" - "Chamada de emergência" - "A ligar o rádio..." - "Sem serviço. A tentar novamente…" - "Não é possível telefonar. %s não é um número de emergência." - "Não é possível telefonar. Marque um número de emergência." - "Utilizar o teclado para marcar" - "Colocar chamada em espera" - "Retomar chamada" - "Terminar chamada" - "Mostrar o teclado" - "Ocultar o teclado" - "Desativar som" - "Reativar o som" - "Adicionar chamada" - "Intercalar chamadas" - "Trocar" - "Gerir chamadas" - "Gerir conferência" - "Conferência" - "Gerir" - "Áudio" - "Videochamada" - "Mudar para chamada de voz" - "Trocar câmara" - "Ativar câmara" - "Desativar câmara" - "Mais opções" - "Leitor iniciado" - "Leitor interrompido" - "A câmara não está pronta" - "Câmara pronta" - "Evento de sessão de chamada desconhecido" - "Serviço" - "Configuração" - "<Não definido>" - "Outras definições de chamadas" - "A telefonar através de %s" - "Recebidas através de %s" - "foto do contacto" - "tornar privado" - "selecionar contacto" - "Escreva a sua própria..." - "Cancelar" - "Enviar" - "Atender" - "Enviar SMS" - "Recusar" - "Atender como videochamada" - "Atender como chamada de áudio" - "Aceitar pedido de vídeo" - "Recusar pedido de vídeo" - "Aceitar pedido para transmitir vídeo" - "Recusar pedido para transmitir vídeo" - "Aceitar pedido para receber vídeo" - "Recusar pedido para receber vídeo" - "Deslize lentamente para cima para %s." - "Deslize lentamente para a esquerda para %s." - "Deslize lentamente para a direita para %s." - "Deslize lentamente para baixo para %s." - "Vibrar" - "Vibrar" - "Som" - "Som predefinido (%1$s)" - "Toque do telemóvel" - "Vibrar ao tocar" - "Tocar e vibrar" - "Gerir conferência" - "Número de emergência" - "Foto do perfil" - "Câmara desligada" - "através de %s" - "Nota enviada" - "Mensagens recentes" - "Informações da empresa" - "A %.1f milhas de distância" - "A %.1f km de distância" - "%1$s, %2$s" - "%1$s%2$s" - "%1$s, %2$s" - "Abre amanhã às %s" - "Abre hoje às %s" - "Fecha às %s" - "Fechou hoje às %s" - "Aberto agora" - "Fechado agora" - "Chmd. spam suspeita" - "Chamada terminada: %1$s" - "É a primeira vez que este número lhe liga." - "Suspeitamos que a pessoa que fez esta chamada seja um spammer." - "Bloq./denunciar spam" - "Adicionar contacto" - "Não é spam" - diff --git a/InCallUI/res/values-pt/strings.xml b/InCallUI/res/values-pt/strings.xml deleted file mode 100644 index 5271f54cc..000000000 --- a/InCallUI/res/values-pt/strings.xml +++ /dev/null @@ -1,195 +0,0 @@ - - - - - "Telefone" - "Em espera" - "Desconhecido" - "Número privado" - "Chamada a cobrar" - "Teleconferência" - "A chamada caiu." - "Alto-falante" - "Minifone do aparelho" - "Fone de ouvido com fio" - "Bluetooth" - "Enviar os seguintes tons?\n" - "Enviando tons\n" - "Enviar" - "Sim" - "Não" - "Substituir caractere curinga por" - "Teleconferência %s" - "Número do correio de voz" - "Discando" - "Rediscando" - "Teleconferência" - "Chamada recebida" - "Chamada trabalho recebida" - "Chamada encerrada" - "Em espera" - "Desligando" - "Em chamada" - "Meu número é %s" - "Conectando vídeo" - "Videochamada" - "Solicitando vídeo" - "Não é possível conectar a videochamada" - "Solicitação de vídeo rejeitada" - "Seu número de retorno de chamada\n %1$s" - "Seu número de retorno de chamada de emergência\n %1$s" - "Discando" - "Chamada perdida" - "Chamadas perdidas" - "%s chamadas perdidas" - "Chamada perdida de %s" - "Chamanda em andamento" - "Chamada de trabalho em andamento" - "Chamada por Wi-Fi em andamento" - "Chamada de trabalho por Wi-Fi em andamento" - "Em espera" - "Chamada recebida" - "Chamada de trabalho recebida" - "Chamada por Wi-Fi recebida" - "Chamada de trabalho recebida por Wi-Fi" - "Videochamada recebida" - "Chamada recebida suspeita (spam)" - "Solicitação de vídeo recebida" - "Novo correio de voz" - "Novo correio de voz (%d)" - "Discar %s" - "Número correio de voz desconhecido" - "Sem serviço" - "A rede selecionada (%s) está indisponível" - "Atender" - "Desligar" - "Vídeo" - "Voz" - "Aceitar" - "Dispensar" - "Retor. cham." - "Mensagem" - "Chamada em andamento em outro dispositivo" - "Transferir chamada" - "Para fazer uma chamada, primeiro desative o modo avião." - "Não registrado na rede." - "Rede celular não disponível." - "Para realizar uma chamada, digite um número válido." - "Não é possível realizar chamadas." - "Iniciando sequência MMI…" - "Serviço não compatível." - "Não é possível alternar as chamadas." - "Não é possível separar a chamada." - "Não é possível transferir a chamada." - "Não é possível fazer uma conferência." - "Não é possível rejeitar a chamada." - "Não é possível liberar chamadas." - "Chamada SIP" - "Chamada de emergência" - "Ativando o rádio…" - "Sem serviço. Tentando novamente..." - "Não é possível realizar chamadas. %s não é um número de emergência." - "Não é possível realizar chamadas. Disque um número de emergência." - "Use o teclado para discar" - "Colocar chamada em espera" - "Retomar chamada" - "Encerrar chamada" - "Mostrar teclado" - "Ocultar teclado" - "Desativar som" - "Ativar som" - "Adicionar chamada" - "Juntar chamadas" - "Trocar" - "Gerenciar chamadas" - "Gerenciar teleconferência" - "Teleconferência" - "Gerenciar" - "Áudio" - "Videocham." - "Alterar para chamada de voz" - "Alternar câmera" - "Ativar câmera" - "Desativar câmera" - "Mais opções" - "Player iniciado" - "Player interrompido" - "A câmera não está pronta" - "Câmera pronta" - "Evento de sessão de chamada desconhecido" - "Serviço" - "Configuração" - "<Não definido>" - "Outras configurações de chamada" - "Chamando via %s" - "Chamada de %s" - "foto do contato" - "conversar em particular" - "selecionar contato" - "Escreva sua resposta..." - "Cancelar" - "Enviar" - "Atender" - "Enviar SMS" - "Recusar" - "Atender como videochamada" - "Atender como chamada de áudio" - "Aceitar solicitação de vídeo" - "Recusar solicitação de vídeo" - "Aceitar solicitação de transmissão de vídeo" - "Recusar solicitação de transmissão de vídeo" - "Aceitar solicitação de recebimento de vídeo" - "Recusar solicitação de recebimento de vídeo" - "Para %s, deslize para cima." - "Para %s, deslize para a esquerda." - "Para %s, deslize para a direita." - "Para %s, deslize para baixo." - "Vibrar" - "Vibrar" - "Som" - "Som padrão (%1$s)" - "Toque do telefone" - "Vibrar ao tocar" - "Toque e vibração" - "Gerenciar teleconferência" - "Número de emergência" - "Foto do perfil" - "Câmera desligada" - "via %s" - "Nota enviada" - "Mensagens recentes" - "Informações sobre a empresa" - "%.1f milhas de distância" - "%.1f km de distância" - "%1$s, %2$s" - "%1$s - %2$s" - "%1$s, %2$s" - "Abre amanhã às %s" - "Abre hoje às %s" - "Fecha às %s" - "Fechou hoje às %s" - "Aberto agora" - "Fechado agora" - "Autor suspeito (spam)" - "Chamada encerra %1$s" - "Esta é a primeira vez que este número ligou para você." - "Suspeitamos que esta chamada seja de um criador de spams." - "Bloq./denunciar spam" - "Adicionar contato" - "Não é spam" - diff --git a/InCallUI/res/values-ro/strings.xml b/InCallUI/res/values-ro/strings.xml deleted file mode 100644 index ca0036d0d..000000000 --- a/InCallUI/res/values-ro/strings.xml +++ /dev/null @@ -1,195 +0,0 @@ - - - - - "Telefon" - "În așteptare" - "Necunoscut" - "Număr privat" - "Telefon public" - "Conferință telefonică" - "Apelul s-a încheiat" - "Difuzor" - "Casca receptorului" - "Set căști-microfon cu fir" - "Bluetooth" - "Trimiteți următoarele tonuri?\n" - "Se trimit tonuri\n" - "Trimiteți" - "Da" - "Nu" - "Înlocuiți metacaracterul cu" - "Conferință telefonică %s" - "Numărul mesageriei vocale" - "Se apelează" - "Se reapelează" - "Conferință telefonică" - "Apel primit" - "Apel de serviciu primit" - "Apel încheiat" - "În așteptare" - "Se încheie apelul" - "Apel în desfășurare" - "Numărul meu este %s" - "Se conectează apelul video" - "Apel video" - "Se solicită apel video" - "Nu se poate conecta apelul video" - "Solicitarea pentru apel video a fost respinsă" - "Numărul de apelare inversă\n%1$s" - "Numărul de apelare inversă de urgență\n%1$s" - "Se apelează" - "Apel nepreluat" - "Apeluri nepreluate" - "%s (de) apeluri nepreluate" - "Apel nepreluat de la %s" - "Apel în desfășurare" - "Apel de serviciu în desfășurare" - "Apel prin Wi-Fi în desfășurare" - "Apel de serviciu prin Wi-Fi în desfășurare" - "În așteptare" - "Apel primit" - "Apel de serviciu primit" - "Apel prin Wi-Fi primit" - "Apel de serviciu prin Wi-Fi primit" - "Apel video primit" - "Un apel primit posibil spam" - "Solicitare de trecere la apel video" - "Mesaj vocal nou" - "Mesaj vocal nou (%d)" - "Apelați %s" - "Numărul mesageriei vocale este necunoscut" - "Fără semnal" - "Rețeaua selectată (%s) nu este disponibilă" - "Răspundeți" - "Încheiați apelul" - "Apel video" - "Apel vocal" - "Acceptați" - "Refuzați" - "Apelați înapoi" - "Trimiteți mesaj" - "Apel în curs pe alt dispozitiv" - "Transferați apelul" - "Pentru a apela, mai întâi dezactivați modul Avion." - "Neînregistrat în rețea." - "Rețeaua mobilă nu este disponibilă." - "Pentru a apela, introduceți un număr valid." - "Nu se poate apela." - "Se pornește secvența MMI…" - "Serviciul nu este acceptat." - "Apelurile nu pot fi comutate." - "Apelul nu poate fi separat." - "Nu se poate transfera." - "Conferința telefonică nu poate fi inițiată." - "Apelul nu poate fi respins." - "Apelurile nu pot fi eliberate." - "Apel SIP" - "Apel de urgență" - "Se activează radio…" - "Fără semnal. Se încearcă din nou…" - "Nu se poate apela. %s nu este un număr de urgență." - "Nu se poate apela. Formați un număr de urgență." - "Folosiți tastatura pentru a apela" - "Puneți apelul în așteptare" - "Reluați apelul" - "Încheiați apelul" - "Afișează tastatura numerică" - "Ascunde tastatura numerică" - "Dezactivează sunetul" - "Activează sunetul" - "Adăugați un apel" - "Îmbinați apelurile" - "Schimbați" - "Gestionați apelurile" - "Gestionați conferința telefonică" - "Conferință telefonică" - "Gestionați" - "Audio" - "Apel video" - "Treceți la apel vocal" - "Comutați camera foto" - "Activați camera" - "Dezactivați camera" - "Mai multe opțiuni" - "Playerul a pornit" - "Playerul s-a oprit" - "Camera foto nu este pregătită" - "Camera foto este pregătită" - "Eveniment necunoscut privind o sesiune de apeluri" - "Furnizor de servicii" - "Configurați" - "<Nesetat>" - "Alte setări de apel" - "Se apelează prin %s" - "Primite prin %s" - "fotografia persoanei de contact" - "treceți în modul privat" - "selectați o persoană de contact" - "Scrieți propriul răspuns…" - "Anulați" - "Trimiteți" - "Răspundeți" - "Trimiteți SMS" - "Refuzați" - "Răspundeți ca apel video" - "Răspundeți ca apel audio" - "Acceptați solicitarea de a trece la apel video" - "Refuzați solicitarea de a trece la apel video" - "Acceptați solicitarea de a transmite conținut video" - "Refuzați solicitarea de a transmite conținut video" - "Acceptați solicitarea de a primi conținut video" - "Refuzați solicitarea de a primi conținut video" - "Glisați în sus ca să %s." - "Glisați spre stânga ca să %s." - "Glisați spre dreapta ca să %s." - "Glisați în jos ca să %s." - "Vibrații" - "Vibrații" - "Sunet" - "Sunet prestabilit (%1$s)" - "Ton de sonerie pentru telefon" - "Vibrează când sună" - "Ton de sonerie și vibrații" - "Gestionați conferința telefonică" - "Număr de urgență" - "Fotografie de profil" - "Camera foto este oprită" - "pe %s" - "Nota a fost trimisă" - "Mesaje recente" - "Informații despre companie" - "%.1f mi distanță" - "%.1f km distanță" - "%1$s, %2$s" - "%1$s%2$s" - "%1$s, %2$s" - "Deschide mâine la %s" - "Deschide astăzi la %s" - "Închide la %s" - "A închis astăzi la %s" - "Acum este deschis" - "Acum este închis" - "Posibil apelant spam" - "Apelul s-a încheiat %1$s" - "Aceasta este prima dată când ați primit apel de la acest număr." - "Suspectăm că acesta este un apel spam." - "Blocați/raportați" - "Adăugați persoana" - "Nu este spam" - diff --git a/InCallUI/res/values-ru/strings.xml b/InCallUI/res/values-ru/strings.xml deleted file mode 100644 index 552ad4d02..000000000 --- a/InCallUI/res/values-ru/strings.xml +++ /dev/null @@ -1,195 +0,0 @@ - - - - - "Телефон" - "На удержании" - "Неизвестный абонент" - "Скрытый номер" - "Телефон-автомат" - "Конференц-вызов" - "Звонок сброшен" - "Динамик" - "Динамик гарнитуры" - "Проводная гарнитура" - "Bluetooth" - "Отправить следующие тоны?\n" - "Отправка тональных сигналов\n" - "Отправить" - "Да" - "Нет" - "Заменить универсальный символ на" - "Конференц-вызов: %s" - "Номер голосовой почты" - "Набор номера…" - "Повторный вызов" - "Конференц-вызов" - "Входящий вызов" - "Входящий вызов (работа)" - "Вызов завершен" - "На удержании" - "Завершение разговора" - "Вызов" - "Мой номер: %s" - "Подключение видео" - "Видеовызов" - "Запрос видео" - "Не удалось совершить видеовызов" - "Видеовызов отклонен" - "Номер обратного вызова:\n%1$s" - "Номер обратного вызова для экстренных служб:\n%1$s" - "Набор номера…" - "Пропущенный вызов" - "Пропущенные вызовы" - "Пропущенных вызовов: %s" - "Пропущенные вызовы от абонента %s" - "Текущий вызов" - "Текущий звонок (работа)" - "Текущий Wi-Fi-звонок" - "Текущий Wi-Fi-звонок (работа)" - "На удержании" - "Входящий вызов" - "Входящий вызов (работа)" - "Входящий Wi-Fi-звонок" - "Входящий Wi-Fi-звонок (работа)" - "Входящий видеовызов" - "Входящий вызов: подозрение на спам" - "Входящий видеовызов" - "Новое сообщение голосовой почты" - "Новое сообщение голосовой почты (%d)" - "Набрать номер %s" - "Номер голосовой почты неизвестен" - "Нет сигнала" - "Выбранная сеть (%s) недоступна." - "Ответить" - "Завершить" - "Видео" - "Голос" - "Разрешить" - "Закрыть" - "Перезвонить" - "Написать SMS" - "Вы участвуете в разговоре на другом устройстве" - "Перевести на это устройство" - "Отключите режим полета." - "Нет регистрации в сети." - "Мобильная сеть недоступна." - "Недействительный номер." - "Не удалось позвонить." - "Запуск последовательности MMI..." - "Сервис не поддерживается." - "Не удалось переключить вызов." - "Не удалось разделить вызов." - "Не удалось перенести." - "Не удалось выполнить конференц-вызов." - "Не удалось отклонить вызов." - "Не удалось разъединить." - "Вызов SIP" - "Экстренный вызов" - "Включение радио…" - "Нет сигнала. Повторная попытка…" - "Не удалось позвонить. Номер %s не принадлежит экстренным службам." - "Не удалось позвонить. Наберите номер экстренных служб." - "Используйте клавиатуру для набора номера" - "Удерживать вызов" - "Возобновить вызов" - "Завершить вызов" - "Показать панель набора номера" - "Скрыть панель набора номера" - "Выключить звук" - "Включить звук" - "Добавить вызов" - "Объединить вызовы" - "Перевести звонок" - "Управление вызовами" - "Настройка конференц-связи" - "Конференц-вызов" - "Управление" - "Аудио" - "Видеовызов" - "Отключить видео" - "Сменить камеру" - "Включить камеру" - "Выключить камеру" - "Другие настройки" - "Видеоплеер включен" - "Видеоплеер отключен" - "Камера недоступна" - "Камера доступна" - "Неизвестное событие сеанса связи" - "Служба" - "Настройка" - "<Не задано>" - "Другие настройки вызовов" - "Звонок через %s" - "Входящий вызов (оператор: %s)" - "фотография контакта" - "приватная конференция" - "выбрать контакт" - "Ваш ответ…" - "Отмена" - "Отправить" - "Ответить" - "Отправить SMS" - "Отклонить" - "Ответить с видео" - "Ответить на голосовой вызов" - "Ответить на видеовызов" - "Отклонить видеовызов" - "Разрешить передачу видео" - "Отклонить передачу видео" - "Принять видео" - "Отклонить видео" - "Проведите вверх, чтобы %s." - "Проведите влево, чтобы %s." - "Проведите вправо, чтобы %s." - "Проведите вниз, чтобы %s." - "Вибросигнал" - "Вибросигнал" - "Звук" - "По умолчанию (%1$s)" - "Рингтон" - "Вибросигнал и рингтон" - "Мелодия звонка и вибросигнал" - "Настройка конференц-связи" - "Экстренная служба" - "Фото профиля" - "Камера отключена" - "через %s" - "Сообщение отправлено" - "Недавние сообщения" - "Информация о компании" - "%.1f мил." - "%.1f км" - "%1$s, %2$s" - "%1$s%2$s" - "%1$s, %2$s" - "Откроется завтра в %s" - "Откроется сегодня в %s" - "Работает до %s" - "Сегодня не работает с %s" - "Сейчас открыто" - "Сейчас закрыто" - "Подозрение на спам" - "Вызов завершен (%1$s)" - "Это первый вызов с этого номера." - "Похоже, этот вызов – спам." - "Заблокировать/в спам" - "Добавить контакт" - "Не спам" - diff --git a/InCallUI/res/values-si/strings.xml b/InCallUI/res/values-si/strings.xml deleted file mode 100644 index de0267a58..000000000 --- a/InCallUI/res/values-si/strings.xml +++ /dev/null @@ -1,195 +0,0 @@ - - - - - "දුරකථනය" - "රඳවා ගනිමින්" - "නොදනී" - "රහසිගත අංකය" - "පේෆෝනය" - "සම්මන්ත්‍රණ ඇමතුම" - "ඇමතුම නැවතුණි" - "නාදකය" - "හෑන්ඩ්සෙටයේ සවන් කඬ" - "රැහැන් සහිත හෙඩ්සෙටය" - "බ්ලූටූත්" - "පහත නාද යවන්නද?\n" - "නාද යවමින්\n" - "යවන්න" - "ඔව්" - "නැත" - "අනුලකුණ ප්‍රතිස්ථාපනය කරන්නේ" - "සම්මන්ත්‍රණ ඇමතුම %s" - "හඬ තැපැල් අංකය" - "ඩයල් කරමින්" - "නැවත ඩයල් කරමින්" - "සම්මන්ත්‍රණ ඇමතුම" - "එන ඇමතුම" - "එන කාර්යාල ඇමතුම" - "ඇමතුම අවසන් විය" - "රඳවා ගනිමින්" - "විසන්ධි කරමින්" - "ඇමතුමක" - "මගේ අංකය %s" - "වීඩියෝවකට සම්බන්ධ කරමින්" - "වීඩියෝ ඇමතුම" - "වීඩියෝවක් ඉල්ලමින්" - "වීඩියෝ ඇමතුම සම්බන්ධ කළ නොහැක" - "වීඩියෝ ඉල්ලීම ප්‍රතික්ෂේප කරන ලදී" - "ඔබේ පසුඇමතුම් අංකය\n %1$s" - "ඔබගේ හදිසි පසුඇමතුම් අංකය\n %1$s" - "ඩයල් කරමින්" - "මඟ හැරුණු ඇමතුම" - "මඟ හැරුණු ඇමතුම්" - "මඟ හැරුණු ඇමතුම් %s" - "%s වෙතින් මඟ හැරුණු ඇමතුම" - "කරගෙන යන ඇමතුම" - "කරගෙන යන කාර්යාල ඇමතුම" - "දැනට කරගෙන යන Wi-Fi ඇමතුම" - "කරගෙන යන Wi-Fi කාර්යාල ඇමතුම" - "රඳවා ගනිමින්" - "එන ඇමතුම" - "එන කාර්යාල ඇමතුම" - "එන Wi-Fi ඇමතුම" - "එන Wi-Fi කාර්යාල ඇමතුම" - "එන වීඩියෝ ඇමතුම" - "එන සැකසහිත අයාචිත තැපැල් ඇමතුම" - "එන වීඩියෝ ඉල්ලීම" - "නව හඬ තැපෑල" - "නව හඬ තැපැල් (%d)" - "%s ඩයල් කරන්න" - "හඬ තැපැල් අංකය නොදනී" - "සේවාව නැත" - "තෝරා ඇති ජාලය (%s) නොමැත" - "පිළිතුරු දෙන්න" - "විසන්ධි කරන්න" - "වීඩියෝව" - "හඬ" - "පිළිගන්න" - "අස් කරන්න" - "පසුඇමතුම" - "පණිවිඩය" - "වෙනත් උපාංගයක සිදු වන ඇමතුම" - "ඇමතුම මාරු කරන්න" - "ඇමතුමක් ගැනීමට, මුලින්ම ගුවන් යානා ප්‍රකාරය ක්‍රියාවිරහිත කරන්න." - "ජාලය මත ලියාපදිංචි වී නැත." - "සෙලියුලර් ජාලය නොතිබේ." - "ඇමතුමක් ගැනීමට, වලංගු අංකයක් ඇතුළු කරන්න." - "ඇමතුම් ගැනීමට නොහැක." - "MMI අනුපිළිවෙළ ආරම්භ කරමින්…" - "සේවාවට සහාය දක්වන්නේ නැත." - "ඇමතුම් මාරු කිරීම කළ නොහැක." - "ඇමතුම වෙන් කිරීම කළ නොහැක." - "මාරු කිරීමට නොහැක." - "සම්මන්ත්‍රණය කළ නොහැක." - "ඇමතුම ප්‍රතික්ෂේප කළ නොහැක." - "ඇමතුම(ම්) මුදාහැරීම කළ නොහැක." - "SIP ඇමතුම" - "හදිසි ඇමතුම" - "රේඩියෝව ක්‍රියාත්මක කරමින්…" - "සේවාව නැත. නැවත උත්සාහ කරමින්…" - "ඇමතීමට නොහැකිය. %s මෙය හදිසි ඇමතුම් අංකයක් නොවේ." - "ඇමතිය නොහැක. හදිසි අංකයක් අමතන්න." - "ඩයල් කිරීමට යතුරු පුවරුව භාවිත කරන්න" - "ඇමතුම රඳවා ගන්න" - "ඇමතුම නැවත පටන් ගන්න" - "ඇමතුම අවසන් කරන්න" - "ඇමතුම් පෑඩය පෙන්වන්න" - "ඇමතුම් පෑඩය සඟවන්න" - "නිහඬ කරන්න" - "නිහඬ කිරීම ඉවත් කරන්න" - "ඇමතුමක් එක් කරන්න" - "ඇමතුම් ඒකාබද්ධ කරන්න" - "මාරු කරන්න" - "ඇමතුම් කළමනාකරණය කරන්න" - "සම්මන්ත්‍රණ ඇමතුම කළමනාකරණය කරන්න" - "සම්මන්ත්‍රණ ඇමතුම" - "කළමනාකරණය කරන්න" - "ශ්‍රව්‍යය" - "වීඩියෝ ඇමතුම" - "හඬ ඇමතුමක් වෙත මාරු කරන්න" - "කැමරාව මාරු කරන්න" - "කැමරාව ක්‍රියාත්මක කරන්න" - "කැමරාව ක්‍රියා විරහිත කරන්න" - "තවත් විකල්ප" - "ධාවකය ආරම්භ කරන ලදි" - "ධාවකය නැවතුණි" - "කැමරාව සූදානම් නැහැ" - "කැමරාව සූදානම්" - "නොදන්නා ඇමතුම් සැසි සිදුවීම" - "සේවාව" - "පිහිටුවීම" - "<පිහිටුවා නැත>" - "වෙනත් ඇමතුම් සැකසීම්" - "%s හරහා අමතමින්" - "%s හරහා එන" - "සම්බන්ධතා ඡායාරූපය" - "රහසිගත වන්න" - "සම්බන්ධතාවය තෝරාගන්න" - "ඔබේම එකක් ලියන්න..." - "අවලංගු කරන්න" - "යවන්න" - "පිළිතුරු දෙන්න" - "SMS යවන්න" - "ප්‍රතික්ෂේප කිරීම" - "වීඩියෝ ඇමතුමට පිළිතුරු දෙන්න" - "ශ්‍රව්‍ය ඇමතුමට පිළිතුරු දෙන්න" - "වීඩියෝ ඉල්ලීම පිළිගන්න" - "වීඩියෝ ඉල්ලීම ප්‍රතික්ෂේප කරන්න" - "වීඩියෝ සම්ප්‍ර්ෂණ ඉල්ලීම පිළිගන්න" - "වීඩියෝ සම්ප්‍ර්ෂණ ඉල්ලීම ප්‍රතික්ෂේප කරන්න" - "වීඩියෝ ලැබීමේ ඉල්ලීම පිළිගන්නා ලදි" - "වීඩියෝ ලැබීමේ ඉල්ලීම ප්‍රතික්ෂේප කරන්න" - "%s සඳහා උඩට සර්පණය කරන්න." - "%s සඳහා වමට සර්පණය කරන්න." - "%s සඳහා දකුණට සර්පණය කරන්න." - "%s සඳහා පහළට සර්පණය කරන්න." - "කම්පනය" - "කම්පනය" - "හඬ" - "පෙරනිමි ශබ්දය (%1$s)" - "දුරකථන රිගින්ටෝනය" - "රිගින් වන විට කම්පන වන්න" - "රිගින් ටෝන් සහ කම්පනය කරන්න" - "සම්මන්ත්‍රණ ඇමතුම කළමනාකරණය කරන්න" - "හදිසි ඇමතුම් අංකය" - "පැතිකඩ ඡායාරූපය" - "කැමරාව ක්‍රියාවිරහිතයි" - "%s හරහා" - "සටහන යවන ලදී" - "මෑත පණිවිඩ" - "ව්‍යාපාර තොරතුරු" - "සැතපුම් %.1fක් ඈතින්" - "කි.මි. %.1fක් ඈතින්" - "%1$s, %2$s" - "%1$s - %2$s" - "%1$s, %2$s" - "හෙට %sට විවෘත කෙරේ" - "අද %sට විවෘත කෙරේ" - "%sට වසයි" - "අද %sට වසන ලදී" - "දැන් විවෘතයි" - "දැන් වසා ඇත" - "සැකසහිත අයාචිත තැපැල් අමතන්නා" - "ඇමතුම අවසන් විය %1$s" - "මෙය ඔබට මෙම අංකයෙන් ඇමතුමක් ලැබුණ පළමු අවස්ථාව වේ." - "මෙම ඇමතුම අයාචිත එවන්නෙකු අපි සැක කළෙමු." - "අවහිර ක./අයාචිත වා." - "සම්බන්ධතාව එක් කරන්න" - "අයාචිත තැපෑලක් නොවේ" - diff --git a/InCallUI/res/values-sk/strings.xml b/InCallUI/res/values-sk/strings.xml deleted file mode 100644 index 07e8de671..000000000 --- a/InCallUI/res/values-sk/strings.xml +++ /dev/null @@ -1,195 +0,0 @@ - - - - - "Telefón" - "Podržaný hovor" - "Neznáme" - "Súkromné číslo" - "Telefónny automat" - "Konferenčný hovor" - "Hovor bol prerušený" - "Reproduktor" - "Slúchadlo" - "Náhlavná súprava s káblom" - "Bluetooth" - "Odoslať nasledujúce tóny?\n" - "Odosielanie tónov\n" - "Odoslať" - "Áno" - "Nie" - "Nahradiť zástupný znak znakom" - "Konferenčný hovor %s" - "Číslo hlasovej schránky" - "Vytáča sa" - "Znova sa vytáča" - "Konferenčný hovor" - "Prichádzajúci hovor" - "Prichádzajúci prac. hovor" - "Hovor bol ukončený" - "Podržaný hovor" - "Ukončovanie hovoru" - "Prebieha hovor" - "Moje číslo je %s" - "Pripája sa video" - "Videohovor" - "Žiada sa video" - "Videohovor nie je možné pripojiť" - "Žiadosť o video bola odmietnutá" - "Vaše číslo na spätné volanie\n %1$s" - "Vaše číslo na spätné tiesňové volanie\n %1$s" - "Vytáča sa" - "Zmeškaný hovor" - "Zmeškané hovory" - "Zmeškané hovory: %s" - "Zmeškaný hovor od volajúceho %s" - "Prebiehajúci hovor" - "Prebiehajúci pracovný hovor" - "Odchádzajúci hovor cez Wi-Fi" - "Prebiehajúci pracovný hovor cez Wi-Fi" - "Podržaný hovor" - "Prichádzajúci hovor" - "Prichádzajúci pracovný hovor" - "Prichádzajúci hovor cez Wi-Fi" - "Prichádzajúci pracovný hovor cez Wi-Fi" - "Prichádzajúci videohovor" - "Prichádzajúci hovor, pri ktorom je podozrenie, že ide o spam" - "Prichádzajúca žiadosť o video" - "Nová hlasová správa" - "Nová hlasová správa (%d)" - "Zavolať hlasovú schránku %s" - "Číslo hlasovej schránky je neznáme" - "Žiadny signál" - "Vybraná sieť (%s) nie je k dispozícii" - "Prijať" - "Položiť" - "Video" - "Hlas" - "Prijať" - "Odmietnuť" - "Zavolať späť" - "Správa" - "Prebiehajúci hovor v inom zariadení" - "Prepojiť hovor" - "Ak chcete volať, vypnite najprv režim v lietadle." - "Prihlásenie do siete nebolo úspešné." - "Mobilná sieť nie je k dispozícii." - "Ak chcete volať, zadajte platné číslo." - "Hovor sa nedá uskutočniť." - "Prebieha spúšťanie sekvencie MMI…" - "Služba nie je podporovaná." - "Nedajú sa prepínať hovory." - "Nedá sa rozdeliť hovor." - "Nedá sa preniesť." - "Konferenčný hovor sa nedá uskutočniť." - "Nedá sa odmietnuť hovor." - "Nedajú sa ukončiť hovory." - "Hovor SIP" - "Tiesňové volanie" - "Zapína sa rádio..." - "Žiadny signál. Prebieha ďalší pokus…" - "Hovor sa nedá uskutočniť. %s nie je číslo tiesňového volania." - "Hovor nie je možné uskutočniť. Vytočte číslo tiesňového volania." - "Číslo vytočíte pomocou klávesnice" - "Podržať hovor" - "Obnoviť hovor" - "Ukončiť hovor" - "Zobraziť číselnú klávesnicu" - "Skryť číselnú klávesnicu" - "Vypnúť zvuk" - "Zapnúť zvuk" - "Pridať hovor" - "Zlúčiť hovory" - "Zameniť" - "Spravovať hovory" - "Spravovať konferenčný hovor" - "Konferenčný hovor" - "Spravovať" - "Zvuk" - "Videohovor" - "Zmeniť na hlasový hovor" - "Zapnúť kameru" - "Zapnúť fotoaparát" - "Vypnúť fotoaparát" - "Ďalšie možnosti" - "Prehrávač bol spustený" - "Prehrávač bol zastavený" - "Kamera nie je pripravená" - "Kamera je pripravená" - "Neznáma udalosť relácie volania" - "Služba" - "Nastavenie" - "<Nenastavené>" - "Ďalšie nastavenia hovorov" - "Voláte prostredníctvom poskytovateľa %s" - "Prichádz. hovor prostred. poskytovateľa %s" - "fotka kontaktu" - "prepnúť na súkromné" - "vybrať kontakt" - "Napísať vlastnú..." - "Zrušiť" - "Odoslať" - "Prijať" - "Odoslať SMS" - "Odmietnuť" - "Prijať ako videohovor" - "Prijať ako zvukový hovor" - "Prijať žiadosť o videohovor" - "Odmietnuť žiadosť o videohovor" - "Prijať žiadosť o prenos videa" - "Odmietnuť žiadosť o prenos videa" - "Povoliť žiadosť o prijatie videa" - "Odmietnuť žiadosť o prijatie videa" - "Prejdite prstom nahor: %s." - "Prejdite prstom doľava: %s." - "Prejdite prstom doprava: %s." - "Prejdite prstom nadol: %s." - "Vibrovanie" - "Vibrovanie" - "Zvuk" - "Predvolený zvuk (%1$s)" - "Tón zvonenia telefónu" - "Vibrovať pri zvonení" - "Vyzváňací tón a vibrovanie" - "Správa konferenčného hovoru" - "Číslo tiesňového volania" - "Profilová fotka" - "Kamera je vypnutá" - "na čísle %s" - "Poznámka bola odoslaná" - "Nedávne správy" - "Informácie o firme" - "Vzdialené %.1f mi" - "Vzdialené %.1f km" - "%1$s, %2$s" - "%1$s%2$s" - "%1$s, %2$s" - "Zajtra sa otvára o %s" - "Dnes sa otvára o %s" - "Zatvára sa o %s" - "Dnes bolo zatvorené o %s" - "Otvorené" - "Zatvorené" - "Podozrenie na spam" - "Hovor sa skončil %1$s" - "Toto bol prvý hovor z tohto čísla." - "Mali sme podozrenie, že tento hovor bol od šíriteľa spamu." - "Blok./nahlásiť spam" - "Pridať kontakt" - "Toto nie je spam" - diff --git a/InCallUI/res/values-sl/strings.xml b/InCallUI/res/values-sl/strings.xml deleted file mode 100644 index a2cf2102b..000000000 --- a/InCallUI/res/values-sl/strings.xml +++ /dev/null @@ -1,195 +0,0 @@ - - - - - "Telefon" - "Zadržan" - "Neznan" - "Zasebna številka" - "Telefonska govorilnica" - "Konferenčni klic" - "Klic je bil prekinjen" - "Zvočnik" - "Slušalka" - "Žične slušalke" - "Bluetooth" - "Ali želite poslati naslednje tone?\n" - "Pošiljanje tonov\n" - "Pošlji" - "Da" - "Ne" - "Zamenjaj nadomestni znak z" - "Konferenčni klic: %s" - "Številka odzivnika" - "Klicanje" - "Vnovično klicanje" - "Konferenčni klic" - "Dohodni klic" - "Dohodni delovni klic" - "Klic je končan" - "Zadržan" - "Prekinjanje" - "Klic poteka" - "Moja številka je %s" - "Povezovanje videa" - "Videoklic" - "Zahtevanje videa" - "Videoklica ni mogoče vzpostaviti" - "Zavrnjena zahteva za videoklic" - "Vaša številka za povratni klic:\n %1$s" - "Vaša številka za povratni klic v sili:\n %1$s" - "Klicanje" - "Neodgovorjeni klic" - "Neodgovorjeni klici" - "Št. neodgovorjenih klicev: %s" - "Neodgovorjeni klic od: %s" - "Aktivni klic" - "Aktivni delovni klic" - "Aktivni klic prek omrežja Wi-Fi" - "Aktivni delovni klic prek omrežja Wi-Fi" - "Zadržan" - "Dohodni klic" - "Dohodni delovni klic" - "Dohodni klic Wi-Fi" - "Dohodni delovni klic prek omrežja Wi-Fi" - "Dohodni videoklic" - "Domnevno neželeni dohodni klic" - "Zahteva za dohodni video" - "Novo sporočilo v odzivniku" - "Novo sporočilo v odzivniku (%d)" - "Klic: %s" - "Neznana številka odzivnika" - "Ni signala" - "Izbrano omrežje (%s) ni na voljo" - "Odgovor" - "Prekinitev" - "Video" - "Govor" - "Sprejmem" - "Opusti" - "Povrat. klic" - "SMS" - "Aktivni klic v drugi napravi" - "Prenos klica" - "Če želite poklicati, najprej izklopite način za letalo." - "Ni registrirano v omrežju." - "Mobilno omrežje ni na voljo." - "Če želite opraviti klic, vnesite veljavno številko." - "Klicanje ni mogoče." - "Začetek zaporedja MMI ..." - "Storitev ni podprta." - "Preklop med klici ni mogoč." - "Ločitev klica ni mogoča." - "Prenos ni mogoč." - "Konferenčni klic ni mogoč." - "Zavrnitev klica ni mogoča." - "Prekinitev klica ni mogoča." - "Klic SIP" - "Klic v sili" - "Vklop radia …" - "Ni signala. Vnovičen poskus …" - "Klicanje ni mogoče. %s ni številka za klic v sili." - "Klicanje ni mogoče. Opravite klic v sili." - "Za izbiranje številke uporabite tipkovnico" - "Zadrži klic" - "Nadaljuj klic" - "Končaj klic" - "Prikaži tipkovnico" - "Skrij tipkovnico" - "Izklopi zvok" - "Vklopi zvok" - "Dodaj klic" - "Združi klice" - "Zamenjaj" - "Upravljaj klice" - "Upravljaj konferenčne klice" - "Konferenčni klic" - "Upravljaj" - "Zvok" - "Videoklic" - "Preklopi na glasovni klic" - "Preklopi med fotoaparati" - "Vklopi kamero" - "Izklopi kamero" - "Več možnosti" - "Predvajanje začeto" - "Predvajanje ustavljeno" - "Fotoaparat ni pripravljen" - "Fotoaparat je pripravljen" - "Neznan dogodek seje klica" - "Storitev" - "Nastavitev" - "<Ni nastavljeno>" - "Druge klicne nastavitve" - "Klicanje prek ponudnika %s" - "Dohodni prek %s" - "fotografija stika" - "zasebno" - "izbira stika" - "Napišite lasten odgovor …" - "Prekliči" - "Pošlji" - "Odgovor" - "Pošiljanje SMS-ja" - "Zavrnitev" - "Odgovor z video povezavo" - "Odgovor z zvočno povezavo" - "Sprejemanje zahteve za video" - "Zavrnitev zahteve za video" - "Sprejemanje zahteve za pošiljanje videa" - "Zavrnitev zahteve za pošiljanje videa" - "Sprejemanje zahteve za prejem videa" - "Zavrnitev zahteve za prejem videa" - "Povlecite navzgor za %s." - "Povlecite v levo za %s." - "Povlecite v desno za %s." - "Povlecite navzdol za %s." - "Vibriranje" - "Vibriranje" - "Zvok" - "Privzeti zvok (%1$s)" - "Ton zvonjenja telefona" - "Vibriranje ob zvonjenju" - "Zvonjenje in vibriranje" - "Upravljanje konferenčnih klicev" - "Številka za klic v sili" - "Fotografija profila" - "Fotoaparat je izklopljen" - "prek %s" - "Opomba poslana" - "Nedavna sporočila" - "Podatki o podjetju" - "%.1f mi stran" - "%.1f km stran" - "%1$s, %2$s" - "%1$s%2$s" - "%1$s, %2$s" - "Odpre se jutri ob %s" - "Odpre se danes ob %s" - "Zapre se ob %s" - "Zaprto danes ob %s" - "Trenutno odprto" - "Trenutno zaprto" - "Neželeni klicatelj" - "Klic je bil končan %1$s" - "To je prvi klic, ki ste ga prejeli s te številke." - "Predvidevali smo, da je to neželeni klic." - "Blok./prij. než. kl." - "Dodaj stik" - "Ni neželeni klic" - diff --git a/InCallUI/res/values-sq/strings.xml b/InCallUI/res/values-sq/strings.xml deleted file mode 100644 index 43fd2263d..000000000 --- a/InCallUI/res/values-sq/strings.xml +++ /dev/null @@ -1,195 +0,0 @@ - - - - - "Telefoni" - "Në pritje" - "I panjohur" - "Numër privat" - "Telefon me pagesë" - "Telefonatë konferencë" - "Telefonata ra" - "Altoparlant" - "Kufje për vesh" - "Kufje me tel" - "Bluetooth" - "Dërgo tonet e mëposhtme?\n" - "Po dërgon tone\n" - "Dërgo" - "Po" - "Jo" - "Zëvendëso karakterin variabël me" - "Telefonatë konferencë %s" - "Numri i postës zanore" - "Po formon numrin" - "Po riformon numrin" - "Telefonatë konferencë" - "Telefonatë hyrëse" - "Telefonatë pune hyrëse" - "Telefonata përfundoi" - "Në pritje" - "Mbyllja" - "Në telefonatë" - "Numri im është %s" - "Po rilidh videon" - "Telefonatë me video" - "Po kërkon video" - "Nuk mund të lidhë telefonatën me video" - "Kërkesa me video u refuzua" - "Numri i kthimit të telefonatës\n %1$s" - "Numri i kthimit të telefonatës së urgjencës\n %1$s" - "Po formon numrin" - "Telefonatë e humbur" - "Telefonata të humbura" - "%s telefonata të humbura" - "Telefonatë e humbur nga %s" - "Telefonatë në vazhdim" - "Telefonatë pune dalëse" - "Telefonatë me Wi-Fi në vazhdim" - "Telefonatë pune dalëse me Wi-Fi" - "Në pritje" - "Telefonatë hyrëse" - "Telefonatë pune hyrëse" - "Telefonatë hyrëse me Wi-Fi" - "Telefonatë pune hyrëse me Wi-Fi" - "Telefonatë hyrëse me video" - "Telefonatë e dyshuar si e padëshiruar" - "Kërkesë për video hyrëse" - "Postë e re zanore" - "Postë e re zanore (%d)" - "Formo numrin %s" - "Numri i postës zanore është i panjohur" - "Nuk ka shërbim" - "Rrjeti i zgjedhur (%s) i padisponueshëm" - "Përgjigju" - "Mbyll" - "Video" - "Zanore" - "Prano" - "Largoje" - "Ri-telefono" - "Mesazh" - "Telefonatë në vazhdim në një pajisje tjetër" - "Transfero telefonatën" - "Për të kryer telefonatë, së pari çaktivizo modalitetin e aeroplanit." - "I paregjistruar në rrjet." - "Rrjeti celular nuk mundësohet." - "Për të kryer një telefonatë, fut një numër të vlefshëm." - "Nuk mund të telefonojë." - "Po fillon sekuencën MMI…" - "Shërbimi nuk mbështetet." - "Nuk mund të ndryshojë telefonatat." - "Nuk mund të ndajë telefonatën." - "Nuk mund të transferojë." - "Nuk mund të kryejë telefonatë konference." - "Nuk mund të refuzojë telefonatën." - "Nuk mund të lëshojë telefonatën(at)." - "Telefonatë SIP" - "Telefonata e urgjencës" - "Po aktivizon radion…" - "Nuk ka shërbim. Po provon sërish…" - "Nuk mund të telefonohet. %s nuk është një numër urgjence." - "Nuk mund të telefonohet. Formo një numër urgjence." - "Përdor tastierën për të formuar numrin" - "Vendose në pritje telefonatën" - "Rifillo telefonatën" - "Mbylle telefonatën" - "Shfaq bllokun e formimit të numrit" - "Fshih bllokun e formimit të numrit" - "Çaktivizo audion" - "Aktivizo audion" - "Shto telefonatë" - "Shkri telefonatat" - "Shkëmbe" - "Menaxho telefonatat" - "Menaxho telefonatën konferencë" - "Telefonatë konferencë" - "Menaxho" - "Audioja" - "Telefonatë me video" - "Ndërro në telefonatë me video" - "Ndërro kamerën" - "Aktivizo kamerën" - "Çaktivizo kamerën" - "Opsione të tjera" - "Luajtësi filloi" - "Luajtësi ndaloi" - "Kamera nuk është gati" - "Kamera është gati" - "Ngjarje e panjohur në sesionin e telefonatës" - "Shërbimi" - "Konfigurimi" - "<I pavendosur>" - "Cilësime të tjera të telefonatës" - "Telefonatë nëpërmjet %s" - "Hyrëse nëpërmjet %s" - "fotografia e kontaktit" - "bëje private" - "përzgjidh kontaktin" - "Shkruaj përgjigjen tënde..." - "Anulo" - "Dërgo" - "Përgjigju" - "Dërgo SMS" - "Refuzo" - "Përgjigju si telefonatë me video" - "Përgjigju si telefonatë me audio" - "Prano kërkesën për video" - "Refuzo kërkesën për video" - "Prano kërkesën për transmetimin e videos" - "Refuzo kërkesën për transmetimin e videos" - "Prano kërkesën për marrjen e videos" - "Refuzo kërkesën për marrjen e videos" - "Rrëshqit lart për %s." - "Rrëshqit majtas për %s" - "Rrëshqit djathtas për %s" - "Rrëshqit poshtë për %s." - "Dridhja" - "Dridhja" - "Tingulli" - "Tingulli i parazgjedhur (%1$s)" - "Toni i ziles i telefonit" - "Dridhje edhe kur bie zilja" - "Me zile dhe me dridhje" - "Menaxho telefonatën konferencë" - "Numri i urgjencës" - "Fotografia e profilit" - "Kamera joaktive" - "përmes %s" - "Shënimi u dërgua" - "Mesazhet e fundit" - "Informacioni i biznesit" - "%.1f milje larg" - "%.1f km larg" - "%1$s, %2$s" - "%1$s - %2$s" - "%1$s, %2$s" - "Hapet nesër në %s" - "Hapet sot në %s" - "Mbyllet në %s" - "Mbyllur sot në %s" - "Tani është hapur" - "Tani është mbyllur" - "I padëshirueshëm" - "Telefonata përfundoi %1$s" - "Kjo është hera e parë që ky numër ka telefonuar." - "Ne dyshojmë që kjo telefonatë të jetë e padëshirueshme." - "Blloko/raporto të padëshiruar" - "Shto një kontakt" - "Jo i padëshiruar" - diff --git a/InCallUI/res/values-sr/strings.xml b/InCallUI/res/values-sr/strings.xml deleted file mode 100644 index 3a3820d8c..000000000 --- a/InCallUI/res/values-sr/strings.xml +++ /dev/null @@ -1,195 +0,0 @@ - - - - - "Телефон" - "На чекању" - "Непознат" - "Приватан број" - "Телефонска говорница" - "Конференцијски позив" - "Позив је прекинут" - "Звучник" - "Слушалица телефона" - "Жичане наглавне слушалице" - "Bluetooth" - "Желите ли да пошаљете следеће тонове?\n" - "Тонови се шаљу\n" - "Пошаљи" - "Да" - "Не" - "Замените џокер знак са" - "Конференцијски позив %s" - "Број говорне поште" - "Позива се" - "Поново се бира" - "Конференцијски позив" - "Долазни позив" - "Долазни позив за Work" - "Позив је завршен" - "На чекању" - "Веза се прекида" - "Позив је у току" - "Мој број је %s" - "Повезује се видео позив" - "Видео позив" - "Захтева се видео позив" - "Повезивање видео позива није успело" - "Захтев за видео позив је одбијен" - "Број за повратни позив\n %1$s" - "Број за хитан повратни позив\n %1$s" - "Позива се" - "Пропуштен позив" - "Пропуштени позиви" - "Број пропуштених позива: %s" - "Пропуштен позив од: %s" - "Текући позив" - "Текући позив за Work" - "Текући Wi-Fi позив" - "Текући позив за Work преко Wi-Fi-ја" - "На чекању" - "Долазни позив" - "Долазни позив за Work" - "Долазни Wi-Fi позив" - "Долазни позив за Work преко Wi-Fi-ја" - "Долазни видео позив" - "Сумња на непожељан долазни позив" - "Захтев за долазни видео позив" - "Нова порука говорне поште" - "Нова порука говорне поште (%d)" - "Позови %s" - "Непознат број говорне поште" - "Мобилна мрежа није доступна" - "Изабрана мрежа (%s) није доступна" - "Одговори" - "Прекини везу" - "Видео" - "Гласовни" - "Прихватам" - "Одбаци" - "Узврати позив" - "Пошаљи SMS" - "Позив је у току на другом уређају" - "Пребаци позив" - "Да бисте упутили позив, прво искључите режим рада у авиону." - "Није регистровано на мрежи." - "Мобилна мрежа није доступна." - "Да бисте упутили позив, унесите важећи број." - "Позив није успео." - "Покреће се MMI секвенца..." - "Услуга није подржана." - "Замена позива није успела." - "Раздвајање позива није успело." - "Пребацивање није успело." - "Конференцијски позив није успео." - "Одбијање позива није успело." - "Успостављање позива није успело." - "SIP позив" - "Хитни позив" - "Укључује се радио…" - "Мобилна мрежа није доступна. Покушавамо поново…" - "Позив није успео. %s није број за хитне случајеве." - "Позив није успео. Позовите број за хитне случајеве." - "Користите тастатуру за позивање" - "Стави позив на чекање" - "Настави позив" - "Заврши позив" - "Прикажи нумеричку тастатуру" - "Сакриј нумеричку тастатуру" - "Искључи звук" - "Укључи звук" - "Додај позив" - "Обједини позиве" - "Замени" - "Управљај позивима" - "Управљај конференцијским позивом" - "Конференцијски позив" - "Управљај" - "Аудио" - "Видео позив" - "Промени у гласовни позив" - "Промени камеру" - "Укључи камеру" - "Искључи камеру" - "Још опција" - "Плејер је покренут" - "Плејер је заустављен" - "Камера није спремна" - "Камера је спремна" - "Непознат догађај сесије позива" - "Услуга" - "Подешавање" - "<Није подешено>" - "Друга подешавања позива" - "Позива се преко добављача %s" - "Долазни позив преко %s" - "слика контакта" - "иди на приватно" - "изаберите контакт" - "Напишите сами…" - "Откажи" - "Пошаљи" - "Одговори" - "Пошаљи SMS" - "Одбиј" - "Одговори видео позивом" - "Одговори аудио-позивом" - "Прихвати захтев за видео" - "Одбиј захтев за видео" - "Прихвати захтев за одлазни видео позив" - "Одбиј захтев за одлазни видео позив" - "Прихвати захтев за долазни видео позив" - "Одбиј захтев за долазни видео позив" - "Превуците нагоре за %s." - "Превуците улево за %s." - "Превуците удесно за %s." - "Превуците надоле за %s." - "Вибрација" - "Вибрација" - "Звук" - "Подразумевани звук (%1$s)" - "Мелодија звона телефона" - "Вибрирај када звони" - "Мелодија звона и вибрација" - "Управљај конференцијским позивом" - "Број за хитне случајеве" - "Слика профила" - "Камера је искључена" - "на %s" - "Белешка је послата" - "Недавне поруке" - "Информације о предузећу" - "Удаљеност је %.1f mi" - "Удаљеност је %.1f km" - "%1$s, %2$s" - "%1$s%2$s" - "%1$s, %2$s" - "Отвара се сутра у %s" - "Отвара се данас у %s" - "Затвара се у %s" - "Затворило се данас у %s" - "Тренутно отворено" - "Тренутно затворено" - "Непожељан позивалац" - "Позив се завршио у %1$s" - "Ово је био први позив са овог броја." - "Сумњамо да је овај позив непожељан." - "Блокирај/пријави" - "Додај контакт" - "Није непожељан" - diff --git a/InCallUI/res/values-sv/strings.xml b/InCallUI/res/values-sv/strings.xml deleted file mode 100644 index 980ecdb07..000000000 --- a/InCallUI/res/values-sv/strings.xml +++ /dev/null @@ -1,195 +0,0 @@ - - - - - "Telefon" - "Parkerat" - "Okänd" - "Privat nummer" - "Telefonautomat" - "Konferenssamtal" - "Samtalet avbröts" - "Högtalare" - "Telefonlur" - "Trådanslutet headset" - "Bluetooth" - "Ska följande toner skickas?\nBREAK" - "Skickar signaler\n" - "Skicka" - "Ja" - "Nej" - "Ersätt jokertecknet med" - "Konferenssamtal %s" - "Nummer till röstbrevlåda" - "Ringer" - "Ringer upp igen" - "Konferenssamtal" - "Inkommande samtal" - "Inkommande jobbsamtal" - "Samtal avslutat" - "Parkerat" - "Lägger på" - "I samtal" - "Mitt telefonnummer är %s" - "Ansluter video" - "Videosamtal" - "Begär video" - "Det gick inte att ansluta till videosamtalet" - "Videobegäran avslogs" - "Ditt nummer för återuppringning\n %1$s" - "Ditt nummer för återuppringning vid nödsamtal\n %1$s" - "Ringer" - "Missat samtal" - "Missade samtal" - "%s missade samtal" - "Missat samtal från %s" - "Pågående samtal" - "Pågående jobbsamtal" - "Pågående Wi-Fi-samtal" - "Pågående jobbsamtal via Wi-Fi" - "Parkerat" - "Inkommande samtal" - "Inkommande jobbsamtal" - "Inkommande Wi-Fi-samtal" - "Inkommande jobbsamtal via Wi-Fi" - "Inkommande videosamtal" - "Inkommande misstänkt spamsamtal" - "Inkommande begäran om videosamtal" - "Nytt röstmeddelande" - "Nytt röstmeddelande (%d)" - "Ring %s" - "Nummer till röstbrevlåda okänt" - "Ingen tjänst" - "Det valda nätverket (%s) är inte tillgängligt" - "Svara" - "Lägg på" - "Video" - "Röstsamtal" - "Godkänn" - "Ignorera" - "Ring upp" - "Meddelande" - "Pågående samtal på en annan enhet" - "Överför samtal" - "Om du vill ringa måste du först inaktivera flygplansläge." - "Inte registrerat på nätverk." - "Det finns inget mobilnät tillgängligt." - "Ange ett giltigt nummer om du vill ringa ett samtal." - "Det gick inte att ringa." - "Startar sekvens för MMI-kod …" - "Tjänsten stöds inte." - "Det gick inte att växla mellan samtal." - "Det gick inte att koppla isär samtalen." - "Det gick inte att överföra." - "Det gick inte att starta ett konferenssamtal." - "Det gick inte att avvisa samtalet." - "Det gick inte att släppa samtal." - "SIP-samtal" - "Nödsamtal" - "Sätter på radion …" - "Ingen tjänst. Försöker igen …" - "Det gick inte att ringa. %s är inget nödnummer." - "Det gick inte att ringa. Slå ett nödnummer." - "Använd tangentbordet om du vill ringa" - "Parkera samtal" - "Återuppta samtal" - "Avsluta samtal" - "Visa knappsats" - "Dölj knappsats" - "Ljud av" - "Sluta ignorera" - "Lägg till samtal" - "Koppla ihop samtal" - "Byt" - "Hantera samtal" - "Hantera konferenssamtal" - "Konferenssamtal" - "Hantera" - "Ljud" - "Videosamt." - "Byt till röstsamtal" - "Byt kamera" - "Slå på kameran" - "Stäng av kameran" - "Fler alternativ" - "Videospelaren har startats" - "Videospelaren har stoppats" - "Kameran är inte klar" - "Kameran är klar" - "Okänd händelse vid samtalssession" - "Tjänst" - "Konfiguration" - "<Har inte angetts>" - "Övriga samtalsinställningar" - "Ringer via %s" - "Inkommande via %s" - "kontaktbild" - "gör privat" - "välj kontakt" - "Skriv ett eget svar …" - "Avbryt" - "Skicka" - "Svara" - "Skicka sms" - "Avvisa" - "Svara som videosamtal" - "Svara som röstsamtal" - "Godkänn videobegäran" - "Avvisa videobegäran" - "Godkänn begäran om att skicka video" - "Avvisa begäran om att skicka video" - "Godkänn begäran om att ta emot video" - "Avvisa begäran om att ta emot video" - "%s genom att dra uppåt." - "%s genom att dra åt vänster." - "%s genom att dra åt höger." - "%s genom att dra nedåt." - "Vibrera" - "Vibrera" - "Ljud" - "Standardsignal (%1$s)" - "Ringsignal" - "Enheten vibrerar vid samtal" - "Ringsignal och vibration" - "Hantera konferenssamtal" - "Nödsamtalsnummer" - "Profilbild" - "Kamera av" - "via %s" - "Anteckningen har skickats" - "Senaste meddelandena" - "Företagsuppgifter" - "%.1f miles bort" - "%.1f km bort" - "%1$s, %2$s" - "%1$s%2$s" - "%1$s, %2$s" - "Öppnar i morgon kl. %s" - "Öppnar i dag kl. %s" - "Stänger kl. %s" - "Stängde i dag kl. %s" - "Öppet" - "Stängt" - "Misstänkt spamsamtal" - "Samtalet avslutat %1$s" - "Det här är första gången det här numret ringde dig." - "Vi misstänkte att det här samtalet var en spammare." - "Blockera/rapp. spam" - "Lägg till kontakt" - "Inte spam" - diff --git a/InCallUI/res/values-sw/strings.xml b/InCallUI/res/values-sw/strings.xml deleted file mode 100644 index d60c4901a..000000000 --- a/InCallUI/res/values-sw/strings.xml +++ /dev/null @@ -1,195 +0,0 @@ - - - - - "Simu" - "Inangoja" - "Isiyojulikana" - "Nambari ya faragha" - "Simu ya kulipia" - "Simu ya mkutano" - "Simu imekatwa" - "Spika" - "Kipaza sauti cha kichwani" - "Vifaa vya sauti visivyo na waya" - "Bluetooth" - "Ungependa kutuma milio ya sauti inayofuata? \n" - "Inatuma milio ya simu\n" - "Tuma" - "Ndiyo" - "Hapana" - "Badilisha herufi inayojitegemea kwa" - "Simu ya mkutano %s" - "Nambari ya ujumbe wa sauti" - "Inapiga" - "Inapiga simu tena" - "Simu ya mkutano" - "Unapigiwa simu" - "Simu ya kazi inayoingia" - "Simu imekamilika" - "Inangoja" - "Kukata simu" - "Katika simu" - "Nambari yangu ni %s" - "Inaunganisha video" - "Hangout ya Video" - "Inaomba video" - "Haiwezi kuunganisha Hangout ya video" - "Ombi la video limekataliwa" - "Nambari yako ya kupigiwa simu\n%1$s" - "Nambari yako ya dharura ya kupigiwa simu\n%1$s" - "Inapiga" - "Simu ambayo hukujibu" - "Simu ambazo hukujibu" - "Simu %s ambazo hukujibu" - "Simu ambayo hukujibu kutoka %s" - "Simu inayoendelea" - "Simu ya kazi inayoendelea" - "Simu ya Wi-Fi inayoendelea" - "Simu ya Wi-Fi ya kazi inayoendelea" - "Inangoja" - "Unapigiwa simu" - "Unapigiwa simu ya kazi" - "Unapigiwa simu kupitia Wi-Fi" - "Unapigiwa simu ya kazini kupitia Wi-Fi" - "Hangout ya Video inayoingia" - "Simu inayoingia inashukiwa kuwa taka" - "Ombi linaloingia la video" - "Ujumbe mpya wa sauti" - "Ujumbe (%d) mpya wa sauti" - "Piga %s" - "Nambari ya ujumbe wa sauti haijulikani." - "Hakuna huduma" - "Mtandao uliochaguliwa (%s) haupatikani" - "Jibu" - "Kata simu" - "Video" - "Sauti" - "Kubali" - "Ondoa" - "Mpigie" - "Ujumbe" - "Una Hangout inayoendelea kwenye kifaa kingine" - "Hamisha Hangout" - "Ili upige simu kwanza, zima Hali ya ndegeni." - "Haijasajiliwa kwenye mtandao." - "Mitandao ya simu za mkononi haipatikani." - "Ili upige simu, weka nambari sahihi." - "Haiwezi kupiga simu." - "Inaanzisha msururu wa MMI…" - "Huduma haitumiki." - "Haiwezi kubadili simu." - "Haiwezi kutenganisha simu." - "Haiwezi kuhamisha." - "Haiwezi kushiriki katika simu ya mkutano." - "Haiwezi kukataa simu." - "Haiwezi kutoa simu." - "Simu ya SIP" - "Simu ya dharura" - "Inawasha redio..." - "Hakuna huduma. Inajaribu tena..." - "Haiwezi kupiga simu. %s si nambari ya dharura." - "Haiwezi kupiga simu. Piga simu nambari ya dharura." - "Tumia kibodi kubonyeza" - "Shikilia Simu" - "Endelea na Simu" - "Kata Simu" - "Onyesha Vitufe vya Kupiga Simu" - "Ficha Vitufe vya Kupiga Simu" - "Zima Sauti" - "Rejesha sauti" - "Ongeza simu" - "Unganisha simu" - "Badili" - "Dhibiti simu" - "Dhibiti simu ya mkutano" - "Mkutano kwenye simu" - "Dhibiti" - "Sauti" - "Hangout ya Video" - "Badilisha iwe simu ya sauti" - "Badilisha kamera" - "Washa kamera" - "Zima kamera" - "Chaguo zaidi" - "Kichezaji Kimeanzishwa" - "Kichezaji Kimekomeshwa" - "Kamera haiko tayari" - "Kamera iko tayari" - "Tukio lisilojulikana la kipindi cha simu" - "Huduma" - "Weka mipangilio" - "<Haijawekwa>" - "Mipangilio mingine ya simu" - "Kupiga simu kupitia %s" - "Simu zinazoingia kupitia %s" - "picha ya anwani" - "tumia kwa faragha" - "chagua anwani" - "Andika yako binafsi..." - "Ghairi" - "Tuma" - "Jibu" - "Tuma SMS" - "Kataa" - "Pokea kama Hangout ya Video" - "Pokea kama simu ya sauti" - "Kubali ombi la video" - "Kataa ombi la video" - "Kubali ombi la kutuma kupitia hangout ya video" - "Kataa ombi la kutuma kupitia hangout ya video" - "Kubali ombi la kupokea kupitia hangout ya video" - "Kataa ombi la kupokea kupitia hangout ya video" - "Telezesha kidole juu ili %s ." - "Telezesha kidole kushoto ili %s." - "Telezesha kidole kulia ili %s." - "Telezesha kidole chini ili %s." - "Mtetemo" - "Mtetemo" - "Mlio" - "Sauti chaguo-msingi (%1$s)" - "Mlio wa simu" - "Tetema wakati wa kuita" - "Mlio wa simu na Mtetemo" - "Dhibiti simu ya mkutano" - "Nambari ya dharura" - "Picha ya wasifu" - "Kamera imezimwa" - "kupitia %s" - "Dokezo limetumwa" - "Ujumbe wa hivi majuzi" - "Maelezo ya biashara" - "Umbali wa maili %.1f" - "Umbali wa kilomita %.1f" - "%1$s, %2$s" - "%1$s - %2$s" - "%1$s, %2$s" - "Itafunguliwa kesho saa %s" - "Itafunguliwa leo saa %s" - "Hufungwa saa %s" - "Imefungwa leo saa %s" - "Sasa imefunguliwa" - "Sasa imefungwa" - "Mpiga simu taka" - "Simu imekatwa %1$s" - "Hii ndiyo mara ya kwanza nambari hii imekupigia." - "Tunashuku kwamba simu hii ni taka." - "Zuia/ripoti taka" - "Ongeza anwani" - "Si barua taka" - diff --git a/InCallUI/res/values-sw360dp/dimens.xml b/InCallUI/res/values-sw360dp/dimens.xml deleted file mode 100644 index 9fbcd605b..000000000 --- a/InCallUI/res/values-sw360dp/dimens.xml +++ /dev/null @@ -1,35 +0,0 @@ - - - - - - - - 22sp - 18sp - 45dp - 34sp - 18sp - - - @dimen/dialpad_key_number_default_margin_bottom - - @dimen/dialpad_zero_key_number_default_margin_bottom - @dimen/dialpad_digits_text_size - @dimen/dialpad_digits_height - @dimen/dialpad_key_numbers_default_size - diff --git a/InCallUI/res/values-sw410dp/config.xml b/InCallUI/res/values-sw410dp/config.xml deleted file mode 100644 index a57f86784..000000000 --- a/InCallUI/res/values-sw410dp/config.xml +++ /dev/null @@ -1,21 +0,0 @@ - - - - - 6 - \ No newline at end of file diff --git a/InCallUI/res/values-ta/strings.xml b/InCallUI/res/values-ta/strings.xml deleted file mode 100644 index 1ee57b4ba..000000000 --- a/InCallUI/res/values-ta/strings.xml +++ /dev/null @@ -1,195 +0,0 @@ - - - - - "ஃபோன்" - "ஹோல்டில் உள்ளது" - "தெரியாத எண்" - "தனிப்பட்ட எண்" - "கட்டணத் தொலைபேசி" - "குழு அழைப்பு" - "அழைப்பு நிறுத்தப்பட்டது" - "ஸ்பீக்கர்" - "ஹேண்ட்செட் இயர்ஃபீஸ்" - "வயருள்ள ஹெட்செட்" - "புளூடூத்" - "பின்வரும் டோன்களை அனுப்பவா?\n" - "டோன்களை அனுப்புகிறது\n" - "அனுப்பு" - "ஆம்" - "வேண்டாம்" - "சிறப்புக்குறியை இதன் மூலம் மாற்றியமை" - "குழு அழைப்பு: %s" - "குரலஞ்சல் எண்" - "அழைக்கிறது" - "மீண்டும் டயல் செய்கிறது" - "குழு அழைப்பு" - "உள்வரும் அழைப்பு" - "உள்வரும் அழைப்பு (பணி)" - "அழைப்பு முடிந்தது" - "ஹோல்டில் உள்ளது" - "துண்டிக்கிறது" - "அழைப்பில்" - "எனது எண்: %s" - "வீடியோவை இணைக்கிறது" - "வீடியோ அழைப்பு" - "வீடியோவைக் கோருகிறது" - "வீடியோ அழைப்பை இணைக்க முடியவில்லை" - "வீடியோ கோரிக்கை நிராகரிக்கப்பட்டது" - "உங்களைத் திரும்ப அழைப்பதற்கான எண்\n %1$s" - "அவசர அழைப்பு எண்\n %1$s" - "அழைக்கிறது" - "தவறிய அழைப்பு" - "தவறிய அழைப்புகள்" - "%s தவறிய அழைப்புகள்" - "%s இடமிருந்து தவறிய அழைப்பு" - "செயலில் இருக்கும் அழைப்பு" - "செயலில் இருக்கும் அழைப்பு (பணி)" - "செயலில் இருக்கும் வைஃபை அழைப்பு" - "செயலில் இருக்கும் வைஃபை அழைப்பு" - "ஹோல்டில் உள்ளது" - "உள்வரும் அழைப்பு" - "உள்வரும் அழைப்பு (பணி)" - "உள்வரும் வைஃபை அழைப்பு" - "உள்வரும் வைஃபை அழைப்பு (பணி)" - "உள்வரும் வீடியோ அழைப்பு" - "உள்வரும் சந்தேகத்திற்குரிய ஸ்பேம் அழைப்பு" - "உள்வரும் வீடியோ கோரிக்கை" - "புதிய குரலஞ்சல்" - "புதிய குரலஞ்சல் (%d)" - "%sஐ அழை" - "குரலஞ்சல் எண் அறியப்படவில்லை" - "சேவை இல்லை" - "தேர்ந்தெடுத்த நெட்வொர்க் (%s) கிடைக்கவில்லை" - "பதிலளி" - "துண்டி" - "வீடியோ" - "குரல்" - "ஏற்கிறேன்" - "நிராகரி" - "திரும்ப அழை" - "செய்தி அனுப்பு" - "மற்றொரு சாதனத்தில் செயலில் இருக்கும் அழைப்பு" - "அழைப்பை இடமாற்று" - "அழைப்பதற்கு, முதலில் விமானப் பயன்முறையை முடக்கவும்." - "நெட்வொர்க்கில் பதிவுசெய்யப்படவில்லை." - "செல்லுலார் நெட்வொர்க் கிடைக்கவில்லை." - "அழைக்க, சரியான எண்ணை உள்ளிடவும்." - "அழைக்க முடியாது." - "MMI வரிசையைத் தொடங்குகிறது..." - "சேவை ஆதரிக்கப்படவில்லை." - "அழைப்புகளில் மாற முடியாது." - "அழைப்பைப் பிரிக்க முடியாது." - "மாற்ற முடியாது." - "குழு அழைப்பு செய்ய முடியாது." - "அழைப்பை நிராகரிக்க முடியாது." - "அழைப்பை(அழைப்புகளை) விடுவிக்க முடியாது." - "SIP அழைப்பு" - "அவசர அழைப்பு" - "ரேடியோவை இயக்குகிறது…" - "சேவை இல்லை. மீண்டும் முயல்கிறது…" - "%s என்பது அவசர அழைப்பு எண் இல்லை என்பதால் அழைக்க முடியாது." - "அழைக்க முடியாது. அவசர அழைப்பு எண்ணை அழைக்கவும்." - "டயல் செய்ய, விசைப்பலகையைப் பயன்படுத்தவும்" - "அழைப்பை ஹோல்டில் வை" - "அழைப்பை மீண்டும் தொடங்கு" - "அழைப்பை முடி" - "டயல்பேடைக் காட்டு" - "டயல்பேடை மறை" - "ஒலியடக்கு" - "ஒலி இயக்கு" - "அழைப்பைச் சேர்" - "அழைப்புகளை இணை" - "மாற்று" - "அழைப்புகளை நிர்வகி" - "குழு அழைப்பை நிர்வகி" - "குழு அழைப்பு" - "நிர்வகி" - "ஆடியோ" - "வீடியோ அழைப்பு" - "குரல் அழைப்பிற்கு மாறு" - "கேமராவை மாற்று" - "கேமராவை இயக்கு" - "கேமராவை முடக்கு" - "கூடுதல் விருப்பங்கள்" - "வீடியோ பிளேயர் துவங்கியது" - "வீடியோ பிளேயர் நிறுத்தப்பட்டது" - "கேமரா தயாராக இல்லை" - "கேமரா தயார்" - "தெரியாத அழைப்பு நேர நிகழ்வு" - "சேவை" - "அமை" - "<அமைக்கப்படவில்லை>" - "பிற அழைப்பு அமைப்புகள்" - "%s வழியாக அழைக்கிறது" - "%s மூலம் உள்வரும் அழைப்புகள்" - "தொடர்புப் படம்" - "தனிப்பட்டதிற்குச் செல்" - "தொடர்பைத் தேர்ந்தெடுக்கவும்" - "சொந்தமாக எழுதவும்..." - "ரத்துசெய்" - "அனுப்பு" - "பதிலளி" - "SMS அனுப்பு" - "நிராகரி" - "வீடியோ அழைப்பில் பதிலளி" - "ஆடியோ அழைப்பில் பதிலளி" - "வீடியோ கோரிக்கையை அனுமதி" - "வீடியோ கோரிக்கையை நிராகரி" - "வீடியோவைப் பரிமாற்றும் கோரிக்கையை அனுமதி" - "வீடியோவைப் பரிமாற்றும் கோரிக்கையை நிராகரி" - "வீடியோவைப் பெறும் கோரிக்கையை அனுமதி" - "வீடியோவைப் பெறும் கோரிக்கையை நிராகரி" - "%s, மேலே ஸ்லைடு செய்க." - "%s, இடப்புறம் ஸ்லைடு செய்க." - "%s, வலப்புறம் ஸ்லைடு செய்க." - "%s, கீழே ஸ்லைடு செய்க." - "அதிர்வுறு" - "அதிர்வுறு" - "ஒலி" - "இயல்பு ஒலி (%1$s)" - "ஃபோனின் ரிங்டோன்" - "அழைக்கும் போது அதிர்வுறு" - "ரிங்டோன் & அதிர்வு" - "குழு அழைப்பை நிர்வகி" - "அவசர அழைப்பு எண்" - "சுயவிவரப் படம்" - "கேமரா முடக்கப்பட்டது" - "%s வழியாக" - "குறிப்பு அனுப்பப்பட்டது" - "சமீபத்திய செய்திகள்" - "வணிகத் தகவல்" - "%.1f மைல் தொலைவில்" - "%.1f கிமீ தொலைவில்" - "%1$s, %2$s" - "%1$s - %2$s" - "%1$s, %2$s" - "நாளை %sக்குத் திறக்கப்படும்" - "இன்று %sக்குத் திறக்கப்படும்" - "%sக்கு மூடப்படும்" - "இன்று %sக்கு மூடப்பட்டது" - "இப்போது திறக்கப்பட்டுள்ளது" - "இப்போது மூடப்பட்டுள்ளது" - "சந்தேகத்திற்குரிய ஸ்பேம் அழைப்பாளர்" - "அழைப்பு துண்டிக்கப்பட்டது %1$s" - "இந்த எண்ணிலிருந்து உங்களுக்கு அழைப்பு வந்தது இதுவே முதல் முறை." - "இந்த அழைப்பு ஸ்பேமராக இருக்கக்கூடும் என சந்தேகிக்கிறோம்." - "தடு/ஸ்பேமென புகாரளி" - "தொடர்பைச் சேர்" - "ஸ்பேமில்லை" - diff --git a/InCallUI/res/values-te/strings.xml b/InCallUI/res/values-te/strings.xml deleted file mode 100644 index 936f1be7c..000000000 --- a/InCallUI/res/values-te/strings.xml +++ /dev/null @@ -1,195 +0,0 @@ - - - - - "ఫోన్" - "హోల్డ్‌లో ఉంది" - "తెలియదు" - "ప్రైవేట్ నంబర్" - "పే ఫోన్" - "కాన్ఫరెన్స్ కాల్" - "కాల్ కట్ అయింది" - "స్పీకర్" - "హ్యాండ్‌సెట్ ఇయర్‌పీస్" - "వైర్ గల హెడ్‌సెట్" - "బ్లూటూత్" - "కింది టోన్‌లను పంపాలా?\n" - "టోన్‌లు పంపుతోంది\n" - "పంపు" - "అవును" - "వద్దు" - "దీనితో వైల్డ అక్షరాన్ని భర్తీ చేయండి" - "కాన్ఫరెన్స్ కాల్ %s" - "వాయిస్ మెయిల్ నంబర్" - "డయల్ చేస్తోంది" - "మళ్లీ డయల్ చేస్తోంది" - "కాన్ఫరెన్స్ కాల్" - "ఇన్‌కమింగ్ కాల్" - "ఇన్‌కమింగ్ కార్యాలయ కాల్" - "కాల్ ముగిసింది" - "హోల్డ్‌లో ఉంది" - "ముగిస్తోంది" - "కాల్‌లో ఉంది" - "నా నంబర్ %s" - "వీడియోను కనెక్ట్ చేస్తోంది" - "వీడియో కాల్" - "వీడియో కోసం అభ్యర్థిస్తోంది" - "వీడియో కాల్‌ను కనెక్ట్ చేయలేరు" - "వీడియో అభ్యర్థన తిరస్కరించబడింది" - "మీ కాల్‌బ్యాక్ నంబర్\n %1$s" - "మీ అత్యవసర కాల్‌బ్యాక్ నంబర్\n %1$s" - "డయల్ చేస్తోంది" - "సమాధానం ఇవ్వని కాల్" - "సమాధానం ఇవ్వని కాల్‌లు" - "%s సమాధానం ఇవ్వని కాల్‌లు" - "%s నుండి సమాధానం ఇవ్వని కాల్" - "కాల్ కొనసాగుతోంది" - "కార్యాలయ కాల్ కొనసాగుతోంది" - "Wi-Fi కాల్ కొనసాగుతోంది" - "Wi-Fi కార్యాలయ కాల్ కొనసాగుతోంది" - "హోల్డ్‌లో ఉంది" - "ఇన్‌కమింగ్ కాల్" - "ఇన్‌కమింగ్ కార్యాలయ కాల్" - "ఇన్‌కమింగ్ Wi-Fi కాల్" - "ఇన్‌కమింగ్ Wi-Fi కార్యాలయ కాల్" - "ఇన్‌కమింగ్ వీడియో కాల్" - "అనుమానాస్పద స్పామ్ కాల్ వస్తోంది" - "ఇన్‌కమింగ్ వీడియో అభ్యర్థన" - "కొత్త వాయిస్ మెయిల్" - "కొత్త వాయిస్ మెయిల్ (%d)" - "%sకు డయల్ చేయండి" - "వాయిస్ మెయిల్ నంబర్ తెలియదు" - "సేవ లేదు" - "ఎంచుకున్న నెట్‌వర్క్ (%s) అందుబాటులో లేదు" - "సమాధానం" - "కాల్ ముగించు" - "వీడియో" - "వాయిస్" - "ఆమోదిస్తున్నాను" - "తీసివేయి" - "తిరిగి కాల్ చేయి" - "సందేశం పంపు" - "మరో పరికరంలో కాల్ జరుగుతోంది" - "కాల్‌ను బదిలీ చేయి" - "కాల్ చేయడానికి, ముందుగా ఎయిర్‌ప్లైన్ మోడ్‌ను ఆపివేయండి." - "నెట్‌వర్క్‌లో నమోదు కాలేదు." - "సెల్యులార్ నెట్‌వర్క్ అందుబాటులో లేదు." - "కాల్ చేయడానికి, చెల్లుబాటు అయ్యే నంబర్‌ను నమోదు చేయండి." - "కాల్ చేయలేరు." - "MMI శ్రేణిని ప్రారంభిస్తోంది…" - "సేవకు మద్దతు లేదు." - "కాల్‌లను మార్చలేరు." - "కాల్‌ను వేరు చేయలేరు." - "బదిలీ చేయలేరు." - "కాన్ఫరెన్స్ కాల్ కుదరదు." - "కాల్‌ను తిరస్కరించలేరు." - "కాల్(ల)ను విడిచిపెట్టలేరు." - "SIP కాల్" - "అత్యవసర కాల్" - "రేడియోను ఆన్ చేస్తోంది…" - "సేవ లేదు. మళ్లీ ప్రయత్నిస్తోంది…" - "కాల్ చేయలేరు. %s అత్యవసర నంబర్ కాదు." - "కాల్ చేయలేరు. అత్యవసర నంబర్‌కు డయల్ చేయండి." - "డయల్ చేయడానికి కీబోర్డ్‌ను ఉపయోగించండి" - "కాల్‌ను హోల్డ్‌లో ఉంచు" - "కాల్‌ను పునఃప్రారంభించు" - "కాల్‌ని ముగించు" - "డయల్‌ప్యాడ్‌ను చూపు" - "డయల్‌ప్యాడ్‌ను దాచు" - "మ్యూట్ చేయి" - "అన్‌మ్యూట్ చేయి" - "కాల్‌ను జోడించు" - "కాల్‌లను విలీనం చేయి" - "స్వాప్ చేయి" - "కాల్‌లను నిర్వహించు" - "కాన్ఫరెన్స్ కాల్‌ను నిర్వహించు" - "కాన్ఫరెన్స్ కాల్" - "నిర్వహించు" - "ఆడియో" - "వీడియో కాల్" - "వాయిస్ కాల్‌కి మార్చు" - "కెమెరాను మార్చు" - "కెమెరాను ఆన్ చేయి" - "కెమెరాను ఆఫ్ చేయి" - "మరిన్ని ఎంపికలు" - "ప్లేయర్ ప్రారంభమైంది" - "ప్లేయర్ ఆపివేయబడింది" - "కెమెరా సిద్ధంగా లేదు" - "కెమెరా సిద్ధంగా ఉంది" - "తెలియని కాల్ సెషన్ ఉదంతం" - "సేవ" - "సెటప్ చేయండి" - "<సెట్ చేయలేదు>" - "ఇతర కాల్ సెట్టింగ్‌లు" - "%s ద్వారా కాల్ చేయబడుతోంది" - "%s ద్వారా ఇన్‌కమింగ్" - "పరిచయం ఫోటో" - "ప్రైవేట్‌గా వెళ్లు" - "పరిచయాన్ని ఎంచుకోండి" - "మీ స్వంతంగా వ్రాయండి…" - "రద్దు చేయి" - "పంపు" - "సమాధానం" - "SMSని పంపుతుంది" - "తిరస్కరిస్తుంది" - "వీడియో కాల్ రూపంలో సమాధానం" - "ఆడియో కాల్ రూపంలో సమాధానం" - "వీడియో అభ్యర్థనను ఆమోదిస్తుంది" - "వీడియో అభ్యర్థనను తిరస్కరిస్తుంది" - "వీడియో ప్రసరణ అభ్యర్థనను ఆమోదిస్తుంది" - "వీడియో ప్రసరణ అభ్యర్థనను తిరస్కరిస్తుంది" - "వీడియో స్వీకరణ అభ్యర్థనను ఆమోదిస్తుంది" - "వీడియో స్వీకరణ అభ్యర్థనను తిరస్కరిస్తుంది" - "%s కోసం పైకి స్లైడ్ చేయండి." - "%s కోసం ఎడమవైపుకు స్లైడ్ చేయండి." - "%s కోసం కుడివైపుకు స్లైడ్ చేయండి." - "%s కోసం కిందికి స్లైడ్ చేయండి." - "వైబ్రేట్" - "వైబ్రేట్" - "ధ్వని" - "డిఫాల్ట్ ధ్వని (%1$s)" - "ఫోన్ రింగ్‌టోన్" - "రింగ్ అయ్యేప్పుడు వైబ్రేషన్" - "రింగ్‌టోన్ & వైబ్రేట్" - "కాన్ఫరెన్స్ కాల్‌ను నిర్వహించు" - "అత్యవసర నంబర్" - "ప్రొఫైల్ ఫోటో" - "కెమెరా ఆఫ్‌లో ఉంది" - "%s ద్వారా" - "గమనిక పంపబడింది" - "ఇటీవలి సందేశాలు" - "వ్యాపార సంస్థ సమాచారం" - "%.1f మై దూరంలో ఉంది" - "%.1f కి.మీ దూరంలో ఉంది" - "%1$s, %2$s" - "%1$s - %2$s" - "%1$s, %2$s" - "రేపు %sకి తెరవబడుతుంది" - "ఈరోజు %sకి తెరవబడుతుంది" - "%sకి మూసివేయబడుతుంది" - "ఈరోజు %sకి మూసివేయబడి ఉంటుంది" - "ఇప్పుడు తెరిచి ఉంది" - "ఇప్పుడు మూసివేయబడింది" - "అనుమానిత స్పామ్ కాలర్" - "కాల్ ముగిసింది %1$s" - "ఈ నంబర్ నుండి మీకు కాల్ రావడం ఇదే మొదటిసారి." - "ఈ కాల్ స్పామర్ కావచ్చని మేము అనుమానిస్తున్నాము." - "బ్లాక్/స్పామ్ నివే." - "పరిచయాన్ని జోడించు" - "స్పామ్ కాదు" - diff --git a/InCallUI/res/values-th/strings.xml b/InCallUI/res/values-th/strings.xml deleted file mode 100644 index 69ae44d07..000000000 --- a/InCallUI/res/values-th/strings.xml +++ /dev/null @@ -1,195 +0,0 @@ - - - - - "โทรศัพท์" - "พักสาย" - "ไม่ทราบ" - "หมายเลขส่วนตัว" - "โทรศัพท์สาธารณะ" - "การประชุมสาย" - "สายหลุด" - "ลำโพง" - "ชุดหูฟังโทรศัพท์" - "ชุดหูฟังแบบมีสาย" - "บลูทูธ" - "ส่งหมายเลขต่อไปไหม\n" - "กำลังส่งหมายเลข\n" - "ส่ง" - "ใช่" - "ไม่" - "แทนที่อักขระแทนด้วย" - "การประชุมสาย %s" - "หมายเลขข้อความเสียง" - "กำลังโทรออก" - "โทรใหม่" - "การประชุมสาย" - "สายเรียกเข้า" - "มีสายเรียกเข้าจากที่ทำงาน" - "วางสายแล้ว" - "พักสาย" - "กำลังวางสาย" - "กำลังใช้สาย" - "หมายเลขของฉันคือ %s" - "กำลังเชื่อมต่อวิดีโอ" - "แฮงเอาท์วิดีโอ" - "กำลังขอวิดีโอ" - "ไม่สามารถเชื่อมต่อแฮงเอาท์วิดีโอได้" - "คำขอวิดีโอถูกปฏิเสธ" - "หมายเลขโทรกลับของคุณ\n %1$s" - "หมายเลขโทรกลับฉุกเฉินของคุณ\n %1$s" - "กำลังโทรออก" - "สายที่ไม่ได้รับ" - "สายที่ไม่ได้รับ" - "ไม่ได้รับ %s สาย" - "สายที่ไม่ได้รับจาก %s" - "โทรต่อเนื่อง" - "กำลังอยู่ในสายจากที่ทำงาน" - "กำลังโทรผ่าน Wi-Fi" - "กำลังอยู่ในสายจากที่ทำงานผ่าน Wi-Fi" - "พักสาย" - "สายเรียกเข้า" - "มีสายเรียกเข้าจากที่ทำงาน" - "สายโทรเข้าผ่าน Wi-Fi" - "มีสายเรียกเข้าจากที่ทำงานผ่าน Wi-Fi" - "แฮงเอาท์วิดีโอเรียกเข้า" - "สายเรียกเข้าที่สงสัยว่าเป็นสแปม" - "คำขอโทรเข้าเป็นวิดีโอ" - "ข้อความเสียงใหม่" - "ข้อความเสียงใหม่ (%d)" - "หมุนหมายเลข %s" - "ไม่ทราบหมายเลขข้อความเสียง" - "ไม่มีบริการ" - "เครือข่ายที่เลือกไว้ (%s) ไม่พร้อมใช้งาน" - "รับสาย" - "วางสาย" - "วิดีโอ" - "เสียง" - "ยอมรับ" - "ปิด" - "โทรกลับ" - "ข้อความ" - "กำลังใช้สายบนอุปกรณ์อื่น" - "โอนสาย" - "หากต้องการโทรออก ให้ปิดโหมดบนเครื่องบินก่อน" - "ยังไม่ได้ลงทะเบียนบนเครือข่าย" - "เครือข่ายมือถือใช้งานไม่ได้" - "หากต้องการโทรออก โปรดป้อนหมายเลขที่ถูกต้อง" - "ไม่สามารถโทรได้" - "กำลังเริ่มต้นลำดับ MMI..." - "ไม่สนับสนุนบริการนี้" - "ไม่สามารถสลับสายได้" - "ไม่สามารถแยกสายได้" - "ไม่สามารถโอนได้" - "ไม่สามารถประชุมได้" - "ไม่สามารถปฏิเสธสายได้" - "ไม่สามารถเริ่มการโทรได้" - "โทรแบบ SIP" - "หมายเลขฉุกเฉิน" - "กำลังเปิดวิทยุ…" - "ไม่มีบริการ โปรดลองอีกครั้ง…" - "โทรออกไม่ได้ %s ไม่ใช่หมายเลขฉุกเฉิน" - "ไม่สามารถโทรออก โทรหมายเลขฉุกเฉิน" - "ใช้แป้นพิมพ์กดหมายเลขโทรศัพท์" - "พักสาย" - "โทรต่อ" - "วางสาย" - "แสดงแป้นหมายเลข" - "ซ่อนแป้นหมายเลข" - "ปิดเสียง" - "เปิดเสียง" - "เพิ่มการโทร" - "รวมสาย" - "สลับ" - "จัดการการโทร" - "จัดการการประชุมสาย" - "การประชุมสาย" - "จัดการ" - "เสียง" - "แฮงเอาท์วิดีโอ" - "เปลี่ยนเป็นการโทรด้วยเสียง" - "เปลี่ยนกล้อง" - "เปิดกล้อง" - "ปิดกล้อง" - "ตัวเลือกเพิ่มเติม" - "โปรแกรมเล่นเริ่มทำงานแล้ว" - "โปรแกรมเล่นหยุดแล้ว" - "กล้องไม่พร้อมทำงาน" - "กล้องพร้อมทำงาน" - "เหตุการณ์เซสชันการโทรที่ไม่รู้จัก" - "บริการ" - "ตั้งค่า" - "<ไม่ได้ตั้งค่า>" - "การตั้งค่าการโทรอื่นๆ" - "โทรผ่าน %s" - "สายเรียกเข้าผ่าน %s" - "ภาพของรายชื่อติดต่อ" - "เข้าสู่โหมดส่วนตัว" - "เลือกรายชื่อติดต่อ" - "เขียนคำตอบของคุณเอง..." - "ยกเลิก" - "ส่ง" - "รับสาย" - "ส่ง SMS" - "ปฏิเสธ" - "รับสายเป็นแฮงเอาท์วิดีโอ" - "รับสายเป็นการโทรด้วยเสียง" - "ยอมรับคำขอวิดีโอ" - "ปฏิเสธคำขอวิดีโอ" - "ยอมรับคำขอให้ส่งวิดีโอ" - "ปฏิเสธคำขอให้ส่งวิดีโอ" - "ยอมรับคำขอให้รับวิดีโอ" - "ปฏิเสธคำขอให้รับวิดีโอ" - "เลื่อนไปข้างบนเพื่อ %s" - "เลื่อนไปทางซ้ายเพื่อ %s" - "เลื่อนไปทางขวาเพื่อ %s" - "เลื่อนลงเพื่อ %s" - "สั่น" - "สั่น" - "เสียง" - "เสียงเริ่มต้น (%1$s)" - "เสียงเรียกเข้าโทรศัพท์" - "สั่นเมื่อมีสายเข้า" - "เสียงเรียกเข้าและสั่น" - "จัดการการประชุมสาย" - "หมายเลขฉุกเฉิน" - "รูปโปรไฟล์" - "ปิดกล้อง" - "ผ่านหมายเลข %s" - "ส่งโน้ตแล้ว" - "ข้อความล่าสุด" - "ข้อมูลธุรกิจ" - "อยู่ห่างออกไป %.1f ไมล์" - "อยู่ห่างออกไป %.1f กม." - "%1$s, %2$s" - "%1$s - %2$s" - "%1$s, %2$s" - "เปิดให้บริการพรุ่งนี้เวลา %s" - "เปิดให้บริการวันนี้เวลา %s" - "ปิดให้บริการเวลา %s" - "ปิดให้บริการแล้ววันนี้เวลา %s" - "ขณะนี้เปิดทำการ" - "ขณะนี้ปิดทำการ" - "ผู้โทรที่สงสัยว่าเป็นสแปม" - "วางสายแล้ว %1$s" - "หมายเลขนี้โทรหาคุณเป็นครั้งแรก" - "เราสงสัยว่าสายนี้จะเป็นนักส่งสแปม" - "บล็อก/รายงานสแปม" - "เพิ่มผู้ติดต่อ" - "ไม่ใช่สแปม" - diff --git a/InCallUI/res/values-tl/strings.xml b/InCallUI/res/values-tl/strings.xml deleted file mode 100644 index b5658d705..000000000 --- a/InCallUI/res/values-tl/strings.xml +++ /dev/null @@ -1,195 +0,0 @@ - - - - - "Telepono" - "Naka-hold" - "Hindi alam" - "Pribadong numero" - "Payphone" - "Conference call" - "Naputol ang tawag" - "Speaker" - "Handset earpiece" - "Wired na headset" - "Bluetooth" - "Ipapadala ba ang mga sumusunod na tono?\n" - "Nagpapadala ng mga tono\n" - "Ipadala" - "Oo" - "Hindi" - "Palitan ang wild character ng" - "Conference call %s" - "Numero ng voicemail" - "Dina-dial" - "Muling dina-dial" - "Conference call" - "Papasok na tawag" - "Papasok na tawag sa trabaho" - "Ibinaba ang tawag" - "Naka-hold" - "Binababa" - "Nasa tawag" - "Ang aking numero ay %s" - "Ikinokonekta ang video" - "Mag-video call" - "Humihiling ng video" - "Hindi makakonekta sa video call" - "Tinanggihan ang kahilingan sa video" - "Ang iyong numero ng callback\n %1$s" - "Ang iyong emergency na numero ng callback\n %1$s" - "Dina-dial" - "Hindi nasagot na tawag" - "Mga hindi nasagot na tawag" - "%s (na) hindi nasagot na tawag" - "Hindi nasagot ang tawag mula kay %s" - "Kasalukuyang tawag" - "Kasalukuyang tawag sa trabaho" - "Kasalukuyang tawag sa Wi-Fi" - "Kasalukuyang tawag sa trabaho sa pamamagitan ng Wi-Fi" - "Naka-hold" - "Papasok na tawag" - "Papasok na tawag sa trabaho" - "Papasok na tawag sa Wi-Fi" - "Papasok na tawag sa trabaho sa pamamagitan ng Wi-Fi" - "Papasok na video call" - "Papasok na pinaghihinalaang spam na tawag" - "Papasok na kahilingan ng video" - "Bagong voicemail" - "Bagong voicemail (%d)" - "I-dial ang %s" - "Hindi kilala ang numero ng voicemail" - "Walang serbisyo" - "Hindi available ang piniling network (%s)" - "Sagutin" - "Ibaba" - "Video" - "Boses" - "Tanggapin" - "I-dismiss" - "Tawagan" - "Mensahe" - "Kasalukuyang tawag sa isa pang device" - "Ilipat ang Tawag" - "Upang tumawag, paki-off muna ang Airplane mode." - "Hindi nakarehistro sa network." - "Hindi available ang cellular network." - "Upang tumawag, maglagay ng wastong numero." - "Hindi makatawag." - "Sinisimulan ang pagkakasunud-sunod ng MMI…" - "Hindi sinusuportahan ang serbisyo." - "Hindi mailipat ang mga tawag." - "Hindi mapaghiwalay ang tawag." - "Hindi mailipat." - "Hindi makapag-conference." - "Hindi matanggihan ang tawag." - "Hindi mailabas ang (mga) tawag." - "Tawag sa SIP" - "Emergency na tawag" - "Ino-on ang radyo…" - "Walang serbisyo. Sinusubukang muli…" - "Hindi makatawag. Ang %s ay hindi isang pang-emergency na numero." - "Hindi makatawag. Mag-dial ng pang-emergency na numero." - "Gamitin ang keyboard upang mag-dial" - "I-hold ang Tawag" - "Ituloy ang Tawag" - "Ibaba ang Tawag" - "Ipakita ang Dialpad" - "Itago ang Dialpad" - "I-mute" - "Alisin sa pagkaka-mute" - "Magdagdag ng tawag" - "Pagsamahin ang mga tawag" - "Pagpalitin" - "Pamahalaan ang mga tawag" - "Pamahalaan ang conference call" - "Conference call" - "Pamahalaan" - "Audio" - "Mag-video call" - "Gawing voice call" - "Lumipat ng camera" - "I-on ang camera" - "I-off ang camera" - "Higit pang mga opsyon" - "Nagsimula na ang Player" - "Huminto ang Player" - "Hindi pa handa ang camera" - "Handa na ang camera" - "Hindi alam na kaganapan ng session ng tawag" - "Serbisyo" - "I-setup" - "<Hindi nakatakda>" - "Iba pang mga setting ng tawag" - "Tumatawag sa pamamagitan ng %s" - "Papasok sa pamamagitan ng %s" - "larawan ng contact" - "maging pribado" - "pumili ng contact" - "Sumulat ng sarili mong tugon…" - "Kanselahin" - "Ipadala" - "Sagutin" - "Magpadala ng SMS" - "Tanggihan" - "Sagutin bilang video call" - "Sagutin bilang audio call" - "Tanggapin ang kahilingan sa video" - "Tanggihan ang kahilingan sa video" - "Tanggapin ang kahilingan sa pagpapadala ng video" - "Tanggihan ang kahilingan sa pagpapadala ng video" - "Tanggapin ang kahilingan sa pagtanggap ng video" - "Tanggihan ang kahilingan sa pagtanggap ng video" - "Mag-slide pataas para sa %s." - "Mag-slide pakaliwa para sa %s." - "Mag-slide pakanan para sa %s." - "Mag-slide pababa para sa %s." - "Mag-vibrate" - "Mag-vibrate" - "Tunog" - "Default na tunog (%1$s)" - "Ringtone ng telepono" - "Mag-vibrate kapag nagri-ring" - "Ringtone at Pag-vibrate" - "Pamahalaan ang conference call" - "Pang-emergency na numero" - "Larawan sa profile" - "Naka-off ang camera" - "sa pamamagitan ng %s" - "Naipadala ang tala" - "Mga kamakailang mensahe" - "Impormasyon ng negosyo" - "%.1f (na) milya ang layo" - "%.1f (na) kilometro ang layo" - "%1$s, %2$s" - "%1$s - %2$s" - "%1$s, %2$s" - "Magbubukas bukas nang %s" - "Magbubukas ngayon nang %s" - "Magsasara nang %s" - "Sarado ngayon nang %s" - "Bukas ngayon" - "Sarado ngayon" - "Hinihinalang spam na tumatawag" - "Natapos ang tawag %1$s" - "Ito ang unang beses na tinawagan ka ng numerong ito." - "Pinaghihinalaan naming isang spammer ang tawag na ito." - "I-block/iulat na spam" - "Magdagdag ng contact" - "Hindi spam" - diff --git a/InCallUI/res/values-tr/strings.xml b/InCallUI/res/values-tr/strings.xml deleted file mode 100644 index 405bab8db..000000000 --- a/InCallUI/res/values-tr/strings.xml +++ /dev/null @@ -1,195 +0,0 @@ - - - - - "Telefon" - "Beklemede" - "Bilinmiyor" - "Gizli numara" - "Ankesörlü telefon" - "Konferans görüşmesi" - "Çağrı kesildi" - "Hoparlör" - "Mobil cihaz kulaklığı" - "Kablolu kulaklık" - "Bluetooth" - "Aşağıdaki zil sesleri gönderilsin mi?\n" - "Numara tonları gönderiliyor\n" - "Gönder" - "Evet" - "Hayır" - "Joker karakteri şununla değiştir:" - "Konferans görüşmesi %s" - "Sesli mesaj numarası" - "Numara çevriliyor" - "Yeniden çevriliyor" - "Konferans görüşmesi" - "Gelen çağrı" - "İşle ilgili gelen çağrı" - "Çağrı sonlandırıldı" - "Beklemede" - "Sonlandırılıyor" - "Görüşmede" - "Numaram: %s" - "Video bağlanıyor" - "Video görüşmesi" - "Video isteniyor" - "Video görüşmesi bağlantısı yapılamıyor" - "Video isteği reddedildi" - "Geri aranacağınız numara\n %1$s" - "Acil durumda geri aranacağınız numara\n %1$s" - "Numara çevriliyor" - "Cevapsız çağrı" - "Cevapsız çağrılar" - "%s cevapsız çağrı" - "Cevapsız çağrı: %s" - "Devam eden çağrı" - "İşle ilgili devam eden çağrı" - "Devam eden kablosuz çağrı" - "İşle ilgili devam eden kablosuz çağrı" - "Beklemede" - "Gelen çağrı" - "İşle ilgili gelen çağrı" - "Gelen kablosuz çağrı" - "İşle ilgili gelen kablosuz çağrı" - "Gelen video görüşmesi isteği" - "Spam olabilecek gelen arama" - "Gelen video isteği" - "Yeni sesli mesaj" - "Yeni sesli mesaj (%d)" - "Çevir: %s" - "Sesli mesaj numarası bilinmiyor" - "Servis yok" - "Seçili ağ (%s) kullanılamıyor" - "Yanıtla" - "Kapat" - "Video" - "Ses" - "Kabul et" - "Yok say" - "Geri ara" - "İleti" - "Başka bir cihazda devam eden çağrı" - "Çağrıyı Aktar" - "Çağrı yapmak için öncelikle Uçak modunu kapatın." - "Ağda kayıtlı değil." - "Hücresel ağ kullanılamıyor." - "Çağrı yapmak için geçerli bir numara girin." - "Çağrı yapılamıyor." - "MMI dizisi başlatılıyor…" - "Service desteklenmiyor" - "Çağrı geçişi yapılamıyor." - "Çağrı ayrılamıyor." - "Aktarılamıyor." - "Konferans çağrısı yapılamıyor." - "Çağrı reddedilemiyor." - "Çağrılar bırakılamıyor." - "SIP çağrısı" - "Acil durum çağrısı" - "Radyo açılıyor…" - "Servis yok. Tekrar deneniyor…" - "Çağrı yapılamıyor. %s bir acil durum numarası değil." - "Çağrı yapılamıyor. Acil durum numarasını çevirin." - "Çevirmek için klavyeyi kullan" - "Çağrıyı Beklet" - "Çağrıyı Devam Ettir" - "Çağrıyı Sonlandır" - "Tuş Takımını Göster" - "Tuş Takımını Gizle" - "Sesi kapat" - "Sesi aç" - "Çağrı ekle" - "Çağrıları birleştir" - "Değiştir" - "Çağrıları yönet" - "Konferans çağrısını yönet" - "Konferans çağrısı" - "Yönet" - "Ses" - "Vid. görşm" - "Sesli çağrıya geç" - "Kamerayı değiştir" - "Kamerayı aç" - "Kamerayı kapat" - "Diğer seçenekler" - "Oynatıcı Başlatıldı" - "Oynatıcı Durduruldu" - "Kamera hazır değil" - "Kamera hazır" - "Bilinmeyen çağrı oturumu etkinliği" - "Hizmet" - "Kurulum" - "<Ayarlanmadı>" - "Diğer çağrı ayarları" - "%s üzerinden çağrı yapılıyor" - "%s adlı sağlayıcı üzerinden gelen çağrı" - "kişi fotoğrafı" - "özel görüşmeye geç" - "kişi seçin" - "Kendi yanıtınızı oluşturun…" - "İptal" - "Gönder" - "Yanıtla" - "SMS gönder" - "Reddet" - "Video görüşmesi olarak yanıtla" - "Sesli görüşme olarak yanıtla" - "Video isteğini kabul et" - "Video isteğini reddet" - "Video aktarma isteğini kabul et" - "Video aktarma isteğini reddet" - "Video alma isteğini kabul et" - "Video alma isteğini reddet" - "%s için yukarı kaydırın." - "%s için sola kaydırın." - "%s için sağa kaydırın." - "%s için aşağı kaydırın." - "Titreşim" - "Titreşim" - "Ses" - "Varsayılan ses (%1$s)" - "Telefon zil sesi" - "Çalarken titret" - "Zil Sesi ve Titreşim" - "Konferans çağrısını yönetin" - "Acil durum numarası" - "Profil fotoğrafı" - "Kamera kapalı" - "%s üzerinden" - "Not gönderildi" - "Son iletiler" - "İşletme bilgileri" - "%.1f mil uzakta" - "%.1f km uzakta" - "%1$s, %2$s" - "%1$s - %2$s" - "%1$s, %2$s" - "Yarın açılış saati: %s" - "Bugün açılış saati: %s" - "Kapanış saati: %s" - "Bugün kapanış saati: %s" - "Şu an açık" - "Şu an kapalı" - "Spam olabilck arayan" - "Arama sona erdi %1$s" - "Bu, bu numaradan ilk aranışınız." - "Bu aramanın spam olduğundan şüpheleniliyor." - "Engelle/spam bildir" - "Kişi ekle" - "Spam değil" - diff --git a/InCallUI/res/values-uk/strings.xml b/InCallUI/res/values-uk/strings.xml deleted file mode 100644 index b323acd04..000000000 --- a/InCallUI/res/values-uk/strings.xml +++ /dev/null @@ -1,195 +0,0 @@ - - - - - "Номер телефону" - "Очікування" - "Невідомо" - "Приватний номер" - "Таксофон" - "Конференц-зв’язок" - "Виклик перервано" - "Динамік" - "Динамік гарнітури" - "Дротова гарнітура" - "Bluetooth" - "Надіслати вказані нижче сигнали?\n" - "Надсилання сигналів\n" - "Надіслати" - "Так" - "Ні" - "Замінити довільний символ на" - "Конференц-зв’язок %s" - "Номер голосової пошти" - "Набір номера" - "Повторний набір" - "Конференц-зв’язок" - "Вхідний виклик" - "Вхідний робочий виклик" - "Виклик завершено" - "Очікування" - "Завершення виклику" - "Триває виклик" - "Мій номер: %s" - "Відеодзвінок: з’єднання" - "Відеодзвінок" - "Надсилання запиту на відеодзвінок" - "Не вдалося здійснити відеодзвінок" - "Запрошення на відеодзвінок відхилено" - "Номер для зв’язку:\n%1$s" - "Екстрений номер:\n%1$s" - "Набір номера" - "Пропущений виклик" - "Пропущені виклики" - "Пропущено викликів: %s" - "Пропущений виклик: %s" - "Поточний виклик" - "Поточний виклик на робочий телефон" - "Поточний виклик через Wi-Fi" - "Поточний виклик на робочий телефон через Wi-Fi" - "Очікування" - "Вхідний виклик" - "Вхідний виклик на робочий телефон" - "Вхідний виклик через Wi-Fi" - "Вхідний виклик на робочий телефон через Wi-Fi" - "Вхідний відеодзвінок" - "Цей дзвінок може бути спамом" - "Запит на вхідний відеодзвінок" - "Нові голосові повідомлення" - "Нові голосові повідомлення (%d)" - "Набрати %s" - "Невідомий номер голосової пошти" - "Немає зв’язку" - "Вибрана мережа (%s) недоступна" - "Відповісти" - "Завершити" - "Відео" - "Гол. виклик" - "Прийняти" - "Відхилити" - "Передзвонити" - "Написати SMS" - "Поточний виклик на іншому пристрої" - "Передати виклик" - "Щоб зателефонувати, вимкніть режим польоту." - "Не зареєстровано в мережі." - "Мобільна мережа недоступна." - "Щоб зателефонувати, введіть дійсний номер." - "Не вдається зателефонувати." - "Запуск ряду MMI…" - "Служба не підтримується." - "Неможливо переключитися між викликами." - "Неможливо розділити виклик." - "Неможливо перенести." - "Конференц-зв’язок недоступний." - "Неможливо відхилити виклик." - "Неможливо телефонувати." - "Виклик через протокол SIP" - "Екстрений виклик" - "Увімкнення радіо…" - "Немає зв’язку. Повторна спроба…" - "Не вдається зателефонувати. %s не є екстреним номером." - "Не вдається зателефонувати. Наберіть екстрений номер." - "Використовуйте для набору клавіатуру" - "Призупинити виклик" - "Відновити виклик" - "Завершити виклик" - "Показати цифрову клавіатуру" - "Сховати цифрову клавіатуру" - "Ігнорувати" - "Не ігнорувати" - "Додати виклик" - "Об’єднати виклики" - "Поміняти виклики" - "Керувати викликами" - "Керувати конференц-зв’язком" - "Конференц-зв’язок" - "Керувати" - "Аудіо" - "Відеодзвінок" - "Перейти в режим голосового виклику" - "Вибрати камеру" - "Увімкнути камеру" - "Вимкнути камеру" - "Інші опції" - "Програвач запущено" - "Програвач зупинено" - "Камера неготова" - "Камера готова" - "Невідомий сеанс виклику" - "Служба" - "Налаштування" - "<Не налаштовано>" - "Інші налаштування виклику" - "Виклик здійснюється через оператора %s" - "Вхідні виклики через оператора %s" - "фото контакта" - "приватна розмова" - "вибрати контакт" - "Напишіть власну відповідь…" - "Скасувати" - "Надіслати" - "Відповісти" - "Надіслати SMS" - "Відхилити" - "Відповісти в режимі відеодзвінка" - "Відповісти в режимі аудіодзвінка" - "Прийняти запит на відео" - "Відхилити запит на відео" - "Прийняти запит на передавання відео" - "Відхилити запит на передавання відео" - "Прийняти запит на отримання відео" - "Відхилити запит на отримання відео" - "Проведіть пальцем угору, щоб %s." - "Проведіть пальцем ліворуч, щоб %s." - "Проведіть пальцем праворуч, щоб %s." - "Проведіть пальцем донизу, щоб %s." - "Вібросигнал" - "Вібросигнал" - "Звук" - "Звук за умовчанням (%1$s)" - "Сигнал дзвінка телефона" - "Вібрувати під час виклику" - "Сигнал дзвінка та вібросигнал" - "Керування конференц-зв’язком" - "Екстрений номер" - "Фотографія профілю" - "Камеру вимкнено" - "на номер %s" - "Нотатку надіслано" - "Нещодавні повідомлення" - "Інформація про компанію" - "За %.1f мил." - "За %.1f км" - "%1$s, %2$s" - "%1$s%2$s" - "%1$s, %2$s" - "Відчиняється завтра о %s" - "Відчиняється сьогодні о %s" - "Зачиняється о %s" - "Зачинено сьогодні о %s" - "Відчинено" - "Зачинено" - "Може бути спамом" - "Дзвінок завершено %1$s" - "З цього номера вам телефонують уперше." - "Ми підозрюємо, що телефонував спамер." - "Заблокувати/це спам" - "Додати контакт" - "Не спам" - diff --git a/InCallUI/res/values-ur/strings.xml b/InCallUI/res/values-ur/strings.xml deleted file mode 100644 index 32e0d45aa..000000000 --- a/InCallUI/res/values-ur/strings.xml +++ /dev/null @@ -1,195 +0,0 @@ - - - - - "فون" - "ہولڈ پر ہے" - "نامعلوم" - "نجی نمبر" - "پے فون" - "کانفرنس کال" - "کال ختم ہو گئی" - "اسپیکر" - "ہینڈسیٹ ایئرپیس" - "تار والا ہیڈسیٹ" - "بلوٹوتھ" - "درج ذیل ٹونز بھیجیں؟\n" - "ٹونز بھیج رہا ہے\n" - "بھیجیں" - "ہاں" - "نہیں" - "وائلڈ کریکٹر کو اس کے ساتھ بدلیں" - "کانفرنس کال %s" - "صوتی میل نمبر" - "ڈائل ہو رہا ہے" - "دوبارہ ڈائل ہو رہا ہے" - "کانفرنس کال" - "آنے والی کال" - "کام سے متعلق آنے والی کال" - "کال ختم ہوگئی" - "ہولڈ پر ہے" - "کال منقطع ہو رہی ہے" - "کال میں" - "میرا نمبر ہے %s" - "ویڈیو منسلک ہو رہی ہے" - "ویڈیو کال" - "ویڈیو کی درخواست کی جا رہی ہے" - "ویڈیو کال منسلک نہیں ہو سکتی" - "ویڈیو کی درخواست مسترد ہو گئی" - "‏آپ کا کال بیک نمبر‎\n %1$s" - "‏آپ کا ہنگامی کال بیک نمبر‎\n %1$s" - "ڈائل ہو رہا ہے" - "چھوٹی ہوئی کال" - "چھوٹی ہوئی کالیں" - "%s چھوٹی ہوئی کالیں" - "%s کی جانب سے چھوٹی ہوئی کال" - "جاری کال" - "کام سے متعلق جاری کال" - "‏Wi-Fi کال جاری ہے" - "‏کام سے متعلق جاری Wi-Fi کال" - "ہولڈ پر ہے" - "آنے والی کال" - "کام سے متعلق آنے والی کال" - "‏آنے والی Wi-Fi کال" - "‏کام سے متعلق آنے والی Wi-Fi کال" - "آنے والی ویڈیو کال" - "آنے والی مشتبہ سپام کال" - "آنے والی ویڈیو کی درخواست" - "نیا صوتی میل" - "نیا صوتی میل (%d)" - "%s ڈائل کریں" - "صوتی میل نمبر نامعلوم ہے" - "کوئی سروس نہیں ہے" - "منتخب کردہ نیٹ ورک (%s) دستیاب نہیں ہے" - "جواب" - "کال منقطع کریں" - "ویڈیو" - "آواز" - "قبول کریں" - "برخاست کریں" - "واپس کال کریں" - "پیغام" - "ایک اور آلے پر جاری کال" - "کال منتقل کریں" - "کال کرنے کیلئے، پہلے ہوائی جہاز طرز کو آف کریں۔" - "نیٹ ورک پر رجسٹرڈ نہیں ہے۔" - "سیلولر نیٹ ورک دستیاب نہیں ہے۔" - "کال کرنے کیلئے، ایک درست نمبر درج کریں۔" - "کال نہیں ہو سکتی۔" - "‏MMI ترتیب شروع ہو رہی ہے…" - "سروس تعاون یافتہ نہیں ہے۔" - "کالز سوئچ نہیں ہو سکتیں۔" - "کال الگ نہیں ہو سکتی۔" - "منتقل نہیں ہو سکتی۔" - "کانفرنس نہیں ہو سکتی۔" - "کال مسترد نہیں ہو سکتی۔" - "کال(ز) ریلیز نہیں ہو سکتیں۔" - "‏SIP کال" - "ہنگامی کال" - "ریڈیو آن ہو رہا ہے…" - "کوئی سروس نہیں ہے۔ دوبارہ کوشش کی جا رہی ہے…" - "کال نہیں کی جا سکتی۔ %s ایک ہنگامی نمبر نہیں ہے۔" - "کال نہیں کی جا سکتی۔ ایک ہنگامی نمبر ڈائل کریں۔" - "ڈائل کرنے کیلئے کی بورڈ استعمال کریں" - "کال کو ہولڈ کریں" - "کال کو دوبارہ شروع کریں" - "کال ختم کریں" - "ڈائل پیڈ دکھائیں" - "ڈائل پیڈ چھپائیں" - "خاموش کریں" - "آواز چالو کریں" - "کال شامل کریں" - "کالز کو ضم کریں" - "تبادلہ کریں" - "کالز کا نظم کریں" - "کانفرنس کال کا نظم کریں" - "کانفرنس کال" - "نظم کریں" - "آڈیو" - "ویڈیو کال" - "صوتی کال میں تبدیل کریں" - "کیمرا سوئچ کریں" - "کیمرا آن کریں" - "کیمرا آف کریں" - "مزید اختیارات" - "پلیئر شروع ہوگیا" - "پلیئر بند ہوگیا" - "کیمرا تیار نہیں ہے" - "کیمرا تیار ہے" - "نامعلوم کال سیشن ایونٹ" - "سروس" - "ترتیب دیں" - "‏‎<سیٹ نہیں ہے>‎" - "کال کی دیگر ترتیبات" - "کالنگ بذریعہ %s" - "%s کے ذریعے آنے والی" - "رابطہ کی تصویر" - "نجی ہوجائیں" - "رابطہ منتخب کریں" - "اپنا ذاتی تحریر کریں…" - "منسوخ کریں" - "بھیجیں" - "جواب دیں" - "‏SMS بھیجیں" - "مسترد کریں" - "ویڈیو کال کے بطور جواب دیں" - "آڈیو کال کے بطور جواب دیں" - "ویڈیو کی درخواست قبول کریں" - "ویڈیو کی درخواست مسترد کریں" - "ویڈیو منتقل کرنے کی درخواست قبول کریں" - "ویڈیو منتقل کرنے کی درخواست مسترد کریں" - "ویڈیو موصول کرنے کی درخواست قبول کریں" - "ویڈیو موصول کرنے کی درخواست مسترد کریں" - "%s کیلئے اوپر سلائیڈ کریں۔" - "%s کیلئے بائیں سلائیڈ کریں۔" - "%s کیلئے دائیں سلائیڈ کریں۔" - "%s کیلئے نیچے سلائیڈ کریں۔" - "ارتعاش" - "ارتعاش" - "آواز" - "ڈیفالٹ آواز (%1$s)" - "فون رِنگ ٹون" - "رِنگ کے وقت مرتعش کریں" - "رنگ ٹون اور ارتعاش" - "کانفرنس کال کا نظم کریں" - "ہنگامی نمبر" - "پروفائل کی تصویر" - "کیمرا آف ہے" - "بذریعہ %s" - "نوٹ بھیج دیا گیا" - "حالیہ پیغامات" - "کاروباری معلومات" - "%.1f میل دور" - "%.1f کلومیٹر دور" - "%1$s، %2$s" - "%1$s - %2$s" - "%1$s، %2$s" - "کل %s بجے کھلے گا" - "آج %s بجے کھلے گا" - "%s بجے بند ہوگا" - "آج %s بجے بند ہوا" - "ابھی کھلا ہے" - "اب بند ہے" - "مشتبہ سپام کالر" - "‏کال ختم ہو گئی ‎%1$s" - "اس نمبر سے پہلی بار آپ کو کال آئی ہے۔" - "ہمیں شک ہے کہ یہ کال سپامر تھی۔" - "مسدود کریں/سپام کی اطلاع دیں" - "رابطہ شامل کریں" - "سپام نہیں ہے" - diff --git a/InCallUI/res/values-uz/strings.xml b/InCallUI/res/values-uz/strings.xml deleted file mode 100644 index 15d534d25..000000000 --- a/InCallUI/res/values-uz/strings.xml +++ /dev/null @@ -1,195 +0,0 @@ - - - - - "Telefon" - "Kutilmoqda" - "Noma’lum" - "Maxfiy raqam" - "Taksofon" - "Konferens-aloqa" - "Chaqiruv uzilib qoldi" - "Karnay" - "Telefon quloqchini" - "Simli garnitura" - "Bluetooth" - "Quyidagi tovush signallari yuborilsinmi?\n" - "Tovush signallari yuborilmoqda\n" - "Yuborish" - "Ha" - "Yo‘q" - "Universal belgini bunga almashtirish" - "Konferens-aloqa: %s" - "Ovozli pochta raqami" - "Chaqiruv" - "Qayta terilmoqda" - "Konferens-aloqa" - "Kiruvchi qo‘ng‘iroq" - "Kiruvchi qo‘ng‘iroq (ish)" - "Chaqiruv tugadi" - "Kutilmoqda" - "Suhbat tugatilmoqda" - "Suhbat" - "Mening raqamim – %s" - "Videoga ulanmoqda" - "Video qo‘ng‘iroq" - "Video so‘ralmoqda" - "Video qo‘ng‘iroqqa ulanib bo‘lmadi" - "Video qo‘ng‘iroq so‘rovi rad etildi" - "Teskari qo‘ng‘iroq raqamingiz\n %1$s" - "Favqulodda holatlar uchun teskari qo‘ng‘iroq raqamingiz\n %1$s" - "Chaqiruv" - "Javobsiz qo‘ng‘iroq" - "Javobsiz qo‘ng‘iroqlar" - "%s ta javobsiz qo‘ng‘iroq" - "%s qo‘ng‘irog‘i javobsiz qoldirildi" - "Joriy qo‘ng‘iroq" - "Joriy qo‘ng‘iroq (ish)" - "Joriy Wi-Fi qo‘ng‘iroq" - "Joriy Wi-Fi qo‘ng‘iroq (ish)" - "Kutilmoqda" - "Kiruvchi qo‘ng‘iroq" - "Kiruvchi qo‘ng‘iroq (ish)" - "Kiruvchi Wi-Fi qo‘ng‘iroq" - "Kiruvchi Wi-Fi qo‘ng‘iroq (ish)" - "Kiruvchi video qo‘ng‘iroq" - "Shubhali kiruvchi qo‘ng‘iroq" - "Kiruvchi video qo‘ng‘iroq" - "Yangi ovozli xabar" - "Yangi ovozli xabar (%d)" - "%s raqamini terish" - "Ovozli pochta raqami noma’lum" - "Xizmat mavjud emas" - "Tanlangan tarmoq (%s) mavjud emas" - "Javob berish" - "Tugatish" - "Video aloqa" - "Ovozli aloqa" - "Qabul qilish" - "Rad etish" - "Telefon qilish" - "SMS yuborish" - "Boshqa qurilmada hozir qo‘ng‘iroq amalga oshirilmoqda." - "Qo‘ng‘iroqni o‘tkazish" - "Parvoz rejimini o‘chirib qo‘ying." - "Tarmoqda ro‘yxatdan o‘tmagan." - "Uyali tarmoq mavjud emas." - "Raqam noto‘g‘ri." - "Qo‘ng‘iroq qilib bo‘lmadi." - "MMI tartibi ishga tushmoqda…" - "Xizmat qo‘llab-quvvatlanmaydi." - "Qo‘ng‘iroqlarni almashtirib bo‘lmadi." - "Qo‘ng‘iroqni ajratib bo‘lmadi." - "O‘tkazib bo‘lmadi." - "Konferens-aloqa o‘rnatib bo‘lmadi." - "Qo‘ng‘iroqni rad qilib bo‘lmadi." - "Qo‘ng‘iroq(lar)ni chiqarib bo‘lmadi." - "SIP qo‘ng‘iroq" - "Favqulodda chaqiruv" - "Radio yoqilmoqda…" - "Aloqa yo‘q. Qayta urinilmoqda…" - "Qo‘ng‘iroq qilib bo‘lmadi. %s favqulodda raqam emas." - "Qo‘ng‘iroq qilib bo‘lmadi. Favqulodda raqamga tering." - "Terish uchun klaviaturadan foydalaning" - "Qo‘ng‘iroqni ushlab turish" - "Qo‘ng‘iroqni davom ettirish" - "Chaqiruvni tugatish" - "Raqam terish panelini ochish" - "Raqam terish panelini yopish" - "Ovozni o‘chirish" - "Ovozni yoqish" - "Chaqiruv qo‘shish" - "Qo‘ng‘iroqlarni birlashtirish" - "Almashtirish" - "Qo‘ng‘iroqlarni boshqarish" - "Konferens-aloqani sozlash" - "Konferens-aloqa" - "Boshqarish" - "Audio" - "Video qo‘ng‘iroq" - "Ovozli qo‘ng‘iroqqa o‘zgartirish" - "Kamerani almashtirish" - "Kamerani yoqish" - "Kamerani o‘chirish" - "Boshqa sozlamalar" - "Pleyer ishga tushirildi" - "Pleyer to‘xtatildi" - "Kamera tayyor emas" - "Kamera tayyor" - "Aloqa seansining noma’lum hodisasi" - "Xizmat" - "Sozlash" - "<Ko‘rsatilmagan>" - "Boshqa qo‘ng‘iroq sozlamalari" - "%s orqali qo‘ng‘rioq qilinmoqda" - "%s orqali kiruvchi qo‘ng‘iroqlar" - "kontakt rasmi" - "alohida suhbatga o‘tish" - "kontaktni tanlash" - "O‘z javobingizni yozing…" - "Bekor qilish" - "Yuborish" - "Javob berish" - "SMS yuborish" - "Rad etish" - "Video qo‘ng‘iroqqa javob berish" - "Ovozli qo‘ng‘iroqqa javob berish" - "Video qo‘ng‘iroq so‘rovini qabul qilish" - "Video qo‘ng‘iroq so‘rovini rad etish" - "Video uzatishga ruxsat berish" - "Video uzatishga ruxsat bermaslik" - "Kiruvchi video qo‘ng‘iroqni qabul qilish" - "Kiruvchi video qo‘ng‘iroqni rad etish" - "%s uchun tepaga suring." - "%s uchun chapga suring." - "%s uchun o‘ngga suring." - "%s uchun pastga suring." - "Tebranish" - "Tebranish" - "Ovoz" - "Standart ovoz (%1$s)" - "Telefon ringtoni" - "Jiringlash vaqtida tebranish" - "Qo‘ng‘iroq ohangi va tebranish" - "Konferens-aloqani sozlash" - "Favqulodda qo‘ng‘iroq raqami" - "Profil rasmi" - "Kamera o‘chiq" - "%s orqali" - "Xabar yuborildi" - "So‘nggi xabarlar" - "Kompaniya haqida ma’lumot" - "%.1f mil masofada" - "%.1f km masofada" - "%1$s, %2$s" - "%1$s%2$s" - "%1$s, %2$s" - "Ertaga %s da ochiladi" - "Bugun %s da ochiladi" - "%s da yopiladi" - "Bugun %s da yopiladi" - "Ochiq" - "Yopiq" - "Shubhali abonent" - "Qo‘ng‘iroq yakunlandi (%1$s)" - "Sizga bu raqamdan birinchi marta qo‘ng‘iroq qilishdi." - "Bu spam-qo‘ng‘iroqqa o‘xshayapti." - "Bloklash/spamga" - "Kontaktni qo‘shish" - "Spam emas" - diff --git a/InCallUI/res/values-vi/strings.xml b/InCallUI/res/values-vi/strings.xml deleted file mode 100644 index 58a50c278..000000000 --- a/InCallUI/res/values-vi/strings.xml +++ /dev/null @@ -1,195 +0,0 @@ - - - - - "Điện thoại" - "Đang chờ" - "Không xác định" - "Số cá nhân" - "Điện thoại trả tiền" - "Cuộc gọi nhiều bên" - "Cuộc gọi bị gián đoạn" - "Loa" - "Tai nghe ĐTDĐ" - "Tai nghe có dây" - "Bluetooth" - "Gửi các âm sau?\n" - "Đang gửi âm\n" - "Gửi" - "Có" - "Không" - "Thay thế ký tự tự do bằng" - "Cuộc gọi nhiều bên %s" - "Số thư thoại" - "Đang gọi" - "Đang quay số lại" - "Cuộc gọi nhiều bên" - "Cuộc gọi đến" - "Cuộc gọi đến về công việc" - "Cuộc gọi đã kết thúc" - "Đang chờ" - "Kết thúc cuộc gọi" - "Trong cuộc gọi" - "Số điện thoại của tôi là %s" - "Đang kết nối video" - "Cuộc gọi điện video" - "Đang yêu cầu video" - "Không kết nối được cuộc gọi điện video" - "Đã từ chối yêu cầu video" - "Số gọi lại của bạn\n %1$s" - "Số gọi lại khẩn cấp của bạn\n %1$s" - "Đang gọi" - "Cuộc gọi nhỡ" - "Cuộc gọi nhỡ" - "%s cuộc gọi nhỡ" - "Cuộc gọi nhỡ từ %s" - "Cuộc gọi đang thực hiện" - "Cuộc gọi đang diễn ra về công việc" - "Cuộc gọi đang diễn ra qua Wi-Fi" - "Cuộc gọi đang diễn ra qua Wi-Fi về công việc" - "Đang chờ" - "Cuộc gọi đến" - "Cuộc gọi đến về công việc" - "Cuộc gọi đến qua Wi-Fi" - "Cuộc gọi đến qua Wi-Fi về công việc" - "Cuộc gọi điện video đến" - "Cuộc gọi spam đến bị nghi ngờ" - "Yêu cầu video đến" - "Thư thoại mới" - "Thư thoại mới (%d)" - "Quay số %s" - "Số thư thoại không xác định" - "Không có dịch vụ" - "Mạng được chọn (%s) không khả dụng" - "Trả lời" - "Gác máy" - "Video" - "Thoại" - "Chấp nhận" - "Loại bỏ" - "Gọi lại" - "Tin nhắn" - "Cuộc gọi đang diễn ra trên một thiết bị khác" - "Chuyển cuộc gọi" - "Để thực hiện cuộc gọi, trước tiên, hãy tắt chế độ trên Máy bay." - "Chưa được đăng ký trên mạng." - "Không có mạng di động." - "Để thực hiện cuộc gọi, hãy nhập một số hợp lệ." - "Không thực hiện được cuộc gọi." - "Đang khởi động chuỗi MMI…" - "Dịch vụ không được hỗ trợ." - "Không chuyển đổi được cuộc gọi." - "Không tách được cuộc gọi." - "Không chuyển được cuộc gọi." - "Không thực hiện được cuộc gọi nhiều bên." - "Không từ chối được cuộc gọi." - "Không thực hiện được cuộc gọi." - "Cuộc gọi qua SIP" - "Cuộc gọi khẩn cấp" - "Đang bật radio..." - "Không có dịch vụ nào. Đang thử lại…" - "Không thực hiện được cuộc gọi. %s không phải là số khẩn cấp." - "Không thực hiện được cuộc gọi. Hãy quay số khẩn cấp." - "Sử dụng bàn phím để quay số" - "Giữ cuộc gọi" - "Tiếp tục cuộc gọi" - "Kết thúc cuộc gọi" - "Hiển thị bàn phím số" - "Ẩn bàn phím số" - "Tắt tiếng" - "Bật tiếng" - "Thêm cuộc gọi" - "Hợp nhất cuộc gọi" - "Hoán đổi" - "Quản lý cuộc gọi" - "Quản lý cuộc gọi nhiều bên" - "Cuộc gọi nhiều bên" - "Quản lý" - "Âm thanh" - "Cuộc gọi điện video" - "Thay đổi thành cuộc gọi thoại" - "Chuyển máy ảnh" - "Bật máy ảnh" - "Tắt máy ảnh" - "Tùy chọn khác" - "Đã khởi động trình phát" - "Đã dừng trình phát" - "Máy ảnh chưa sẵn sàng" - "Máy ảnh đã sẵn sàng" - "Sự kiện phiên cuộc gọi không xác định" - "Dịch vụ" - "Thiết lập" - "<Chưa được đặt>" - "Cài đặt cuộc gọi khác" - "Gọi điện qua %s" - "Cuộc gọi đến qua %s" - "ảnh liên hệ" - "chuyển thành riêng tư" - "chọn địa chỉ liên hệ" - "Viết trả lời của riêng bạn..." - "Hủy" - "Gửi" - "Trả lời" - "Gửi SMS" - "Từ chối" - "Trả lời là cuộc gọi điện video" - "Trả lời là cuộc gọi âm thanh" - "Chấp nhận yêu cầu cuộc gọi video" - "Từ chối yêu cầu cuộc gọi video" - "Chấp nhận yêu cầu truyền video" - "Từ chối yêu cầu truyền video" - "Chấp nhận yêu cầu nhận video" - "Từ chối yêu cầu nhận video" - "Trượt lên để %s." - "Trượt sang trái để %s." - "Trượt sang phải để %s." - "Trượt xuống để %s." - "Rung" - "Rung" - "Âm thanh" - "Âm thanh mặc định (%1$s)" - "Nhạc chuông điện thoại" - "Rung khi đổ chuông" - "Nhạc chuông và rung" - "Quản lý cuộc gọi nhiều bên" - "Số khẩn cấp" - "Ảnh hồ sơ" - "Tắt máy ảnh" - "qua %s" - "Đã gửi ghi chú" - "Tin nhắn gần đây" - "Thông tin doanh nghiệp" - "Cách %.1f dặm" - "Cách %.1f km" - "%1$s, %2$s" - "%1$s - %2$s" - "%1$s, %2$s" - "Mở cửa lúc %s ngày mai" - "Mở cửa lúc %s hôm nay" - "Đóng cửa lúc %s" - "Đã đóng cửa lúc %s hôm nay" - "Mở ngay bây giờ" - "Hiện đã đóng cửa" - "Người gọi spam bị nghi ngờ" - "Đã kết thúc cuộc gọi %1$s" - "Đây là lần đầu tiên số điện thoại này gọi điện cho bạn." - "Chúng tôi đã nghi ngờ cuộc gọi này là người gửi spam." - "Chặn/báo cáo spam" - "Thêm liên hệ" - "Không phải là spam" - diff --git a/InCallUI/res/values-w500dp-land/colors.xml b/InCallUI/res/values-w500dp-land/colors.xml deleted file mode 100644 index 77eea2e68..000000000 --- a/InCallUI/res/values-w500dp-land/colors.xml +++ /dev/null @@ -1,21 +0,0 @@ - - - - - - #000000 - diff --git a/InCallUI/res/values-w500dp-land/dimens.xml b/InCallUI/res/values-w500dp-land/dimens.xml deleted file mode 100644 index 112ec5f09..000000000 --- a/InCallUI/res/values-w500dp-land/dimens.xml +++ /dev/null @@ -1,35 +0,0 @@ - - - - - - true - - - true - - - 40dp - - - 30dp - - 2dp - - 20dp - diff --git a/InCallUI/res/values-zh-rCN/strings.xml b/InCallUI/res/values-zh-rCN/strings.xml deleted file mode 100644 index f9c43764d..000000000 --- a/InCallUI/res/values-zh-rCN/strings.xml +++ /dev/null @@ -1,195 +0,0 @@ - - - - - "电话" - "保持" - "未知" - "私密号码" - "公用电话" - "电话会议" - "通话中断" - "扬声器" - "手机听筒" - "有线耳机" - "蓝牙" - "发送以下信号音?\n" - "正在发送信号音\n" - "发送" - "是" - "否" - "将通配符替换为" - "电话会议(%s)" - "语音信箱号码" - "正在拨号" - "正在重拨" - "电话会议" - "来电" - "工作来电" - "通话已结束" - "保持" - "正在挂断" - "正在通话" - "我的电话号码:%s" - "正在接通视频" - "视频通话" - "正在发出视频请求" - "无法接通视频通话" - "视频请求遭拒" - "您的回拨号码如下:\n%1$s" - "您的紧急回拨号码如下:\n%1$s" - "正在拨号" - "未接电话" - "未接电话" - "%s 个未接电话" - "来自%s的未接电话" - "通话进行中" - "工作通话进行中" - "WLAN 通话进行中" - "WLAN 工作通话进行中" - "保持" - "来电" - "工作来电" - "WLAN 来电" - "WLAN 工作来电" - "视频通话来电" - "有疑似骚扰来电" - "收到视频通话请求" - "新语音邮件" - "新语音邮件 (%d)" - "拨打 %s" - "语音信箱号码未知" - "没有服务" - "所选网络(%s)不可用" - "接听" - "挂断" - "视频" - "语音" - "接受" - "拒绝" - "回电" - "发短信" - "其他设备上有正在进行的通话" - "转接通话" - "要拨打电话,请先关闭飞行模式。" - "尚未注册网络。" - "无法连接到移动网络。" - "要拨打电话,请输入有效的电话号码。" - "无法拨打该电话。" - "正在启动 MMI 序列…" - "服务不受支持。" - "无法切换通话。" - "无法单独通话。" - "无法转移呼叫。" - "无法进行电话会议。" - "无法拒接来电。" - "无法挂断。" - "SIP 通话" - "紧急呼救" - "正在开启无线装置…" - "找不到服务信号,正在重试…" - "无法拨打该电话。%s 不是紧急呼救号码。" - "无法拨打该电话。请拨打紧急呼救号码。" - "使用键盘拨号" - "保持通话" - "恢复通话" - "结束通话" - "显示拨号键盘" - "隐藏拨号键盘" - "静音" - "取消静音" - "添加通话" - "合并通话" - "切换" - "管理通话" - "管理电话会议" - "电话会议" - "管理" - "音频" - "视频通话" - "改为语音通话" - "切换摄像头" - "开启摄像头" - "关闭摄像头" - "更多选项" - "播放器已启动" - "播放器已停止" - "摄像头尚未准备就绪" - "摄像头已准备就绪" - "未知通话事件" - "服务" - "设置" - "<未设置>" - "其他通话设置" - "正在通过%s进行通话" - "有人通过%s来电" - "联系人照片" - "单独通话" - "选择联系人" - "自行撰写回复…" - "取消" - "发送" - "接听" - "发送短信" - "拒绝" - "以视频通话的形式接听" - "以音频通话的形式接听" - "接受视频请求" - "拒绝视频请求" - "接受视频传输请求" - "拒绝视频传输请求" - "接受视频接收请求" - "拒绝视频接收请求" - "向上滑动即可%s。" - "向左滑动即可%s。" - "向右滑动即可%s。" - "向下滑动即可%s。" - "振动" - "振动" - "提示音" - "默认提示音(%1$s)" - "手机铃声" - "响铃时振动" - "铃声和振动" - "管理电话会议" - "紧急呼救号码" - "个人资料照片" - "摄像头已关闭" - "通过 %s" - "已发送备注" - "最近的信息" - "商家信息" - "%.1f 英里远" - "%.1f 公里远" - "%2$s%1$s" - "%1$s - %2$s" - "%1$s%2$s" - "将于明天%s开始营业" - "将于今天%s开始营业" - "将于%s结束营业" - "已于今天%s结束营业" - "营业中" - "现已结束营业" - "疑似骚扰电话号码" - "通话已结束 %1$s" - "这是此号码的第一次来电。" - "我们怀疑这是骚扰电话。" - "屏蔽/举报骚扰电话号码" - "添加联系人" - "非骚扰电话号码" - diff --git a/InCallUI/res/values-zh-rHK/strings.xml b/InCallUI/res/values-zh-rHK/strings.xml deleted file mode 100644 index bf6f016cb..000000000 --- a/InCallUI/res/values-zh-rHK/strings.xml +++ /dev/null @@ -1,195 +0,0 @@ - - - - - "電話" - "保留通話" - "不明" - "私人號碼" - "公共電話" - "會議通話" - "通話已中斷" - "喇叭" - "免提聽筒" - "有線耳機" - "藍牙" - "要傳送以下訊號音嗎?\n" - "正在傳送訊號音\n" - "傳送" - "是" - "否" - "將萬用字元改為" - "會議通話:%s" - "留言號碼" - "正在撥號" - "正在重撥" - "會議通話" - "來電" - "工作來電" - "通話已結束" - "保留通話" - "正在掛斷電話" - "正在通話" - "我的電話號碼:%s" - "正在建立視像通話連線" - "視像通話" - "正在提出視像通話要求" - "無法建立視像通話連線" - "視像通話要求被拒" - "您的回撥號碼:\n%1$s" - "您的緊急回撥號碼:\n%1$s" - "正在撥號" - "未接來電" - "未接來電" - "%s 個未接來電" - "來自 %s 的未接來電" - "通話中" - "正在進行工作通話" - "正在進行 Wi-Fi 通話" - "正在進行 Wi-Fi 工作通話" - "保留通話" - "來電" - "工作來電" - "Wi-Fi 來電" - "Wi-Fi 工作來電" - "視像通話來電" - "疑似收到垃圾來電" - "收到視像通話要求" - "新留言" - "新留言 (%d 個)" - "撥打 %s" - "留言號碼不明" - "沒有服務" - "您選取的網絡 (%s) 無法使用" - "接聽" - "掛斷電話" - "視像通話" - "語音通話" - "接受" - "拒絕" - "回電" - "短訊" - "其他裝置上有正在進行的通話" - "轉接來電" - "如要撥打電話,請先關閉飛行模式。" - "未在網絡上註冊。" - "無法連線至流動網絡。" - "如要撥打電話,請輸入有效的號碼。" - "無法通話。" - "開始 MMI 序列…" - "不支援此服務。" - "無法切換通話。" - "無法分開通話。" - "無法轉接。" - "無法進行會議通話。" - "無法拒接來電。" - "無法結束通話。" - "SIP 通話" - "緊急電話" - "正在開啟無線電…" - "找不到服務,請再試一次…" - "無法通話。%s 不是緊急電話號碼。" - "無法通話。請撥打緊急電話號碼。" - "使用鍵盤撥號" - "保留通話" - "恢復通話" - "結束通話" - "顯示撥號鍵盤" - "隱藏撥號鍵盤" - "略過" - "取消靜音" - "新增通話" - "合併通話" - "切換" - "管理通話" - "管理會議通話" - "會議通話" - "管理" - "音訊" - "視像通話" - "變更為語音通話" - "切換鏡頭" - "開啟攝影機" - "關閉攝影機" - "更多選項" - "已啟動播放器" - "已停止播放器" - "相機未準備好" - "相機已準備就緒" - "不明的通話工作階段活動" - "服務" - "設定" - "<未設定>" - "其他通話設定" - "正在透過 %s 撥號" - "有人透過 %s 來電" - "聯絡人相片" - "私人通話" - "選取聯絡人" - "自行撰寫回覆..." - "取消" - "傳送" - "接聽" - "傳送短訊" - "拒絕" - "接聽視像通話" - "接聽語音通話" - "接受視像通話要求" - "拒絕視像通話要求" - "接受視像通話轉駁要求" - "拒絕視像通話轉駁要求" - "接受視像接收要求" - "拒絕視像接收要求" - "向上滑動即可%s。" - "向左滑動即可%s。" - "向右滑動即可%s。" - "向下滑動即可%s。" - "震動" - "震動" - "音效" - "預設音效 (%1$s)" - "手機鈴聲" - "響鈴時震動" - "鈴聲和震動" - "管理會議通話" - "緊急電話號碼" - "個人檔案相片" - "相機已關閉" - "透過 %s" - "已傳送筆記" - "最近的訊息" - "公司資料" - "%.1f 英里外" - "%.1f 公里外" - "%2$s%1$s" - "%1$s - %2$s" - "%1$s%2$s" - "將於明天%s開始營業" - "將於今天%s開始營業" - "將於%s關門" - "已於今天%s關門" - "營業中" - "目前休息" - "疑似垃圾來電者" - "通話結束 %1$s" - "這是此號碼的第一次來電。" - "我們懷疑此來電為垃圾來電。" - "封鎖/舉報為垃圾來電" - "新增聯絡人" - "非垃圾來電" - diff --git a/InCallUI/res/values-zh-rTW/strings.xml b/InCallUI/res/values-zh-rTW/strings.xml deleted file mode 100644 index e316c7d40..000000000 --- a/InCallUI/res/values-zh-rTW/strings.xml +++ /dev/null @@ -1,195 +0,0 @@ - - - - - "電話" - "保留" - "不明" - "私人號碼" - "公用電話" - "電話會議" - "通話已中斷" - "喇叭" - "手機聽筒" - "有線耳機" - "藍牙" - "要傳送以下的信號音嗎?\n" - "正在傳送信號音\n" - "傳送" - "是" - "否" - "將萬用字元替換為" - "電話會議 %s" - "語音留言號碼" - "撥號中" - "重撥中" - "電話會議" - "來電" - "公司來電" - "通話已結束" - "保留" - "掛斷中" - "通話中" - "我的電話號碼:%s" - "正在建立視訊通話連線" - "視訊通話" - "正在提出視訊通話要求" - "無法建立視訊通話連線" - "視訊通話要求遭拒" - "您的回撥號碼如下\n %1$s" - "您的緊急回撥號碼如下\n %1$s" - "撥號中" - "未接來電" - "未接來電" - "%s 通未接來電" - "來自 %s 的未接來電" - "進行中的通話" - "進行中的公司通話" - "進行中的通話 (透過 Wi-Fi)" - "進行中的公司通話 (透過 Wi-Fi)" - "保留" - "來電" - "公司來電" - "來電 (透過 Wi-Fi)" - "公司來電 (透過 Wi-Fi)" - "視訊通話來電" - "可疑的騷擾/廣告來電" - "收到視訊通話要求" - "新的語音留言" - "新的語音留言 (%d)" - "撥打 %s" - "語音留言號碼不明" - "沒有服務" - "您所選取的網路 (%s) 無法使用" - "接聽" - "掛斷" - "視訊通話" - "語音通話" - "接受" - "拒絕" - "回撥" - "傳送簡訊" - "其他裝置上有進行中的通話" - "轉接來電" - "撥號前,請先關閉飛航模式。" - "尚未註冊網路。" - "無法連線到行動網路。" - "如要撥打電話,請輸入有效的號碼。" - "無法通話。" - "開始 MMI 序列…" - "不支援的服務。" - "無法切換通話。" - "無法分割通話。" - "無法轉接。" - "無法進行電話會議。" - "無法拒接來電。" - "無法掛斷電話。" - "SIP 通話" - "緊急電話" - "正在開啟無線通訊…" - "找不到服務訊號,重試中…" - "無法通話。%s 不是緊急電話號碼。" - "無法通話。只能撥打緊急號碼。" - "使用鍵盤撥號" - "保留通話" - "恢復通話" - "結束通話" - "顯示撥號鍵盤" - "隱藏撥號鍵盤" - "忽略" - "取消忽略" - "新增通話" - "合併通話" - "切換" - "管理通話" - "管理電話會議" - "電話會議" - "管理" - "音訊" - "視訊通話" - "變更為語音通話" - "切換鏡頭" - "開啟攝影機" - "關閉攝影機" - "更多選項" - "已啟動播放器" - "已停止播放器" - "相機尚未就緒" - "相機已準備就緒" - "不明的通話工作階段事件" - "服務" - "設定" - "<未設定>" - "其他通話設定" - "正在透過 %s 撥號" - "有人透過 %s 來電" - "聯絡人相片" - "私人通話" - "選取聯絡人" - "自行撰寫回應…" - "取消" - "傳送" - "接聽" - "傳送簡訊" - "拒絕" - "接聽視訊通話" - "接聽語音通話" - "接受視訊通話要求" - "拒絕視訊通話要求" - "接受視訊傳送要求" - "拒絕視訊傳送要求" - "接受視訊接收要求" - "拒絕視訊接收要求" - "向上滑動即可%s。" - "向左滑動即可%s。" - "向右滑動即可%s。" - "向下滑動即可%s。" - "震動" - "震動" - "音效" - "預設音效 (%1$s)" - "手機鈴聲" - "鈴響時震動" - "鈴聲與震動" - "管理電話會議" - "緊急電話號碼" - "個人資料相片" - "相機已停用" - "透過 %s" - "備註已送出" - "最近的訊息" - "商家資訊" - "%.1f 英里遠" - "%.1f 公里遠" - "%2$s%1$s" - "%1$s - %2$s" - "%1$s%2$s" - "將於明日%s開始營業" - "將於本日%s開始營業" - "將於%s結束營業" - "已於本日%s結束營業" - "營業中" - "本日已結束營業" - "可疑的騷擾/廣告來電者" - "通話結束 %1$s" - "這組號碼首次致電給您。" - "我們懷疑這通來電是騷擾/廣告電話。" - "封鎖/回報為騷擾/廣告電話" - "新增聯絡人" - "非騷擾/廣告電話" - diff --git a/InCallUI/res/values-zu/strings.xml b/InCallUI/res/values-zu/strings.xml deleted file mode 100644 index 46bf5afbb..000000000 --- a/InCallUI/res/values-zu/strings.xml +++ /dev/null @@ -1,195 +0,0 @@ - - - - - "Ifoni" - "Ibanjiwe" - "Akwaziwa" - "Inombolo eyimfihlo" - "Ucingo olufakwa imali" - "Ikholi yenkomfa" - "Ikholi ivaliwe" - "Isipikha" - "Isipikha sendlebe sama-ear phone" - "Ama-earphone anezintambo" - "I-Bluetooth" - "Thumela amathoni alandelayo?\n" - "Ithumela amathoni\n" - "Thumela" - "Yebo" - "Cha" - "Miselela uhlamvu lwasendle nge" - "Ikholi yenkomfa engu-%s" - "Inombolo yevoyisimeyili" - "Iyadayela" - "Iphinda iyadayela" - "Ikholi yenkomfa" - "Ikholi engenayo" - "Ikholi engenayo yomsebenzi" - "Ikholi iqediwe" - "Ibanjiwe" - "Iyavala" - "Ukukholi" - "Inombolo yami ngu-%s" - "Ixhuma ividiyo" - "Ikholi yevidiyo" - "Icela ividiyo" - "Ayikwazi ukuxhuma ikholi yevidiyo" - "Isicelo sevidiyo sinqatshelwe" - "Inombolo yakho yokuphinda ushaye\n%1$s" - "Inombolo yakho yokuphinda ushayelwe yesimo esiphuthumayo\n%1$s" - "Iyadayela" - "Ikholi ephuthelwe" - "Amakholi akuphuthele" - "%s amakholi akulahlekele" - "Uphuthelwe ikholi kusukela ku-%s" - "Ikholi eqhubekayo" - "Ikholi yomsebenzi eqhubekayo" - "Ikholi ye-Wi-Fi eqhubekayo" - "Ikholi yomsebenzi eqhubekayo ye-Wi-Fi" - "Ibanjiwe" - "Ikholi engenayo" - "Ikholi engenayo yomsebenzi" - "Ikholi ye-Wi-Fi engenayo" - "Ikholi engenayo yomsebenzi ye-Wi-Fi" - "Ikholi yevidiyo engenayo" - "Ikholi engenayo osolisayo kagaxekile" - "Isicelo sevidiyo engenayo" - "Ivoyisimeyili entsha" - "Ivoyisimeyili entsha (%d)" - "Dayela u-%s" - "Inombolo yevoyisimeyili ayaziwa" - "Ayikho isevisi" - "Inethiwekhi ekhethiwe (%s) ayitholakali" - "Phendula" - "Vala ikholi" - "Ividiyo" - "Izwi" - "Yamukela" - "Cashisa" - "Phinda ushayele" - "Umlayezo" - "Ikholi eqhubekayo kwenye idivayisi" - "Dlulisela ikholi" - "Ukwenza ikholi, vala kuqala imodi Yendiza." - "Ayibhalisiwe kwinethiwekhi." - "Inethiwekhi yeselula ayitholakali." - "Ukuze wenze ikholi, faka inombolo evumelekile." - "Ayikwazi ukushaya." - "Iqalisa ukulandelana kwe-MMI..." - "Isevisi ayisekelwe." - "Ayikwazi ukushintsha amakholi." - "Ayikwazi ukuhlukanisa ikholi." - "Ayikwazi ukudlulisela." - "Ayikwazi ukwenza inkomfa." - "Ayikwazi ukunqabela ikholi." - "Ayikwazi ukukhipha amakholi." - "Ikholi ye-SIP" - "Ikholi ephuthumayo" - "Ivula irediyo..." - "Ayikho isevisi. Iyazama futhi…" - "Ayikwazi ukushaya. U-%s akuyona inombolo yesimo esiphuthumayo." - "Ayikwazi ukushaya. Shayela inombolo yesimo esiphuthumayo." - "Sebenzisa ikhibhodi ukudayela" - "Bamba ikholi" - "Qalisa kabusha ikholi" - "Qeda ikholi" - "Bonisa iphedi yokudayela" - "Fihla iphedi yokudayela" - "Thulisa" - "Susa ukuthula" - "Engeza ikholi" - "Hlanganisa amakholi" - "Shintsha" - "Phatha amakholi" - "Phatha ucingo lwengqungquthela" - "Ikholi yenkomfa" - "Phatha" - "Umsindo" - "Ikholi yevidiyo" - "Shintshela kukholi yezwi" - "Shintsha Ikhamera" - "Vula ikhamera" - "Vala ikhamera" - "Izinketho eziningi" - "Umdlali uqalile" - "Umdlali umisiwe" - "Ikhamera ayilungile" - "Ikhamera ilungile" - "Umcimbi wesikhathi sekholi ongaziwa" - "Isevisi" - "Ukusetha" - "<Ayisethiwe>" - "Ezinye izilungiselelo zekholi" - "Ishaya nge-%s" - "Ingena nge-%s" - "isithombe soxhumana naye" - "yenza kube imfihlo" - "khetha othintana naye" - "Bhala okwakho…" - "Khansela" - "Thumela" - "Phendula" - "Thumela i-SMS" - "Yenqaba" - "Phendula njengekholi yevidiyo" - "Phendula njengekholi yomsindo" - "Yamukela isicelo sevidiyo" - "Yenqaba isicelo sevidiyo" - "Yamukela isicelo sokudlulisa ividiyo" - "Yenqaba isicelo sokudlulisa ividiyo" - "Yamukela isicelo sokwamukela ividiyo" - "Yenqaba isicelo sokwamukela ividiyo" - "Slayidela phezulu ku-%s." - "Slayida ngakwesokunxele ku-%s." - "Slayida ngakwesokudla ku-%s." - "Slayida ngezansi ku-%s." - "Dlidlizela" - "Dlidlizela" - "Umsindo" - "Umsindo ozenzakalelayo (%1$s)" - "Ithoni yokukhala yefoni" - "Dlidlizisa uma ikhala" - "Ithoni yokukhala nokudlidliza" - "Phatha ucingo lwengqungquthela" - "Inombolo ephuthumayo" - "Isithombe sephrofayela" - "Ikhamera ivaliwe" - "nge-%s" - "Inothi lithunyelwe" - "Imilayezo yakamuva" - "Ulwazi lwebhizinisi" - "%.1f amamitha kude" - "%.1f amakhilomitha kude" - "%1$s, %2$s" - "%1$s - %2$s" - "%1$s, %2$s" - "Kuvulwa kusasa ngo-%s" - "Kuvulwa namuhla ngo-%s" - "Kuvalwa ngo-%s" - "Kuvalwe namuhla ngo-%s" - "Kuvuliwe manje" - "Kuvaliwe manje" - "Ofonayo osolisayo wogaxekile" - "Ikholi iphelile %1$s" - "Lesi isikhathi sokuqala le nombolo ikushayela." - "Sisolele le kholi ukuthi ugaxekile." - "Vimba/bika ugaxekile" - "Engeza oxhumana naye" - "Akusiko okugaxekile" - diff --git a/InCallUI/res/values/animation_constants.xml b/InCallUI/res/values/animation_constants.xml deleted file mode 100644 index 8df6a7281..000000000 --- a/InCallUI/res/values/animation_constants.xml +++ /dev/null @@ -1,22 +0,0 @@ - - - - - 333 - 333 - 257 - diff --git a/InCallUI/res/values/array.xml b/InCallUI/res/values/array.xml deleted file mode 100644 index 7877ec8f3..000000000 --- a/InCallUI/res/values/array.xml +++ /dev/null @@ -1,135 +0,0 @@ - - - - - - - - - - @drawable/ic_lockscreen_answer - @null - @drawable/ic_lockscreen_decline - @null" - - - @string/description_target_answer - @null - @string/description_target_decline - @null" - - - @string/description_direction_right - @null - @string/description_direction_left - @null - - - - - @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" - - - @string/description_direction_right - @string/description_direction_up - @string/description_direction_left - @null - - - - - @drawable/ic_lockscreen_answer - @null - @drawable/ic_lockscreen_decline - @drawable/ic_lockscreen_answer_video - - - @string/description_target_answer_video_call - @null - @string/description_target_decline - @string/description_target_answer_audio_call - - - @string/description_direction_right - @null - @string/description_direction_left - @string/description_direction_down - - - - - @drawable/ic_lockscreen_answer_video - @drawable/ic_lockscreen_text - @drawable/ic_lockscreen_decline - @drawable/ic_lockscreen_answer - - - @string/description_target_answer_video_call - @string/description_target_send_sms - @string/description_target_decline - @string/description_target_answer_audio_call - - - @string/description_direction_right - @string/description_direction_up - @string/description_direction_left - @string/description_direction_down - - - - - @drawable/ic_lockscreen_answer_video - @drawable/ic_lockscreen_decline_video - - - - @string/description_target_accept_upgrade_to_video_request - @null - @string/description_target_decline_upgrade_to_video_request - @null" - - - @string/description_direction_right - @null - @string/description_direction_left - @null - - diff --git a/InCallUI/res/values/attrs.xml b/InCallUI/res/values/attrs.xml deleted file mode 100644 index e135fb72d..000000000 --- a/InCallUI/res/values/attrs.xml +++ /dev/null @@ -1,71 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/InCallUI/res/values/colors.xml b/InCallUI/res/values/colors.xml deleted file mode 100644 index 238d36033..000000000 --- a/InCallUI/res/values/colors.xml +++ /dev/null @@ -1,133 +0,0 @@ - - - - - - - @color/dialer_theme_color - #ffffff - - - @color/incall_background_color - #ffffff - - #ffffff - #f5f5f5 - #333333 - - @color/incall_background_color - @color/incall_call_banner_text_color - - #545454 - - - #cc000000 - - #f8f8f8 - #4d4d4d - #999999 - - #999999 - #ffffff - - #dddddd - - - #333 - - #ffffff - #ccaaaaaa - - @color/incall_background_color - @color/dialer_theme_color_dark - - #b3ffffff - - #33ffffff - - - @color/dialer_theme_color - - @color/dialer_theme_color - - #33999999 - - - #b3000000 - - #26ffffff - #ffffff - #ffffff - #cccccc - #00c853 - #ff1744 - #a3a3a3 - #ffffff - - - #B2FFFFFF - - - #330288d1 - - - - #00796B - #3367D6 - #303F9F - #7B1FA2 - #C2185B - #C53929 - #A52714 - - - - - #00695C - #2A56C6 - #283593 - #6A1B9A - #AD1457 - #B93221 - #841F10 - - - - #A52714 - - - #40000000 - - @color/incall_call_banner_subtext_color - @color/dialer_theme_color - @color/incall_call_banner_subtext_color - @color/incall_call_banner_subtext_color - @color/incall_call_banner_subtext_color - - - #ffffff - - - #919191 - diff --git a/InCallUI/res/values/config.xml b/InCallUI/res/values/config.xml deleted file mode 100644 index b81ba3ca0..000000000 --- a/InCallUI/res/values/config.xml +++ /dev/null @@ -1,27 +0,0 @@ - - - - 5 - - - true - - 5000 - \ No newline at end of file diff --git a/InCallUI/res/values/dimens.xml b/InCallUI/res/values/dimens.xml deleted file mode 100644 index 59da7860a..000000000 --- a/InCallUI/res/values/dimens.xml +++ /dev/null @@ -1,150 +0,0 @@ - - - - - - false - - - false - - - - 0dp - 20dp - - 3dp - - - 2dp - - - 24dp - - 16dp - 24dp - 32dp - 16sp - - - 8dp - - - 16sp - 12sp - 34dp - 28sp - 16sp - - 50sp - - - 48dp - - 0dp - 2dp - - - 1dp - - 0dp - 20sp - 50dp - 36dp - - -10dp - - 8dp - 6dp - - - 10dp - 5dp - 10dp - - - 64dp - - - 56dp - - - 250dp - - 125dp - - - 70dip - - - 40dip - - - 15dip - - -48dip - 0dip - - 2dp - - 2dp - - 50dp - - - 90dp - - 0dp - - 72dp - 56dp - - 64dp - 46dp - - 14sp - 19dp - 23dp - 13dp - 13dp - - 30dp - 16sp - 7dp - 12dp - 15dp - 2dp - 7dp - 14sp - - 10dp - 25dp - 20dp - 16sp - 12sp - - 40dp - diff --git a/InCallUI/res/values/ids.xml b/InCallUI/res/values/ids.xml deleted file mode 100644 index accb8fb73..000000000 --- a/InCallUI/res/values/ids.xml +++ /dev/null @@ -1,20 +0,0 @@ - - - - - - - diff --git a/InCallUI/res/values/strings.xml b/InCallUI/res/values/strings.xml deleted file mode 100644 index 92de14042..000000000 --- a/InCallUI/res/values/strings.xml +++ /dev/null @@ -1,540 +0,0 @@ - - - - - - - Phone - - - InCallUI - - - - - On hold - - - Unknown - - Private number - - Payphone - - - Conference call - - Call dropped - - - - - - Speaker - - Handset earpiece - - Wired headset - - Bluetooth - - - - Send the following tones?\n - - Sending tones\n - - Send - - Yes - - No - - Replace wild character with - - - Conference call %s - - - (650) 555-1234 - - Incoming phone number - - Fake Incoming Call - - - Voicemail number - - - - Dialing - - Redialing - - Conference call - - Incoming call - - Incoming work call - - Call ended - - On hold - - Hanging up - - In call - - My number is %s - - Connecting video - - Video call - - Requesting video - - Can\'t connect video call - - Video request rejected - - - Your callback number\n - %1$s - - - - Your emergency callback number\n - %1$s - - - - - Dialing - - Missed call - - Missed calls - - %s missed calls - - Missed call from %s - - Ongoing call - - Ongoing work call - - Ongoing Wi-Fi call - - Ongoing Wi-Fi work call - - On hold - - Incoming call - - Incoming work call - - Incoming Wi-Fi call - - Incoming Wi-Fi work call - - Incoming video call - - Incoming suspected spam call - - Incoming video request - - New voicemail - - New voicemail (%d) - - Dial %s - - Voicemail number unknown - - No service - - Selected network (%s) unavailable - - Answer - - Hang up - - Video - - Voice - - Accept - - Dismiss - - - Call back - - Message - - Ongoing call on another device - - Transfer Call - - - To place a call, first turn off Airplane mode. - - Not registered on network. - - Cellular network not available. - - To place a call, enter a valid number. - - Can\'t call. - - Starting MMI sequence\u2026 - - Service not supported. - - Can\'t switch calls. - - Can\'t separate call. - - Can\'t transfer. - - Can\'t conference. - - Can\'t reject call. - - Can\'t release call(s). - - - SIP call - - - Emergency call - - Turning on radio\u2026 - - No service. Trying again\u2026 - - - - Can\'t call. %s is not an emergency number. - - Can\'t call. Dial an emergency number. - - - Use keyboard to dial - - - Hold Call - - Resume Call - - End Call - - Show Dialpad - - Hide Dialpad - - Mute - - Unmute - - Add call - - Merge calls - - Swap - - Manage calls - - Manage conference call - - Conference call - - Manage - - Audio - - Video call - - Change to voice call - - Switch camera - - Turn on camera - - Turn off camera - - More options - - - Player Started - - Player Stopped - - Camera not ready - - Camera ready - - "Unkown call session event" - - - - ABSENT NUMBER - ABSENTNUMBER - - - - Service - - - Setup - - - <Not set> - - - Other call settings - - - Calling via %s - - Incoming via %s - - - contact photo - - go private - - select contact - - - Write your own... - - Cancel - - Send - - - Answer - - Send SMS - - Decline - - Answer as video call - - Answer as audio call - - Accept video request - - Decline video request - - Accept video transmit request - - Decline video transmit request - - Accept video receive request - - Decline video receive request - - - Slide up for %s. - - "Slide left for %s. - - Slide right for %s. - - Slide down for %s. - - - Vibrate - - Vibrate - - - Sound - - - Default sound (%1$s) - - - never - - - - always - silent - never - - - - Phone ringtone - - - Vibrate when ringing - - - Ringtone & Vibrate - - - Manage conference call - - - Emergency number - - - Profile photo - - - Camera off - - - via %s - - - Note sent - - - Recent messages - - - Business info - - - - - %.1f mi away - - %.1f km away - - %1$s, %2$s - - %1$s - %2$s - - %1$s, %2$s - - Opens tomorrow at %s - - Opens today at %s - - Closes at %s - - Closed today at %s - - Open now - - Closed now - - Suspected spam caller - - - Call ended %1$s - - This is the first time this number called you. - - We suspected this call to be a spammer. - - Block/report spam - - Add contact - - Not spam - diff --git a/InCallUI/res/values/styles.xml b/InCallUI/res/values/styles.xml deleted file mode 100644 index 11d636261..000000000 --- a/InCallUI/res/values/styles.xml +++ /dev/null @@ -1,100 +0,0 @@ - - - - - #FF333333 - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/InCallUI/src/com/android/incallui/AccelerometerListener.java b/InCallUI/src/com/android/incallui/AccelerometerListener.java deleted file mode 100644 index b5ad29675..000000000 --- a/InCallUI/src/com/android/incallui/AccelerometerListener.java +++ /dev/null @@ -1,169 +0,0 @@ -/* - * Copyright (C) 2009 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.incallui; - -import android.content.Context; -import android.hardware.Sensor; -import android.hardware.SensorEvent; -import android.hardware.SensorEventListener; -import android.hardware.SensorManager; -import android.os.Handler; -import android.os.Message; -import android.util.Log; - -/** - * This class is used to listen to the accelerometer to monitor the - * orientation of the phone. The client of this class is notified when - * the orientation changes between horizontal and vertical. - */ -public class AccelerometerListener { - private static final String TAG = "AccelerometerListener"; - private static final boolean DEBUG = true; - private static final boolean VDEBUG = false; - - private SensorManager mSensorManager; - private Sensor mSensor; - - // mOrientation is the orientation value most recently reported to the client. - private int mOrientation; - - // mPendingOrientation is the latest orientation computed based on the sensor value. - // This is sent to the client after a rebounce delay, at which point it is copied to - // mOrientation. - private int mPendingOrientation; - - private OrientationListener mListener; - - // Device orientation - public static final int ORIENTATION_UNKNOWN = 0; - public static final int ORIENTATION_VERTICAL = 1; - public static final int ORIENTATION_HORIZONTAL = 2; - - private static final int ORIENTATION_CHANGED = 1234; - - private static final int VERTICAL_DEBOUNCE = 100; - private static final int HORIZONTAL_DEBOUNCE = 500; - private static final double VERTICAL_ANGLE = 50.0; - - public interface OrientationListener { - public void orientationChanged(int orientation); - } - - public AccelerometerListener(Context context) { - mSensorManager = (SensorManager)context.getSystemService(Context.SENSOR_SERVICE); - mSensor = mSensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER); - } - - public void setListener(OrientationListener listener) { - mListener = listener; - } - - public void enable(boolean enable) { - if (DEBUG) Log.d(TAG, "enable(" + enable + ")"); - synchronized (this) { - if (enable) { - mOrientation = ORIENTATION_UNKNOWN; - mPendingOrientation = ORIENTATION_UNKNOWN; - mSensorManager.registerListener(mSensorListener, mSensor, - SensorManager.SENSOR_DELAY_NORMAL); - } else { - mSensorManager.unregisterListener(mSensorListener); - mHandler.removeMessages(ORIENTATION_CHANGED); - } - } - } - - private void setOrientation(int orientation) { - synchronized (this) { - if (mPendingOrientation == orientation) { - // Pending orientation has not changed, so do nothing. - return; - } - - // Cancel any pending messages. - // We will either start a new timer or cancel alltogether - // if the orientation has not changed. - mHandler.removeMessages(ORIENTATION_CHANGED); - - if (mOrientation != orientation) { - // Set timer to send an event if the orientation has changed since its - // previously reported value. - mPendingOrientation = orientation; - final Message m = mHandler.obtainMessage(ORIENTATION_CHANGED); - // set delay to our debounce timeout - int delay = (orientation == ORIENTATION_VERTICAL ? VERTICAL_DEBOUNCE - : HORIZONTAL_DEBOUNCE); - mHandler.sendMessageDelayed(m, delay); - } else { - // no message is pending - mPendingOrientation = ORIENTATION_UNKNOWN; - } - } - } - - private void onSensorEvent(double x, double y, double z) { - if (VDEBUG) Log.d(TAG, "onSensorEvent(" + x + ", " + y + ", " + z + ")"); - - // If some values are exactly zero, then likely the sensor is not powered up yet. - // ignore these events to avoid false horizontal positives. - if (x == 0.0 || y == 0.0 || z == 0.0) return; - - // magnitude of the acceleration vector projected onto XY plane - final double xy = Math.hypot(x, y); - // compute the vertical angle - double angle = Math.atan2(xy, z); - // convert to degrees - angle = angle * 180.0 / Math.PI; - final int orientation = (angle > VERTICAL_ANGLE ? ORIENTATION_VERTICAL : ORIENTATION_HORIZONTAL); - if (VDEBUG) Log.d(TAG, "angle: " + angle + " orientation: " + orientation); - setOrientation(orientation); - } - - SensorEventListener mSensorListener = new SensorEventListener() { - @Override - public void onSensorChanged(SensorEvent event) { - onSensorEvent(event.values[0], event.values[1], event.values[2]); - } - - @Override - public void onAccuracyChanged(Sensor sensor, int accuracy) { - // ignore - } - }; - - Handler mHandler = new Handler() { - @Override - public void handleMessage(Message msg) { - switch (msg.what) { - case ORIENTATION_CHANGED: - synchronized (this) { - mOrientation = mPendingOrientation; - if (DEBUG) { - Log.d(TAG, "orientation: " + - (mOrientation == ORIENTATION_HORIZONTAL ? "horizontal" - : (mOrientation == ORIENTATION_VERTICAL ? "vertical" - : "unknown"))); - } - if (mListener != null) { - mListener.orientationChanged(mOrientation); - } - } - break; - } - } - }; -} diff --git a/InCallUI/src/com/android/incallui/AccessibleAnswerFragment.java b/InCallUI/src/com/android/incallui/AccessibleAnswerFragment.java deleted file mode 100644 index 89c78ec61..000000000 --- a/InCallUI/src/com/android/incallui/AccessibleAnswerFragment.java +++ /dev/null @@ -1,157 +0,0 @@ -/* - * Copyright (C) 2013 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License - */ - -package com.android.incallui; - -import android.os.Bundle; -import android.telecom.VideoProfile; -import android.view.GestureDetector; -import android.view.GestureDetector.SimpleOnGestureListener; -import android.view.LayoutInflater; -import android.view.MotionEvent; -import android.view.View; -import android.view.ViewGroup; - -import com.android.dialer.R; - -/** - * AnswerFragment to use when touch exploration is enabled in accessibility. - */ -public class AccessibleAnswerFragment extends AnswerFragment { - - private static final String TAG = AccessibleAnswerFragment.class.getSimpleName(); - private static final int SWIPE_THRESHOLD = 100; - - private View mAnswer; - private View mDecline; - private View mText; - - private TouchListener mTouchListener; - private GestureDetector mGestureDetector; - - @Override - public View onCreateView(LayoutInflater inflater, ViewGroup container, - Bundle savedInstanceState) { - ViewGroup group = (ViewGroup) inflater.inflate(R.layout.accessible_answer_fragment, - container, false); - - mTouchListener = new TouchListener(); - mGestureDetector = new GestureDetector(getContext(), new SimpleOnGestureListener() { - @Override - public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, - float velocityY) { - return AccessibleAnswerFragment.this.onFling(e1, e2, velocityX, velocityX); - } - }); - - mAnswer = group.findViewById(R.id.accessible_answer_fragment_answer); - mAnswer.setOnClickListener(new View.OnClickListener() { - @Override - public void onClick(View v) { - Log.d(TAG, "Answer Button Clicked"); - onAnswer(VideoProfile.STATE_AUDIO_ONLY, getContext()); - } - }); - mDecline = group.findViewById(R.id.accessible_answer_fragment_decline); - mDecline.setOnClickListener(new View.OnClickListener() { - @Override - public void onClick(View v) { - Log.d(TAG, "Decline Button Clicked"); - onDecline(getContext()); - } - }); - - mText = group.findViewById(R.id.accessible_answer_fragment_text); - mText.setOnClickListener(new View.OnClickListener() { - @Override - public void onClick(View v) { - Log.d(TAG, "Text Button Clicked"); - onText(); - } - }); - return group; - } - - @Override - public void onResume() { - super.onResume(); - // Intercept all touch events for full screen swiping gesture. - InCallActivity activity = (InCallActivity) getActivity(); - activity.setDispatchTouchEventListener(mTouchListener); - } - - @Override - public void onPause() { - super.onPause(); - InCallActivity activity = (InCallActivity) getActivity(); - activity.setDispatchTouchEventListener(null); - } - - private class TouchListener implements View.OnTouchListener { - @Override - public boolean onTouch(View v, MotionEvent event) { - return mGestureDetector.onTouchEvent(event); - } - } - - private boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, - float velocityY) { - if (hasPendingDialogs()) { - return false; - } - - float diffY = e2.getY() - e1.getY(); - float diffX = e2.getX() - e1.getX(); - if (Math.abs(diffX) > Math.abs(diffY)) { - if (Math.abs(diffX) > SWIPE_THRESHOLD) { - if (diffX > 0) { - onSwipeRight(); - } else { - onSwipeLeft(); - } - } - return true; - } else if (Math.abs(diffY) > SWIPE_THRESHOLD) { - if (diffY > 0) { - onSwipeDown(); - } else { - onSwipeUp(); - } - return true; - } - - return false; - } - - private void onSwipeUp() { - Log.d(TAG, "onSwipeUp"); - onText(); - } - - private void onSwipeDown() { - Log.d(TAG, "onSwipeDown"); - } - - private void onSwipeLeft() { - Log.d(TAG, "onSwipeLeft"); - onDecline(getContext()); - } - - private void onSwipeRight() { - Log.d(TAG, "onSwipeRight"); - onAnswer(VideoProfile.STATE_AUDIO_ONLY, getContext()); - } -} diff --git a/InCallUI/src/com/android/incallui/AnswerFragment.java b/InCallUI/src/com/android/incallui/AnswerFragment.java deleted file mode 100644 index 44ddfcd49..000000000 --- a/InCallUI/src/com/android/incallui/AnswerFragment.java +++ /dev/null @@ -1,307 +0,0 @@ -/* - * Copyright (C) 2013 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License - */ - -package com.android.incallui; - -import android.app.AlertDialog; -import android.app.Dialog; -import android.content.Context; -import android.content.DialogInterface; -import android.os.Bundle; -import android.text.Editable; -import android.text.TextWatcher; -import android.view.LayoutInflater; -import android.view.View; -import android.view.ViewGroup; -import android.view.WindowManager; -import android.widget.AdapterView; -import android.widget.ArrayAdapter; -import android.widget.Button; -import android.widget.EditText; -import android.widget.ListView; - -import com.android.dialer.R; - -import java.util.ArrayList; -import java.util.List; - - -/** - * Provides only common interface and functions. Should be derived to implement the actual UI. - */ -public abstract class AnswerFragment extends BaseFragment - implements AnswerPresenter.AnswerUi { - - public static final int TARGET_SET_FOR_AUDIO_WITHOUT_SMS = 0; - public static final int TARGET_SET_FOR_AUDIO_WITH_SMS = 1; - public static final int TARGET_SET_FOR_VIDEO_WITHOUT_SMS = 2; - public static final int TARGET_SET_FOR_VIDEO_WITH_SMS = 3; - public static final int TARGET_SET_FOR_VIDEO_ACCEPT_REJECT_REQUEST = 4; - - /** - * This fragment implement no UI at all. Derived class should do it. - */ - @Override - public abstract View onCreateView(LayoutInflater inflater, ViewGroup container, - Bundle savedInstanceState); - - /** - * The popup showing the list of canned responses. - * - * This is an AlertDialog containing a ListView showing the possible choices. This may be null - * if the InCallScreen hasn't ever called showRespondViaSmsPopup() yet, or if the popup was - * visible once but then got dismissed. - */ - private Dialog mCannedResponsePopup = null; - - /** - * The popup showing a text field for users to type in their custom message. - */ - private AlertDialog mCustomMessagePopup = null; - - private ArrayAdapter mSmsResponsesAdapter; - - private final List mSmsResponses = new ArrayList<>(); - - @Override - public AnswerPresenter createPresenter() { - return InCallPresenter.getInstance().getAnswerPresenter(); - } - - @Override - public AnswerPresenter.AnswerUi getUi() { - return this; - } - - @Override - public void showMessageDialog() { - final AlertDialog.Builder builder = new AlertDialog.Builder(getActivity()); - - mSmsResponsesAdapter = new ArrayAdapter<>(builder.getContext(), - android.R.layout.simple_list_item_1, android.R.id.text1, mSmsResponses); - - final ListView lv = new ListView(getActivity()); - lv.setAdapter(mSmsResponsesAdapter); - lv.setOnItemClickListener(new RespondViaSmsItemClickListener()); - - builder.setCancelable(true).setView(lv).setOnCancelListener( - new DialogInterface.OnCancelListener() { - @Override - public void onCancel(DialogInterface dialogInterface) { - onMessageDialogCancel(); - dismissCannedResponsePopup(); - getPresenter().onDismissDialog(); - } - }); - mCannedResponsePopup = builder.create(); - mCannedResponsePopup.getWindow().addFlags(WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED); - mCannedResponsePopup.show(); - } - - private boolean isCannedResponsePopupShowing() { - if (mCannedResponsePopup != null) { - return mCannedResponsePopup.isShowing(); - } - return false; - } - - private boolean isCustomMessagePopupShowing() { - if (mCustomMessagePopup != null) { - return mCustomMessagePopup.isShowing(); - } - return false; - } - - /** - * Dismiss the canned response list popup. - * - * This is safe to call even if the popup is already dismissed, and even if you never called - * showRespondViaSmsPopup() in the first place. - */ - protected void dismissCannedResponsePopup() { - if (mCannedResponsePopup != null) { - mCannedResponsePopup.dismiss(); // safe even if already dismissed - mCannedResponsePopup = null; - } - } - - /** - * Dismiss the custom compose message popup. - */ - private void dismissCustomMessagePopup() { - if (mCustomMessagePopup != null) { - mCustomMessagePopup.dismiss(); - mCustomMessagePopup = null; - } - } - - public void dismissPendingDialogs() { - if (isCannedResponsePopupShowing()) { - dismissCannedResponsePopup(); - } - - if (isCustomMessagePopupShowing()) { - dismissCustomMessagePopup(); - } - } - - public boolean hasPendingDialogs() { - return !(mCannedResponsePopup == null && mCustomMessagePopup == null); - } - - /** - * Shows the custom message entry dialog. - */ - public void showCustomMessageDialog() { - // Create an alert dialog containing an EditText - final AlertDialog.Builder builder = new AlertDialog.Builder(getActivity()); - final EditText et = new EditText(builder.getContext()); - builder.setCancelable(true).setView(et) - .setPositiveButton(R.string.custom_message_send, - new DialogInterface.OnClickListener() { - @Override - public void onClick(DialogInterface dialog, int which) { - // The order is arranged in a way that the popup will be destroyed - // when the InCallActivity is about to finish. - final String textMessage = et.getText().toString().trim(); - dismissCustomMessagePopup(); - getPresenter().rejectCallWithMessage(textMessage); - } - }) - .setNegativeButton(R.string.custom_message_cancel, - new DialogInterface.OnClickListener() { - @Override - public void onClick(DialogInterface dialog, int which) { - dismissCustomMessagePopup(); - getPresenter().onDismissDialog(); - } - }) - .setOnCancelListener(new DialogInterface.OnCancelListener() { - @Override - public void onCancel(DialogInterface dialogInterface) { - dismissCustomMessagePopup(); - getPresenter().onDismissDialog(); - } - }) - .setTitle(R.string.respond_via_sms_custom_message); - mCustomMessagePopup = builder.create(); - - // Enable/disable the send button based on whether there is a message in the EditText - et.addTextChangedListener(new TextWatcher() { - @Override - public void beforeTextChanged(CharSequence s, int start, int count, int after) { - } - - @Override - public void onTextChanged(CharSequence s, int start, int before, int count) { - } - - @Override - public void afterTextChanged(Editable s) { - final Button sendButton = mCustomMessagePopup.getButton( - DialogInterface.BUTTON_POSITIVE); - sendButton.setEnabled(s != null && s.toString().trim().length() != 0); - } - }); - - // Keyboard up, show the dialog - mCustomMessagePopup.getWindow().setSoftInputMode( - WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_VISIBLE); - mCustomMessagePopup.getWindow().addFlags(WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED); - mCustomMessagePopup.show(); - - // Send button starts out disabled - final Button sendButton = mCustomMessagePopup.getButton(DialogInterface.BUTTON_POSITIVE); - sendButton.setEnabled(false); - } - - @Override - public void configureMessageDialog(List textResponses) { - mSmsResponses.clear(); - mSmsResponses.addAll(textResponses); - mSmsResponses.add(getResources().getString( - R.string.respond_via_sms_custom_message)); - if (mSmsResponsesAdapter != null) { - mSmsResponsesAdapter.notifyDataSetChanged(); - } - } - - @Override - public Context getContext() { - return getActivity(); - } - - public void onAnswer(int videoState, Context context) { - Log.d(this, "onAnswer videoState=" + videoState + " context=" + context); - getPresenter().onAnswer(videoState, context); - } - - public void onDecline(Context context) { - getPresenter().onDecline(context); - } - - public void onDeclineUpgradeRequest(Context context) { - InCallPresenter.getInstance().declineUpgradeRequest(context); - } - - public void onText() { - getPresenter().onText(); - } - - /** - * OnItemClickListener for the "Respond via SMS" popup. - */ - public class RespondViaSmsItemClickListener implements AdapterView.OnItemClickListener { - - /** - * Handles the user selecting an item from the popup. - */ - @Override - public void onItemClick(AdapterView parent, // The ListView - View view, // The TextView that was clicked - int position, long id) { - Log.d(this, "RespondViaSmsItemClickListener.onItemClick(" + position + ")..."); - final String message = (String) parent.getItemAtPosition(position); - Log.v(this, "- message: '" + message + "'"); - dismissCannedResponsePopup(); - - // The "Custom" choice is a special case. - // (For now, it's guaranteed to be the last item.) - if (position == (parent.getCount() - 1)) { - // Show the custom message dialog - showCustomMessageDialog(); - } else { - getPresenter().rejectCallWithMessage(message); - } - } - } - - public void onShowAnswerUi(boolean shown) { - // Do Nothing - } - - public void showTargets(int targetSet) { - // Do Nothing - } - - public void showTargets(int targetSet, int videoState) { - // Do Nothing - } - - protected void onMessageDialogCancel() { - // Do nothing. - } -} diff --git a/InCallUI/src/com/android/incallui/AnswerPresenter.java b/InCallUI/src/com/android/incallui/AnswerPresenter.java deleted file mode 100644 index 883b54fed..000000000 --- a/InCallUI/src/com/android/incallui/AnswerPresenter.java +++ /dev/null @@ -1,312 +0,0 @@ -/* - * Copyright (C) 2013 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License - */ - -package com.android.incallui; - -import android.content.Context; - -import com.android.dialer.compat.UserManagerCompat; -import com.android.dialer.util.TelecomUtil; -import com.android.incallui.InCallPresenter.InCallState; - -import java.util.List; - -/** - * Presenter for the Incoming call widget. The {@link AnswerPresenter} handles the logic during - * incoming calls. It is also in charge of responding to incoming calls, so there needs to be - * an instance alive so that it can receive onIncomingCall callbacks. - * - * An instance of {@link AnswerPresenter} is created by InCallPresenter at startup, registers - * for callbacks via InCallPresenter, and shows/hides the {@link AnswerFragment} via IncallActivity. - * - */ -public class AnswerPresenter extends Presenter - implements CallList.CallUpdateListener, InCallPresenter.InCallUiListener, - InCallPresenter.IncomingCallListener, - CallList.Listener { - - private static final String TAG = AnswerPresenter.class.getSimpleName(); - - private String mCallId; - private Call mCall = null; - private boolean mHasTextMessages = false; - - @Override - public void onUiShowing(boolean showing) { - if (showing) { - CallList.getInstance().addListener(this); - final CallList calls = CallList.getInstance(); - Call call; - call = calls.getIncomingCall(); - if (call != null) { - processIncomingCall(call); - } - call = calls.getVideoUpgradeRequestCall(); - Log.d(this, "getVideoUpgradeRequestCall call =" + call); - if (call != null) { - showAnswerUi(true); - processVideoUpgradeRequestCall(call); - } - } else { - CallList.getInstance().removeListener(this); - // This is necessary because the activity can be destroyed while an incoming call exists. - // This happens when back button is pressed while incoming call is still being shown. - if (mCallId != null) { - CallList.getInstance().removeCallUpdateListener(mCallId, this); - } - } - } - - @Override - public void onIncomingCall(InCallState oldState, InCallState newState, Call call) { - Log.d(this, "onIncomingCall: " + this); - Call modifyCall = CallList.getInstance().getVideoUpgradeRequestCall(); - if (modifyCall != null) { - showAnswerUi(false); - Log.d(this, "declining upgrade request id: "); - CallList.getInstance().removeCallUpdateListener(mCallId, this); - InCallPresenter.getInstance().declineUpgradeRequest(); - } - if (!call.getId().equals(mCallId)) { - // A new call is coming in. - processIncomingCall(call); - } - } - - @Override - public void onIncomingCall(Call call) { - } - - @Override - public void onCallListChange(CallList list) { - } - - @Override - public void onDisconnect(Call call) { - // no-op - } - - public void onSessionModificationStateChange(int sessionModificationState) { - boolean isUpgradePending = sessionModificationState == - Call.SessionModificationState.RECEIVED_UPGRADE_TO_VIDEO_REQUEST; - - if (!isUpgradePending) { - // Stop listening for updates. - CallList.getInstance().removeCallUpdateListener(mCallId, this); - showAnswerUi(false); - } - } - - @Override - public void onLastForwardedNumberChange() { - // no-op - } - - @Override - public void onChildNumberChange() { - // no-op - } - - private boolean isVideoUpgradePending(Call call) { - return call.getSessionModificationState() - == Call.SessionModificationState.RECEIVED_UPGRADE_TO_VIDEO_REQUEST; - } - - @Override - public void onUpgradeToVideo(Call call) { - Log.d(this, "onUpgradeToVideo: " + this + " call=" + call); - showAnswerUi(true); - boolean isUpgradePending = isVideoUpgradePending(call); - InCallPresenter inCallPresenter = InCallPresenter.getInstance(); - if (isUpgradePending - && inCallPresenter.getInCallState() == InCallPresenter.InCallState.INCOMING) { - Log.d(this, "declining upgrade request"); - //If there is incoming call reject upgrade request - inCallPresenter.declineUpgradeRequest(getUi().getContext()); - } else if (isUpgradePending) { - Log.d(this, "process upgrade request as no MT call"); - processVideoUpgradeRequestCall(call); - } - } - - private void processIncomingCall(Call call) { - mCallId = call.getId(); - mCall = call; - - // Listen for call updates for the current call. - CallList.getInstance().addCallUpdateListener(mCallId, this); - - Log.d(TAG, "Showing incoming for call id: " + mCallId + " " + this); - if (showAnswerUi(true)) { - final List textMsgs = CallList.getInstance().getTextResponses(call.getId()); - configureAnswerTargetsForSms(call, textMsgs); - } - } - - private boolean showAnswerUi(boolean show) { - final InCallActivity activity = InCallPresenter.getInstance().getActivity(); - if (activity != null) { - activity.showAnswerFragment(show); - if (getUi() != null) { - getUi().onShowAnswerUi(show); - } - return true; - } else { - return false; - } - } - - private void processVideoUpgradeRequestCall(Call call) { - Log.d(this, " processVideoUpgradeRequestCall call=" + call); - mCallId = call.getId(); - mCall = call; - - // Listen for call updates for the current call. - CallList.getInstance().addCallUpdateListener(mCallId, this); - - final int currentVideoState = call.getVideoState(); - final int modifyToVideoState = call.getRequestedVideoState(); - - if (currentVideoState == modifyToVideoState) { - Log.w(this, "processVideoUpgradeRequestCall: Video states are same. Return."); - return; - } - - AnswerUi ui = getUi(); - - if (ui == null) { - Log.e(this, "Ui is null. Can't process upgrade request"); - return; - } - showAnswerUi(true); - ui.showTargets(AnswerFragment.TARGET_SET_FOR_VIDEO_ACCEPT_REJECT_REQUEST, - modifyToVideoState); - } - - private boolean isEnabled(int videoState, int mask) { - return (videoState & mask) == mask; - } - - @Override - public void onCallChanged(Call call) { - Log.d(this, "onCallStateChange() " + call + " " + this); - if (call.getState() != Call.State.INCOMING) { - boolean isUpgradePending = isVideoUpgradePending(call); - if (!isUpgradePending) { - // Stop listening for updates. - CallList.getInstance().removeCallUpdateListener(mCallId, this); - } - - final Call incall = CallList.getInstance().getIncomingCall(); - if (incall != null || isUpgradePending) { - showAnswerUi(true); - } else { - showAnswerUi(false); - } - - mHasTextMessages = false; - } else if (!mHasTextMessages) { - final List textMsgs = CallList.getInstance().getTextResponses(call.getId()); - if (textMsgs != null) { - configureAnswerTargetsForSms(call, textMsgs); - } - } - } - - public void onAnswer(int videoState, Context context) { - if (mCallId == null) { - return; - } - - if (mCall.getSessionModificationState() - == Call.SessionModificationState.RECEIVED_UPGRADE_TO_VIDEO_REQUEST) { - Log.d(this, "onAnswer (upgradeCall) mCallId=" + mCallId + " videoState=" + videoState); - InCallPresenter.getInstance().acceptUpgradeRequest(videoState, context); - } else { - Log.d(this, "onAnswer (answerCall) mCallId=" + mCallId + " videoState=" + videoState); - TelecomAdapter.getInstance().answerCall(mCall.getId(), videoState); - } - } - - /** - * TODO: We are using reject and decline interchangeably. We should settle on - * reject since it seems to be more prevalent. - */ - public void onDecline(Context context) { - Log.d(this, "onDecline " + mCallId); - if (mCall.getSessionModificationState() - == Call.SessionModificationState.RECEIVED_UPGRADE_TO_VIDEO_REQUEST) { - InCallPresenter.getInstance().declineUpgradeRequest(context); - } else { - TelecomAdapter.getInstance().rejectCall(mCall.getId(), false, null); - } - } - - public void onText() { - if (getUi() != null) { - TelecomUtil.silenceRinger(getUi().getContext()); - getUi().showMessageDialog(); - } - } - - public void rejectCallWithMessage(String message) { - Log.d(this, "sendTextToDefaultActivity()..."); - TelecomAdapter.getInstance().rejectCall(mCall.getId(), true, message); - - onDismissDialog(); - } - - public void onDismissDialog() { - InCallPresenter.getInstance().onDismissDialog(); - } - - private void configureAnswerTargetsForSms(Call call, List textMsgs) { - if (getUi() == null) { - return; - } - mHasTextMessages = textMsgs != null; - boolean withSms = UserManagerCompat.isUserUnlocked(getUi().getContext()) - && call.can(android.telecom.Call.Details.CAPABILITY_RESPOND_VIA_TEXT) - && mHasTextMessages; - - // Only present the user with the option to answer as a video call if the incoming call is - // a bi-directional video call. - if (VideoUtils.isBidirectionalVideoCall(call)) { - if (withSms) { - getUi().showTargets(AnswerFragment.TARGET_SET_FOR_VIDEO_WITH_SMS); - getUi().configureMessageDialog(textMsgs); - } else { - getUi().showTargets(AnswerFragment.TARGET_SET_FOR_VIDEO_WITHOUT_SMS); - } - } else { - if (withSms) { - getUi().showTargets(AnswerFragment.TARGET_SET_FOR_AUDIO_WITH_SMS); - getUi().configureMessageDialog(textMsgs); - } else { - getUi().showTargets(AnswerFragment.TARGET_SET_FOR_AUDIO_WITHOUT_SMS); - } - } - } - - interface AnswerUi extends Ui { - public void onShowAnswerUi(boolean shown); - public void showTargets(int targetSet); - public void showTargets(int targetSet, int videoState); - public void showMessageDialog(); - public void configureMessageDialog(List textResponses); - public Context getContext(); - } -} diff --git a/InCallUI/src/com/android/incallui/AudioModeProvider.java b/InCallUI/src/com/android/incallui/AudioModeProvider.java deleted file mode 100644 index ea56dd624..000000000 --- a/InCallUI/src/com/android/incallui/AudioModeProvider.java +++ /dev/null @@ -1,105 +0,0 @@ -/* - * Copyright (C) 2013 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License - */ - -package com.android.incallui; - -import android.telecom.CallAudioState; - -import com.google.common.collect.Lists; - -import java.util.List; - -/** - * Proxy class for getting and setting the audio mode. - */ -public class AudioModeProvider { - - static final int AUDIO_MODE_INVALID = 0; - - private static AudioModeProvider sAudioModeProvider = new AudioModeProvider(); - private int mAudioMode = CallAudioState.ROUTE_EARPIECE; - private boolean mMuted = false; - private int mSupportedModes = CallAudioState.ROUTE_EARPIECE - | CallAudioState.ROUTE_BLUETOOTH | CallAudioState.ROUTE_WIRED_HEADSET - | CallAudioState.ROUTE_SPEAKER; - private final List mListeners = Lists.newArrayList(); - - public static AudioModeProvider getInstance() { - return sAudioModeProvider; - } - - public void onAudioStateChanged(boolean isMuted, int route, int supportedRouteMask) { - onAudioModeChange(route, isMuted); - onSupportedAudioModeChange(supportedRouteMask); - } - - public void onAudioModeChange(int newMode, boolean muted) { - if (mAudioMode != newMode) { - mAudioMode = newMode; - for (AudioModeListener l : mListeners) { - l.onAudioMode(mAudioMode); - } - } - - if (mMuted != muted) { - mMuted = muted; - for (AudioModeListener l : mListeners) { - l.onMute(mMuted); - } - } - } - - public void onSupportedAudioModeChange(int newModeMask) { - mSupportedModes = newModeMask; - - for (AudioModeListener l : mListeners) { - l.onSupportedAudioMode(mSupportedModes); - } - } - - public void addListener(AudioModeListener listener) { - if (!mListeners.contains(listener)) { - mListeners.add(listener); - listener.onSupportedAudioMode(mSupportedModes); - listener.onAudioMode(mAudioMode); - listener.onMute(mMuted); - } - } - - public void removeListener(AudioModeListener listener) { - if (mListeners.contains(listener)) { - mListeners.remove(listener); - } - } - - public int getSupportedModes() { - return mSupportedModes; - } - - public int getAudioMode() { - return mAudioMode; - } - - public boolean getMute() { - return mMuted; - } - - /* package */ interface AudioModeListener { - void onAudioMode(int newMode); - void onMute(boolean muted); - void onSupportedAudioMode(int modeMask); - } -} diff --git a/InCallUI/src/com/android/incallui/BaseFragment.java b/InCallUI/src/com/android/incallui/BaseFragment.java deleted file mode 100644 index 58d991acd..000000000 --- a/InCallUI/src/com/android/incallui/BaseFragment.java +++ /dev/null @@ -1,84 +0,0 @@ -/* - * Copyright (C) 2013 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License - */ - -package com.android.incallui; - -import android.app.Activity; -import android.app.Fragment; -import android.os.Bundle; - -/** - * Parent for all fragments that use Presenters and Ui design. - */ -public abstract class BaseFragment, U extends Ui> extends Fragment { - - private static final String KEY_FRAGMENT_HIDDEN = "key_fragment_hidden"; - - private T mPresenter; - - public abstract T createPresenter(); - - public abstract U getUi(); - - protected BaseFragment() { - mPresenter = createPresenter(); - } - - /** - * Presenter will be available after onActivityCreated(). - * - * @return The presenter associated with this fragment. - */ - public T getPresenter() { - return mPresenter; - } - - @Override - public void onActivityCreated(Bundle savedInstanceState) { - super.onActivityCreated(savedInstanceState); - mPresenter.onUiReady(getUi()); - } - - @Override - public void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - if (savedInstanceState != null) { - mPresenter.onRestoreInstanceState(savedInstanceState); - if (savedInstanceState.getBoolean(KEY_FRAGMENT_HIDDEN)) { - getFragmentManager().beginTransaction().hide(this).commit(); - } - } - } - - @Override - public void onDestroyView() { - super.onDestroyView(); - mPresenter.onUiDestroy(getUi()); - } - - @Override - public void onSaveInstanceState(Bundle outState) { - super.onSaveInstanceState(outState); - mPresenter.onSaveInstanceState(outState); - outState.putBoolean(KEY_FRAGMENT_HIDDEN, isHidden()); - } - - @Override - public void onAttach(Activity activity) { - super.onAttach(activity); - ((FragmentDisplayManager) activity).onFragmentAttached(this); - } -} diff --git a/InCallUI/src/com/android/incallui/Call.java b/InCallUI/src/com/android/incallui/Call.java deleted file mode 100644 index 1ad37e01a..000000000 --- a/InCallUI/src/com/android/incallui/Call.java +++ /dev/null @@ -1,1023 +0,0 @@ -/* - * Copyright (C) 2013 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.incallui; - -import android.content.Context; -import android.hardware.camera2.CameraCharacteristics; -import android.net.Uri; -import android.os.Bundle; -import android.os.Trace; -import android.support.annotation.IntDef; -import android.telecom.Call.Details; -import android.telecom.Connection; -import android.telecom.DisconnectCause; -import android.telecom.GatewayInfo; -import android.telecom.InCallService.VideoCall; -import android.telecom.PhoneAccount; -import android.telecom.PhoneAccountHandle; -import android.telecom.TelecomManager; -import android.telecom.VideoProfile; -import android.text.TextUtils; - -import com.android.contacts.common.CallUtil; -import com.android.contacts.common.compat.CallSdkCompat; -import com.android.contacts.common.compat.CompatUtils; -import com.android.contacts.common.compat.SdkVersionOverride; -import com.android.contacts.common.compat.telecom.TelecomManagerCompat; -import com.android.contacts.common.testing.NeededForTesting; -import com.android.dialer.util.IntentUtil; -import com.android.incallui.util.TelecomCallUtil; - -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.util.ArrayList; -import java.util.List; -import java.util.Locale; -import java.util.Objects; - -/** - * Describes a single call and its state. - */ -@NeededForTesting -public class Call { - - /** - * Specifies whether a number is in the call history or not. - * {@link #CALL_HISTORY_STATUS_UNKNOWN} means there is no result. - */ - @IntDef({CALL_HISTORY_STATUS_UNKNOWN, CALL_HISTORY_STATUS_PRESENT, - CALL_HISTORY_STATUS_NOT_PRESENT}) - @Retention(RetentionPolicy.SOURCE) - public @interface CallHistoryStatus {} - public static final int CALL_HISTORY_STATUS_UNKNOWN = 0; - public static final int CALL_HISTORY_STATUS_PRESENT = 1; - public static final int CALL_HISTORY_STATUS_NOT_PRESENT = 2; - - /* Defines different states of this call */ - public static class State { - public static final int INVALID = 0; - public static final int NEW = 1; /* The call is new. */ - public static final int IDLE = 2; /* The call is idle. Nothing active */ - public static final int ACTIVE = 3; /* There is an active call */ - public static final int INCOMING = 4; /* A normal incoming phone call */ - public static final int CALL_WAITING = 5; /* Incoming call while another is active */ - public static final int DIALING = 6; /* An outgoing call during dial phase */ - public static final int REDIALING = 7; /* Subsequent dialing attempt after a failure */ - public static final int ONHOLD = 8; /* An active phone call placed on hold */ - public static final int DISCONNECTING = 9; /* A call is being ended. */ - public static final int DISCONNECTED = 10; /* State after a call disconnects */ - public static final int CONFERENCED = 11; /* Call part of a conference call */ - public static final int SELECT_PHONE_ACCOUNT = 12; /* Waiting for account selection */ - public static final int CONNECTING = 13; /* Waiting for Telecom broadcast to finish */ - public static final int BLOCKED = 14; /* The number was found on the block list */ - - - public static boolean isConnectingOrConnected(int state) { - switch(state) { - case ACTIVE: - case INCOMING: - case CALL_WAITING: - case CONNECTING: - case DIALING: - case REDIALING: - case ONHOLD: - case CONFERENCED: - return true; - default: - } - return false; - } - - public static boolean isDialing(int state) { - return state == DIALING || state == REDIALING; - } - - public static String toString(int state) { - switch (state) { - case INVALID: - return "INVALID"; - case NEW: - return "NEW"; - case IDLE: - return "IDLE"; - case ACTIVE: - return "ACTIVE"; - case INCOMING: - return "INCOMING"; - case CALL_WAITING: - return "CALL_WAITING"; - case DIALING: - return "DIALING"; - case REDIALING: - return "REDIALING"; - case ONHOLD: - return "ONHOLD"; - case DISCONNECTING: - return "DISCONNECTING"; - case DISCONNECTED: - return "DISCONNECTED"; - case CONFERENCED: - return "CONFERENCED"; - case SELECT_PHONE_ACCOUNT: - return "SELECT_PHONE_ACCOUNT"; - case CONNECTING: - return "CONNECTING"; - case BLOCKED: - return "BLOCKED"; - default: - return "UNKNOWN"; - } - } - } - - /** - * Defines different states of session modify requests, which are used to upgrade to video, or - * downgrade to audio. - */ - public static class SessionModificationState { - public static final int NO_REQUEST = 0; - public static final int WAITING_FOR_RESPONSE = 1; - public static final int REQUEST_FAILED = 2; - public static final int RECEIVED_UPGRADE_TO_VIDEO_REQUEST = 3; - public static final int UPGRADE_TO_VIDEO_REQUEST_TIMED_OUT = 4; - public static final int REQUEST_REJECTED = 5; - } - - public static class VideoSettings { - public static final int CAMERA_DIRECTION_UNKNOWN = -1; - public static final int CAMERA_DIRECTION_FRONT_FACING = - CameraCharacteristics.LENS_FACING_FRONT; - public static final int CAMERA_DIRECTION_BACK_FACING = - CameraCharacteristics.LENS_FACING_BACK; - - private int mCameraDirection = CAMERA_DIRECTION_UNKNOWN; - - /** - * Sets the camera direction. if camera direction is set to CAMERA_DIRECTION_UNKNOWN, - * the video state of the call should be used to infer the camera direction. - * - * @see {@link CameraCharacteristics#LENS_FACING_FRONT} - * @see {@link CameraCharacteristics#LENS_FACING_BACK} - */ - public void setCameraDir(int cameraDirection) { - if (cameraDirection == CAMERA_DIRECTION_FRONT_FACING - || cameraDirection == CAMERA_DIRECTION_BACK_FACING) { - mCameraDirection = cameraDirection; - } else { - mCameraDirection = CAMERA_DIRECTION_UNKNOWN; - } - } - - /** - * Gets the camera direction. if camera direction is set to CAMERA_DIRECTION_UNKNOWN, - * the video state of the call should be used to infer the camera direction. - * - * @see {@link CameraCharacteristics#LENS_FACING_FRONT} - * @see {@link CameraCharacteristics#LENS_FACING_BACK} - */ - public int getCameraDir() { - return mCameraDirection; - } - - @Override - public String toString() { - return "(CameraDir:" + getCameraDir() + ")"; - } - } - - /** - * Tracks any state variables that is useful for logging. There is some amount of overlap with - * existing call member variables, but this duplication helps to ensure that none of these - * logging variables will interface with/and affect call logic. - */ - public static class LogState { - - // Contact lookup type constants - // Unknown lookup result (lookup not completed yet?) - public static final int LOOKUP_UNKNOWN = 0; - public static final int LOOKUP_NOT_FOUND = 1; - public static final int LOOKUP_LOCAL_CONTACT = 2; - public static final int LOOKUP_LOCAL_CACHE = 3; - public static final int LOOKUP_REMOTE_CONTACT = 4; - public static final int LOOKUP_EMERGENCY = 5; - public static final int LOOKUP_VOICEMAIL = 6; - - // Call initiation type constants - public static final int INITIATION_UNKNOWN = 0; - public static final int INITIATION_INCOMING = 1; - public static final int INITIATION_DIALPAD = 2; - public static final int INITIATION_SPEED_DIAL = 3; - public static final int INITIATION_REMOTE_DIRECTORY = 4; - public static final int INITIATION_SMART_DIAL = 5; - public static final int INITIATION_REGULAR_SEARCH = 6; - public static final int INITIATION_CALL_LOG = 7; - public static final int INITIATION_CALL_LOG_FILTER = 8; - public static final int INITIATION_VOICEMAIL_LOG = 9; - public static final int INITIATION_CALL_DETAILS = 10; - public static final int INITIATION_QUICK_CONTACTS = 11; - public static final int INITIATION_EXTERNAL = 12; - - public DisconnectCause disconnectCause; - public boolean isIncoming = false; - public int contactLookupResult = LOOKUP_UNKNOWN; - public int callInitiationMethod = INITIATION_EXTERNAL; - // If this was a conference call, the total number of calls involved in the conference. - public int conferencedCalls = 0; - public long duration = 0; - public boolean isLogged = false; - - @Override - public String toString() { - return String.format(Locale.US, "[" - + "%s, " // DisconnectCause toString already describes the object type - + "isIncoming: %s, " - + "contactLookup: %s, " - + "callInitiation: %s, " - + "duration: %s" - + "]", - disconnectCause, - isIncoming, - lookupToString(contactLookupResult), - initiationToString(callInitiationMethod), - duration); - } - - private static String lookupToString(int lookupType) { - switch (lookupType) { - case LOOKUP_LOCAL_CONTACT: - return "Local"; - case LOOKUP_LOCAL_CACHE: - return "Cache"; - case LOOKUP_REMOTE_CONTACT: - return "Remote"; - case LOOKUP_EMERGENCY: - return "Emergency"; - case LOOKUP_VOICEMAIL: - return "Voicemail"; - default: - return "Not found"; - } - } - - private static String initiationToString(int initiationType) { - switch (initiationType) { - case INITIATION_INCOMING: - return "Incoming"; - case INITIATION_DIALPAD: - return "Dialpad"; - case INITIATION_SPEED_DIAL: - return "Speed Dial"; - case INITIATION_REMOTE_DIRECTORY: - return "Remote Directory"; - case INITIATION_SMART_DIAL: - return "Smart Dial"; - case INITIATION_REGULAR_SEARCH: - return "Regular Search"; - case INITIATION_CALL_LOG: - return "Call Log"; - case INITIATION_CALL_LOG_FILTER: - return "Call Log Filter"; - case INITIATION_VOICEMAIL_LOG: - return "Voicemail Log"; - case INITIATION_CALL_DETAILS: - return "Call Details"; - case INITIATION_QUICK_CONTACTS: - return "Quick Contacts"; - default: - return "Unknown"; - } - } - } - - - private static final String ID_PREFIX = Call.class.getSimpleName() + "_"; - private static int sIdCounter = 0; - - private final android.telecom.Call.Callback mTelecomCallCallback = - new android.telecom.Call.Callback() { - @Override - public void onStateChanged(android.telecom.Call call, int newState) { - Log.d(this, "TelecomCallCallback onStateChanged call=" + call + " newState=" - + newState); - update(); - } - - @Override - public void onParentChanged(android.telecom.Call call, - android.telecom.Call newParent) { - Log.d(this, "TelecomCallCallback onParentChanged call=" + call + " newParent=" - + newParent); - update(); - } - - @Override - public void onChildrenChanged(android.telecom.Call call, - List children) { - update(); - } - - @Override - public void onDetailsChanged(android.telecom.Call call, - android.telecom.Call.Details details) { - Log.d(this, "TelecomCallCallback onStateChanged call=" + call + " details=" - + details); - update(); - } - - @Override - public void onCannedTextResponsesLoaded(android.telecom.Call call, - List cannedTextResponses) { - Log.d(this, "TelecomCallCallback onStateChanged call=" + call - + " cannedTextResponses=" + cannedTextResponses); - update(); - } - - @Override - public void onPostDialWait(android.telecom.Call call, - String remainingPostDialSequence) { - Log.d(this, "TelecomCallCallback onStateChanged call=" + call - + " remainingPostDialSequence=" + remainingPostDialSequence); - update(); - } - - @Override - public void onVideoCallChanged(android.telecom.Call call, - VideoCall videoCall) { - Log.d(this, "TelecomCallCallback onStateChanged call=" + call + " videoCall=" - + videoCall); - update(); - } - - @Override - public void onCallDestroyed(android.telecom.Call call) { - Log.d(this, "TelecomCallCallback onStateChanged call=" + call); - call.unregisterCallback(this); - } - - @Override - public void onConferenceableCallsChanged(android.telecom.Call call, - List conferenceableCalls) { - update(); - } - }; - - private final android.telecom.Call mTelecomCall; - private final LatencyReport mLatencyReport; - private boolean mIsEmergencyCall; - private Uri mHandle; - private final String mId; - private int mState = State.INVALID; - private DisconnectCause mDisconnectCause; - private int mSessionModificationState; - private final List mChildCallIds = new ArrayList<>(); - private final VideoSettings mVideoSettings = new VideoSettings(); - private int mVideoState; - - /** - * mRequestedVideoState is used to store requested upgrade / downgrade video state - */ - private int mRequestedVideoState = VideoProfile.STATE_AUDIO_ONLY; - - private InCallVideoCallCallback mVideoCallCallback; - private boolean mIsVideoCallCallbackRegistered; - private String mChildNumber; - private String mLastForwardedNumber; - private String mCallSubject; - private PhoneAccountHandle mPhoneAccountHandle; - @CallHistoryStatus private int mCallHistoryStatus = CALL_HISTORY_STATUS_UNKNOWN; - private boolean mIsSpam; - - /** - * Indicates whether the phone account associated with this call supports specifying a call - * subject. - */ - private boolean mIsCallSubjectSupported; - - private long mTimeAddedMs; - - private final LogState mLogState = new LogState(); - - /** - * Used only to create mock calls for testing - */ - @NeededForTesting - Call(int state) { - mTelecomCall = null; - mLatencyReport = new LatencyReport(); - mId = ID_PREFIX + Integer.toString(sIdCounter++); - setState(state); - } - - /** - * Creates a new instance of a {@link Call}. Registers a callback for - * {@link android.telecom.Call} events. - */ - public Call(android.telecom.Call telecomCall, LatencyReport latencyReport) { - this(telecomCall, latencyReport, true /* registerCallback */); - } - - /** - * Creates a new instance of a {@link Call}. Optionally registers a callback for - * {@link android.telecom.Call} events. - * - * Intended for use when creating a {@link Call} instance for use with the - * {@link ContactInfoCache}, where we do not want to register callbacks for the new call. - */ - public Call(android.telecom.Call telecomCall, LatencyReport latencyReport, - boolean registerCallback) { - mTelecomCall = telecomCall; - mLatencyReport = latencyReport; - mId = ID_PREFIX + Integer.toString(sIdCounter++); - - updateFromTelecomCall(registerCallback); - - if (registerCallback) { - mTelecomCall.registerCallback(mTelecomCallCallback); - } - - mTimeAddedMs = System.currentTimeMillis(); - } - - public android.telecom.Call getTelecomCall() { - return mTelecomCall; - } - - /** - * @return video settings of the call, null if the call is not a video call. - * @see VideoProfile - */ - public VideoSettings getVideoSettings() { - return mVideoSettings; - } - - private void update() { - Trace.beginSection("Update"); - int oldState = getState(); - // We want to potentially register a video call callback here. - updateFromTelecomCall(true /* registerCallback */); - if (oldState != getState() && getState() == Call.State.DISCONNECTED) { - CallList.getInstance().onDisconnect(this); - } else { - CallList.getInstance().onUpdate(this); - } - Trace.endSection(); - } - - private void updateFromTelecomCall(boolean registerCallback) { - Log.d(this, "updateFromTelecomCall: " + mTelecomCall.toString()); - final int translatedState = translateState(mTelecomCall.getState()); - if (mState != State.BLOCKED) { - setState(translatedState); - setDisconnectCause(mTelecomCall.getDetails().getDisconnectCause()); - maybeCancelVideoUpgrade(mTelecomCall.getDetails().getVideoState()); - } - - if (registerCallback && mTelecomCall.getVideoCall() != null) { - if (mVideoCallCallback == null) { - mVideoCallCallback = new InCallVideoCallCallback(this); - } - mTelecomCall.getVideoCall().registerCallback(mVideoCallCallback); - mIsVideoCallCallbackRegistered = true; - } - - mChildCallIds.clear(); - final int numChildCalls = mTelecomCall.getChildren().size(); - for (int i = 0; i < numChildCalls; i++) { - mChildCallIds.add( - CallList.getInstance().getCallByTelecomCall( - mTelecomCall.getChildren().get(i)).getId()); - } - - // The number of conferenced calls can change over the course of the call, so use the - // maximum number of conferenced child calls as the metric for conference call usage. - mLogState.conferencedCalls = Math.max(numChildCalls, mLogState.conferencedCalls); - - updateFromCallExtras(mTelecomCall.getDetails().getExtras()); - - // If the handle of the call has changed, update state for the call determining if it is an - // emergency call. - Uri newHandle = mTelecomCall.getDetails().getHandle(); - if (!Objects.equals(mHandle, newHandle)) { - mHandle = newHandle; - updateEmergencyCallState(); - } - - // If the phone account handle of the call is set, cache capability bit indicating whether - // the phone account supports call subjects. - PhoneAccountHandle newPhoneAccountHandle = mTelecomCall.getDetails().getAccountHandle(); - if (!Objects.equals(mPhoneAccountHandle, newPhoneAccountHandle)) { - mPhoneAccountHandle = newPhoneAccountHandle; - - if (mPhoneAccountHandle != null) { - TelecomManager mgr = InCallPresenter.getInstance().getTelecomManager(); - PhoneAccount phoneAccount = - TelecomManagerCompat.getPhoneAccount(mgr, mPhoneAccountHandle); - if (phoneAccount != null) { - mIsCallSubjectSupported = phoneAccount.hasCapabilities( - PhoneAccount.CAPABILITY_CALL_SUBJECT); - } - } - } - } - - /** - * Tests corruption of the {@code callExtras} bundle by calling {@link - * Bundle#containsKey(String)}. If the bundle is corrupted a {@link IllegalArgumentException} - * will be thrown and caught by this function. - * - * @param callExtras the bundle to verify - * @returns {@code true} if the bundle is corrupted, {@code false} otherwise. - */ - protected boolean areCallExtrasCorrupted(Bundle callExtras) { - /** - * There's currently a bug in Telephony service (b/25613098) that could corrupt the - * extras bundle, resulting in a IllegalArgumentException while validating data under - * {@link Bundle#containsKey(String)}. - */ - try { - callExtras.containsKey(Connection.EXTRA_CHILD_ADDRESS); - return false; - } catch (IllegalArgumentException e) { - Log.e(this, "CallExtras is corrupted, ignoring exception", e); - return true; - } - } - - protected void updateFromCallExtras(Bundle callExtras) { - if (callExtras == null || areCallExtrasCorrupted(callExtras)) { - /** - * If the bundle is corrupted, abandon information update as a work around. These are - * not critical for the dialer to function. - */ - return; - } - // Check for a change in the child address and notify any listeners. - if (callExtras.containsKey(Connection.EXTRA_CHILD_ADDRESS)) { - String childNumber = callExtras.getString(Connection.EXTRA_CHILD_ADDRESS); - if (!Objects.equals(childNumber, mChildNumber)) { - mChildNumber = childNumber; - CallList.getInstance().onChildNumberChange(this); - } - } - - // Last forwarded number comes in as an array of strings. We want to choose the - // last item in the array. The forwarding numbers arrive independently of when the - // call is originally set up, so we need to notify the the UI of the change. - if (callExtras.containsKey(Connection.EXTRA_LAST_FORWARDED_NUMBER)) { - ArrayList lastForwardedNumbers = - callExtras.getStringArrayList(Connection.EXTRA_LAST_FORWARDED_NUMBER); - - if (lastForwardedNumbers != null) { - String lastForwardedNumber = null; - if (!lastForwardedNumbers.isEmpty()) { - lastForwardedNumber = lastForwardedNumbers.get( - lastForwardedNumbers.size() - 1); - } - - if (!Objects.equals(lastForwardedNumber, mLastForwardedNumber)) { - mLastForwardedNumber = lastForwardedNumber; - CallList.getInstance().onLastForwardedNumberChange(this); - } - } - } - - // Call subject is present in the extras at the start of call, so we do not need to - // notify any other listeners of this. - if (callExtras.containsKey(Connection.EXTRA_CALL_SUBJECT)) { - String callSubject = callExtras.getString(Connection.EXTRA_CALL_SUBJECT); - if (!Objects.equals(mCallSubject, callSubject)) { - mCallSubject = callSubject; - } - } - } - - /** - * Determines if a received upgrade to video request should be cancelled. This can happen if - * another InCall UI responds to the upgrade to video request. - * - * @param newVideoState The new video state. - */ - private void maybeCancelVideoUpgrade(int newVideoState) { - boolean isVideoStateChanged = mVideoState != newVideoState; - - if (mSessionModificationState == SessionModificationState.RECEIVED_UPGRADE_TO_VIDEO_REQUEST - && isVideoStateChanged) { - - Log.v(this, "maybeCancelVideoUpgrade : cancelling upgrade notification"); - setSessionModificationState(SessionModificationState.NO_REQUEST); - } - mVideoState = newVideoState; - } - private static int translateState(int state) { - switch (state) { - case android.telecom.Call.STATE_NEW: - case android.telecom.Call.STATE_CONNECTING: - return Call.State.CONNECTING; - case android.telecom.Call.STATE_SELECT_PHONE_ACCOUNT: - return Call.State.SELECT_PHONE_ACCOUNT; - case android.telecom.Call.STATE_DIALING: - return Call.State.DIALING; - case android.telecom.Call.STATE_RINGING: - return Call.State.INCOMING; - case android.telecom.Call.STATE_ACTIVE: - return Call.State.ACTIVE; - case android.telecom.Call.STATE_HOLDING: - return Call.State.ONHOLD; - case android.telecom.Call.STATE_DISCONNECTED: - return Call.State.DISCONNECTED; - case android.telecom.Call.STATE_DISCONNECTING: - return Call.State.DISCONNECTING; - default: - return Call.State.INVALID; - } - } - - public String getId() { - return mId; - } - - public long getTimeAddedMs() { - return mTimeAddedMs; - } - - public String getNumber() { - return TelecomCallUtil.getNumber(mTelecomCall); - } - - public void blockCall() { - mTelecomCall.reject(false, null); - setState(State.BLOCKED); - } - - public Uri getHandle() { - return mTelecomCall == null ? null : mTelecomCall.getDetails().getHandle(); - } - - public boolean isEmergencyCall() { - return mIsEmergencyCall; - } - - public int getState() { - if (mTelecomCall != null && mTelecomCall.getParent() != null) { - return State.CONFERENCED; - } else { - return mState; - } - } - - public void setState(int state) { - mState = state; - if (mState == State.INCOMING) { - mLogState.isIncoming = true; - } else if (mState == State.DISCONNECTED) { - mLogState.duration = getConnectTimeMillis() == 0 ? - 0: System.currentTimeMillis() - getConnectTimeMillis(); - } - } - - public int getNumberPresentation() { - return mTelecomCall == null ? null : mTelecomCall.getDetails().getHandlePresentation(); - } - - public int getCnapNamePresentation() { - return mTelecomCall == null ? null - : mTelecomCall.getDetails().getCallerDisplayNamePresentation(); - } - - public String getCnapName() { - return mTelecomCall == null ? null - : getTelecomCall().getDetails().getCallerDisplayName(); - } - - public Bundle getIntentExtras() { - return mTelecomCall.getDetails().getIntentExtras(); - } - - public Bundle getExtras() { - return mTelecomCall == null ? null : mTelecomCall.getDetails().getExtras(); - } - - /** - * @return The child number for the call, or {@code null} if none specified. - */ - public String getChildNumber() { - return mChildNumber; - } - - /** - * @return The last forwarded number for the call, or {@code null} if none specified. - */ - public String getLastForwardedNumber() { - return mLastForwardedNumber; - } - - /** - * @return The call subject, or {@code null} if none specified. - */ - public String getCallSubject() { - return mCallSubject; - } - - /** - * @return {@code true} if the call's phone account supports call subjects, {@code false} - * otherwise. - */ - public boolean isCallSubjectSupported() { - return mIsCallSubjectSupported; - } - - /** Returns call disconnect cause, defined by {@link DisconnectCause}. */ - public DisconnectCause getDisconnectCause() { - if (mState == State.DISCONNECTED || mState == State.IDLE) { - return mDisconnectCause; - } - - return new DisconnectCause(DisconnectCause.UNKNOWN); - } - - public void setDisconnectCause(DisconnectCause disconnectCause) { - mDisconnectCause = disconnectCause; - mLogState.disconnectCause = mDisconnectCause; - } - - /** Returns the possible text message responses. */ - public List getCannedSmsResponses() { - return mTelecomCall.getCannedTextResponses(); - } - - /** Checks if the call supports the given set of capabilities supplied as a bit mask. */ - public boolean can(int capabilities) { - int supportedCapabilities = mTelecomCall.getDetails().getCallCapabilities(); - - if ((capabilities & android.telecom.Call.Details.CAPABILITY_MERGE_CONFERENCE) != 0) { - // We allow you to merge if the capabilities allow it or if it is a call with - // conferenceable calls. - if (mTelecomCall.getConferenceableCalls().isEmpty() && - ((android.telecom.Call.Details.CAPABILITY_MERGE_CONFERENCE - & supportedCapabilities) == 0)) { - // Cannot merge calls if there are no calls to merge with. - return false; - } - capabilities &= ~android.telecom.Call.Details.CAPABILITY_MERGE_CONFERENCE; - } - return (capabilities == (capabilities & mTelecomCall.getDetails().getCallCapabilities())); - } - - public boolean hasProperty(int property) { - return mTelecomCall.getDetails().hasProperty(property); - } - - /** Gets the time when the call first became active. */ - public long getConnectTimeMillis() { - return mTelecomCall.getDetails().getConnectTimeMillis(); - } - - public boolean isConferenceCall() { - return hasProperty(android.telecom.Call.Details.PROPERTY_CONFERENCE); - } - - public GatewayInfo getGatewayInfo() { - return mTelecomCall == null ? null : mTelecomCall.getDetails().getGatewayInfo(); - } - - public PhoneAccountHandle getAccountHandle() { - return mTelecomCall == null ? null : mTelecomCall.getDetails().getAccountHandle(); - } - - /** - * @return The {@link VideoCall} instance associated with the {@link android.telecom.Call}. - * Will return {@code null} until {@link #updateFromTelecomCall()} has registered a valid - * callback on the {@link VideoCall}. - */ - public VideoCall getVideoCall() { - return mTelecomCall == null || !mIsVideoCallCallbackRegistered ? null - : mTelecomCall.getVideoCall(); - } - - public List getChildCallIds() { - return mChildCallIds; - } - - public String getParentId() { - android.telecom.Call parentCall = mTelecomCall.getParent(); - if (parentCall != null) { - return CallList.getInstance().getCallByTelecomCall(parentCall).getId(); - } - return null; - } - - public int getVideoState() { - return mTelecomCall.getDetails().getVideoState(); - } - - public boolean isVideoCall(Context context) { - return CallUtil.isVideoEnabled(context) && - VideoUtils.isVideoCall(getVideoState()); - } - - /** - * Handles incoming session modification requests. Stores the pending video request and sets - * the session modification state to - * {@link SessionModificationState#RECEIVED_UPGRADE_TO_VIDEO_REQUEST} so that we can keep track - * of the fact the request was received. Only upgrade requests require user confirmation and - * will be handled by this method. The remote user can turn off their own camera without - * confirmation. - * - * @param videoState The requested video state. - */ - public void setRequestedVideoState(int videoState) { - Log.d(this, "setRequestedVideoState - video state= " + videoState); - if (videoState == getVideoState()) { - mSessionModificationState = Call.SessionModificationState.NO_REQUEST; - Log.w(this,"setRequestedVideoState - Clearing session modification state"); - return; - } - - mSessionModificationState = Call.SessionModificationState.RECEIVED_UPGRADE_TO_VIDEO_REQUEST; - mRequestedVideoState = videoState; - CallList.getInstance().onUpgradeToVideo(this); - - Log.d(this, "setRequestedVideoState - mSessionModificationState=" - + mSessionModificationState + " video state= " + videoState); - update(); - } - - /** - * Set the session modification state. Used to keep track of pending video session modification - * operations and to inform listeners of these changes. - * - * @param state the new session modification state. - */ - public void setSessionModificationState(int state) { - boolean hasChanged = mSessionModificationState != state; - mSessionModificationState = state; - Log.d(this, "setSessionModificationState " + state + " mSessionModificationState=" - + mSessionModificationState); - if (hasChanged) { - CallList.getInstance().onSessionModificationStateChange(this, state); - } - } - - /** - * Determines if the call handle is an emergency number or not and caches the result to avoid - * repeated calls to isEmergencyNumber. - */ - private void updateEmergencyCallState() { - mIsEmergencyCall = TelecomCallUtil.isEmergencyCall(mTelecomCall); - } - - /** - * Gets the video state which was requested via a session modification request. - * - * @return The video state. - */ - public int getRequestedVideoState() { - return mRequestedVideoState; - } - - public static boolean areSame(Call call1, Call call2) { - if (call1 == null && call2 == null) { - return true; - } else if (call1 == null || call2 == null) { - return false; - } - - // otherwise compare call Ids - return call1.getId().equals(call2.getId()); - } - - public static boolean areSameNumber(Call call1, Call call2) { - if (call1 == null && call2 == null) { - return true; - } else if (call1 == null || call2 == null) { - return false; - } - - // otherwise compare call Numbers - return TextUtils.equals(call1.getNumber(), call2.getNumber()); - } - - /** - * Gets the current video session modification state. - * - * @return The session modification state. - */ - public int getSessionModificationState() { - return mSessionModificationState; - } - - public LogState getLogState() { - return mLogState; - } - - /** - * Determines if the call is an external call. - * - * An external call is one which does not exist locally for the - * {@link android.telecom.ConnectionService} it is associated with. - * - * External calls are only supported in N and higher. - * - * @return {@code true} if the call is an external call, {@code false} otherwise. - */ - public boolean isExternalCall() { - return CompatUtils.isNCompatible() && - hasProperty(CallSdkCompat.Details.PROPERTY_IS_EXTERNAL_CALL); - } - - /** - * Determines if the external call is pullable. - * - * An external call is one which does not exist locally for the - * {@link android.telecom.ConnectionService} it is associated with. An external call may be - * "pullable", which means that the user can request it be transferred to the current device. - * - * External calls are only supported in N and higher. - * - * @return {@code true} if the call is an external call, {@code false} otherwise. - */ - public boolean isPullableExternalCall() { - return CompatUtils.isNCompatible() && - (mTelecomCall.getDetails().getCallCapabilities() - & CallSdkCompat.Details.CAPABILITY_CAN_PULL_CALL) - == CallSdkCompat.Details.CAPABILITY_CAN_PULL_CALL; - } - - /** - * Logging utility methods - */ - public void logCallInitiationType() { - if (isExternalCall()) { - return; - } - - if (getState() == State.INCOMING) { - getLogState().callInitiationMethod = LogState.INITIATION_INCOMING; - } else if (getIntentExtras() != null) { - getLogState().callInitiationMethod = - getIntentExtras().getInt(IntentUtil.EXTRA_CALL_INITIATION_TYPE, - LogState.INITIATION_EXTERNAL); - } - } - - @Override - public String toString() { - if (mTelecomCall == null) { - // This should happen only in testing since otherwise we would never have a null - // Telecom call. - return String.valueOf(mId); - } - - return String.format(Locale.US, "[%s, %s, %s, %s, children:%s, parent:%s, " + - "conferenceable:%s, videoState:%s, mSessionModificationState:%d, VideoSettings:%s]", - mId, - State.toString(getState()), - Details.capabilitiesToString(mTelecomCall.getDetails().getCallCapabilities()), - Details.propertiesToString(mTelecomCall.getDetails().getCallProperties()), - mChildCallIds, - getParentId(), - this.mTelecomCall.getConferenceableCalls(), - VideoProfile.videoStateToString(mTelecomCall.getDetails().getVideoState()), - mSessionModificationState, - getVideoSettings()); - } - - public String toSimpleString() { - return super.toString(); - } - - public void setCallHistoryStatus(@CallHistoryStatus int callHistoryStatus) { - mCallHistoryStatus = callHistoryStatus; - } - - @CallHistoryStatus - public int getCallHistoryStatus() { - return mCallHistoryStatus; - } - - public void setSpam(boolean isSpam) { - mIsSpam = isSpam; - } - - public boolean isSpam() { - return mIsSpam; - } - - public LatencyReport getLatencyReport() { - return mLatencyReport; - } -} diff --git a/InCallUI/src/com/android/incallui/CallButtonFragment.java b/InCallUI/src/com/android/incallui/CallButtonFragment.java deleted file mode 100644 index 6b633eaf3..000000000 --- a/InCallUI/src/com/android/incallui/CallButtonFragment.java +++ /dev/null @@ -1,819 +0,0 @@ -/* - * Copyright (C) 2013 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License - */ - -package com.android.incallui; - -import static com.android.incallui.CallButtonFragment.Buttons.BUTTON_ADD_CALL; -import static com.android.incallui.CallButtonFragment.Buttons.BUTTON_AUDIO; -import static com.android.incallui.CallButtonFragment.Buttons.BUTTON_COUNT; -import static com.android.incallui.CallButtonFragment.Buttons.BUTTON_DIALPAD; -import static com.android.incallui.CallButtonFragment.Buttons.BUTTON_DOWNGRADE_TO_AUDIO; -import static com.android.incallui.CallButtonFragment.Buttons.BUTTON_HOLD; -import static com.android.incallui.CallButtonFragment.Buttons.BUTTON_MANAGE_VIDEO_CONFERENCE; -import static com.android.incallui.CallButtonFragment.Buttons.BUTTON_MERGE; -import static com.android.incallui.CallButtonFragment.Buttons.BUTTON_MUTE; -import static com.android.incallui.CallButtonFragment.Buttons.BUTTON_PAUSE_VIDEO; -import static com.android.incallui.CallButtonFragment.Buttons.BUTTON_SWAP; -import static com.android.incallui.CallButtonFragment.Buttons.BUTTON_SWITCH_CAMERA; -import static com.android.incallui.CallButtonFragment.Buttons.BUTTON_UPGRADE_TO_VIDEO; - -import android.content.Context; -import android.content.res.ColorStateList; -import android.content.res.Resources; -import android.graphics.drawable.Drawable; -import android.graphics.drawable.GradientDrawable; -import android.graphics.drawable.LayerDrawable; -import android.graphics.drawable.RippleDrawable; -import android.graphics.drawable.StateListDrawable; -import android.os.Bundle; -import android.telecom.CallAudioState; -import android.util.SparseIntArray; -import android.view.ContextThemeWrapper; -import android.view.HapticFeedbackConstants; -import android.view.LayoutInflater; -import android.view.Menu; -import android.view.MenuItem; -import android.view.View; -import android.view.ViewGroup; -import android.widget.CompoundButton; -import android.widget.ImageButton; -import android.widget.PopupMenu; -import android.widget.PopupMenu.OnDismissListener; -import android.widget.PopupMenu.OnMenuItemClickListener; - -import com.android.contacts.common.util.MaterialColorMapUtils.MaterialPalette; -import com.android.dialer.R; - -/** - * Fragment for call control buttons - */ -public class CallButtonFragment - extends BaseFragment - implements CallButtonPresenter.CallButtonUi, OnMenuItemClickListener, OnDismissListener, - View.OnClickListener { - - private int mButtonMaxVisible; - // The button is currently visible in the UI - private static final int BUTTON_VISIBLE = 1; - // The button is hidden in the UI - private static final int BUTTON_HIDDEN = 2; - // The button has been collapsed into the overflow menu - private static final int BUTTON_MENU = 3; - - public interface Buttons { - - public static final int BUTTON_AUDIO = 0; - public static final int BUTTON_MUTE = 1; - public static final int BUTTON_DIALPAD = 2; - public static final int BUTTON_HOLD = 3; - public static final int BUTTON_SWAP = 4; - public static final int BUTTON_UPGRADE_TO_VIDEO = 5; - public static final int BUTTON_SWITCH_CAMERA = 6; - public static final int BUTTON_DOWNGRADE_TO_AUDIO = 7; - public static final int BUTTON_ADD_CALL = 8; - public static final int BUTTON_MERGE = 9; - public static final int BUTTON_PAUSE_VIDEO = 10; - public static final int BUTTON_MANAGE_VIDEO_CONFERENCE = 11; - public static final int BUTTON_COUNT = 12; - } - - private SparseIntArray mButtonVisibilityMap = new SparseIntArray(BUTTON_COUNT); - - private CompoundButton mAudioButton; - private CompoundButton mMuteButton; - private CompoundButton mShowDialpadButton; - private CompoundButton mHoldButton; - private ImageButton mSwapButton; - private ImageButton mChangeToVideoButton; - private ImageButton mChangeToVoiceButton; - private CompoundButton mSwitchCameraButton; - private ImageButton mAddCallButton; - private ImageButton mMergeButton; - private CompoundButton mPauseVideoButton; - private ImageButton mOverflowButton; - private ImageButton mManageVideoCallConferenceButton; - - private PopupMenu mAudioModePopup; - private boolean mAudioModePopupVisible; - private PopupMenu mOverflowPopup; - - private int mPrevAudioMode = 0; - - // Constants for Drawable.setAlpha() - private static final int HIDDEN = 0; - private static final int VISIBLE = 255; - - private boolean mIsEnabled; - private MaterialPalette mCurrentThemeColors; - - @Override - public CallButtonPresenter createPresenter() { - // TODO: find a cleaner way to include audio mode provider than having a singleton instance. - return new CallButtonPresenter(); - } - - @Override - public CallButtonPresenter.CallButtonUi getUi() { - return this; - } - - @Override - public void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - - for (int i = 0; i < BUTTON_COUNT; i++) { - mButtonVisibilityMap.put(i, BUTTON_HIDDEN); - } - - mButtonMaxVisible = getResources().getInteger(R.integer.call_card_max_buttons); - } - - @Override - public View onCreateView(LayoutInflater inflater, ViewGroup container, - Bundle savedInstanceState) { - final View parent = inflater.inflate(R.layout.call_button_fragment, container, false); - - mAudioButton = (CompoundButton) parent.findViewById(R.id.audioButton); - mAudioButton.setOnClickListener(this); - mMuteButton = (CompoundButton) parent.findViewById(R.id.muteButton); - mMuteButton.setOnClickListener(this); - mShowDialpadButton = (CompoundButton) parent.findViewById(R.id.dialpadButton); - mShowDialpadButton.setOnClickListener(this); - mHoldButton = (CompoundButton) parent.findViewById(R.id.holdButton); - mHoldButton.setOnClickListener(this); - mSwapButton = (ImageButton) parent.findViewById(R.id.swapButton); - mSwapButton.setOnClickListener(this); - mChangeToVideoButton = (ImageButton) parent.findViewById(R.id.changeToVideoButton); - mChangeToVideoButton.setOnClickListener(this); - mChangeToVoiceButton = (ImageButton) parent.findViewById(R.id.changeToVoiceButton); - mChangeToVoiceButton.setOnClickListener(this); - mSwitchCameraButton = (CompoundButton) parent.findViewById(R.id.switchCameraButton); - mSwitchCameraButton.setOnClickListener(this); - mAddCallButton = (ImageButton) parent.findViewById(R.id.addButton); - mAddCallButton.setOnClickListener(this); - mMergeButton = (ImageButton) parent.findViewById(R.id.mergeButton); - mMergeButton.setOnClickListener(this); - mPauseVideoButton = (CompoundButton) parent.findViewById(R.id.pauseVideoButton); - mPauseVideoButton.setOnClickListener(this); - mOverflowButton = (ImageButton) parent.findViewById(R.id.overflowButton); - mOverflowButton.setOnClickListener(this); - mManageVideoCallConferenceButton = (ImageButton) parent.findViewById( - R.id.manageVideoCallConferenceButton); - mManageVideoCallConferenceButton.setOnClickListener(this); - return parent; - } - - @Override - public void onActivityCreated(Bundle savedInstanceState) { - super.onActivityCreated(savedInstanceState); - - // set the buttons - updateAudioButtons(); - } - - @Override - public void onResume() { - if (getPresenter() != null) { - getPresenter().refreshMuteState(); - } - super.onResume(); - - updateColors(); - } - - @Override - public void onClick(View view) { - int id = view.getId(); - Log.d(this, "onClick(View " + view + ", id " + id + ")..."); - - if (id == R.id.audioButton) { - onAudioButtonClicked(); - } else if (id == R.id.addButton) { - getPresenter().addCallClicked(); - } else if (id == R.id.muteButton) { - getPresenter().muteClicked(!mMuteButton.isSelected()); - } else if (id == R.id.mergeButton) { - getPresenter().mergeClicked(); - mMergeButton.setEnabled(false); - } else if (id == R.id.holdButton) { - getPresenter().holdClicked(!mHoldButton.isSelected()); - } else if (id == R.id.swapButton) { - getPresenter().swapClicked(); - } else if (id == R.id.dialpadButton) { - getPresenter().showDialpadClicked(!mShowDialpadButton.isSelected()); - } else if (id == R.id.changeToVideoButton) { - getPresenter().changeToVideoClicked(); - } else if (id == R.id.changeToVoiceButton) { - getPresenter().changeToVoiceClicked(); - } else if (id == R.id.switchCameraButton) { - getPresenter().switchCameraClicked( - mSwitchCameraButton.isSelected() /* useFrontFacingCamera */); - } else if (id == R.id.pauseVideoButton) { - getPresenter().pauseVideoClicked( - !mPauseVideoButton.isSelected() /* pause */); - } else if (id == R.id.overflowButton) { - if (mOverflowPopup != null) { - mOverflowPopup.show(); - } - } else if (id == R.id.manageVideoCallConferenceButton) { - onManageVideoCallConferenceClicked(); - } else { - Log.wtf(this, "onClick: unexpected"); - return; - } - - view.performHapticFeedback( - HapticFeedbackConstants.VIRTUAL_KEY, - HapticFeedbackConstants.FLAG_IGNORE_GLOBAL_SETTING); - } - - public void updateColors() { - MaterialPalette themeColors = InCallPresenter.getInstance().getThemeColors(); - - if (mCurrentThemeColors != null && mCurrentThemeColors.equals(themeColors)) { - return; - } - - View[] compoundButtons = { - mAudioButton, - mMuteButton, - mShowDialpadButton, - mHoldButton, - mSwitchCameraButton, - mPauseVideoButton - }; - - for (View button : compoundButtons) { - final LayerDrawable layers = (LayerDrawable) button.getBackground(); - final RippleDrawable btnCompoundDrawable = compoundBackgroundDrawable(themeColors); - layers.setDrawableByLayerId(R.id.compoundBackgroundItem, btnCompoundDrawable); - } - - ImageButton[] normalButtons = { - mSwapButton, - mChangeToVideoButton, - mChangeToVoiceButton, - mAddCallButton, - mMergeButton, - mOverflowButton - }; - - for (ImageButton button : normalButtons) { - final LayerDrawable layers = (LayerDrawable) button.getBackground(); - final RippleDrawable btnDrawable = backgroundDrawable(themeColors); - layers.setDrawableByLayerId(R.id.backgroundItem, btnDrawable); - } - - mCurrentThemeColors = themeColors; - } - - /** - * Generate a RippleDrawable which will be the background for a compound button, i.e. - * a button with pressed and unpressed states. The unpressed state will be the same color - * as the rest of the call card, the pressed state will be the dark version of that color. - */ - private RippleDrawable compoundBackgroundDrawable(MaterialPalette palette) { - Resources res = getResources(); - ColorStateList rippleColor = - ColorStateList.valueOf(res.getColor(R.color.incall_accent_color)); - - StateListDrawable stateListDrawable = new StateListDrawable(); - addSelectedAndFocused(res, stateListDrawable); - addFocused(res, stateListDrawable); - addSelected(res, stateListDrawable, palette); - addUnselected(res, stateListDrawable, palette); - - return new RippleDrawable(rippleColor, stateListDrawable, null); - } - - /** - * Generate a RippleDrawable which will be the background of a button to ensure it - * is the same color as the rest of the call card. - */ - private RippleDrawable backgroundDrawable(MaterialPalette palette) { - Resources res = getResources(); - ColorStateList rippleColor = - ColorStateList.valueOf(res.getColor(R.color.incall_accent_color)); - - StateListDrawable stateListDrawable = new StateListDrawable(); - addFocused(res, stateListDrawable); - addUnselected(res, stateListDrawable, palette); - - return new RippleDrawable(rippleColor, stateListDrawable, null); - } - - // state_selected and state_focused - private void addSelectedAndFocused(Resources res, StateListDrawable drawable) { - int[] selectedAndFocused = {android.R.attr.state_selected, android.R.attr.state_focused}; - Drawable selectedAndFocusedDrawable = res.getDrawable(R.drawable.btn_selected_focused); - drawable.addState(selectedAndFocused, selectedAndFocusedDrawable); - } - - // state_focused - private void addFocused(Resources res, StateListDrawable drawable) { - int[] focused = {android.R.attr.state_focused}; - Drawable focusedDrawable = res.getDrawable(R.drawable.btn_unselected_focused); - drawable.addState(focused, focusedDrawable); - } - - // state_selected - private void addSelected(Resources res, StateListDrawable drawable, MaterialPalette palette) { - int[] selected = {android.R.attr.state_selected}; - LayerDrawable selectedDrawable = (LayerDrawable) res.getDrawable(R.drawable.btn_selected); - ((GradientDrawable) selectedDrawable.getDrawable(0)).setColor(palette.mSecondaryColor); - drawable.addState(selected, selectedDrawable); - } - - // default - private void addUnselected(Resources res, StateListDrawable drawable, MaterialPalette palette) { - LayerDrawable unselectedDrawable = - (LayerDrawable) res.getDrawable(R.drawable.btn_unselected); - ((GradientDrawable) unselectedDrawable.getDrawable(0)).setColor(palette.mPrimaryColor); - drawable.addState(new int[0], unselectedDrawable); - } - - @Override - public void setEnabled(boolean isEnabled) { - mIsEnabled = isEnabled; - - mAudioButton.setEnabled(isEnabled); - mMuteButton.setEnabled(isEnabled); - mShowDialpadButton.setEnabled(isEnabled); - mHoldButton.setEnabled(isEnabled); - mSwapButton.setEnabled(isEnabled); - mChangeToVideoButton.setEnabled(isEnabled); - mChangeToVoiceButton.setEnabled(isEnabled); - mSwitchCameraButton.setEnabled(isEnabled); - mAddCallButton.setEnabled(isEnabled); - mMergeButton.setEnabled(isEnabled); - mPauseVideoButton.setEnabled(isEnabled); - mOverflowButton.setEnabled(isEnabled); - mManageVideoCallConferenceButton.setEnabled(isEnabled); - } - - @Override - public void showButton(int buttonId, boolean show) { - mButtonVisibilityMap.put(buttonId, show ? BUTTON_VISIBLE : BUTTON_HIDDEN); - } - - @Override - public void enableButton(int buttonId, boolean enable) { - final View button = getButtonById(buttonId); - if (button != null) { - button.setEnabled(enable); - } - } - - private View getButtonById(int id) { - if (id == BUTTON_AUDIO) { - return mAudioButton; - } else if (id == BUTTON_MUTE) { - return mMuteButton; - } else if (id == BUTTON_DIALPAD) { - return mShowDialpadButton; - } else if (id == BUTTON_HOLD) { - return mHoldButton; - } else if (id == BUTTON_SWAP) { - return mSwapButton; - } else if (id == BUTTON_UPGRADE_TO_VIDEO) { - return mChangeToVideoButton; - } else if (id == BUTTON_DOWNGRADE_TO_AUDIO) { - return mChangeToVoiceButton; - } else if (id == BUTTON_SWITCH_CAMERA) { - return mSwitchCameraButton; - } else if (id == BUTTON_ADD_CALL) { - return mAddCallButton; - } else if (id == BUTTON_MERGE) { - return mMergeButton; - } else if (id == BUTTON_PAUSE_VIDEO) { - return mPauseVideoButton; - } else if (id == BUTTON_MANAGE_VIDEO_CONFERENCE) { - return mManageVideoCallConferenceButton; - } else { - Log.w(this, "Invalid button id"); - return null; - } - } - - @Override - public void setHold(boolean value) { - if (mHoldButton.isSelected() != value) { - mHoldButton.setSelected(value); - mHoldButton.setContentDescription(getContext().getString( - value ? R.string.onscreenHoldText_selected - : R.string.onscreenHoldText_unselected)); - } - } - - @Override - public void setCameraSwitched(boolean isBackFacingCamera) { - mSwitchCameraButton.setSelected(isBackFacingCamera); - } - - @Override - public void setVideoPaused(boolean isVideoPaused) { - mPauseVideoButton.setSelected(isVideoPaused); - - if (isVideoPaused) { - mPauseVideoButton.setContentDescription(getText(R.string.onscreenTurnOnCameraText)); - } else { - mPauseVideoButton.setContentDescription(getText(R.string.onscreenTurnOffCameraText)); - } - } - - @Override - public void setMute(boolean value) { - if (mMuteButton.isSelected() != value) { - mMuteButton.setSelected(value); - mMuteButton.setContentDescription(getContext().getString( - value ? R.string.onscreenMuteText_selected - : R.string.onscreenMuteText_unselected)); - } - } - - private void addToOverflowMenu(int id, View button, PopupMenu menu) { - button.setVisibility(View.GONE); - menu.getMenu().add(Menu.NONE, id, Menu.NONE, button.getContentDescription()); - mButtonVisibilityMap.put(id, BUTTON_MENU); - } - - private PopupMenu getPopupMenu() { - return new PopupMenu(new ContextThemeWrapper(getActivity(), R.style.InCallPopupMenuStyle), - mOverflowButton); - } - - /** - * Iterates through the list of buttons and toggles their visibility depending on the - * setting configured by the CallButtonPresenter. If there are more visible buttons than - * the allowed maximum, the excess buttons are collapsed into a single overflow menu. - */ - @Override - public void updateButtonStates() { - View prevVisibleButton = null; - int prevVisibleId = -1; - PopupMenu menu = null; - int visibleCount = 0; - for (int i = 0; i < BUTTON_COUNT; i++) { - final int visibility = mButtonVisibilityMap.get(i); - final View button = getButtonById(i); - if (visibility == BUTTON_VISIBLE) { - visibleCount++; - if (visibleCount <= mButtonMaxVisible) { - button.setVisibility(View.VISIBLE); - prevVisibleButton = button; - prevVisibleId = i; - } else { - if (menu == null) { - menu = getPopupMenu(); - } - // Collapse the current button into the overflow menu. If is the first visible - // button that exceeds the threshold, also collapse the previous visible button - // so that the total number of visible buttons will never exceed the threshold. - if (prevVisibleButton != null) { - addToOverflowMenu(prevVisibleId, prevVisibleButton, menu); - prevVisibleButton = null; - prevVisibleId = -1; - } - addToOverflowMenu(i, button, menu); - } - } else if (visibility == BUTTON_HIDDEN) { - button.setVisibility(View.GONE); - } - } - - mOverflowButton.setVisibility(menu != null ? View.VISIBLE : View.GONE); - if (menu != null) { - mOverflowPopup = menu; - mOverflowPopup.setOnMenuItemClickListener(new OnMenuItemClickListener() { - @Override - public boolean onMenuItemClick(MenuItem item) { - final int id = item.getItemId(); - getButtonById(id).performClick(); - return true; - } - }); - } - } - - @Override - public void setAudio(int mode) { - updateAudioButtons(); - refreshAudioModePopup(); - - if (mPrevAudioMode != mode) { - updateAudioButtonContentDescription(mode); - mPrevAudioMode = mode; - } - } - - @Override - public void setSupportedAudio(int modeMask) { - updateAudioButtons(); - refreshAudioModePopup(); - } - - @Override - public boolean onMenuItemClick(MenuItem item) { - Log.d(this, "- onMenuItemClick: " + item); - Log.d(this, " id: " + item.getItemId()); - Log.d(this, " title: '" + item.getTitle() + "'"); - - int mode = CallAudioState.ROUTE_WIRED_OR_EARPIECE; - int resId = item.getItemId(); - - if (resId == R.id.audio_mode_speaker) { - mode = CallAudioState.ROUTE_SPEAKER; - } else if (resId == R.id.audio_mode_earpiece || resId == R.id.audio_mode_wired_headset) { - // InCallCallAudioState.ROUTE_EARPIECE means either the handset earpiece, - // or the wired headset (if connected.) - mode = CallAudioState.ROUTE_WIRED_OR_EARPIECE; - } else if (resId == R.id.audio_mode_bluetooth) { - mode = CallAudioState.ROUTE_BLUETOOTH; - } else { - Log.e(this, "onMenuItemClick: unexpected View ID " + item.getItemId() - + " (MenuItem = '" + item + "')"); - } - - getPresenter().setAudioMode(mode); - - return true; - } - - // PopupMenu.OnDismissListener implementation; see showAudioModePopup(). - // This gets called when the PopupMenu gets dismissed for *any* reason, like - // the user tapping outside its bounds, or pressing Back, or selecting one - // of the menu items. - @Override - public void onDismiss(PopupMenu menu) { - Log.d(this, "- onDismiss: " + menu); - mAudioModePopupVisible = false; - updateAudioButtons(); - } - - /** - * Checks for supporting modes. If bluetooth is supported, it uses the audio - * pop up menu. Otherwise, it toggles the speakerphone. - */ - private void onAudioButtonClicked() { - Log.d(this, "onAudioButtonClicked: " + - CallAudioState.audioRouteToString(getPresenter().getSupportedAudio())); - - if (isSupported(CallAudioState.ROUTE_BLUETOOTH)) { - showAudioModePopup(); - } else { - getPresenter().toggleSpeakerphone(); - } - } - - private void onManageVideoCallConferenceClicked() { - Log.d(this, "onManageVideoCallConferenceClicked"); - InCallPresenter.getInstance().showConferenceCallManager(true); - } - - /** - * Refreshes the "Audio mode" popup if it's visible. This is useful - * (for example) when a wired headset is plugged or unplugged, - * since we need to switch back and forth between the "earpiece" - * and "wired headset" items. - * - * This is safe to call even if the popup is already dismissed, or even if - * you never called showAudioModePopup() in the first place. - */ - public void refreshAudioModePopup() { - if (mAudioModePopup != null && mAudioModePopupVisible) { - // Dismiss the previous one - mAudioModePopup.dismiss(); // safe even if already dismissed - // And bring up a fresh PopupMenu - showAudioModePopup(); - } - } - - /** - * Updates the audio button so that the appriopriate visual layers - * are visible based on the supported audio formats. - */ - private void updateAudioButtons() { - final boolean bluetoothSupported = isSupported(CallAudioState.ROUTE_BLUETOOTH); - final boolean speakerSupported = isSupported(CallAudioState.ROUTE_SPEAKER); - - boolean audioButtonEnabled = false; - boolean audioButtonChecked = false; - boolean showMoreIndicator = false; - - boolean showBluetoothIcon = false; - boolean showSpeakerphoneIcon = false; - boolean showHandsetIcon = false; - - boolean showToggleIndicator = false; - - if (bluetoothSupported) { - Log.d(this, "updateAudioButtons - popup menu mode"); - - audioButtonEnabled = true; - audioButtonChecked = true; - showMoreIndicator = true; - - // Update desired layers: - if (isAudio(CallAudioState.ROUTE_BLUETOOTH)) { - showBluetoothIcon = true; - } else if (isAudio(CallAudioState.ROUTE_SPEAKER)) { - showSpeakerphoneIcon = true; - } else { - showHandsetIcon = true; - // TODO: if a wired headset is plugged in, that takes precedence - // over the handset earpiece. If so, maybe we should show some - // sort of "wired headset" icon here instead of the "handset - // earpiece" icon. (Still need an asset for that, though.) - } - - // The audio button is NOT a toggle in this state, so set selected to false. - mAudioButton.setSelected(false); - } else if (speakerSupported) { - Log.d(this, "updateAudioButtons - speaker toggle mode"); - - audioButtonEnabled = true; - - // The audio button *is* a toggle in this state, and indicated the - // current state of the speakerphone. - audioButtonChecked = isAudio(CallAudioState.ROUTE_SPEAKER); - mAudioButton.setSelected(audioButtonChecked); - - // update desired layers: - showToggleIndicator = true; - showSpeakerphoneIcon = true; - } else { - Log.d(this, "updateAudioButtons - disabled..."); - - // The audio button is a toggle in this state, but that's mostly - // irrelevant since it's always disabled and unchecked. - audioButtonEnabled = false; - audioButtonChecked = false; - mAudioButton.setSelected(false); - - // update desired layers: - showToggleIndicator = true; - showSpeakerphoneIcon = true; - } - - // Finally, update it all! - - Log.v(this, "audioButtonEnabled: " + audioButtonEnabled); - Log.v(this, "audioButtonChecked: " + audioButtonChecked); - Log.v(this, "showMoreIndicator: " + showMoreIndicator); - Log.v(this, "showBluetoothIcon: " + showBluetoothIcon); - Log.v(this, "showSpeakerphoneIcon: " + showSpeakerphoneIcon); - Log.v(this, "showHandsetIcon: " + showHandsetIcon); - - // Only enable the audio button if the fragment is enabled. - mAudioButton.setEnabled(audioButtonEnabled && mIsEnabled); - mAudioButton.setChecked(audioButtonChecked); - - final LayerDrawable layers = (LayerDrawable) mAudioButton.getBackground(); - Log.d(this, "'layers' drawable: " + layers); - - layers.findDrawableByLayerId(R.id.compoundBackgroundItem) - .setAlpha(showToggleIndicator ? VISIBLE : HIDDEN); - - layers.findDrawableByLayerId(R.id.moreIndicatorItem) - .setAlpha(showMoreIndicator ? VISIBLE : HIDDEN); - - layers.findDrawableByLayerId(R.id.bluetoothItem) - .setAlpha(showBluetoothIcon ? VISIBLE : HIDDEN); - - layers.findDrawableByLayerId(R.id.handsetItem) - .setAlpha(showHandsetIcon ? VISIBLE : HIDDEN); - - layers.findDrawableByLayerId(R.id.speakerphoneItem) - .setAlpha(showSpeakerphoneIcon ? VISIBLE : HIDDEN); - - } - - /** - * Update the content description of the audio button. - */ - private void updateAudioButtonContentDescription(int mode) { - int stringId = 0; - - // If bluetooth is not supported, the audio buttion will toggle, so use the label "speaker". - // Otherwise, use the label of the currently selected audio mode. - if (!isSupported(CallAudioState.ROUTE_BLUETOOTH)) { - stringId = R.string.audio_mode_speaker; - } else { - switch (mode) { - case CallAudioState.ROUTE_EARPIECE: - stringId = R.string.audio_mode_earpiece; - break; - case CallAudioState.ROUTE_BLUETOOTH: - stringId = R.string.audio_mode_bluetooth; - break; - case CallAudioState.ROUTE_WIRED_HEADSET: - stringId = R.string.audio_mode_wired_headset; - break; - case CallAudioState.ROUTE_SPEAKER: - stringId = R.string.audio_mode_speaker; - break; - } - } - - if (stringId != 0) { - mAudioButton.setContentDescription(getResources().getString(stringId)); - } - } - - private void showAudioModePopup() { - Log.d(this, "showAudioPopup()..."); - - final ContextThemeWrapper contextWrapper = new ContextThemeWrapper(getActivity(), - R.style.InCallPopupMenuStyle); - mAudioModePopup = new PopupMenu(contextWrapper, mAudioButton /* anchorView */); - mAudioModePopup.getMenuInflater().inflate(R.menu.incall_audio_mode_menu, - mAudioModePopup.getMenu()); - mAudioModePopup.setOnMenuItemClickListener(this); - mAudioModePopup.setOnDismissListener(this); - - final Menu menu = mAudioModePopup.getMenu(); - - // TODO: Still need to have the "currently active" audio mode come - // up pre-selected (or focused?) with a blue highlight. Still - // need exact visual design, and possibly framework support for this. - // See comments below for the exact logic. - - final MenuItem speakerItem = menu.findItem(R.id.audio_mode_speaker); - speakerItem.setEnabled(isSupported(CallAudioState.ROUTE_SPEAKER)); - // TODO: Show speakerItem as initially "selected" if - // speaker is on. - - // We display *either* "earpiece" or "wired headset", never both, - // depending on whether a wired headset is physically plugged in. - final MenuItem earpieceItem = menu.findItem(R.id.audio_mode_earpiece); - final MenuItem wiredHeadsetItem = menu.findItem(R.id.audio_mode_wired_headset); - - final boolean usingHeadset = isSupported(CallAudioState.ROUTE_WIRED_HEADSET); - earpieceItem.setVisible(!usingHeadset); - earpieceItem.setEnabled(!usingHeadset); - wiredHeadsetItem.setVisible(usingHeadset); - wiredHeadsetItem.setEnabled(usingHeadset); - // TODO: Show the above item (either earpieceItem or wiredHeadsetItem) - // as initially "selected" if speakerOn and - // bluetoothIndicatorOn are both false. - - final MenuItem bluetoothItem = menu.findItem(R.id.audio_mode_bluetooth); - bluetoothItem.setEnabled(isSupported(CallAudioState.ROUTE_BLUETOOTH)); - // TODO: Show bluetoothItem as initially "selected" if - // bluetoothIndicatorOn is true. - - mAudioModePopup.show(); - - // Unfortunately we need to manually keep track of the popup menu's - // visiblity, since PopupMenu doesn't have an isShowing() method like - // Dialogs do. - mAudioModePopupVisible = true; - } - - private boolean isSupported(int mode) { - return (mode == (getPresenter().getSupportedAudio() & mode)); - } - - private boolean isAudio(int mode) { - return (mode == getPresenter().getAudioMode()); - } - - @Override - public void displayDialpad(boolean value, boolean animate) { - if (getActivity() != null && getActivity() instanceof InCallActivity) { - boolean changed = ((InCallActivity) getActivity()).showDialpadFragment(value, animate); - if (changed) { - mShowDialpadButton.setSelected(value); - mShowDialpadButton.setContentDescription(getContext().getString( - value /* show */ ? R.string.onscreenShowDialpadText_unselected - : R.string.onscreenShowDialpadText_selected)); - } - } - } - - @Override - public boolean isDialpadVisible() { - if (getActivity() != null && getActivity() instanceof InCallActivity) { - return ((InCallActivity) getActivity()).isDialpadVisible(); - } - return false; - } - - @Override - public Context getContext() { - return getActivity(); - } -} diff --git a/InCallUI/src/com/android/incallui/CallButtonPresenter.java b/InCallUI/src/com/android/incallui/CallButtonPresenter.java deleted file mode 100644 index defafda99..000000000 --- a/InCallUI/src/com/android/incallui/CallButtonPresenter.java +++ /dev/null @@ -1,486 +0,0 @@ -/* - * Copyright (C) 2013 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License - */ - -package com.android.incallui; - -import static com.android.incallui.CallButtonFragment.Buttons.BUTTON_ADD_CALL; -import static com.android.incallui.CallButtonFragment.Buttons.BUTTON_AUDIO; -import static com.android.incallui.CallButtonFragment.Buttons.BUTTON_DIALPAD; -import static com.android.incallui.CallButtonFragment.Buttons.BUTTON_DOWNGRADE_TO_AUDIO; -import static com.android.incallui.CallButtonFragment.Buttons.BUTTON_HOLD; -import static com.android.incallui.CallButtonFragment.Buttons.BUTTON_MERGE; -import static com.android.incallui.CallButtonFragment.Buttons.BUTTON_MUTE; -import static com.android.incallui.CallButtonFragment.Buttons.BUTTON_PAUSE_VIDEO; -import static com.android.incallui.CallButtonFragment.Buttons.BUTTON_SWAP; -import static com.android.incallui.CallButtonFragment.Buttons.BUTTON_SWITCH_CAMERA; -import static com.android.incallui.CallButtonFragment.Buttons.BUTTON_UPGRADE_TO_VIDEO; - -import android.content.Context; -import android.os.Build; -import android.os.Bundle; -import android.telecom.CallAudioState; -import android.telecom.InCallService.VideoCall; -import android.telecom.VideoProfile; - -import com.android.contacts.common.compat.CallSdkCompat; -import com.android.contacts.common.compat.SdkVersionOverride; -import com.android.dialer.compat.UserManagerCompat; -import com.android.incallui.AudioModeProvider.AudioModeListener; -import com.android.incallui.InCallCameraManager.Listener; -import com.android.incallui.InCallPresenter.CanAddCallListener; -import com.android.incallui.InCallPresenter.InCallDetailsListener; -import com.android.incallui.InCallPresenter.InCallState; -import com.android.incallui.InCallPresenter.InCallStateListener; -import com.android.incallui.InCallPresenter.IncomingCallListener; - -/** - * Logic for call buttons. - */ -public class CallButtonPresenter extends Presenter - implements InCallStateListener, AudioModeListener, IncomingCallListener, - InCallDetailsListener, CanAddCallListener, Listener { - - private static final String KEY_AUTOMATICALLY_MUTED = "incall_key_automatically_muted"; - private static final String KEY_PREVIOUS_MUTE_STATE = "incall_key_previous_mute_state"; - - private Call mCall; - private boolean mAutomaticallyMuted = false; - private boolean mPreviousMuteState = false; - - public CallButtonPresenter() { - } - - @Override - public void onUiReady(CallButtonUi ui) { - super.onUiReady(ui); - - AudioModeProvider.getInstance().addListener(this); - - // register for call state changes last - final InCallPresenter inCallPresenter = InCallPresenter.getInstance(); - inCallPresenter.addListener(this); - inCallPresenter.addIncomingCallListener(this); - inCallPresenter.addDetailsListener(this); - inCallPresenter.addCanAddCallListener(this); - inCallPresenter.getInCallCameraManager().addCameraSelectionListener(this); - - // Update the buttons state immediately for the current call - onStateChange(InCallState.NO_CALLS, inCallPresenter.getInCallState(), - CallList.getInstance()); - } - - @Override - public void onUiUnready(CallButtonUi ui) { - super.onUiUnready(ui); - - InCallPresenter.getInstance().removeListener(this); - AudioModeProvider.getInstance().removeListener(this); - InCallPresenter.getInstance().removeIncomingCallListener(this); - InCallPresenter.getInstance().removeDetailsListener(this); - InCallPresenter.getInstance().getInCallCameraManager().removeCameraSelectionListener(this); - InCallPresenter.getInstance().removeCanAddCallListener(this); - } - - @Override - public void onStateChange(InCallState oldState, InCallState newState, CallList callList) { - CallButtonUi ui = getUi(); - - if (newState == InCallState.OUTGOING) { - mCall = callList.getOutgoingCall(); - } else if (newState == InCallState.INCALL) { - mCall = callList.getActiveOrBackgroundCall(); - - // When connected to voice mail, automatically shows the dialpad. - // (On previous releases we showed it when in-call shows up, before waiting for - // OUTGOING. We may want to do that once we start showing "Voice mail" label on - // the dialpad too.) - if (ui != null) { - if (oldState == InCallState.OUTGOING && mCall != null) { - if (CallerInfoUtils.isVoiceMailNumber(ui.getContext(), mCall)) { - ui.displayDialpad(true /* show */, true /* animate */); - } - } - } - } else if (newState == InCallState.INCOMING) { - if (ui != null) { - ui.displayDialpad(false /* show */, true /* animate */); - } - mCall = callList.getIncomingCall(); - } else { - mCall = null; - } - updateUi(newState, mCall); - } - - /** - * Updates the user interface in response to a change in the details of a call. - * Currently handles changes to the call buttons in response to a change in the details for a - * call. This is important to ensure changes to the active call are reflected in the available - * buttons. - * - * @param call The active call. - * @param details The call details. - */ - @Override - public void onDetailsChanged(Call call, android.telecom.Call.Details details) { - // Only update if the changes are for the currently active call - if (getUi() != null && call != null && call.equals(mCall)) { - updateButtonsState(call); - } - } - - @Override - public void onIncomingCall(InCallState oldState, InCallState newState, Call call) { - onStateChange(oldState, newState, CallList.getInstance()); - } - - @Override - public void onCanAddCallChanged(boolean canAddCall) { - if (getUi() != null && mCall != null) { - updateButtonsState(mCall); - } - } - - @Override - public void onAudioMode(int mode) { - if (getUi() != null) { - getUi().setAudio(mode); - } - } - - @Override - public void onSupportedAudioMode(int mask) { - if (getUi() != null) { - getUi().setSupportedAudio(mask); - } - } - - @Override - public void onMute(boolean muted) { - if (getUi() != null && !mAutomaticallyMuted) { - getUi().setMute(muted); - } - } - - public int getAudioMode() { - return AudioModeProvider.getInstance().getAudioMode(); - } - - public int getSupportedAudio() { - return AudioModeProvider.getInstance().getSupportedModes(); - } - - public void setAudioMode(int mode) { - - // TODO: Set a intermediate state in this presenter until we get - // an update for onAudioMode(). This will make UI response immediate - // if it turns out to be slow - - Log.d(this, "Sending new Audio Mode: " + CallAudioState.audioRouteToString(mode)); - TelecomAdapter.getInstance().setAudioRoute(mode); - } - - /** - * Function assumes that bluetooth is not supported. - */ - public void toggleSpeakerphone() { - // this function should not be called if bluetooth is available - if (0 != (CallAudioState.ROUTE_BLUETOOTH & getSupportedAudio())) { - - // It's clear the UI is wrong, so update the supported mode once again. - Log.e(this, "toggling speakerphone not allowed when bluetooth supported."); - getUi().setSupportedAudio(getSupportedAudio()); - return; - } - - int newMode = CallAudioState.ROUTE_SPEAKER; - - // if speakerphone is already on, change to wired/earpiece - if (getAudioMode() == CallAudioState.ROUTE_SPEAKER) { - newMode = CallAudioState.ROUTE_WIRED_OR_EARPIECE; - } - - setAudioMode(newMode); - } - - public void muteClicked(boolean checked) { - Log.d(this, "turning on mute: " + checked); - TelecomAdapter.getInstance().mute(checked); - } - - public void holdClicked(boolean checked) { - if (mCall == null) { - return; - } - if (checked) { - Log.i(this, "Putting the call on hold: " + mCall); - TelecomAdapter.getInstance().holdCall(mCall.getId()); - } else { - Log.i(this, "Removing the call from hold: " + mCall); - TelecomAdapter.getInstance().unholdCall(mCall.getId()); - } - } - - public void swapClicked() { - if (mCall == null) { - return; - } - - Log.i(this, "Swapping the call: " + mCall); - TelecomAdapter.getInstance().swap(mCall.getId()); - } - - public void mergeClicked() { - TelecomAdapter.getInstance().merge(mCall.getId()); - } - - public void addCallClicked() { - // Automatically mute the current call - mAutomaticallyMuted = true; - mPreviousMuteState = AudioModeProvider.getInstance().getMute(); - // Simulate a click on the mute button - muteClicked(true); - TelecomAdapter.getInstance().addCall(); - } - - public void changeToVoiceClicked() { - VideoCall videoCall = mCall.getVideoCall(); - if (videoCall == null) { - return; - } - - VideoProfile videoProfile = new VideoProfile(VideoProfile.STATE_AUDIO_ONLY); - videoCall.sendSessionModifyRequest(videoProfile); - } - - public void showDialpadClicked(boolean checked) { - Log.v(this, "Show dialpad " + String.valueOf(checked)); - getUi().displayDialpad(checked /* show */, true /* animate */); - } - - public void changeToVideoClicked() { - VideoCall videoCall = mCall.getVideoCall(); - if (videoCall == null) { - return; - } - int currVideoState = mCall.getVideoState(); - int currUnpausedVideoState = VideoUtils.getUnPausedVideoState(currVideoState); - currUnpausedVideoState |= VideoProfile.STATE_BIDIRECTIONAL; - - VideoProfile videoProfile = new VideoProfile(currUnpausedVideoState); - videoCall.sendSessionModifyRequest(videoProfile); - mCall.setSessionModificationState(Call.SessionModificationState.WAITING_FOR_RESPONSE); - } - - /** - * Switches the camera between the front-facing and back-facing camera. - * @param useFrontFacingCamera True if we should switch to using the front-facing camera, or - * false if we should switch to using the back-facing camera. - */ - public void switchCameraClicked(boolean useFrontFacingCamera) { - InCallCameraManager cameraManager = InCallPresenter.getInstance().getInCallCameraManager(); - cameraManager.setUseFrontFacingCamera(useFrontFacingCamera); - - VideoCall videoCall = mCall.getVideoCall(); - if (videoCall == null) { - return; - } - - String cameraId = cameraManager.getActiveCameraId(); - if (cameraId != null) { - final int cameraDir = cameraManager.isUsingFrontFacingCamera() - ? Call.VideoSettings.CAMERA_DIRECTION_FRONT_FACING - : Call.VideoSettings.CAMERA_DIRECTION_BACK_FACING; - mCall.getVideoSettings().setCameraDir(cameraDir); - videoCall.setCamera(cameraId); - videoCall.requestCameraCapabilities(); - } - } - - - /** - * Stop or start client's video transmission. - * @param pause True if pausing the local user's video, or false if starting the local user's - * video. - */ - public void pauseVideoClicked(boolean pause) { - VideoCall videoCall = mCall.getVideoCall(); - if (videoCall == null) { - return; - } - - final int currUnpausedVideoState = VideoUtils.getUnPausedVideoState(mCall.getVideoState()); - if (pause) { - videoCall.setCamera(null); - VideoProfile videoProfile = new VideoProfile(currUnpausedVideoState - & ~VideoProfile.STATE_TX_ENABLED); - videoCall.sendSessionModifyRequest(videoProfile); - } else { - InCallCameraManager cameraManager = InCallPresenter.getInstance(). - getInCallCameraManager(); - videoCall.setCamera(cameraManager.getActiveCameraId()); - VideoProfile videoProfile = new VideoProfile(currUnpausedVideoState - | VideoProfile.STATE_TX_ENABLED); - videoCall.sendSessionModifyRequest(videoProfile); - mCall.setSessionModificationState(Call.SessionModificationState.WAITING_FOR_RESPONSE); - } - getUi().setVideoPaused(pause); - } - - private void updateUi(InCallState state, Call call) { - Log.d(this, "Updating call UI for call: ", call); - - final CallButtonUi ui = getUi(); - if (ui == null) { - return; - } - - final boolean isEnabled = - state.isConnectingOrConnected() &&!state.isIncoming() && call != null; - ui.setEnabled(isEnabled); - - if (call == null) { - return; - } - - updateButtonsState(call); - } - - /** - * Updates the buttons applicable for the UI. - * - * @param call The active call. - */ - private void updateButtonsState(Call call) { - Log.v(this, "updateButtonsState"); - final CallButtonUi ui = getUi(); - final boolean isVideo = VideoUtils.isVideoCall(call); - - // Common functionality (audio, hold, etc). - // Show either HOLD or SWAP, but not both. If neither HOLD or SWAP is available: - // (1) If the device normally can hold, show HOLD in a disabled state. - // (2) If the device doesn't have the concept of hold/swap, remove the button. - final boolean showSwap = call.can( - android.telecom.Call.Details.CAPABILITY_SWAP_CONFERENCE); - final boolean showHold = !showSwap - && call.can(android.telecom.Call.Details.CAPABILITY_SUPPORT_HOLD) - && call.can(android.telecom.Call.Details.CAPABILITY_HOLD); - final boolean isCallOnHold = call.getState() == Call.State.ONHOLD; - - final boolean showAddCall = TelecomAdapter.getInstance().canAddCall() - && UserManagerCompat.isUserUnlocked(ui.getContext()); - final boolean showMerge = call.can( - android.telecom.Call.Details.CAPABILITY_MERGE_CONFERENCE); - final boolean showUpgradeToVideo = !isVideo && hasVideoCallCapabilities(call); - final boolean showDowngradeToAudio = isVideo && isDowngradeToAudioSupported(call); - final boolean showMute = call.can(android.telecom.Call.Details.CAPABILITY_MUTE); - - ui.showButton(BUTTON_AUDIO, true); - ui.showButton(BUTTON_SWAP, showSwap); - ui.showButton(BUTTON_HOLD, showHold); - ui.setHold(isCallOnHold); - ui.showButton(BUTTON_MUTE, showMute); - ui.showButton(BUTTON_ADD_CALL, showAddCall); - ui.showButton(BUTTON_UPGRADE_TO_VIDEO, showUpgradeToVideo); - ui.showButton(BUTTON_DOWNGRADE_TO_AUDIO, showDowngradeToAudio); - ui.showButton(BUTTON_SWITCH_CAMERA, isVideo); - ui.showButton(BUTTON_PAUSE_VIDEO, isVideo); - if (isVideo) { - getUi().setVideoPaused(!VideoUtils.isTransmissionEnabled(call)); - } - ui.showButton(BUTTON_DIALPAD, true); - ui.showButton(BUTTON_MERGE, showMerge); - - ui.updateButtonStates(); - } - - private boolean hasVideoCallCapabilities(Call call) { - if (SdkVersionOverride.getSdkVersion(Build.VERSION_CODES.M) >= Build.VERSION_CODES.M) { - return call.can(android.telecom.Call.Details.CAPABILITY_SUPPORTS_VT_LOCAL_TX) - && call.can(android.telecom.Call.Details.CAPABILITY_SUPPORTS_VT_REMOTE_RX); - } - // In L, this single flag represents both video transmitting and receiving capabilities - return call.can(android.telecom.Call.Details.CAPABILITY_SUPPORTS_VT_LOCAL_TX); - } - - /** - * Determines if downgrading from a video call to an audio-only call is supported. In order to - * support downgrade to audio, the SDK version must be >= N and the call should NOT have the - * {@link android.telecom.Call.Details#CAPABILITY_CANNOT_DOWNGRADE_VIDEO_TO_AUDIO}. - * @param call The call. - * @return {@code true} if downgrading to an audio-only call from a video call is supported. - */ - private boolean isDowngradeToAudioSupported(Call call) { - return !call.can(CallSdkCompat.Details.CAPABILITY_CANNOT_DOWNGRADE_VIDEO_TO_AUDIO); - } - - public void refreshMuteState() { - // Restore the previous mute state - if (mAutomaticallyMuted && - AudioModeProvider.getInstance().getMute() != mPreviousMuteState) { - if (getUi() == null) { - return; - } - muteClicked(mPreviousMuteState); - } - mAutomaticallyMuted = false; - } - - @Override - public void onSaveInstanceState(Bundle outState) { - super.onSaveInstanceState(outState); - outState.putBoolean(KEY_AUTOMATICALLY_MUTED, mAutomaticallyMuted); - outState.putBoolean(KEY_PREVIOUS_MUTE_STATE, mPreviousMuteState); - } - - @Override - public void onRestoreInstanceState(Bundle savedInstanceState) { - mAutomaticallyMuted = - savedInstanceState.getBoolean(KEY_AUTOMATICALLY_MUTED, mAutomaticallyMuted); - mPreviousMuteState = - savedInstanceState.getBoolean(KEY_PREVIOUS_MUTE_STATE, mPreviousMuteState); - super.onRestoreInstanceState(savedInstanceState); - } - - public interface CallButtonUi extends Ui { - void showButton(int buttonId, boolean show); - void enableButton(int buttonId, boolean enable); - void setEnabled(boolean on); - void setMute(boolean on); - void setHold(boolean on); - void setCameraSwitched(boolean isBackFacingCamera); - void setVideoPaused(boolean isPaused); - void setAudio(int mode); - void setSupportedAudio(int mask); - void displayDialpad(boolean on, boolean animate); - boolean isDialpadVisible(); - - /** - * Once showButton() has been called on each of the individual buttons in the UI, call - * this to configure the overflow menu appropriately. - */ - void updateButtonStates(); - Context getContext(); - } - - @Override - public void onActiveCameraSelectionChanged(boolean isUsingFrontFacingCamera) { - if (getUi() == null) { - return; - } - getUi().setCameraSwitched(!isUsingFrontFacingCamera); - } -} diff --git a/InCallUI/src/com/android/incallui/CallCardFragment.java b/InCallUI/src/com/android/incallui/CallCardFragment.java deleted file mode 100644 index c2022d18c..000000000 --- a/InCallUI/src/com/android/incallui/CallCardFragment.java +++ /dev/null @@ -1,1510 +0,0 @@ -/* - * Copyright (C) 2013 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License - */ - -package com.android.incallui; - -import android.animation.Animator; -import android.animation.AnimatorListenerAdapter; -import android.animation.AnimatorSet; -import android.animation.ObjectAnimator; -import android.content.Context; -import android.graphics.Bitmap; -import android.graphics.Canvas; -import android.graphics.drawable.AnimationDrawable; -import android.graphics.drawable.BitmapDrawable; -import android.graphics.drawable.Drawable; -import android.graphics.drawable.GradientDrawable; -import android.os.Bundle; -import android.os.Handler; -import android.os.Looper; -import android.os.Trace; -import android.support.v4.graphics.drawable.RoundedBitmapDrawable; -import android.support.v4.graphics.drawable.RoundedBitmapDrawableFactory; -import android.telecom.DisconnectCause; -import android.telephony.PhoneNumberUtils; -import android.text.TextUtils; -import android.text.format.DateUtils; -import android.view.LayoutInflater; -import android.view.View; -import android.view.View.OnLayoutChangeListener; -import android.view.ViewGroup; -import android.view.ViewPropertyAnimator; -import android.view.ViewTreeObserver; -import android.view.ViewTreeObserver.OnGlobalLayoutListener; -import android.view.accessibility.AccessibilityEvent; -import android.view.accessibility.AccessibilityManager; -import android.view.animation.Animation; -import android.view.animation.AnimationUtils; -import android.widget.ImageButton; -import android.widget.ImageView; -import android.widget.LinearLayout; -import android.widget.ListAdapter; -import android.widget.ListView; -import android.widget.TextView; -import android.widget.Toast; - -import com.android.contacts.common.compat.PhoneNumberUtilsCompat; -import com.android.contacts.common.util.MaterialColorMapUtils.MaterialPalette; -import com.android.contacts.common.widget.FloatingActionButtonController; -import com.android.dialer.R; -import com.android.phone.common.animation.AnimUtils; - -import java.util.List; - -/** - * Fragment for call card. - */ -public class CallCardFragment extends BaseFragment - implements CallCardPresenter.CallCardUi { - private static final String TAG = "CallCardFragment"; - - /** - * Internal class which represents the call state label which is to be applied. - */ - private class CallStateLabel { - private CharSequence mCallStateLabel; - private boolean mIsAutoDismissing; - - public CallStateLabel(CharSequence callStateLabel, boolean isAutoDismissing) { - mCallStateLabel = callStateLabel; - mIsAutoDismissing = isAutoDismissing; - } - - public CharSequence getCallStateLabel() { - return mCallStateLabel; - } - - /** - * Determines if the call state label should auto-dismiss. - * - * @return {@code true} if the call state label should auto-dismiss. - */ - public boolean isAutoDismissing() { - return mIsAutoDismissing; - } - }; - - private static final String IS_DIALPAD_SHOWING_KEY = "is_dialpad_showing"; - - /** - * The duration of time (in milliseconds) a call state label should remain visible before - * resetting to its previous value. - */ - private static final long CALL_STATE_LABEL_RESET_DELAY_MS = 3000; - /** - * Amount of time to wait before sending an announcement via the accessibility manager. - * When the call state changes to an outgoing or incoming state for the first time, the - * UI can often be changing due to call updates or contact lookup. This allows the UI - * to settle to a stable state to ensure that the correct information is announced. - */ - private static final long ACCESSIBILITY_ANNOUNCEMENT_DELAY_MS = 500; - - private AnimatorSet mAnimatorSet; - private int mShrinkAnimationDuration; - private int mFabNormalDiameter; - private int mFabSmallDiameter; - private boolean mIsLandscape; - private boolean mHasLargePhoto; - private boolean mIsDialpadShowing; - - // Primary caller info - private TextView mPhoneNumber; - private TextView mNumberLabel; - private TextView mPrimaryName; - private View mCallStateButton; - private ImageView mCallStateIcon; - private ImageView mCallStateVideoCallIcon; - private TextView mCallStateLabel; - private TextView mCallTypeLabel; - private ImageView mHdAudioIcon; - private ImageView mForwardIcon; - private ImageView mSpamIcon; - private View mCallNumberAndLabel; - private TextView mElapsedTime; - private Drawable mPrimaryPhotoDrawable; - private TextView mCallSubject; - private ImageView mWorkProfileIcon; - - // Container view that houses the entire primary call card, including the call buttons - private View mPrimaryCallCardContainer; - // Container view that houses the primary call information - private ViewGroup mPrimaryCallInfo; - private View mCallButtonsContainer; - private ImageView mPhotoSmall; - - // Secondary caller info - private View mSecondaryCallInfo; - private TextView mSecondaryCallName; - private View mSecondaryCallProviderInfo; - private TextView mSecondaryCallProviderLabel; - private View mSecondaryCallConferenceCallIcon; - private View mSecondaryCallVideoCallIcon; - private View mProgressSpinner; - - // Call card content - private View mCallCardContent; - private ImageView mPhotoLarge; - private View mContactContext; - private TextView mContactContextTitle; - private ListView mContactContextListView; - private LinearLayout mContactContextListHeaders; - - private View mManageConferenceCallButton; - - // Dark number info bar - private TextView mInCallMessageLabel; - - private FloatingActionButtonController mFloatingActionButtonController; - private View mFloatingActionButtonContainer; - private ImageButton mFloatingActionButton; - private int mFloatingActionButtonVerticalOffset; - - private float mTranslationOffset; - private Animation mPulseAnimation; - - private int mVideoAnimationDuration; - // Whether or not the call card is currently in the process of an animation - private boolean mIsAnimating; - - private MaterialPalette mCurrentThemeColors; - - /** - * Call state label to set when an auto-dismissing call state label is dismissed. - */ - private CharSequence mPostResetCallStateLabel; - private boolean mCallStateLabelResetPending = false; - private Handler mHandler; - - /** - * Determines if secondary call info is populated in the secondary call info UI. - */ - private boolean mHasSecondaryCallInfo = false; - - @Override - public CallCardPresenter.CallCardUi getUi() { - return this; - } - - @Override - public CallCardPresenter createPresenter() { - return new CallCardPresenter(); - } - - @Override - public void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - - mHandler = new Handler(Looper.getMainLooper()); - mShrinkAnimationDuration = getResources().getInteger(R.integer.shrink_animation_duration); - mVideoAnimationDuration = getResources().getInteger(R.integer.video_animation_duration); - mFloatingActionButtonVerticalOffset = getResources().getDimensionPixelOffset( - R.dimen.floating_action_button_vertical_offset); - mFabNormalDiameter = getResources().getDimensionPixelOffset( - R.dimen.end_call_floating_action_button_diameter); - mFabSmallDiameter = getResources().getDimensionPixelOffset( - R.dimen.end_call_floating_action_button_small_diameter); - - if (savedInstanceState != null) { - mIsDialpadShowing = savedInstanceState.getBoolean(IS_DIALPAD_SHOWING_KEY, false); - } - } - - @Override - public void onActivityCreated(Bundle savedInstanceState) { - super.onActivityCreated(savedInstanceState); - - final CallList calls = CallList.getInstance(); - final Call call = calls.getFirstCall(); - getPresenter().init(getActivity(), call); - } - - @Override - public void onSaveInstanceState(Bundle outState) { - outState.putBoolean(IS_DIALPAD_SHOWING_KEY, mIsDialpadShowing); - super.onSaveInstanceState(outState); - } - - @Override - public View onCreateView(LayoutInflater inflater, ViewGroup container, - Bundle savedInstanceState) { - Trace.beginSection(TAG + " onCreate"); - mTranslationOffset = - getResources().getDimensionPixelSize(R.dimen.call_card_anim_translate_y_offset); - final View view = inflater.inflate(R.layout.call_card_fragment, container, false); - Trace.endSection(); - return view; - } - - @Override - public void onViewCreated(View view, Bundle savedInstanceState) { - super.onViewCreated(view, savedInstanceState); - - mPulseAnimation = - AnimationUtils.loadAnimation(view.getContext(), R.anim.call_status_pulse); - - mPhoneNumber = (TextView) view.findViewById(R.id.phoneNumber); - mPrimaryName = (TextView) view.findViewById(R.id.name); - mNumberLabel = (TextView) view.findViewById(R.id.label); - mSecondaryCallInfo = view.findViewById(R.id.secondary_call_info); - mSecondaryCallProviderInfo = view.findViewById(R.id.secondary_call_provider_info); - mCallCardContent = view.findViewById(R.id.call_card_content); - mPhotoLarge = (ImageView) view.findViewById(R.id.photoLarge); - mPhotoLarge.setOnClickListener(new View.OnClickListener() { - @Override - public void onClick(View v) { - getPresenter().onContactPhotoClick(); - } - }); - - mContactContext = view.findViewById(R.id.contact_context); - mContactContextTitle = (TextView) view.findViewById(R.id.contactContextTitle); - mContactContextListView = (ListView) view.findViewById(R.id.contactContextInfo); - // This layout stores all the list header layouts so they can be easily removed. - mContactContextListHeaders = new LinearLayout(getView().getContext()); - mContactContextListView.addHeaderView(mContactContextListHeaders); - - mCallStateIcon = (ImageView) view.findViewById(R.id.callStateIcon); - mCallStateVideoCallIcon = (ImageView) view.findViewById(R.id.videoCallIcon); - mWorkProfileIcon = (ImageView) view.findViewById(R.id.workProfileIcon); - mCallStateLabel = (TextView) view.findViewById(R.id.callStateLabel); - mHdAudioIcon = (ImageView) view.findViewById(R.id.hdAudioIcon); - mForwardIcon = (ImageView) view.findViewById(R.id.forwardIcon); - mSpamIcon = (ImageView) view.findViewById(R.id.spamIcon); - mCallNumberAndLabel = view.findViewById(R.id.labelAndNumber); - mCallTypeLabel = (TextView) view.findViewById(R.id.callTypeLabel); - mElapsedTime = (TextView) view.findViewById(R.id.elapsedTime); - mPrimaryCallCardContainer = view.findViewById(R.id.primary_call_info_container); - mPrimaryCallInfo = (ViewGroup) view.findViewById(R.id.primary_call_banner); - mCallButtonsContainer = view.findViewById(R.id.callButtonFragment); - mPhotoSmall = (ImageView) view.findViewById(R.id.photoSmall); - mPhotoSmall.setVisibility(View.GONE); - mInCallMessageLabel = (TextView) view.findViewById(R.id.connectionServiceMessage); - mProgressSpinner = view.findViewById(R.id.progressSpinner); - - mFloatingActionButtonContainer = view.findViewById( - R.id.floating_end_call_action_button_container); - mFloatingActionButton = (ImageButton) view.findViewById( - R.id.floating_end_call_action_button); - mFloatingActionButton.setOnClickListener(new View.OnClickListener() { - @Override - public void onClick(View v) { - getPresenter().endCallClicked(); - } - }); - mFloatingActionButtonController = new FloatingActionButtonController(getActivity(), - mFloatingActionButtonContainer, mFloatingActionButton); - - mSecondaryCallInfo.setOnClickListener(new View.OnClickListener() { - @Override - public void onClick(View v) { - getPresenter().secondaryInfoClicked(); - updateFabPositionForSecondaryCallInfo(); - } - }); - - mCallStateButton = view.findViewById(R.id.callStateButton); - mCallStateButton.setOnLongClickListener(new View.OnLongClickListener() { - @Override - public boolean onLongClick(View v) { - getPresenter().onCallStateButtonTouched(); - return false; - } - }); - - mManageConferenceCallButton = view.findViewById(R.id.manage_conference_call_button); - mManageConferenceCallButton.setOnClickListener(new View.OnClickListener() { - @Override - public void onClick(View v) { - InCallActivity activity = (InCallActivity) getActivity(); - activity.showConferenceFragment(true); - } - }); - - mPrimaryName.setElegantTextHeight(false); - mCallStateLabel.setElegantTextHeight(false); - mCallSubject = (TextView) view.findViewById(R.id.callSubject); - } - - @Override - public void setVisible(boolean on) { - if (on) { - getView().setVisibility(View.VISIBLE); - } else { - getView().setVisibility(View.INVISIBLE); - } - } - - /** - * Hides or shows the progress spinner. - * - * @param visible {@code True} if the progress spinner should be visible. - */ - @Override - public void setProgressSpinnerVisible(boolean visible) { - mProgressSpinner.setVisibility(visible ? View.VISIBLE : View.GONE); - } - - @Override - public void setContactContextTitle(View headerView) { - mContactContextListHeaders.removeAllViews(); - mContactContextListHeaders.addView(headerView); - } - - @Override - public void setContactContextContent(ListAdapter listAdapter) { - mContactContextListView.setAdapter(listAdapter); - } - - @Override - public void showContactContext(boolean show) { - showImageView(mPhotoLarge, !show); - showImageView(mPhotoSmall, show); - mPrimaryCallCardContainer.setElevation( - show ? 0 : getResources().getDimension(R.dimen.primary_call_elevation)); - mContactContext.setVisibility(show ? View.VISIBLE : View.GONE); - } - - /** - * Sets the visibility of the primary call card. - * Ensures that when the primary call card is hidden, the video surface slides over to fill the - * entire screen. - * - * @param visible {@code True} if the primary call card should be visible. - */ - @Override - public void setCallCardVisible(final boolean visible) { - Log.v(this, "setCallCardVisible : isVisible = " + visible); - // When animating the hide/show of the views in a landscape layout, we need to take into - // account whether we are in a left-to-right locale or a right-to-left locale and adjust - // the animations accordingly. - final boolean isLayoutRtl = InCallPresenter.isRtl(); - - // Retrieve here since at fragment creation time the incoming video view is not inflated. - final View videoView = getView().findViewById(R.id.incomingVideo); - if (videoView == null) { - return; - } - - // Determine how much space there is below or to the side of the call card. - final float spaceBesideCallCard = getSpaceBesideCallCard(); - - // We need to translate the video surface, but we need to know its position after the layout - // has occurred so use a {@code ViewTreeObserver}. - final ViewTreeObserver observer = getView().getViewTreeObserver(); - observer.addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener() { - @Override - public boolean onPreDraw() { - // We don't want to continue getting called. - getView().getViewTreeObserver().removeOnPreDrawListener(this); - - float videoViewTranslation = 0f; - - // Translate the call card to its pre-animation state. - if (!mIsLandscape) { - mPrimaryCallCardContainer.setTranslationY(visible ? - -mPrimaryCallCardContainer.getHeight() : 0); - - ViewGroup.LayoutParams p = videoView.getLayoutParams(); - videoViewTranslation = p.height / 2 - spaceBesideCallCard / 2; - } - - // Perform animation of video view. - ViewPropertyAnimator videoViewAnimator = videoView.animate() - .setInterpolator(AnimUtils.EASE_OUT_EASE_IN) - .setDuration(mVideoAnimationDuration); - if (mIsLandscape) { - videoViewAnimator - .translationX(visible ? videoViewTranslation : 0); - } else { - videoViewAnimator - .translationY(visible ? videoViewTranslation : 0); - } - videoViewAnimator.start(); - - // Animate the call card sliding. - ViewPropertyAnimator callCardAnimator = mPrimaryCallCardContainer.animate() - .setInterpolator(AnimUtils.EASE_OUT_EASE_IN) - .setDuration(mVideoAnimationDuration) - .setListener(new AnimatorListenerAdapter() { - @Override - public void onAnimationEnd(Animator animation) { - super.onAnimationEnd(animation); - if (!visible) { - mPrimaryCallCardContainer.setVisibility(View.GONE); - } - } - - @Override - public void onAnimationStart(Animator animation) { - super.onAnimationStart(animation); - if (visible) { - mPrimaryCallCardContainer.setVisibility(View.VISIBLE); - } - } - }); - - if (mIsLandscape) { - float translationX = mPrimaryCallCardContainer.getWidth(); - translationX *= isLayoutRtl ? 1 : -1; - callCardAnimator - .translationX(visible ? 0 : translationX) - .start(); - } else { - callCardAnimator - .translationY(visible ? 0 : -mPrimaryCallCardContainer.getHeight()) - .start(); - } - - return true; - } - }); - } - - /** - * Determines the amount of space below the call card for portrait layouts), or beside the - * call card for landscape layouts. - * - * @return The amount of space below or beside the call card. - */ - public float getSpaceBesideCallCard() { - if (mIsLandscape) { - return getView().getWidth() - mPrimaryCallCardContainer.getWidth(); - } else { - final int callCardHeight; - // Retrieve the actual height of the call card, independent of whether or not the - // outgoing call animation is in progress. The animation does not run in landscape mode - // so this only needs to be done for portrait. - if (mPrimaryCallCardContainer.getTag(R.id.view_tag_callcard_actual_height) != null) { - callCardHeight = (int) mPrimaryCallCardContainer.getTag( - R.id.view_tag_callcard_actual_height); - } else { - callCardHeight = mPrimaryCallCardContainer.getHeight(); - } - return getView().getHeight() - callCardHeight; - } - } - - @Override - public void setPrimaryName(String name, boolean nameIsNumber) { - if (TextUtils.isEmpty(name)) { - mPrimaryName.setText(null); - } else { - mPrimaryName.setText(nameIsNumber - ? PhoneNumberUtilsCompat.createTtsSpannable(name) - : name); - - // Set direction of the name field - int nameDirection = View.TEXT_DIRECTION_INHERIT; - if (nameIsNumber) { - nameDirection = View.TEXT_DIRECTION_LTR; - } - mPrimaryName.setTextDirection(nameDirection); - } - } - - /** - * Sets the primary image for the contact photo. - * - * @param image The drawable to set. - * @param isVisible Whether the contact photo should be visible after being set. - */ - @Override - public void setPrimaryImage(Drawable image, boolean isVisible) { - if (image != null) { - setDrawableToImageViews(image); - showImageView(mPhotoLarge, isVisible); - } - } - - @Override - public void setPrimaryPhoneNumber(String number) { - // Set the number - if (TextUtils.isEmpty(number)) { - mPhoneNumber.setText(null); - mPhoneNumber.setVisibility(View.GONE); - } else { - mPhoneNumber.setText(PhoneNumberUtilsCompat.createTtsSpannable(number)); - mPhoneNumber.setVisibility(View.VISIBLE); - mPhoneNumber.setTextDirection(View.TEXT_DIRECTION_LTR); - } - } - - @Override - public void setPrimaryLabel(String label) { - if (!TextUtils.isEmpty(label)) { - mNumberLabel.setText(label); - mNumberLabel.setVisibility(View.VISIBLE); - } else { - mNumberLabel.setVisibility(View.GONE); - } - - } - - /** - * Sets the primary caller information. - * - * @param number The caller phone number. - * @param name The caller name. - * @param nameIsNumber {@code true} if the name should be shown in place of the phone number. - * @param label The label. - * @param photo The contact photo drawable. - * @param isSipCall {@code true} if this is a SIP call. - * @param isContactPhotoShown {@code true} if the contact photo should be shown (it will be - * updated even if it is not shown). - * @param isWorkCall Whether the call is placed through a work phone account or caller is a work - contact. - */ - @Override - public void setPrimary(String number, String name, boolean nameIsNumber, String label, - Drawable photo, boolean isSipCall, boolean isContactPhotoShown, boolean isWorkCall) { - Log.d(this, "Setting primary call"); - // set the name field. - setPrimaryName(name, nameIsNumber); - - if (TextUtils.isEmpty(number) && TextUtils.isEmpty(label)) { - mCallNumberAndLabel.setVisibility(View.GONE); - mElapsedTime.setTextAlignment(View.TEXT_ALIGNMENT_VIEW_START); - } else { - mCallNumberAndLabel.setVisibility(View.VISIBLE); - mElapsedTime.setTextAlignment(View.TEXT_ALIGNMENT_VIEW_END); - } - - setPrimaryPhoneNumber(number); - - // Set the label (Mobile, Work, etc) - setPrimaryLabel(label); - - showInternetCallLabel(isSipCall); - - setDrawableToImageViews(photo); - showImageView(mPhotoLarge, isContactPhotoShown); - showImageView(mWorkProfileIcon, isWorkCall); - } - - @Override - public void setSecondary(boolean show, String name, boolean nameIsNumber, String label, - String providerLabel, boolean isConference, boolean isVideoCall, boolean isFullscreen) { - - if (show) { - mHasSecondaryCallInfo = true; - boolean hasProvider = !TextUtils.isEmpty(providerLabel); - initializeSecondaryCallInfo(hasProvider); - - // Do not show the secondary caller info in fullscreen mode, but ensure it is populated - // in case fullscreen mode is exited in the future. - setSecondaryInfoVisible(!isFullscreen); - - mSecondaryCallConferenceCallIcon.setVisibility(isConference ? View.VISIBLE : View.GONE); - mSecondaryCallVideoCallIcon.setVisibility(isVideoCall ? View.VISIBLE : View.GONE); - - mSecondaryCallName.setText(nameIsNumber - ? PhoneNumberUtilsCompat.createTtsSpannable(name) - : name); - if (hasProvider) { - mSecondaryCallProviderLabel.setText(providerLabel); - } - - int nameDirection = View.TEXT_DIRECTION_INHERIT; - if (nameIsNumber) { - nameDirection = View.TEXT_DIRECTION_LTR; - } - mSecondaryCallName.setTextDirection(nameDirection); - } else { - mHasSecondaryCallInfo = false; - setSecondaryInfoVisible(false); - } - } - - /** - * Sets the visibility of the secondary caller info box. Note, if the {@code visible} parameter - * is passed in {@code true}, and there is no secondary caller info populated (as determined by - * {@code mHasSecondaryCallInfo}, the secondary caller info box will not be shown. - * - * @param visible {@code true} if the secondary caller info should be shown, {@code false} - * otherwise. - */ - @Override - public void setSecondaryInfoVisible(final boolean visible) { - boolean wasVisible = mSecondaryCallInfo.isShown(); - final boolean isVisible = visible && mHasSecondaryCallInfo; - Log.v(this, "setSecondaryInfoVisible: wasVisible = " + wasVisible + " isVisible = " - + isVisible); - - // If visibility didn't change, nothing to do. - if (wasVisible == isVisible) { - return; - } - - // If we are showing the secondary info, we need to show it before animating so that its - // height will be determined on layout. - if (isVisible) { - mSecondaryCallInfo.setVisibility(View.VISIBLE); - } else { - mSecondaryCallInfo.setVisibility(View.GONE); - } - - updateFabPositionForSecondaryCallInfo(); - // We need to translate the secondary caller info, but we need to know its position after - // the layout has occurred so use a {@code ViewTreeObserver}. - final ViewTreeObserver observer = getView().getViewTreeObserver(); - - observer.addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener() { - @Override - public boolean onPreDraw() { - // We don't want to continue getting called. - getView().getViewTreeObserver().removeOnPreDrawListener(this); - - // Get the height of the secondary call info now, and then re-hide the view prior - // to doing the actual animation. - int secondaryHeight = mSecondaryCallInfo.getHeight(); - if (isVisible) { - mSecondaryCallInfo.setVisibility(View.GONE); - } else { - mSecondaryCallInfo.setVisibility(View.VISIBLE); - } - Log.v(this, "setSecondaryInfoVisible: secondaryHeight = " + secondaryHeight); - - // Set the position of the secondary call info card to its starting location. - mSecondaryCallInfo.setTranslationY(visible ? secondaryHeight : 0); - - // Animate the secondary card info slide up/down as it appears and disappears. - ViewPropertyAnimator secondaryInfoAnimator = mSecondaryCallInfo.animate() - .setInterpolator(AnimUtils.EASE_OUT_EASE_IN) - .setDuration(mVideoAnimationDuration) - .translationY(isVisible ? 0 : secondaryHeight) - .setListener(new AnimatorListenerAdapter() { - @Override - public void onAnimationEnd(Animator animation) { - if (!isVisible) { - mSecondaryCallInfo.setVisibility(View.GONE); - } - } - - @Override - public void onAnimationStart(Animator animation) { - if (isVisible) { - mSecondaryCallInfo.setVisibility(View.VISIBLE); - } - } - }); - secondaryInfoAnimator.start(); - - // Notify listeners of a change in the visibility of the secondary info. This is - // important when in a video call so that the video call presenter can shift the - // video preview up or down to accommodate the secondary caller info. - InCallPresenter.getInstance().notifySecondaryCallerInfoVisibilityChanged(visible, - secondaryHeight); - - return true; - } - }); - } - - @Override - public void setCallState( - int state, - int videoState, - int sessionModificationState, - DisconnectCause disconnectCause, - String connectionLabel, - Drawable callStateIcon, - String gatewayNumber, - boolean isWifi, - boolean isConference, - boolean isWorkCall) { - boolean isGatewayCall = !TextUtils.isEmpty(gatewayNumber); - CallStateLabel callStateLabel = getCallStateLabelFromState(state, videoState, - sessionModificationState, disconnectCause, connectionLabel, isGatewayCall, isWifi, - isConference, isWorkCall); - - Log.v(this, "setCallState " + callStateLabel.getCallStateLabel()); - Log.v(this, "AutoDismiss " + callStateLabel.isAutoDismissing()); - Log.v(this, "DisconnectCause " + disconnectCause.toString()); - Log.v(this, "gateway " + connectionLabel + gatewayNumber); - - // Check for video state change and update the visibility of the contact photo. The contact - // photo is hidden when the incoming video surface is shown. - // The contact photo visibility can also change in setPrimary(). - boolean showContactPhoto = !VideoCallPresenter.showIncomingVideo(videoState, state); - mPhotoLarge.setVisibility(showContactPhoto ? View.VISIBLE : View.GONE); - - // Check if the call subject is showing -- if it is, we want to bypass showing the call - // state. - boolean isSubjectShowing = mCallSubject.getVisibility() == View.VISIBLE; - - if (TextUtils.equals(callStateLabel.getCallStateLabel(), mCallStateLabel.getText()) && - !isSubjectShowing) { - // Nothing to do if the labels are the same - if (state == Call.State.ACTIVE || state == Call.State.CONFERENCED) { - mCallStateLabel.clearAnimation(); - mCallStateIcon.clearAnimation(); - } - return; - } - - if (isSubjectShowing) { - changeCallStateLabel(null); - callStateIcon = null; - } else { - // Update the call state label and icon. - setCallStateLabel(callStateLabel); - } - - if (!TextUtils.isEmpty(callStateLabel.getCallStateLabel())) { - if (state == Call.State.ACTIVE || state == Call.State.CONFERENCED) { - mCallStateLabel.clearAnimation(); - } else { - mCallStateLabel.startAnimation(mPulseAnimation); - } - } else { - mCallStateLabel.clearAnimation(); - } - - if (callStateIcon != null) { - mCallStateIcon.setVisibility(View.VISIBLE); - // Invoke setAlpha(float) instead of setAlpha(int) to set the view's alpha. This is - // needed because the pulse animation operates on the view alpha. - mCallStateIcon.setAlpha(1.0f); - mCallStateIcon.setImageDrawable(callStateIcon); - - if (state == Call.State.ACTIVE || state == Call.State.CONFERENCED - || TextUtils.isEmpty(callStateLabel.getCallStateLabel())) { - mCallStateIcon.clearAnimation(); - } else { - mCallStateIcon.startAnimation(mPulseAnimation); - } - - if (callStateIcon instanceof AnimationDrawable) { - ((AnimationDrawable) callStateIcon).start(); - } - } else { - mCallStateIcon.clearAnimation(); - - // Invoke setAlpha(float) instead of setAlpha(int) to set the view's alpha. This is - // needed because the pulse animation operates on the view alpha. - mCallStateIcon.setAlpha(0.0f); - mCallStateIcon.setVisibility(View.GONE); - } - - if (VideoUtils.isVideoCall(videoState) - || (state == Call.State.ACTIVE && sessionModificationState - == Call.SessionModificationState.WAITING_FOR_RESPONSE)) { - mCallStateVideoCallIcon.setVisibility(View.VISIBLE); - } else { - mCallStateVideoCallIcon.setVisibility(View.GONE); - } - } - - private void setCallStateLabel(CallStateLabel callStateLabel) { - Log.v(this, "setCallStateLabel : label = " + callStateLabel.getCallStateLabel()); - - if (callStateLabel.isAutoDismissing()) { - mCallStateLabelResetPending = true; - mHandler.postDelayed(new Runnable() { - @Override - public void run() { - Log.v(this, "restoringCallStateLabel : label = " + - mPostResetCallStateLabel); - changeCallStateLabel(mPostResetCallStateLabel); - mCallStateLabelResetPending = false; - } - }, CALL_STATE_LABEL_RESET_DELAY_MS); - - changeCallStateLabel(callStateLabel.getCallStateLabel()); - } else { - // Keep track of the current call state label; used when resetting auto dismissing - // call state labels. - mPostResetCallStateLabel = callStateLabel.getCallStateLabel(); - - if (!mCallStateLabelResetPending) { - changeCallStateLabel(callStateLabel.getCallStateLabel()); - } - } - } - - private void changeCallStateLabel(CharSequence callStateLabel) { - Log.v(this, "changeCallStateLabel : label = " + callStateLabel); - if (!TextUtils.isEmpty(callStateLabel)) { - mCallStateLabel.setText(callStateLabel); - mCallStateLabel.setAlpha(1); - mCallStateLabel.setVisibility(View.VISIBLE); - } else { - Animation callStateLabelAnimation = mCallStateLabel.getAnimation(); - if (callStateLabelAnimation != null) { - callStateLabelAnimation.cancel(); - } - mCallStateLabel.setText(null); - mCallStateLabel.setAlpha(0); - mCallStateLabel.setVisibility(View.GONE); - } - } - - @Override - public void setCallbackNumber(String callbackNumber, boolean isEmergencyCall) { - if (mInCallMessageLabel == null) { - return; - } - - if (TextUtils.isEmpty(callbackNumber)) { - mInCallMessageLabel.setVisibility(View.GONE); - return; - } - - // TODO: The new Locale-specific methods don't seem to be working. Revisit this. - callbackNumber = PhoneNumberUtils.formatNumber(callbackNumber); - - int stringResourceId = isEmergencyCall ? R.string.card_title_callback_number_emergency - : R.string.card_title_callback_number; - - String text = getString(stringResourceId, callbackNumber); - mInCallMessageLabel.setText(text); - - mInCallMessageLabel.setVisibility(View.VISIBLE); - } - - /** - * Sets and shows the call subject if it is not empty. Hides the call subject otherwise. - * - * @param callSubject The call subject. - */ - @Override - public void setCallSubject(String callSubject) { - boolean showSubject = !TextUtils.isEmpty(callSubject); - - mCallSubject.setVisibility(showSubject ? View.VISIBLE : View.GONE); - if (showSubject) { - mCallSubject.setText(callSubject); - } else { - mCallSubject.setText(null); - } - } - - public boolean isAnimating() { - return mIsAnimating; - } - - private void showInternetCallLabel(boolean show) { - if (show) { - final String label = getView().getContext().getString( - R.string.incall_call_type_label_sip); - mCallTypeLabel.setVisibility(View.VISIBLE); - mCallTypeLabel.setText(label); - } else { - mCallTypeLabel.setVisibility(View.GONE); - } - } - - @Override - public void setPrimaryCallElapsedTime(boolean show, long duration) { - if (show) { - if (mElapsedTime.getVisibility() != View.VISIBLE) { - AnimUtils.fadeIn(mElapsedTime, AnimUtils.DEFAULT_DURATION); - } - String callTimeElapsed = DateUtils.formatElapsedTime(duration / 1000); - mElapsedTime.setText(callTimeElapsed); - - String durationDescription = - InCallDateUtils.formatDuration(duration); - mElapsedTime.setContentDescription( - !TextUtils.isEmpty(durationDescription) ? durationDescription : null); - } else { - // hide() animation has no effect if it is already hidden. - AnimUtils.fadeOut(mElapsedTime, AnimUtils.DEFAULT_DURATION); - } - } - - /** - * Set all the ImageViews to the same photo. Currently there are 2 photo views: the large one - * (which fills about the bottom half of the screen) and the small one, which displays as a - * circle next to the primary contact info. This method does not handle whether the ImageView - * is shown or not. - * - * @param photo The photo to set for the image views. - */ - private void setDrawableToImageViews(Drawable photo) { - if (photo == null) { - photo = ContactInfoCache.getInstance(getView().getContext()) - .getDefaultContactPhotoDrawable(); - } - - if (mPrimaryPhotoDrawable == photo){ - return; - } - mPrimaryPhotoDrawable = photo; - - mPhotoLarge.setImageDrawable(photo); - - // Modify the drawable to be round for the smaller ImageView. - Bitmap bitmap = drawableToBitmap(photo); - if (bitmap != null) { - final RoundedBitmapDrawable drawable = - RoundedBitmapDrawableFactory.create(getResources(), bitmap); - drawable.setAntiAlias(true); - drawable.setCornerRadius(bitmap.getHeight() / 2); - photo = drawable; - } - mPhotoSmall.setImageDrawable(photo); - } - - /** - * Helper method for image view to handle animations. - * - * @param view The image view to show or hide. - * @param isVisible {@code true} if we want to show the image, {@code false} to hide it. - */ - private void showImageView(ImageView view, boolean isVisible) { - if (view.getDrawable() == null) { - if (isVisible) { - AnimUtils.fadeIn(mElapsedTime, AnimUtils.DEFAULT_DURATION); - } - } else { - // Cross fading is buggy and not noticeable due to the multiple calls to this method - // that switch drawables in the middle of the cross-fade animations. Just show the - // photo directly instead. - view.setVisibility(isVisible ? View.VISIBLE : View.GONE); - } - } - - /** - * Converts a drawable into a bitmap. - * - * @param drawable the drawable to be converted. - */ - public static Bitmap drawableToBitmap(Drawable drawable) { - Bitmap bitmap; - if (drawable instanceof BitmapDrawable) { - bitmap = ((BitmapDrawable) drawable).getBitmap(); - } else { - if (drawable.getIntrinsicWidth() <= 0 || drawable.getIntrinsicHeight() <= 0) { - // Needed for drawables that are just a colour. - bitmap = Bitmap.createBitmap(1, 1, Bitmap.Config.ARGB_8888); - } else { - bitmap = Bitmap.createBitmap(drawable.getIntrinsicWidth(), - drawable.getIntrinsicHeight(), Bitmap.Config.ARGB_8888); - } - - Log.i(TAG, "Created bitmap with width " + bitmap.getWidth() + ", height " - + bitmap.getHeight()); - - Canvas canvas = new Canvas(bitmap); - drawable.setBounds(0, 0, canvas.getWidth(), canvas.getHeight()); - drawable.draw(canvas); - } - return bitmap; - } - - /** - * Gets the call state label based on the state of the call or cause of disconnect. - * - * Additional labels are applied as follows: - * 1. All outgoing calls with display "Calling via [Provider]". - * 2. Ongoing calls will display the name of the provider. - * 3. Incoming calls will only display "Incoming via..." for accounts. - * 4. Video calls, and session modification states (eg. requesting video). - * 5. Incoming and active Wi-Fi calls will show label provided by hint. - * - * TODO: Move this to the CallCardPresenter. - */ - private CallStateLabel getCallStateLabelFromState(int state, int videoState, - int sessionModificationState, DisconnectCause disconnectCause, String label, - boolean isGatewayCall, boolean isWifi, boolean isConference, boolean isWorkCall) { - final Context context = getView().getContext(); - CharSequence callStateLabel = null; // Label to display as part of the call banner - - boolean hasSuggestedLabel = label != null; - boolean isAccount = hasSuggestedLabel && !isGatewayCall; - boolean isAutoDismissing = false; - - switch (state) { - case Call.State.IDLE: - // "Call state" is meaningless in this state. - break; - case Call.State.ACTIVE: - // We normally don't show a "call state label" at all in this state - // (but we can use the call state label to display the provider name). - if ((isAccount || isWifi || isConference) && hasSuggestedLabel) { - callStateLabel = label; - } else if (sessionModificationState - == Call.SessionModificationState.REQUEST_REJECTED) { - callStateLabel = context.getString(R.string.card_title_video_call_rejected); - isAutoDismissing = true; - } else if (sessionModificationState - == Call.SessionModificationState.REQUEST_FAILED) { - callStateLabel = context.getString(R.string.card_title_video_call_error); - isAutoDismissing = true; - } else if (sessionModificationState - == Call.SessionModificationState.WAITING_FOR_RESPONSE) { - callStateLabel = context.getString(R.string.card_title_video_call_requesting); - } else if (sessionModificationState - == Call.SessionModificationState.RECEIVED_UPGRADE_TO_VIDEO_REQUEST) { - callStateLabel = context.getString(R.string.card_title_video_call_requesting); - } else if (VideoUtils.isVideoCall(videoState)) { - callStateLabel = context.getString(R.string.card_title_video_call); - } - break; - case Call.State.ONHOLD: - callStateLabel = context.getString(R.string.card_title_on_hold); - break; - case Call.State.CONNECTING: - case Call.State.DIALING: - if (hasSuggestedLabel && !isWifi) { - callStateLabel = context.getString(R.string.calling_via_template, label); - } else { - callStateLabel = context.getString(R.string.card_title_dialing); - } - break; - case Call.State.REDIALING: - callStateLabel = context.getString(R.string.card_title_redialing); - break; - case Call.State.INCOMING: - case Call.State.CALL_WAITING: - if (isWifi && hasSuggestedLabel) { - callStateLabel = label; - } else if (isAccount) { - callStateLabel = context.getString(R.string.incoming_via_template, label); - } else if (VideoUtils.isVideoCall(videoState)) { - callStateLabel = context.getString(R.string.notification_incoming_video_call); - } else { - callStateLabel = - context.getString(isWorkCall ? R.string.card_title_incoming_work_call - : R.string.card_title_incoming_call); - } - break; - case Call.State.DISCONNECTING: - // While in the DISCONNECTING state we display a "Hanging up" - // message in order to make the UI feel more responsive. (In - // GSM it's normal to see a delay of a couple of seconds while - // negotiating the disconnect with the network, so the "Hanging - // up" state at least lets the user know that we're doing - // something. This state is currently not used with CDMA.) - callStateLabel = context.getString(R.string.card_title_hanging_up); - break; - case Call.State.DISCONNECTED: - callStateLabel = disconnectCause.getLabel(); - if (TextUtils.isEmpty(callStateLabel)) { - callStateLabel = context.getString(R.string.card_title_call_ended); - } - break; - case Call.State.CONFERENCED: - callStateLabel = context.getString(R.string.card_title_conf_call); - break; - default: - Log.wtf(this, "updateCallStateWidgets: unexpected call: " + state); - } - return new CallStateLabel(callStateLabel, isAutoDismissing); - } - - private void initializeSecondaryCallInfo(boolean hasProvider) { - // mSecondaryCallName is initialized here (vs. onViewCreated) because it is inaccessible - // until mSecondaryCallInfo is inflated in the call above. - if (mSecondaryCallName == null) { - mSecondaryCallName = (TextView) getView().findViewById(R.id.secondaryCallName); - mSecondaryCallConferenceCallIcon = - getView().findViewById(R.id.secondaryCallConferenceCallIcon); - mSecondaryCallVideoCallIcon = - getView().findViewById(R.id.secondaryCallVideoCallIcon); - } - - if (mSecondaryCallProviderLabel == null && hasProvider) { - mSecondaryCallProviderInfo.setVisibility(View.VISIBLE); - mSecondaryCallProviderLabel = (TextView) getView() - .findViewById(R.id.secondaryCallProviderLabel); - } - } - - public void dispatchPopulateAccessibilityEvent(AccessibilityEvent event) { - if (event.getEventType() == AccessibilityEvent.TYPE_ANNOUNCEMENT) { - // Indicate this call is in active if no label is provided. The label is empty when - // the call is in active, not in other status such as onhold or dialing etc. - if (!mCallStateLabel.isShown() || TextUtils.isEmpty(mCallStateLabel.getText())) { - event.getText().add( - TextUtils.expandTemplate( - getResources().getText(R.string.accessibility_call_is_active), - mPrimaryName.getText())); - } else { - dispatchPopulateAccessibilityEvent(event, mCallStateLabel); - dispatchPopulateAccessibilityEvent(event, mPrimaryName); - dispatchPopulateAccessibilityEvent(event, mCallTypeLabel); - dispatchPopulateAccessibilityEvent(event, mPhoneNumber); - } - return; - } - dispatchPopulateAccessibilityEvent(event, mCallStateLabel); - dispatchPopulateAccessibilityEvent(event, mPrimaryName); - dispatchPopulateAccessibilityEvent(event, mPhoneNumber); - dispatchPopulateAccessibilityEvent(event, mCallTypeLabel); - dispatchPopulateAccessibilityEvent(event, mSecondaryCallName); - dispatchPopulateAccessibilityEvent(event, mSecondaryCallProviderLabel); - - return; - } - - @Override - public void sendAccessibilityAnnouncement() { - mHandler.postDelayed(new Runnable() { - @Override - public void run() { - if (getView() != null && getView().getParent() != null && - isAccessibilityEnabled(getContext())) { - AccessibilityEvent event = AccessibilityEvent.obtain( - AccessibilityEvent.TYPE_ANNOUNCEMENT); - dispatchPopulateAccessibilityEvent(event); - getView().getParent().requestSendAccessibilityEvent(getView(), event); - } - } - - private boolean isAccessibilityEnabled(Context context) { - AccessibilityManager accessibilityManager = - (AccessibilityManager) context.getSystemService(Context.ACCESSIBILITY_SERVICE); - return accessibilityManager != null && accessibilityManager.isEnabled(); - - } - }, ACCESSIBILITY_ANNOUNCEMENT_DELAY_MS); - } - - @Override - public void setEndCallButtonEnabled(boolean enabled, boolean animate) { - if (enabled != mFloatingActionButton.isEnabled()) { - if (animate) { - if (enabled) { - mFloatingActionButtonController.scaleIn(AnimUtils.NO_DELAY); - } else { - mFloatingActionButtonController.scaleOut(); - } - } else { - if (enabled) { - mFloatingActionButtonContainer.setScaleX(1); - mFloatingActionButtonContainer.setScaleY(1); - mFloatingActionButtonContainer.setVisibility(View.VISIBLE); - } else { - mFloatingActionButtonContainer.setVisibility(View.GONE); - } - } - mFloatingActionButton.setEnabled(enabled); - updateFabPosition(); - } - } - - /** - * Changes the visibility of the HD audio icon. - * - * @param visible {@code true} if the UI should show the HD audio icon. - */ - @Override - public void showHdAudioIndicator(boolean visible) { - mHdAudioIcon.setVisibility(visible ? View.VISIBLE : View.GONE); - } - - /** - * Changes the visibility of the forward icon. - * - * @param visible {@code true} if the UI should show the forward icon. - */ - @Override - public void showForwardIndicator(boolean visible) { - mForwardIcon.setVisibility(visible ? View.VISIBLE : View.GONE); - } - - /** - * Changes the visibility of the spam icon. - * - * @param visible {@code true} if the UI should show the spam icon. - */ - @Override - public void showSpamIndicator(boolean visible) { - if (visible) { - mSpamIcon.setVisibility(View.VISIBLE); - mNumberLabel.setText(R.string.label_spam_caller); - mPhoneNumber.setVisibility(View.GONE); - } - } - - /** - * Changes the visibility of the "manage conference call" button. - * - * @param visible Whether to set the button to be visible or not. - */ - @Override - public void showManageConferenceCallButton(boolean visible) { - mManageConferenceCallButton.setVisibility(visible ? View.VISIBLE : View.GONE); - } - - /** - * Determines the current visibility of the manage conference button. - * - * @return {@code true} if the button is visible. - */ - @Override - public boolean isManageConferenceVisible() { - return mManageConferenceCallButton.getVisibility() == View.VISIBLE; - } - - /** - * Determines the current visibility of the call subject. - * - * @return {@code true} if the subject is visible. - */ - @Override - public boolean isCallSubjectVisible() { - return mCallSubject.getVisibility() == View.VISIBLE; - } - - /** - * Get the overall InCallUI background colors and apply to call card. - */ - public void updateColors() { - MaterialPalette themeColors = InCallPresenter.getInstance().getThemeColors(); - - if (mCurrentThemeColors != null && mCurrentThemeColors.equals(themeColors)) { - return; - } - - if (getResources().getBoolean(R.bool.is_layout_landscape)) { - final GradientDrawable drawable = - (GradientDrawable) mPrimaryCallCardContainer.getBackground(); - drawable.setColor(themeColors.mPrimaryColor); - } else { - mPrimaryCallCardContainer.setBackgroundColor(themeColors.mPrimaryColor); - } - mCallButtonsContainer.setBackgroundColor(themeColors.mPrimaryColor); - mCallSubject.setTextColor(themeColors.mPrimaryColor); - mContactContext.setBackgroundColor(themeColors.mPrimaryColor); - //TODO: set color of message text in call context "recent messages" to be the theme color. - - mCurrentThemeColors = themeColors; - } - - private void dispatchPopulateAccessibilityEvent(AccessibilityEvent event, View view) { - if (view == null) return; - final List eventText = event.getText(); - int size = eventText.size(); - view.dispatchPopulateAccessibilityEvent(event); - // if no text added write null to keep relative position - if (size == eventText.size()) { - eventText.add(null); - } - } - - @Override - public void animateForNewOutgoingCall() { - final ViewGroup parent = (ViewGroup) mPrimaryCallCardContainer.getParent(); - - final ViewTreeObserver observer = getView().getViewTreeObserver(); - - mIsAnimating = true; - - observer.addOnGlobalLayoutListener(new OnGlobalLayoutListener() { - @Override - public void onGlobalLayout() { - final ViewTreeObserver observer = getView().getViewTreeObserver(); - if (!observer.isAlive()) { - return; - } - observer.removeOnGlobalLayoutListener(this); - - final LayoutIgnoringListener listener = new LayoutIgnoringListener(); - mPrimaryCallCardContainer.addOnLayoutChangeListener(listener); - - // Prepare the state of views before the slide animation - final int originalHeight = mPrimaryCallCardContainer.getHeight(); - mPrimaryCallCardContainer.setTag(R.id.view_tag_callcard_actual_height, - originalHeight); - mPrimaryCallCardContainer.setBottom(parent.getHeight()); - - // Set up FAB. - mFloatingActionButtonContainer.setVisibility(View.GONE); - mFloatingActionButtonController.setScreenWidth(parent.getWidth()); - - mCallButtonsContainer.setAlpha(0); - mCallStateLabel.setAlpha(0); - mPrimaryName.setAlpha(0); - mCallTypeLabel.setAlpha(0); - mCallNumberAndLabel.setAlpha(0); - - assignTranslateAnimation(mCallStateLabel, 1); - assignTranslateAnimation(mCallStateIcon, 1); - assignTranslateAnimation(mPrimaryName, 2); - assignTranslateAnimation(mCallNumberAndLabel, 3); - assignTranslateAnimation(mCallTypeLabel, 4); - assignTranslateAnimation(mCallButtonsContainer, 5); - - final Animator animator = getShrinkAnimator(parent.getHeight(), originalHeight); - - animator.addListener(new AnimatorListenerAdapter() { - @Override - public void onAnimationEnd(Animator animation) { - mPrimaryCallCardContainer.setTag(R.id.view_tag_callcard_actual_height, - null); - setViewStatePostAnimation(listener); - mIsAnimating = false; - InCallPresenter.getInstance().onShrinkAnimationComplete(); - if (animator != null) { - animator.removeListener(this); - } - } - }); - animator.start(); - } - }); - } - - @Override - public void showNoteSentToast() { - Toast.makeText(getContext(), R.string.note_sent, Toast.LENGTH_LONG).show(); - } - - public void onDialpadVisibilityChange(boolean isShown) { - mIsDialpadShowing = isShown; - updateFabPosition(); - } - - private void updateFabPosition() { - int offsetY = 0; - if (!mIsDialpadShowing) { - offsetY = mFloatingActionButtonVerticalOffset; - if (mSecondaryCallInfo.isShown() && mHasLargePhoto) { - offsetY -= mSecondaryCallInfo.getHeight(); - } - } - - mFloatingActionButtonController.align( - FloatingActionButtonController.ALIGN_MIDDLE, - 0 /* offsetX */, - offsetY, - true); - - mFloatingActionButtonController.resize( - mIsDialpadShowing ? mFabSmallDiameter : mFabNormalDiameter, true); - } - - @Override - public Context getContext() { - return getActivity(); - } - - @Override - public void onResume() { - super.onResume(); - // If the previous launch animation is still running, cancel it so that we don't get - // stuck in an intermediate animation state. - if (mAnimatorSet != null && mAnimatorSet.isRunning()) { - mAnimatorSet.cancel(); - } - - mIsLandscape = getResources().getBoolean(R.bool.is_layout_landscape); - mHasLargePhoto = getResources().getBoolean(R.bool.has_large_photo); - - final ViewGroup parent = ((ViewGroup) mPrimaryCallCardContainer.getParent()); - final ViewTreeObserver observer = parent.getViewTreeObserver(); - parent.getViewTreeObserver().addOnGlobalLayoutListener(new OnGlobalLayoutListener() { - @Override - public void onGlobalLayout() { - ViewTreeObserver viewTreeObserver = observer; - if (!viewTreeObserver.isAlive()) { - viewTreeObserver = parent.getViewTreeObserver(); - } - viewTreeObserver.removeOnGlobalLayoutListener(this); - mFloatingActionButtonController.setScreenWidth(parent.getWidth()); - updateFabPosition(); - } - }); - - updateColors(); - } - - /** - * Adds a global layout listener to update the FAB's positioning on the next layout. This allows - * us to position the FAB after the secondary call info's height has been calculated. - */ - private void updateFabPositionForSecondaryCallInfo() { - mSecondaryCallInfo.getViewTreeObserver().addOnGlobalLayoutListener( - new ViewTreeObserver.OnGlobalLayoutListener() { - @Override - public void onGlobalLayout() { - final ViewTreeObserver observer = mSecondaryCallInfo.getViewTreeObserver(); - if (!observer.isAlive()) { - return; - } - observer.removeOnGlobalLayoutListener(this); - - onDialpadVisibilityChange(mIsDialpadShowing); - } - }); - } - - /** - * Animator that performs the upwards shrinking animation of the blue call card scrim. - * At the start of the animation, each child view is moved downwards by a pre-specified amount - * and then translated upwards together with the scrim. - */ - private Animator getShrinkAnimator(int startHeight, int endHeight) { - final ObjectAnimator shrinkAnimator = - ObjectAnimator.ofInt(mPrimaryCallCardContainer, "bottom", startHeight, endHeight); - shrinkAnimator.setDuration(mShrinkAnimationDuration); - shrinkAnimator.addListener(new AnimatorListenerAdapter() { - @Override - public void onAnimationStart(Animator animation) { - mFloatingActionButton.setEnabled(true); - } - }); - shrinkAnimator.setInterpolator(AnimUtils.EASE_IN); - return shrinkAnimator; - } - - private void assignTranslateAnimation(View view, int offset) { - view.setLayerType(View.LAYER_TYPE_HARDWARE, null); - view.buildLayer(); - view.setTranslationY(mTranslationOffset * offset); - view.animate().translationY(0).alpha(1).withLayer() - .setDuration(mShrinkAnimationDuration).setInterpolator(AnimUtils.EASE_IN); - } - - private void setViewStatePostAnimation(View view) { - view.setTranslationY(0); - view.setAlpha(1); - } - - private void setViewStatePostAnimation(OnLayoutChangeListener layoutChangeListener) { - setViewStatePostAnimation(mCallButtonsContainer); - setViewStatePostAnimation(mCallStateLabel); - setViewStatePostAnimation(mPrimaryName); - setViewStatePostAnimation(mCallTypeLabel); - setViewStatePostAnimation(mCallNumberAndLabel); - setViewStatePostAnimation(mCallStateIcon); - - mPrimaryCallCardContainer.removeOnLayoutChangeListener(layoutChangeListener); - - mFloatingActionButtonController.scaleIn(AnimUtils.NO_DELAY); - } - - private final class LayoutIgnoringListener implements View.OnLayoutChangeListener { - @Override - public void onLayoutChange(View v, - int left, - int top, - int right, - int bottom, - int oldLeft, - int oldTop, - int oldRight, - int oldBottom) { - v.setLeft(oldLeft); - v.setRight(oldRight); - v.setTop(oldTop); - v.setBottom(oldBottom); - } - } -} diff --git a/InCallUI/src/com/android/incallui/CallCardPresenter.java b/InCallUI/src/com/android/incallui/CallCardPresenter.java deleted file mode 100644 index 1ad0c11f1..000000000 --- a/InCallUI/src/com/android/incallui/CallCardPresenter.java +++ /dev/null @@ -1,1181 +0,0 @@ -/* - * Copyright (C) 2013 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License - */ - -package com.android.incallui; - -import com.google.common.base.Preconditions; - -import android.Manifest; -import android.content.Context; -import android.content.Intent; -import android.content.pm.ApplicationInfo; -import android.content.pm.PackageManager; -import android.graphics.drawable.Drawable; -import android.net.Uri; -import android.os.Bundle; -import android.support.annotation.Nullable; -import android.telecom.Call.Details; -import android.telecom.DisconnectCause; -import android.telecom.PhoneAccount; -import android.telecom.PhoneAccountHandle; -import android.telecom.StatusHints; -import android.telecom.TelecomManager; -import android.telecom.VideoProfile; -import android.telephony.PhoneNumberUtils; -import android.text.TextUtils; -import android.view.View; -import android.view.accessibility.AccessibilityManager; -import android.widget.ListAdapter; - -import com.android.contacts.common.ContactsUtils; -import com.android.contacts.common.compat.telecom.TelecomManagerCompat; -import com.android.contacts.common.preference.ContactsPreferences; -import com.android.contacts.common.testing.NeededForTesting; -import com.android.contacts.common.util.ContactDisplayUtils; -import com.android.dialer.R; -import com.android.incallui.Call.State; -import com.android.incallui.ContactInfoCache.ContactCacheEntry; -import com.android.incallui.ContactInfoCache.ContactInfoCacheCallback; -import com.android.incallui.InCallPresenter.InCallDetailsListener; -import com.android.incallui.InCallPresenter.InCallEventListener; -import com.android.incallui.InCallPresenter.InCallState; -import com.android.incallui.InCallPresenter.InCallStateListener; -import com.android.incallui.InCallPresenter.IncomingCallListener; -import com.android.incalluibind.ObjectFactory; - -import java.lang.ref.WeakReference; - -import static com.android.contacts.common.compat.CallSdkCompat.Details.PROPERTY_ENTERPRISE_CALL; -/** - * Presenter for the Call Card Fragment. - *

- * This class listens for changes to InCallState and passes it along to the fragment. - */ -public class CallCardPresenter extends Presenter - implements InCallStateListener, IncomingCallListener, InCallDetailsListener, - InCallEventListener, CallList.CallUpdateListener, DistanceHelper.Listener { - - public interface EmergencyCallListener { - public void onCallUpdated(BaseFragment fragment, boolean isEmergency); - } - - private static final String TAG = CallCardPresenter.class.getSimpleName(); - private static final long CALL_TIME_UPDATE_INTERVAL_MS = 1000; - - private final EmergencyCallListener mEmergencyCallListener = - ObjectFactory.newEmergencyCallListener(); - private DistanceHelper mDistanceHelper; - - private Call mPrimary; - private Call mSecondary; - private ContactCacheEntry mPrimaryContactInfo; - private ContactCacheEntry mSecondaryContactInfo; - private CallTimer mCallTimer; - private Context mContext; - @Nullable private ContactsPreferences mContactsPreferences; - private boolean mSpinnerShowing = false; - private boolean mHasShownToast = false; - private InCallContactInteractions mInCallContactInteractions; - private boolean mIsFullscreen = false; - - public static class ContactLookupCallback implements ContactInfoCacheCallback { - private final WeakReference mCallCardPresenter; - private final boolean mIsPrimary; - - public ContactLookupCallback(CallCardPresenter callCardPresenter, boolean isPrimary) { - mCallCardPresenter = new WeakReference(callCardPresenter); - mIsPrimary = isPrimary; - } - - @Override - public void onContactInfoComplete(String callId, ContactCacheEntry entry) { - CallCardPresenter presenter = mCallCardPresenter.get(); - if (presenter != null) { - presenter.onContactInfoComplete(callId, entry, mIsPrimary); - } - } - - @Override - public void onImageLoadComplete(String callId, ContactCacheEntry entry) { - CallCardPresenter presenter = mCallCardPresenter.get(); - if (presenter != null) { - presenter.onImageLoadComplete(callId, entry); - } - } - - @Override - public void onContactInteractionsInfoComplete(String callId, ContactCacheEntry entry) { - CallCardPresenter presenter = mCallCardPresenter.get(); - if (presenter != null) { - presenter.onContactInteractionsInfoComplete(callId, entry); - } - } - } - - public CallCardPresenter() { - // create the call timer - mCallTimer = new CallTimer(new Runnable() { - @Override - public void run() { - updateCallTime(); - } - }); - } - - public void init(Context context, Call call) { - mContext = Preconditions.checkNotNull(context); - mDistanceHelper = ObjectFactory.newDistanceHelper(mContext, this); - mContactsPreferences = ContactsPreferencesFactory.newContactsPreferences(mContext); - - // Call may be null if disconnect happened already. - if (call != null) { - mPrimary = call; - if (shouldShowNoteSentToast(mPrimary)) { - final CallCardUi ui = getUi(); - if (ui != null) { - ui.showNoteSentToast(); - } - } - CallList.getInstance().addCallUpdateListener(call.getId(), this); - - // start processing lookups right away. - if (!call.isConferenceCall()) { - startContactInfoSearch(call, true, call.getState() == Call.State.INCOMING); - } else { - updateContactEntry(null, true); - } - } - - onStateChange(null, InCallPresenter.getInstance().getInCallState(), CallList.getInstance()); - } - - @Override - public void onUiReady(CallCardUi ui) { - super.onUiReady(ui); - - if (mContactsPreferences != null) { - mContactsPreferences.refreshValue(ContactsPreferences.DISPLAY_ORDER_KEY); - } - - // Contact search may have completed before ui is ready. - if (mPrimaryContactInfo != null) { - updatePrimaryDisplayInfo(); - } - - // Register for call state changes last - InCallPresenter.getInstance().addListener(this); - InCallPresenter.getInstance().addIncomingCallListener(this); - InCallPresenter.getInstance().addDetailsListener(this); - InCallPresenter.getInstance().addInCallEventListener(this); - } - - @Override - public void onUiUnready(CallCardUi ui) { - super.onUiUnready(ui); - - // stop getting call state changes - InCallPresenter.getInstance().removeListener(this); - InCallPresenter.getInstance().removeIncomingCallListener(this); - InCallPresenter.getInstance().removeDetailsListener(this); - InCallPresenter.getInstance().removeInCallEventListener(this); - if (mPrimary != null) { - CallList.getInstance().removeCallUpdateListener(mPrimary.getId(), this); - } - - if (mDistanceHelper != null) { - mDistanceHelper.cleanUp(); - } - - mPrimary = null; - mPrimaryContactInfo = null; - mSecondaryContactInfo = null; - } - - @Override - public void onIncomingCall(InCallState oldState, InCallState newState, Call call) { - // same logic should happen as with onStateChange() - onStateChange(oldState, newState, CallList.getInstance()); - } - - @Override - public void onStateChange(InCallState oldState, InCallState newState, CallList callList) { - Log.d(this, "onStateChange() " + newState); - final CallCardUi ui = getUi(); - if (ui == null) { - return; - } - - Call primary = null; - Call secondary = null; - - if (newState == InCallState.INCOMING) { - primary = callList.getIncomingCall(); - } else if (newState == InCallState.PENDING_OUTGOING || newState == InCallState.OUTGOING) { - primary = callList.getOutgoingCall(); - if (primary == null) { - primary = callList.getPendingOutgoingCall(); - } - - // getCallToDisplay doesn't go through outgoing or incoming calls. It will return the - // highest priority call to display as the secondary call. - secondary = getCallToDisplay(callList, null, true); - } else if (newState == InCallState.INCALL) { - primary = getCallToDisplay(callList, null, false); - secondary = getCallToDisplay(callList, primary, true); - } - - if (mInCallContactInteractions != null && - (oldState == InCallState.INCOMING || newState == InCallState.INCOMING)) { - ui.showContactContext(newState != InCallState.INCOMING); - } - - Log.d(this, "Primary call: " + primary); - Log.d(this, "Secondary call: " + secondary); - - final boolean primaryChanged = !(Call.areSame(mPrimary, primary) && - Call.areSameNumber(mPrimary, primary)); - final boolean secondaryChanged = !(Call.areSame(mSecondary, secondary) && - Call.areSameNumber(mSecondary, secondary)); - - mSecondary = secondary; - Call previousPrimary = mPrimary; - mPrimary = primary; - - if (primaryChanged && shouldShowNoteSentToast(primary)) { - ui.showNoteSentToast(); - } - - // Refresh primary call information if either: - // 1. Primary call changed. - // 2. The call's ability to manage conference has changed. - // 3. The call subject should be shown or hidden. - if (shouldRefreshPrimaryInfo(primaryChanged, ui, shouldShowCallSubject(mPrimary))) { - // primary call has changed - if (previousPrimary != null) { - //clear progess spinner (if any) related to previous primary call - maybeShowProgressSpinner(previousPrimary.getState(), - Call.SessionModificationState.NO_REQUEST); - CallList.getInstance().removeCallUpdateListener(previousPrimary.getId(), this); - } - CallList.getInstance().addCallUpdateListener(mPrimary.getId(), this); - - mPrimaryContactInfo = ContactInfoCache.buildCacheEntryFromCall(mContext, mPrimary, - mPrimary.getState() == Call.State.INCOMING); - updatePrimaryDisplayInfo(); - maybeStartSearch(mPrimary, true); - maybeClearSessionModificationState(mPrimary); - } - - if (previousPrimary != null && mPrimary == null) { - //clear progess spinner (if any) related to previous primary call - maybeShowProgressSpinner(previousPrimary.getState(), - Call.SessionModificationState.NO_REQUEST); - CallList.getInstance().removeCallUpdateListener(previousPrimary.getId(), this); - } - - if (mSecondary == null) { - // Secondary call may have ended. Update the ui. - mSecondaryContactInfo = null; - updateSecondaryDisplayInfo(); - } else if (secondaryChanged) { - // secondary call has changed - mSecondaryContactInfo = ContactInfoCache.buildCacheEntryFromCall(mContext, mSecondary, - mSecondary.getState() == Call.State.INCOMING); - updateSecondaryDisplayInfo(); - maybeStartSearch(mSecondary, false); - maybeClearSessionModificationState(mSecondary); - } - - // Start/stop timers. - if (isPrimaryCallActive()) { - Log.d(this, "Starting the calltime timer"); - mCallTimer.start(CALL_TIME_UPDATE_INTERVAL_MS); - } else { - Log.d(this, "Canceling the calltime timer"); - mCallTimer.cancel(); - ui.setPrimaryCallElapsedTime(false, 0); - } - - // Set the call state - int callState = Call.State.IDLE; - if (mPrimary != null) { - callState = mPrimary.getState(); - updatePrimaryCallState(); - } else { - getUi().setCallState( - callState, - VideoProfile.STATE_AUDIO_ONLY, - Call.SessionModificationState.NO_REQUEST, - new DisconnectCause(DisconnectCause.UNKNOWN), - null, - null, - null, - false /* isWifi */, - false /* isConference */, - false /* isWorkCall */); - getUi().showHdAudioIndicator(false); - } - - maybeShowManageConferenceCallButton(); - - // Hide the end call button instantly if we're receiving an incoming call. - getUi().setEndCallButtonEnabled(shouldShowEndCallButton(mPrimary, callState), - callState != Call.State.INCOMING /* animate */); - - maybeSendAccessibilityEvent(oldState, newState, primaryChanged); - } - - @Override - public void onDetailsChanged(Call call, Details details) { - updatePrimaryCallState(); - - if (call.can(Details.CAPABILITY_MANAGE_CONFERENCE) != - details.can(Details.CAPABILITY_MANAGE_CONFERENCE)) { - maybeShowManageConferenceCallButton(); - } - } - - @Override - public void onCallChanged(Call call) { - // No-op; specific call updates handled elsewhere. - } - - /** - * Handles a change to the session modification state for a call. Triggers showing the progress - * spinner, as well as updating the call state label. - * - * @param sessionModificationState The new session modification state. - */ - @Override - public void onSessionModificationStateChange(int sessionModificationState) { - Log.d(this, "onSessionModificationStateChange : sessionModificationState = " + - sessionModificationState); - - if (mPrimary == null) { - return; - } - maybeShowProgressSpinner(mPrimary.getState(), sessionModificationState); - getUi().setEndCallButtonEnabled(sessionModificationState != - Call.SessionModificationState.RECEIVED_UPGRADE_TO_VIDEO_REQUEST, - true /* shouldAnimate */); - updatePrimaryCallState(); - } - - /** - * Handles a change to the last forwarding number by refreshing the primary call info. - */ - @Override - public void onLastForwardedNumberChange() { - Log.v(this, "onLastForwardedNumberChange"); - - if (mPrimary == null) { - return; - } - updatePrimaryDisplayInfo(); - } - - /** - * Handles a change to the child number by refreshing the primary call info. - */ - @Override - public void onChildNumberChange() { - Log.v(this, "onChildNumberChange"); - - if (mPrimary == null) { - return; - } - updatePrimaryDisplayInfo(); - } - - private boolean shouldRefreshPrimaryInfo(boolean primaryChanged, CallCardUi ui, - boolean shouldShowCallSubject) { - if (mPrimary == null) { - return false; - } - return primaryChanged || - ui.isManageConferenceVisible() != shouldShowManageConference() || - ui.isCallSubjectVisible() != shouldShowCallSubject; - } - - private String getSubscriptionNumber() { - // If it's an emergency call, and they're not populating the callback number, - // then try to fall back to the phone sub info (to hopefully get the SIM's - // number directly from the telephony layer). - PhoneAccountHandle accountHandle = mPrimary.getAccountHandle(); - if (accountHandle != null) { - TelecomManager mgr = InCallPresenter.getInstance().getTelecomManager(); - PhoneAccount account = TelecomManagerCompat.getPhoneAccount(mgr, accountHandle); - if (account != null) { - return getNumberFromHandle(account.getSubscriptionAddress()); - } - } - return null; - } - - private void updatePrimaryCallState() { - if (getUi() != null && mPrimary != null) { - boolean isWorkCall = mPrimary.hasProperty(PROPERTY_ENTERPRISE_CALL) - || (mPrimaryContactInfo == null ? false - : mPrimaryContactInfo.userType == ContactsUtils.USER_TYPE_WORK); - getUi().setCallState( - mPrimary.getState(), - mPrimary.getVideoState(), - mPrimary.getSessionModificationState(), - mPrimary.getDisconnectCause(), - getConnectionLabel(), - getCallStateIcon(), - getGatewayNumber(), - mPrimary.hasProperty(Details.PROPERTY_WIFI), - mPrimary.isConferenceCall(), - isWorkCall); - - maybeShowHdAudioIcon(); - setCallbackNumber(); - } - } - - /** - * Show the HD icon if the call is active and has {@link Details#PROPERTY_HIGH_DEF_AUDIO}, - * except if the call has a last forwarded number (we will show that icon instead). - */ - private void maybeShowHdAudioIcon() { - boolean showHdAudioIndicator = - isPrimaryCallActive() && mPrimary.hasProperty(Details.PROPERTY_HIGH_DEF_AUDIO) && - TextUtils.isEmpty(mPrimary.getLastForwardedNumber()); - getUi().showHdAudioIndicator(showHdAudioIndicator); - } - - private void maybeShowSpamIconAndLabel() { - getUi().showSpamIndicator(mPrimary.isSpam()); - } - - /** - * Only show the conference call button if we can manage the conference. - */ - private void maybeShowManageConferenceCallButton() { - getUi().showManageConferenceCallButton(shouldShowManageConference()); - } - - /** - * Determines if a pending session modification exists for the current call. If so, the - * progress spinner is shown, and the call state is updated. - * - * @param callState The call state. - * @param sessionModificationState The session modification state. - */ - private void maybeShowProgressSpinner(int callState, int sessionModificationState) { - final boolean show = sessionModificationState == - Call.SessionModificationState.WAITING_FOR_RESPONSE - && callState == Call.State.ACTIVE; - if (show != mSpinnerShowing) { - getUi().setProgressSpinnerVisible(show); - mSpinnerShowing = show; - } - } - - /** - * Determines if the manage conference button should be visible, based on the current primary - * call. - * - * @return {@code True} if the manage conference button should be visible. - */ - private boolean shouldShowManageConference() { - if (mPrimary == null) { - return false; - } - - return mPrimary.can(android.telecom.Call.Details.CAPABILITY_MANAGE_CONFERENCE) - && !mIsFullscreen; - } - - private void setCallbackNumber() { - String callbackNumber = null; - - // Show the emergency callback number if either: - // 1. This is an emergency call. - // 2. The phone is in Emergency Callback Mode, which means we should show the callback - // number. - boolean showCallbackNumber = mPrimary.hasProperty(Details.PROPERTY_EMERGENCY_CALLBACK_MODE); - - if (mPrimary.isEmergencyCall() || showCallbackNumber) { - callbackNumber = getSubscriptionNumber(); - } else { - StatusHints statusHints = mPrimary.getTelecomCall().getDetails().getStatusHints(); - if (statusHints != null) { - Bundle extras = statusHints.getExtras(); - if (extras != null) { - callbackNumber = extras.getString(TelecomManager.EXTRA_CALL_BACK_NUMBER); - } - } - } - - final String simNumber = TelecomManagerCompat.getLine1Number( - InCallPresenter.getInstance().getTelecomManager(), - InCallPresenter.getInstance().getTelephonyManager(), - mPrimary.getAccountHandle()); - if (!showCallbackNumber && PhoneNumberUtils.compare(callbackNumber, simNumber)) { - Log.d(this, "Numbers are the same (and callback number is not being forced to show);" + - " not showing the callback number"); - callbackNumber = null; - } - - getUi().setCallbackNumber(callbackNumber, mPrimary.isEmergencyCall() || showCallbackNumber); - } - - public void updateCallTime() { - final CallCardUi ui = getUi(); - - if (ui == null) { - mCallTimer.cancel(); - } else if (!isPrimaryCallActive()) { - ui.setPrimaryCallElapsedTime(false, 0); - mCallTimer.cancel(); - } else { - final long callStart = mPrimary.getConnectTimeMillis(); - if (callStart > 0) { - final long duration = System.currentTimeMillis() - callStart; - ui.setPrimaryCallElapsedTime(true, duration); - } - } - } - - public void onCallStateButtonTouched() { - Intent broadcastIntent = ObjectFactory.getCallStateButtonBroadcastIntent(mContext); - if (broadcastIntent != null) { - Log.d(this, "Sending call state button broadcast: ", broadcastIntent); - mContext.sendBroadcast(broadcastIntent, Manifest.permission.READ_PHONE_STATE); - } - } - - /** - * Handles click on the contact photo by toggling fullscreen mode if the current call is a video - * call. - */ - public void onContactPhotoClick() { - if (mPrimary != null && mPrimary.isVideoCall(mContext)) { - InCallPresenter.getInstance().toggleFullscreenMode(); - } - } - - private void maybeStartSearch(Call call, boolean isPrimary) { - // no need to start search for conference calls which show generic info. - if (call != null && !call.isConferenceCall()) { - startContactInfoSearch(call, isPrimary, call.getState() == Call.State.INCOMING); - } - } - - private void maybeClearSessionModificationState(Call call) { - if (call.getSessionModificationState() != - Call.SessionModificationState.RECEIVED_UPGRADE_TO_VIDEO_REQUEST) { - call.setSessionModificationState(Call.SessionModificationState.NO_REQUEST); - } - } - - /** - * Starts a query for more contact data for the save primary and secondary calls. - */ - private void startContactInfoSearch(final Call call, final boolean isPrimary, - boolean isIncoming) { - final ContactInfoCache cache = ContactInfoCache.getInstance(mContext); - - cache.findInfo(call, isIncoming, new ContactLookupCallback(this, isPrimary)); - } - - private void onContactInfoComplete(String callId, ContactCacheEntry entry, boolean isPrimary) { - final boolean entryMatchesExistingCall = - (isPrimary && mPrimary != null && TextUtils.equals(callId, mPrimary.getId())) || - (!isPrimary && mSecondary != null && TextUtils.equals(callId, mSecondary.getId())); - if (entryMatchesExistingCall) { - updateContactEntry(entry, isPrimary); - } else { - Log.w(this, "Dropping stale contact lookup info for " + callId); - } - - final Call call = CallList.getInstance().getCallById(callId); - if (call != null) { - call.getLogState().contactLookupResult = entry.contactLookupResult; - } - if (entry.contactUri != null) { - CallerInfoUtils.sendViewNotification(mContext, entry.contactUri); - } - } - - private void onImageLoadComplete(String callId, ContactCacheEntry entry) { - if (getUi() == null) { - return; - } - - if (entry.photo != null) { - if (mPrimary != null && callId.equals(mPrimary.getId())) { - boolean showContactPhoto = !VideoCallPresenter.showIncomingVideo( - mPrimary.getVideoState(), mPrimary.getState()); - getUi().setPrimaryImage(entry.photo, showContactPhoto); - } - } - } - - private void onContactInteractionsInfoComplete(String callId, ContactCacheEntry entry) { - if (getUi() == null) { - return; - } - - if (mPrimary != null && callId.equals(mPrimary.getId())) { - mPrimaryContactInfo.locationAddress = entry.locationAddress; - updateContactInteractions(); - } - } - - @Override - public void onLocationReady() { - // This will only update the contacts interactions data if the location returns after - // the contact information is found. - updateContactInteractions(); - } - - private void updateContactInteractions() { - if (mPrimary != null && mPrimaryContactInfo != null - && (mPrimaryContactInfo.locationAddress != null - || mPrimaryContactInfo.openingHours != null)) { - // TODO: This is hardcoded to "isBusiness" because functionality to differentiate - // between business and personal has not yet been added. - if (setInCallContactInteractionsType(true /* isBusiness */)) { - getUi().setContactContextTitle( - mInCallContactInteractions.getBusinessListHeaderView()); - } - - mInCallContactInteractions.setBusinessInfo( - mPrimaryContactInfo.locationAddress, - mDistanceHelper.calculateDistance(mPrimaryContactInfo.locationAddress), - mPrimaryContactInfo.openingHours); - getUi().setContactContextContent(mInCallContactInteractions.getListAdapter()); - getUi().showContactContext(mPrimary.getState() != State.INCOMING); - } else { - getUi().showContactContext(false); - } - } - - /** - * Update the contact interactions type so that the correct UI is shown. - * - * @param isBusiness {@code true} if the interaction is a business interaction, {@code false} if - * it is a personal contact. - * - * @return {@code true} if this is a new type of contact interaction (business or personal). - * {@code false} if it hasn't changed. - */ - private boolean setInCallContactInteractionsType(boolean isBusiness) { - if (mInCallContactInteractions == null) { - mInCallContactInteractions = - new InCallContactInteractions(mContext, isBusiness); - return true; - } - - return mInCallContactInteractions.switchContactType(isBusiness); - } - - private void updateContactEntry(ContactCacheEntry entry, boolean isPrimary) { - if (isPrimary) { - mPrimaryContactInfo = entry; - updatePrimaryDisplayInfo(); - } else { - mSecondaryContactInfo = entry; - updateSecondaryDisplayInfo(); - } - } - - /** - * Get the highest priority call to display. - * Goes through the calls and chooses which to return based on priority of which type of call - * to display to the user. Callers can use the "ignore" feature to get the second best call - * by passing a previously found primary call as ignore. - * - * @param ignore A call to ignore if found. - */ - private Call getCallToDisplay(CallList callList, Call ignore, boolean skipDisconnected) { - // Active calls come second. An active call always gets precedent. - Call retval = callList.getActiveCall(); - if (retval != null && retval != ignore) { - return retval; - } - - // Sometimes there is intemediate state that two calls are in active even one is about - // to be on hold. - retval = callList.getSecondActiveCall(); - if (retval != null && retval != ignore) { - return retval; - } - - // Disconnected calls get primary position if there are no active calls - // to let user know quickly what call has disconnected. Disconnected - // calls are very short lived. - if (!skipDisconnected) { - retval = callList.getDisconnectingCall(); - if (retval != null && retval != ignore) { - return retval; - } - retval = callList.getDisconnectedCall(); - if (retval != null && retval != ignore) { - return retval; - } - } - - // Then we go to background call (calls on hold) - retval = callList.getBackgroundCall(); - if (retval != null && retval != ignore) { - return retval; - } - - // Lastly, we go to a second background call. - retval = callList.getSecondBackgroundCall(); - - return retval; - } - - private void updatePrimaryDisplayInfo() { - final CallCardUi ui = getUi(); - if (ui == null) { - // TODO: May also occur if search result comes back after ui is destroyed. Look into - // removing that case completely. - Log.d(TAG, "updatePrimaryDisplayInfo called but ui is null!"); - return; - } - - if (mPrimary == null) { - // Clear the primary display info. - ui.setPrimary(null, null, false, null, null, false, false, false); - return; - } - - // Hide the contact photo if we are in a video call and the incoming video surface is - // showing. - boolean showContactPhoto = !VideoCallPresenter - .showIncomingVideo(mPrimary.getVideoState(), mPrimary.getState()); - - // Call placed through a work phone account. - boolean hasWorkCallProperty = mPrimary.hasProperty(PROPERTY_ENTERPRISE_CALL); - - if (mPrimary.isConferenceCall()) { - Log.d(TAG, "Update primary display info for conference call."); - - ui.setPrimary( - null /* number */, - getConferenceString(mPrimary), - false /* nameIsNumber */, - null /* label */, - getConferencePhoto(mPrimary), - false /* isSipCall */, - showContactPhoto, - hasWorkCallProperty); - } else if (mPrimaryContactInfo != null) { - Log.d(TAG, "Update primary display info for " + mPrimaryContactInfo); - - String name = getNameForCall(mPrimaryContactInfo); - String number; - - boolean isChildNumberShown = !TextUtils.isEmpty(mPrimary.getChildNumber()); - boolean isForwardedNumberShown = !TextUtils.isEmpty(mPrimary.getLastForwardedNumber()); - boolean isCallSubjectShown = shouldShowCallSubject(mPrimary); - - if (isCallSubjectShown) { - ui.setCallSubject(mPrimary.getCallSubject()); - } else { - ui.setCallSubject(null); - } - - if (isCallSubjectShown) { - number = null; - } else if (isChildNumberShown) { - number = mContext.getString(R.string.child_number, mPrimary.getChildNumber()); - } else if (isForwardedNumberShown) { - // Use last forwarded number instead of second line, if present. - number = mPrimary.getLastForwardedNumber(); - } else { - number = getNumberForCall(mPrimaryContactInfo); - } - - ui.showForwardIndicator(isForwardedNumberShown); - maybeShowHdAudioIcon(); - - boolean nameIsNumber = name != null && name.equals(mPrimaryContactInfo.number); - // Call with caller that is a work contact. - boolean isWorkContact = (mPrimaryContactInfo.userType == ContactsUtils.USER_TYPE_WORK); - ui.setPrimary( - number, - name, - nameIsNumber, - isChildNumberShown || isCallSubjectShown ? null : mPrimaryContactInfo.label, - mPrimaryContactInfo.photo, - mPrimaryContactInfo.isSipCall, - showContactPhoto, - hasWorkCallProperty || isWorkContact); - - updateContactInteractions(); - } else { - // Clear the primary display info. - ui.setPrimary(null, null, false, null, null, false, false, false); - } - - if (mEmergencyCallListener != null) { - boolean isEmergencyCall = mPrimary.isEmergencyCall(); - mEmergencyCallListener.onCallUpdated((BaseFragment) ui, isEmergencyCall); - } - maybeShowSpamIconAndLabel(); - } - - private void updateSecondaryDisplayInfo() { - final CallCardUi ui = getUi(); - if (ui == null) { - return; - } - - if (mSecondary == null) { - // Clear the secondary display info. - ui.setSecondary(false, null, false, null, null, false /* isConference */, - false /* isVideoCall */, mIsFullscreen); - return; - } - - if (mSecondary.isConferenceCall()) { - ui.setSecondary( - true /* show */, - getConferenceString(mSecondary), - false /* nameIsNumber */, - null /* label */, - getCallProviderLabel(mSecondary), - true /* isConference */, - mSecondary.isVideoCall(mContext), - mIsFullscreen); - } else if (mSecondaryContactInfo != null) { - Log.d(TAG, "updateSecondaryDisplayInfo() " + mSecondaryContactInfo); - String name = getNameForCall(mSecondaryContactInfo); - boolean nameIsNumber = name != null && name.equals(mSecondaryContactInfo.number); - ui.setSecondary( - true /* show */, - name, - nameIsNumber, - mSecondaryContactInfo.label, - getCallProviderLabel(mSecondary), - false /* isConference */, - mSecondary.isVideoCall(mContext), - mIsFullscreen); - } else { - // Clear the secondary display info. - ui.setSecondary(false, null, false, null, null, false /* isConference */, - false /* isVideoCall */, mIsFullscreen); - } - } - - - /** - * Gets the phone account to display for a call. - */ - private PhoneAccount getAccountForCall(Call call) { - PhoneAccountHandle accountHandle = call.getAccountHandle(); - if (accountHandle == null) { - return null; - } - return TelecomManagerCompat.getPhoneAccount( - InCallPresenter.getInstance().getTelecomManager(), - accountHandle); - } - - /** - * Returns the gateway number for any existing outgoing call. - */ - private String getGatewayNumber() { - if (hasOutgoingGatewayCall()) { - return getNumberFromHandle(mPrimary.getGatewayInfo().getGatewayAddress()); - } - return null; - } - - /** - * Return the string label to represent the call provider - */ - private String getCallProviderLabel(Call call) { - PhoneAccount account = getAccountForCall(call); - TelecomManager mgr = InCallPresenter.getInstance().getTelecomManager(); - if (account != null && !TextUtils.isEmpty(account.getLabel()) - && TelecomManagerCompat.getCallCapablePhoneAccounts(mgr).size() > 1) { - return account.getLabel().toString(); - } - return null; - } - - /** - * Returns the label (line of text above the number/name) for any given call. - * For example, "calling via [Account/Google Voice]" for outgoing calls. - */ - private String getConnectionLabel() { - StatusHints statusHints = mPrimary.getTelecomCall().getDetails().getStatusHints(); - if (statusHints != null && !TextUtils.isEmpty(statusHints.getLabel())) { - return statusHints.getLabel().toString(); - } - - if (hasOutgoingGatewayCall() && getUi() != null) { - // Return the label for the gateway app on outgoing calls. - final PackageManager pm = mContext.getPackageManager(); - try { - ApplicationInfo info = pm.getApplicationInfo( - mPrimary.getGatewayInfo().getGatewayProviderPackageName(), 0); - return pm.getApplicationLabel(info).toString(); - } catch (PackageManager.NameNotFoundException e) { - Log.e(this, "Gateway Application Not Found.", e); - return null; - } - } - return getCallProviderLabel(mPrimary); - } - - private Drawable getCallStateIcon() { - // Return connection icon if one exists. - StatusHints statusHints = mPrimary.getTelecomCall().getDetails().getStatusHints(); - if (statusHints != null && statusHints.getIcon() != null) { - Drawable icon = statusHints.getIcon().loadDrawable(mContext); - if (icon != null) { - return icon; - } - } - - return null; - } - - private boolean hasOutgoingGatewayCall() { - // We only display the gateway information while STATE_DIALING so return false for any other - // call state. - // TODO: mPrimary can be null because this is called from updatePrimaryDisplayInfo which - // is also called after a contact search completes (call is not present yet). Split the - // UI update so it can receive independent updates. - if (mPrimary == null) { - return false; - } - return Call.State.isDialing(mPrimary.getState()) && mPrimary.getGatewayInfo() != null && - !mPrimary.getGatewayInfo().isEmpty(); - } - - /** - * Gets the name to display for the call. - */ - @NeededForTesting - String getNameForCall(ContactCacheEntry contactInfo) { - String preferredName = ContactDisplayUtils.getPreferredDisplayName( - contactInfo.namePrimary, - contactInfo.nameAlternative, - mContactsPreferences); - if (TextUtils.isEmpty(preferredName)) { - return contactInfo.number; - } - return preferredName; - } - - /** - * Gets the number to display for a call. - */ - @NeededForTesting - String getNumberForCall(ContactCacheEntry contactInfo) { - // If the name is empty, we use the number for the name...so don't show a second - // number in the number field - String preferredName = ContactDisplayUtils.getPreferredDisplayName( - contactInfo.namePrimary, - contactInfo.nameAlternative, - mContactsPreferences); - if (TextUtils.isEmpty(preferredName)) { - return contactInfo.location; - } - return contactInfo.number; - } - - public void secondaryInfoClicked() { - if (mSecondary == null) { - Log.w(this, "Secondary info clicked but no secondary call."); - return; - } - - Log.i(this, "Swapping call to foreground: " + mSecondary); - TelecomAdapter.getInstance().unholdCall(mSecondary.getId()); - } - - public void endCallClicked() { - if (mPrimary == null) { - return; - } - - Log.i(this, "Disconnecting call: " + mPrimary); - final String callId = mPrimary.getId(); - mPrimary.setState(Call.State.DISCONNECTING); - CallList.getInstance().onUpdate(mPrimary); - TelecomAdapter.getInstance().disconnectCall(callId); - } - - private String getNumberFromHandle(Uri handle) { - return handle == null ? "" : handle.getSchemeSpecificPart(); - } - - /** - * Handles a change to the fullscreen mode of the in-call UI. - * - * @param isFullscreenMode {@code True} if the in-call UI is entering full screen mode. - */ - @Override - public void onFullscreenModeChanged(boolean isFullscreenMode) { - mIsFullscreen = isFullscreenMode; - final CallCardUi ui = getUi(); - if (ui == null) { - return; - } - ui.setCallCardVisible(!isFullscreenMode); - ui.setSecondaryInfoVisible(!isFullscreenMode); - maybeShowManageConferenceCallButton(); - } - - @Override - public void onSecondaryCallerInfoVisibilityChanged(boolean isVisible, int height) { - // No-op - the Call Card is the origin of this event. - } - - private boolean isPrimaryCallActive() { - return mPrimary != null && mPrimary.getState() == Call.State.ACTIVE; - } - - private String getConferenceString(Call call) { - boolean isGenericConference = call.hasProperty(Details.PROPERTY_GENERIC_CONFERENCE); - Log.v(this, "getConferenceString: " + isGenericConference); - - final int resId = isGenericConference - ? R.string.card_title_in_call : R.string.card_title_conf_call; - return mContext.getResources().getString(resId); - } - - private Drawable getConferencePhoto(Call call) { - boolean isGenericConference = call.hasProperty(Details.PROPERTY_GENERIC_CONFERENCE); - Log.v(this, "getConferencePhoto: " + isGenericConference); - - final int resId = isGenericConference - ? R.drawable.img_phone : R.drawable.img_conference; - Drawable photo = mContext.getResources().getDrawable(resId); - photo.setAutoMirrored(true); - return photo; - } - - private boolean shouldShowEndCallButton(Call primary, int callState) { - if (primary == null) { - return false; - } - if ((!Call.State.isConnectingOrConnected(callState) - && callState != Call.State.DISCONNECTING) || callState == Call.State.INCOMING) { - return false; - } - if (mPrimary.getSessionModificationState() - == Call.SessionModificationState.RECEIVED_UPGRADE_TO_VIDEO_REQUEST) { - return false; - } - return true; - } - - private void maybeSendAccessibilityEvent(InCallState oldState, InCallState newState, - boolean primaryChanged) { - if (mContext == null) { - return; - } - final AccessibilityManager am = (AccessibilityManager) mContext.getSystemService( - Context.ACCESSIBILITY_SERVICE); - if (!am.isEnabled()) { - return; - } - // Announce the current call if it's new incoming/outgoing call or primary call is changed - // due to switching calls between two ongoing calls (one is on hold). - if ((oldState != InCallState.OUTGOING && newState == InCallState.OUTGOING) - || (oldState != InCallState.INCOMING && newState == InCallState.INCOMING) - || primaryChanged) { - if (getUi() != null) { - getUi().sendAccessibilityAnnouncement(); - } - } - } - - /** - * Determines whether the call subject should be visible on the UI. For the call subject to be - * visible, the call has to be in an incoming or waiting state, and the subject must not be - * empty. - * - * @param call The call. - * @return {@code true} if the subject should be shown, {@code false} otherwise. - */ - private boolean shouldShowCallSubject(Call call) { - if (call == null) { - return false; - } - - boolean isIncomingOrWaiting = mPrimary.getState() == Call.State.INCOMING || - mPrimary.getState() == Call.State.CALL_WAITING; - return isIncomingOrWaiting && !TextUtils.isEmpty(call.getCallSubject()) && - call.getNumberPresentation() == TelecomManager.PRESENTATION_ALLOWED && - call.isCallSubjectSupported(); - } - - /** - * Determines whether the "note sent" toast should be shown. It should be shown for a new - * outgoing call with a subject. - * - * @param call The call - * @return {@code true} if the toast should be shown, {@code false} otherwise. - */ - private boolean shouldShowNoteSentToast(Call call) { - return call != null && hasCallSubject(call) && (call.getState() == Call.State.DIALING - || call.getState() == Call.State.CONNECTING); - } - - private static boolean hasCallSubject(Call call) { - return !TextUtils.isEmpty(call.getTelecomCall().getDetails().getIntentExtras() - .getString(TelecomManager.EXTRA_CALL_SUBJECT)); - } - - public interface CallCardUi extends Ui { - void setVisible(boolean on); - void setContactContextTitle(View listHeaderView); - void setContactContextContent(ListAdapter listAdapter); - void showContactContext(boolean show); - void setCallCardVisible(boolean visible); - void setPrimary(String number, String name, boolean nameIsNumber, String label, - Drawable photo, boolean isSipCall, boolean isContactPhotoShown, boolean isWorkCall); - void setSecondary(boolean show, String name, boolean nameIsNumber, String label, - String providerLabel, boolean isConference, boolean isVideoCall, - boolean isFullscreen); - void setSecondaryInfoVisible(boolean visible); - void setCallState(int state, int videoState, int sessionModificationState, - DisconnectCause disconnectCause, String connectionLabel, - Drawable connectionIcon, String gatewayNumber, boolean isWifi, - boolean isConference, boolean isWorkCall); - void setPrimaryCallElapsedTime(boolean show, long duration); - void setPrimaryName(String name, boolean nameIsNumber); - void setPrimaryImage(Drawable image, boolean isVisible); - void setPrimaryPhoneNumber(String phoneNumber); - void setPrimaryLabel(String label); - void setEndCallButtonEnabled(boolean enabled, boolean animate); - void setCallbackNumber(String number, boolean isEmergencyCalls); - void setCallSubject(String callSubject); - void setProgressSpinnerVisible(boolean visible); - void showHdAudioIndicator(boolean visible); - void showForwardIndicator(boolean visible); - void showSpamIndicator(boolean visible); - void showManageConferenceCallButton(boolean visible); - boolean isManageConferenceVisible(); - boolean isCallSubjectVisible(); - void animateForNewOutgoingCall(); - void sendAccessibilityAnnouncement(); - void showNoteSentToast(); - } -} diff --git a/InCallUI/src/com/android/incallui/CallList.java b/InCallUI/src/com/android/incallui/CallList.java deleted file mode 100644 index 48870f68a..000000000 --- a/InCallUI/src/com/android/incallui/CallList.java +++ /dev/null @@ -1,695 +0,0 @@ -/* - * Copyright (C) 2013 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License - */ - -package com.android.incallui; - -import android.os.Handler; -import android.os.Message; -import android.os.Trace; -import android.telecom.DisconnectCause; -import android.telecom.PhoneAccount; - -import com.android.contacts.common.testing.NeededForTesting; -import com.android.dialer.logging.Logger; -import com.android.dialer.service.ExtendedCallInfoService; -import com.android.incallui.util.TelecomCallUtil; - -import com.google.common.base.Preconditions; -import com.google.common.collect.Maps; - -import java.util.Collections; -import java.util.HashMap; -import java.util.Iterator; -import java.util.List; -import java.util.Set; -import java.util.concurrent.ConcurrentHashMap; -import java.util.concurrent.CopyOnWriteArrayList; -import java.util.concurrent.atomic.AtomicBoolean; - -/** - * Maintains the list of active calls and notifies interested classes of changes to the call list - * as they are received from the telephony stack. Primary listener of changes to this class is - * InCallPresenter. - */ -public class CallList { - - private static final int DISCONNECTED_CALL_SHORT_TIMEOUT_MS = 200; - private static final int DISCONNECTED_CALL_MEDIUM_TIMEOUT_MS = 2000; - private static final int DISCONNECTED_CALL_LONG_TIMEOUT_MS = 5000; - - private static final int EVENT_DISCONNECTED_TIMEOUT = 1; - private static final long BLOCK_QUERY_TIMEOUT_MS = 1000; - - private static CallList sInstance = new CallList(); - - private final HashMap mCallById = new HashMap<>(); - private final HashMap mCallByTelecomCall = new HashMap<>(); - private final HashMap> mCallTextReponsesMap = Maps.newHashMap(); - /** - * ConcurrentHashMap constructor params: 8 is initial table size, 0.9f is - * load factor before resizing, 1 means we only expect a single thread to - * access the map so make only a single shard - */ - private final Set mListeners = Collections.newSetFromMap( - new ConcurrentHashMap(8, 0.9f, 1)); - private final HashMap> mCallUpdateListenerMap = Maps - .newHashMap(); - private final Set mPendingDisconnectCalls = Collections.newSetFromMap( - new ConcurrentHashMap(8, 0.9f, 1)); - private ExtendedCallInfoService mExtendedCallInfoService; - - /** - * Static singleton accessor method. - */ - public static CallList getInstance() { - return sInstance; - } - - /** - * USED ONLY FOR TESTING - * Testing-only constructor. Instance should only be acquired through getInstance(). - */ - @NeededForTesting - CallList() { - } - - public void onCallAdded(final android.telecom.Call telecomCall, LatencyReport latencyReport) { - Trace.beginSection("onCallAdded"); - final Call call = new Call(telecomCall, latencyReport); - Log.d(this, "onCallAdded: callState=" + call.getState()); - - if (call.getState() == Call.State.INCOMING || - call.getState() == Call.State.CALL_WAITING) { - onIncoming(call, call.getCannedSmsResponses()); - if (mExtendedCallInfoService != null) { - String number = TelecomCallUtil.getNumber(telecomCall); - mExtendedCallInfoService.getExtendedCallInfo(number, null, - new ExtendedCallInfoService.Listener() { - @Override - public void onComplete(boolean isSpam) { - call.setSpam(isSpam); - onUpdate(call); - } - }); - } - } else { - onUpdate(call); - } - - call.logCallInitiationType(); - Trace.endSection(); - } - - public void onCallRemoved(android.telecom.Call telecomCall) { - if (mCallByTelecomCall.containsKey(telecomCall)) { - Call call = mCallByTelecomCall.get(telecomCall); - Logger.logCall(call); - if (updateCallInMap(call)) { - Log.w(this, "Removing call not previously disconnected " + call.getId()); - } - updateCallTextMap(call, null); - } - } - - /** - * Called when a single call disconnects. - */ - public void onDisconnect(Call call) { - if (updateCallInMap(call)) { - Log.i(this, "onDisconnect: " + call); - // notify those listening for changes on this specific change - notifyCallUpdateListeners(call); - // notify those listening for all disconnects - notifyListenersOfDisconnect(call); - } - } - - /** - * Called when a single call has changed. - */ - public void onIncoming(Call call, List textMessages) { - if (updateCallInMap(call)) { - Log.i(this, "onIncoming - " + call); - } - updateCallTextMap(call, textMessages); - - for (Listener listener : mListeners) { - listener.onIncomingCall(call); - } - } - - public void onUpgradeToVideo(Call call){ - Log.d(this, "onUpgradeToVideo call=" + call); - for (Listener listener : mListeners) { - listener.onUpgradeToVideo(call); - } - } - /** - * Called when a single call has changed. - */ - public void onUpdate(Call call) { - Trace.beginSection("onUpdate"); - onUpdateCall(call); - notifyGenericListeners(); - Trace.endSection(); - } - - /** - * Called when a single call has changed session modification state. - * - * @param call The call. - * @param sessionModificationState The new session modification state. - */ - public void onSessionModificationStateChange(Call call, int sessionModificationState) { - final List listeners = mCallUpdateListenerMap.get(call.getId()); - if (listeners != null) { - for (CallUpdateListener listener : listeners) { - listener.onSessionModificationStateChange(sessionModificationState); - } - } - } - - /** - * Called when the last forwarded number changes for a call. With IMS, the last forwarded - * number changes due to a supplemental service notification, so it is not pressent at the - * start of the call. - * - * @param call The call. - */ - public void onLastForwardedNumberChange(Call call) { - final List listeners = mCallUpdateListenerMap.get(call.getId()); - if (listeners != null) { - for (CallUpdateListener listener : listeners) { - listener.onLastForwardedNumberChange(); - } - } - } - - /** - * Called when the child number changes for a call. The child number can be received after a - * call is initially set up, so we need to be able to inform listeners of the change. - * - * @param call The call. - */ - public void onChildNumberChange(Call call) { - final List listeners = mCallUpdateListenerMap.get(call.getId()); - if (listeners != null) { - for (CallUpdateListener listener : listeners) { - listener.onChildNumberChange(); - } - } - } - - public void notifyCallUpdateListeners(Call call) { - final List listeners = mCallUpdateListenerMap.get(call.getId()); - if (listeners != null) { - for (CallUpdateListener listener : listeners) { - listener.onCallChanged(call); - } - } - } - - /** - * Add a call update listener for a call id. - * - * @param callId The call id to get updates for. - * @param listener The listener to add. - */ - public void addCallUpdateListener(String callId, CallUpdateListener listener) { - List listeners = mCallUpdateListenerMap.get(callId); - if (listeners == null) { - listeners = new CopyOnWriteArrayList(); - mCallUpdateListenerMap.put(callId, listeners); - } - listeners.add(listener); - } - - /** - * Remove a call update listener for a call id. - * - * @param callId The call id to remove the listener for. - * @param listener The listener to remove. - */ - public void removeCallUpdateListener(String callId, CallUpdateListener listener) { - List listeners = mCallUpdateListenerMap.get(callId); - if (listeners != null) { - listeners.remove(listener); - } - } - - public void addListener(Listener listener) { - Preconditions.checkNotNull(listener); - - mListeners.add(listener); - - // Let the listener know about the active calls immediately. - listener.onCallListChange(this); - } - - public void removeListener(Listener listener) { - if (listener != null) { - mListeners.remove(listener); - } - } - - /** - * TODO: Change so that this function is not needed. Instead of assuming there is an active - * call, the code should rely on the status of a specific Call and allow the presenters to - * update the Call object when the active call changes. - */ - public Call getIncomingOrActive() { - Call retval = getIncomingCall(); - if (retval == null) { - retval = getActiveCall(); - } - return retval; - } - - public Call getOutgoingOrActive() { - Call retval = getOutgoingCall(); - if (retval == null) { - retval = getActiveCall(); - } - return retval; - } - - /** - * A call that is waiting for {@link PhoneAccount} selection - */ - public Call getWaitingForAccountCall() { - return getFirstCallWithState(Call.State.SELECT_PHONE_ACCOUNT); - } - - public Call getPendingOutgoingCall() { - return getFirstCallWithState(Call.State.CONNECTING); - } - - public Call getOutgoingCall() { - Call call = getFirstCallWithState(Call.State.DIALING); - if (call == null) { - call = getFirstCallWithState(Call.State.REDIALING); - } - return call; - } - - public Call getActiveCall() { - return getFirstCallWithState(Call.State.ACTIVE); - } - - public Call getSecondActiveCall() { - return getCallWithState(Call.State.ACTIVE, 1); - } - - public Call getBackgroundCall() { - return getFirstCallWithState(Call.State.ONHOLD); - } - - public Call getDisconnectedCall() { - return getFirstCallWithState(Call.State.DISCONNECTED); - } - - public Call getDisconnectingCall() { - return getFirstCallWithState(Call.State.DISCONNECTING); - } - - public Call getSecondBackgroundCall() { - return getCallWithState(Call.State.ONHOLD, 1); - } - - public Call getActiveOrBackgroundCall() { - Call call = getActiveCall(); - if (call == null) { - call = getBackgroundCall(); - } - return call; - } - - public Call getIncomingCall() { - Call call = getFirstCallWithState(Call.State.INCOMING); - if (call == null) { - call = getFirstCallWithState(Call.State.CALL_WAITING); - } - - return call; - } - - public Call getFirstCall() { - Call result = getIncomingCall(); - if (result == null) { - result = getPendingOutgoingCall(); - } - if (result == null) { - result = getOutgoingCall(); - } - if (result == null) { - result = getFirstCallWithState(Call.State.ACTIVE); - } - if (result == null) { - result = getDisconnectingCall(); - } - if (result == null) { - result = getDisconnectedCall(); - } - return result; - } - - public boolean hasLiveCall() { - Call call = getFirstCall(); - if (call == null) { - return false; - } - return call != getDisconnectingCall() && call != getDisconnectedCall(); - } - - /** - * Returns the first call found in the call map with the specified call modification state. - * @param state The session modification state to search for. - * @return The first call with the specified state. - */ - public Call getVideoUpgradeRequestCall() { - for(Call call : mCallById.values()) { - if (call.getSessionModificationState() == - Call.SessionModificationState.RECEIVED_UPGRADE_TO_VIDEO_REQUEST) { - return call; - } - } - return null; - } - - public Call getCallById(String callId) { - return mCallById.get(callId); - } - - public Call getCallByTelecomCall(android.telecom.Call telecomCall) { - return mCallByTelecomCall.get(telecomCall); - } - - public List getTextResponses(String callId) { - return mCallTextReponsesMap.get(callId); - } - - /** - * Returns first call found in the call map with the specified state. - */ - public Call getFirstCallWithState(int state) { - return getCallWithState(state, 0); - } - - /** - * Returns the [position]th call found in the call map with the specified state. - * TODO: Improve this logic to sort by call time. - */ - public Call getCallWithState(int state, int positionToFind) { - Call retval = null; - int position = 0; - for (Call call : mCallById.values()) { - if (call.getState() == state) { - if (position >= positionToFind) { - retval = call; - break; - } else { - position++; - } - } - } - - return retval; - } - - /** - * This is called when the service disconnects, either expectedly or unexpectedly. - * For the expected case, it's because we have no calls left. For the unexpected case, - * it is likely a crash of phone and we need to clean up our calls manually. Without phone, - * there can be no active calls, so this is relatively safe thing to do. - */ - public void clearOnDisconnect() { - for (Call call : mCallById.values()) { - final int state = call.getState(); - if (state != Call.State.IDLE && - state != Call.State.INVALID && - state != Call.State.DISCONNECTED) { - - call.setState(Call.State.DISCONNECTED); - call.setDisconnectCause(new DisconnectCause(DisconnectCause.UNKNOWN)); - updateCallInMap(call); - } - } - notifyGenericListeners(); - } - - /** - * Called when the user has dismissed an error dialog. This indicates acknowledgement of - * the disconnect cause, and that any pending disconnects should immediately occur. - */ - public void onErrorDialogDismissed() { - final Iterator iterator = mPendingDisconnectCalls.iterator(); - while (iterator.hasNext()) { - Call call = iterator.next(); - iterator.remove(); - finishDisconnectedCall(call); - } - } - - /** - * Processes an update for a single call. - * - * @param call The call to update. - */ - private void onUpdateCall(Call call) { - Log.d(this, "\t" + call); - if (updateCallInMap(call)) { - Log.i(this, "onUpdate - " + call); - } - updateCallTextMap(call, call.getCannedSmsResponses()); - notifyCallUpdateListeners(call); - } - - /** - * Sends a generic notification to all listeners that something has changed. - * It is up to the listeners to call back to determine what changed. - */ - private void notifyGenericListeners() { - for (Listener listener : mListeners) { - listener.onCallListChange(this); - } - } - - private void notifyListenersOfDisconnect(Call call) { - for (Listener listener : mListeners) { - listener.onDisconnect(call); - } - } - - /** - * Updates the call entry in the local map. - * @return false if no call previously existed and no call was added, otherwise true. - */ - private boolean updateCallInMap(Call call) { - Preconditions.checkNotNull(call); - - boolean updated = false; - - if (call.getState() == Call.State.DISCONNECTED) { - // update existing (but do not add!!) disconnected calls - if (mCallById.containsKey(call.getId())) { - // For disconnected calls, we want to keep them alive for a few seconds so that the - // UI has a chance to display anything it needs when a call is disconnected. - - // Set up a timer to destroy the call after X seconds. - final Message msg = mHandler.obtainMessage(EVENT_DISCONNECTED_TIMEOUT, call); - mHandler.sendMessageDelayed(msg, getDelayForDisconnect(call)); - mPendingDisconnectCalls.add(call); - - mCallById.put(call.getId(), call); - mCallByTelecomCall.put(call.getTelecomCall(), call); - updated = true; - } - } else if (!isCallDead(call)) { - mCallById.put(call.getId(), call); - mCallByTelecomCall.put(call.getTelecomCall(), call); - updated = true; - } else if (mCallById.containsKey(call.getId())) { - mCallById.remove(call.getId()); - mCallByTelecomCall.remove(call.getTelecomCall()); - updated = true; - } - - return updated; - } - - private int getDelayForDisconnect(Call call) { - Preconditions.checkState(call.getState() == Call.State.DISCONNECTED); - - - final int cause = call.getDisconnectCause().getCode(); - final int delay; - switch (cause) { - case DisconnectCause.LOCAL: - delay = DISCONNECTED_CALL_SHORT_TIMEOUT_MS; - break; - case DisconnectCause.REMOTE: - case DisconnectCause.ERROR: - delay = DISCONNECTED_CALL_MEDIUM_TIMEOUT_MS; - break; - case DisconnectCause.REJECTED: - case DisconnectCause.MISSED: - case DisconnectCause.CANCELED: - // no delay for missed/rejected incoming calls and canceled outgoing calls. - delay = 0; - break; - default: - delay = DISCONNECTED_CALL_LONG_TIMEOUT_MS; - break; - } - - return delay; - } - - private void updateCallTextMap(Call call, List textResponses) { - Preconditions.checkNotNull(call); - - if (!isCallDead(call)) { - if (textResponses != null) { - mCallTextReponsesMap.put(call.getId(), textResponses); - } - } else if (mCallById.containsKey(call.getId())) { - mCallTextReponsesMap.remove(call.getId()); - } - } - - private boolean isCallDead(Call call) { - final int state = call.getState(); - return Call.State.IDLE == state || Call.State.INVALID == state; - } - - /** - * Sets up a call for deletion and notifies listeners of change. - */ - private void finishDisconnectedCall(Call call) { - if (mPendingDisconnectCalls.contains(call)) { - mPendingDisconnectCalls.remove(call); - } - call.setState(Call.State.IDLE); - updateCallInMap(call); - notifyGenericListeners(); - } - - /** - * Notifies all video calls of a change in device orientation. - * - * @param rotation The new rotation angle (in degrees). - */ - public void notifyCallsOfDeviceRotation(int rotation) { - for (Call call : mCallById.values()) { - // First, ensure that the call videoState has video enabled (there is no need to set - // device orientation on a voice call which has not yet been upgraded to video). - // Second, ensure a VideoCall is set on the call so that the change can be sent to the - // provider (a VideoCall can be present for a call that does not currently have video, - // but can be upgraded to video). - - // NOTE: is it necessary to use this order because getVideoCall references the class - // VideoProfile which is not available on APIs <23 (M). - if (VideoUtils.isVideoCall(call) && call.getVideoCall() != null) { - call.getVideoCall().setDeviceOrientation(rotation); - } - } - } - - /** - * Handles the timeout for destroying disconnected calls. - */ - private Handler mHandler = new Handler() { - @Override - public void handleMessage(Message msg) { - switch (msg.what) { - case EVENT_DISCONNECTED_TIMEOUT: - Log.d(this, "EVENT_DISCONNECTED_TIMEOUT ", msg.obj); - finishDisconnectedCall((Call) msg.obj); - break; - default: - Log.wtf(this, "Message not expected: " + msg.what); - break; - } - } - }; - - public void setExtendedCallInfoService(ExtendedCallInfoService service) { - mExtendedCallInfoService = service; - } - - public void onInCallUiShown(boolean forFullScreenIntent) { - for (Call call : mCallById.values()) { - call.getLatencyReport().onInCallUiShown(forFullScreenIntent); - } - } - - /** - * Listener interface for any class that wants to be notified of changes - * to the call list. - */ - public interface Listener { - /** - * Called when a new incoming call comes in. - * This is the only method that gets called for incoming calls. Listeners - * that want to perform an action on incoming call should respond in this method - * because {@link #onCallListChange} does not automatically get called for - * incoming calls. - */ - public void onIncomingCall(Call call); - /** - * Called when a new modify call request comes in - * This is the only method that gets called for modify requests. - */ - public void onUpgradeToVideo(Call call); - /** - * Called anytime there are changes to the call list. The change can be switching call - * states, updating information, etc. This method will NOT be called for new incoming - * calls and for calls that switch to disconnected state. Listeners must add actions - * to those method implementations if they want to deal with those actions. - */ - public void onCallListChange(CallList callList); - - /** - * Called when a call switches to the disconnected state. This is the only method - * that will get called upon disconnection. - */ - public void onDisconnect(Call call); - - - } - - public interface CallUpdateListener { - // TODO: refactor and limit arg to be call state. Caller info is not needed. - public void onCallChanged(Call call); - - /** - * Notifies of a change to the session modification state for a call. - * - * @param sessionModificationState The new session modification state. - */ - public void onSessionModificationStateChange(int sessionModificationState); - - /** - * Notifies of a change to the last forwarded number for a call. - */ - public void onLastForwardedNumberChange(); - - /** - * Notifies of a change to the child number for a call. - */ - public void onChildNumberChange(); - } -} diff --git a/InCallUI/src/com/android/incallui/CallTimer.java b/InCallUI/src/com/android/incallui/CallTimer.java deleted file mode 100644 index d65e63373..000000000 --- a/InCallUI/src/com/android/incallui/CallTimer.java +++ /dev/null @@ -1,90 +0,0 @@ -/* - * Copyright (C) 2013 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License - */ - -package com.android.incallui; - -import com.google.common.base.Preconditions; - -import android.os.Handler; -import android.os.SystemClock; - -/** - * Helper class used to keep track of events requiring regular intervals. - */ -public class CallTimer extends Handler { - private Runnable mInternalCallback; - private Runnable mCallback; - private long mLastReportedTime; - private long mInterval; - private boolean mRunning; - - public CallTimer(Runnable callback) { - Preconditions.checkNotNull(callback); - - mInterval = 0; - mLastReportedTime = 0; - mRunning = false; - mCallback = callback; - mInternalCallback = new CallTimerCallback(); - } - - public boolean start(long interval) { - if (interval <= 0) { - return false; - } - - // cancel any previous timer - cancel(); - - mInterval = interval; - mLastReportedTime = SystemClock.uptimeMillis(); - - mRunning = true; - periodicUpdateTimer(); - - return true; - } - - public void cancel() { - removeCallbacks(mInternalCallback); - mRunning = false; - } - - private void periodicUpdateTimer() { - if (!mRunning) { - return; - } - - final long now = SystemClock.uptimeMillis(); - long nextReport = mLastReportedTime + mInterval; - while (now >= nextReport) { - nextReport += mInterval; - } - - postAtTime(mInternalCallback, nextReport); - mLastReportedTime = nextReport; - - // Run the callback - mCallback.run(); - } - - private class CallTimerCallback implements Runnable { - @Override - public void run() { - periodicUpdateTimer(); - } - } -} diff --git a/InCallUI/src/com/android/incallui/CallerInfo.java b/InCallUI/src/com/android/incallui/CallerInfo.java deleted file mode 100644 index f3d0e0763..000000000 --- a/InCallUI/src/com/android/incallui/CallerInfo.java +++ /dev/null @@ -1,585 +0,0 @@ -/* - * Copyright (C) 2006 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.incallui; - -import com.android.dialer.util.PhoneLookupUtil; -import com.google.common.primitives.Longs; - -import android.content.Context; -import android.database.Cursor; -import android.graphics.Bitmap; -import android.graphics.drawable.Drawable; -import android.net.Uri; -import android.provider.ContactsContract.CommonDataKinds.Phone; -import android.provider.ContactsContract; -import android.provider.ContactsContract.Contacts; -import android.provider.ContactsContract.Data; -import android.provider.ContactsContract.PhoneLookup; -import android.provider.ContactsContract.RawContacts; -import android.telephony.PhoneNumberUtils; -import android.text.TextUtils; - -import com.android.contacts.common.compat.CompatUtils; -import com.android.contacts.common.compat.PhoneLookupSdkCompat; -import com.android.contacts.common.ContactsUtils; -import com.android.contacts.common.ContactsUtils.UserType; -import com.android.contacts.common.util.PhoneNumberHelper; -import com.android.contacts.common.util.TelephonyManagerUtils; -import com.android.dialer.R; -import com.android.dialer.calllog.ContactInfoHelper; - -/** - * Looks up caller information for the given phone number. - */ -public class CallerInfo { - private static final String TAG = "CallerInfo"; - - // We should always use this projection starting from NYC onward. - private static final String[] DEFAULT_PHONELOOKUP_PROJECTION = new String[] { - PhoneLookupSdkCompat.CONTACT_ID, - PhoneLookup.DISPLAY_NAME, - PhoneLookup.LOOKUP_KEY, - PhoneLookup.NUMBER, - PhoneLookup.NORMALIZED_NUMBER, - PhoneLookup.LABEL, - PhoneLookup.TYPE, - PhoneLookup.PHOTO_URI, - PhoneLookup.CUSTOM_RINGTONE, - PhoneLookup.SEND_TO_VOICEMAIL - }; - - // In pre-N, contact id is stored in {@link PhoneLookup._ID} in non-sip query. - private static final String[] BACKWARD_COMPATIBLE_NON_SIP_DEFAULT_PHONELOOKUP_PROJECTION = - new String[] { - PhoneLookup._ID, - PhoneLookup.DISPLAY_NAME, - PhoneLookup.LOOKUP_KEY, - PhoneLookup.NUMBER, - PhoneLookup.NORMALIZED_NUMBER, - PhoneLookup.LABEL, - PhoneLookup.TYPE, - PhoneLookup.PHOTO_URI, - PhoneLookup.CUSTOM_RINGTONE, - PhoneLookup.SEND_TO_VOICEMAIL - }; - - public static String[] getDefaultPhoneLookupProjection(Uri phoneLookupUri) { - if (CompatUtils.isNCompatible()) { - return DEFAULT_PHONELOOKUP_PROJECTION; - } - // Pre-N - boolean isSip = phoneLookupUri.getBooleanQueryParameter( - ContactsContract.PhoneLookup.QUERY_PARAMETER_SIP_ADDRESS, false); - return (isSip) ? DEFAULT_PHONELOOKUP_PROJECTION - : BACKWARD_COMPATIBLE_NON_SIP_DEFAULT_PHONELOOKUP_PROJECTION; - } - - /** - * Please note that, any one of these member variables can be null, - * and any accesses to them should be prepared to handle such a case. - * - * Also, it is implied that phoneNumber is more often populated than - * name is, (think of calls being dialed/received using numbers where - * names are not known to the device), so phoneNumber should serve as - * a dependable fallback when name is unavailable. - * - * One other detail here is that this CallerInfo object reflects - * information found on a connection, it is an OUTPUT that serves - * mainly to display information to the user. In no way is this object - * used as input to make a connection, so we can choose to display - * whatever human-readable text makes sense to the user for a - * connection. This is especially relevant for the phone number field, - * since it is the one field that is most likely exposed to the user. - * - * As an example: - * 1. User dials "911" - * 2. Device recognizes that this is an emergency number - * 3. We use the "Emergency Number" string instead of "911" in the - * phoneNumber field. - * - * What we're really doing here is treating phoneNumber as an essential - * field here, NOT name. We're NOT always guaranteed to have a name - * for a connection, but the number should be displayable. - */ - public String name; - public String nameAlternative; - public String phoneNumber; - public String normalizedNumber; - public String forwardingNumber; - public String geoDescription; - - public String cnapName; - public int numberPresentation; - public int namePresentation; - public boolean contactExists; - - public String phoneLabel; - /* Split up the phoneLabel into number type and label name */ - public int numberType; - public String numberLabel; - - public int photoResource; - - // Contact ID, which will be 0 if a contact comes from the corp CP2. - public long contactIdOrZero; - public String lookupKeyOrNull; - public boolean needUpdate; - public Uri contactRefUri; - public @UserType long userType; - - /** - * Contact display photo URI. If a contact has no display photo but a thumbnail, it'll be - * the thumbnail URI instead. - */ - public Uri contactDisplayPhotoUri; - - // fields to hold individual contact preference data, - // including the send to voicemail flag and the ringtone - // uri reference. - public Uri contactRingtoneUri; - public boolean shouldSendToVoicemail; - - /** - * Drawable representing the caller image. This is essentially - * a cache for the image data tied into the connection / - * callerinfo object. - * - * This might be a high resolution picture which is more suitable - * for full-screen image view than for smaller icons used in some - * kinds of notifications. - * - * The {@link #isCachedPhotoCurrent} flag indicates if the image - * data needs to be reloaded. - */ - public Drawable cachedPhoto; - /** - * Bitmap representing the caller image which has possibly lower - * resolution than {@link #cachedPhoto} and thus more suitable for - * icons (like notification icons). - * - * In usual cases this is just down-scaled image of {@link #cachedPhoto}. - * If the down-scaling fails, this will just become null. - * - * The {@link #isCachedPhotoCurrent} flag indicates if the image - * data needs to be reloaded. - */ - public Bitmap cachedPhotoIcon; - /** - * Boolean which indicates if {@link #cachedPhoto} and - * {@link #cachedPhotoIcon} is fresh enough. If it is false, - * those images aren't pointing to valid objects. - */ - public boolean isCachedPhotoCurrent; - - /** - * String which holds the call subject sent as extra from the lower layers for this call. This - * is used to display the no-caller ID reason for restricted/unknown number presentation. - */ - public String callSubject; - - private boolean mIsEmergency; - private boolean mIsVoiceMail; - - public CallerInfo() { - // TODO: Move all the basic initialization here? - mIsEmergency = false; - mIsVoiceMail = false; - userType = ContactsUtils.USER_TYPE_CURRENT; - } - - /** - * getCallerInfo given a Cursor. - * @param context the context used to retrieve string constants - * @param contactRef the URI to attach to this CallerInfo object - * @param cursor the first object in the cursor is used to build the CallerInfo object. - * @return the CallerInfo which contains the caller id for the given - * number. The returned CallerInfo is null if no number is supplied. - */ - public static CallerInfo getCallerInfo(Context context, Uri contactRef, Cursor cursor) { - CallerInfo info = new CallerInfo(); - info.photoResource = 0; - info.phoneLabel = null; - info.numberType = 0; - info.numberLabel = null; - info.cachedPhoto = null; - info.isCachedPhotoCurrent = false; - info.contactExists = false; - info.userType = ContactsUtils.USER_TYPE_CURRENT; - - Log.v(TAG, "getCallerInfo() based on cursor..."); - - if (cursor != null) { - if (cursor.moveToFirst()) { - // TODO: photo_id is always available but not taken - // care of here. Maybe we should store it in the - // CallerInfo object as well. - - long contactId = 0L; - int columnIndex; - - // Look for the name - columnIndex = cursor.getColumnIndex(PhoneLookup.DISPLAY_NAME); - if (columnIndex != -1) { - info.name = cursor.getString(columnIndex); - } - - // Look for the number - columnIndex = cursor.getColumnIndex(PhoneLookup.NUMBER); - if (columnIndex != -1) { - info.phoneNumber = cursor.getString(columnIndex); - } - - // Look for the normalized number - columnIndex = cursor.getColumnIndex(PhoneLookup.NORMALIZED_NUMBER); - if (columnIndex != -1) { - info.normalizedNumber = cursor.getString(columnIndex); - } - - // Look for the label/type combo - columnIndex = cursor.getColumnIndex(PhoneLookup.LABEL); - if (columnIndex != -1) { - int typeColumnIndex = cursor.getColumnIndex(PhoneLookup.TYPE); - if (typeColumnIndex != -1) { - info.numberType = cursor.getInt(typeColumnIndex); - info.numberLabel = cursor.getString(columnIndex); - info.phoneLabel = Phone.getTypeLabel(context.getResources(), - info.numberType, info.numberLabel) - .toString(); - } - } - - // Look for the person_id. - columnIndex = getColumnIndexForPersonId(contactRef, cursor); - if (columnIndex != -1) { - contactId = cursor.getLong(columnIndex); - // QuickContacts in M doesn't support enterprise contact id - if (contactId != 0 && (ContactsUtils.FLAG_N_FEATURE - || !Contacts.isEnterpriseContactId(contactId))) { - info.contactIdOrZero = contactId; - Log.v(TAG, "==> got info.contactIdOrZero: " + info.contactIdOrZero); - - // cache the lookup key for later use with person_id to create lookup URIs - columnIndex = cursor.getColumnIndex(PhoneLookup.LOOKUP_KEY); - if (columnIndex != -1) { - info.lookupKeyOrNull = cursor.getString(columnIndex); - } - } - } else { - // No valid columnIndex, so we can't look up person_id. - Log.v(TAG, "Couldn't find contactId column for " + contactRef); - // Watch out: this means that anything that depends on - // person_id will be broken (like contact photo lookups in - // the in-call UI, for example.) - } - - // Display photo URI. - columnIndex = cursor.getColumnIndex(PhoneLookup.PHOTO_URI); - if ((columnIndex != -1) && (cursor.getString(columnIndex) != null)) { - info.contactDisplayPhotoUri = Uri.parse(cursor.getString(columnIndex)); - } else { - info.contactDisplayPhotoUri = null; - } - - // look for the custom ringtone, create from the string stored - // in the database. - columnIndex = cursor.getColumnIndex(PhoneLookup.CUSTOM_RINGTONE); - if ((columnIndex != -1) && (cursor.getString(columnIndex) != null)) { - if (TextUtils.isEmpty(cursor.getString(columnIndex))) { - // make it consistent with frameworks/base/.../CallerInfo.java - info.contactRingtoneUri = Uri.EMPTY; - } else { - info.contactRingtoneUri = Uri.parse(cursor.getString(columnIndex)); - } - } else { - info.contactRingtoneUri = null; - } - - // look for the send to voicemail flag, set it to true only - // under certain circumstances. - columnIndex = cursor.getColumnIndex(PhoneLookup.SEND_TO_VOICEMAIL); - info.shouldSendToVoicemail = (columnIndex != -1) && - ((cursor.getInt(columnIndex)) == 1); - info.contactExists = true; - - // Determine userType by directoryId and contactId - final String directory = contactRef == null ? null - : contactRef.getQueryParameter(ContactsContract.DIRECTORY_PARAM_KEY); - final Long directoryId = directory == null ? null : Longs.tryParse(directory); - info.userType = ContactsUtils.determineUserType(directoryId, contactId); - - info.nameAlternative = ContactInfoHelper.lookUpDisplayNameAlternative( - context, info.lookupKeyOrNull, info.userType, directoryId); - } - cursor.close(); - } - - info.needUpdate = false; - info.name = normalize(info.name); - info.contactRefUri = contactRef; - - return info; - } - - /** - * getCallerInfo given a URI, look up in the call-log database - * for the uri unique key. - * @param context the context used to get the ContentResolver - * @param contactRef the URI used to lookup caller id - * @return the CallerInfo which contains the caller id for the given - * number. The returned CallerInfo is null if no number is supplied. - */ - private static CallerInfo getCallerInfo(Context context, Uri contactRef) { - - return getCallerInfo(context, contactRef, - context.getContentResolver().query(contactRef, null, null, null, null)); - } - - /** - * Performs another lookup if previous lookup fails and it's a SIP call - * and the peer's username is all numeric. Look up the username as it - * could be a PSTN number in the contact database. - * - * @param context the query context - * @param number the original phone number, could be a SIP URI - * @param previousResult the result of previous lookup - * @return previousResult if it's not the case - */ - static CallerInfo doSecondaryLookupIfNecessary(Context context, - String number, CallerInfo previousResult) { - if (!previousResult.contactExists - && PhoneNumberHelper.isUriNumber(number)) { - String username = PhoneNumberHelper.getUsernameFromUriNumber(number); - if (PhoneNumberUtils.isGlobalPhoneNumber(username)) { - previousResult = getCallerInfo(context, - Uri.withAppendedPath(PhoneLookup.ENTERPRISE_CONTENT_FILTER_URI, - Uri.encode(username))); - } - } - return previousResult; - } - - // Accessors - - /** - * @return true if the caller info is an emergency number. - */ - public boolean isEmergencyNumber() { - return mIsEmergency; - } - - /** - * @return true if the caller info is a voicemail number. - */ - public boolean isVoiceMailNumber() { - return mIsVoiceMail; - } - - /** - * Mark this CallerInfo as an emergency call. - * @param context To lookup the localized 'Emergency Number' string. - * @return this instance. - */ - /* package */ CallerInfo markAsEmergency(Context context) { - name = context.getString(R.string.emergency_call_dialog_number_for_display); - phoneNumber = null; - - photoResource = R.drawable.img_phone; - mIsEmergency = true; - return this; - } - - - /** - * Mark this CallerInfo as a voicemail call. The voicemail label - * is obtained from the telephony manager. Caller must hold the - * READ_PHONE_STATE permission otherwise the phoneNumber will be - * set to null. - * @return this instance. - */ - /* package */ CallerInfo markAsVoiceMail(Context context) { - mIsVoiceMail = true; - - try { - // For voicemail calls, we display the voice mail tag - // instead of the real phone number in the "number" - // field. - name = TelephonyManagerUtils.getVoiceMailAlphaTag(context); - phoneNumber = null; - } catch (SecurityException se) { - // Should never happen: if this process does not have - // permission to retrieve VM tag, it should not have - // permission to retrieve VM number and would not call - // this method. - // Leave phoneNumber untouched. - Log.e(TAG, "Cannot access VoiceMail.", se); - } - // TODO: There is no voicemail picture? - // FIXME: FIND ANOTHER ICON - // photoResource = android.R.drawable.badge_voicemail; - return this; - } - - private static String normalize(String s) { - if (s == null || s.length() > 0) { - return s; - } else { - return null; - } - } - - /** - * Returns the column index to use to find the "person_id" field in - * the specified cursor, based on the contact URI that was originally - * queried. - * - * This is a helper function for the getCallerInfo() method that takes - * a Cursor. Looking up the person_id is nontrivial (compared to all - * the other CallerInfo fields) since the column we need to use - * depends on what query we originally ran. - * - * Watch out: be sure to not do any database access in this method, since - * it's run from the UI thread (see comments below for more info.) - * - * @return the columnIndex to use (with cursor.getLong()) to get the - * person_id, or -1 if we couldn't figure out what colum to use. - * - * TODO: Add a unittest for this method. (This is a little tricky to - * test, since we'll need a live contacts database to test against, - * preloaded with at least some phone numbers and SIP addresses. And - * we'll probably have to hardcode the column indexes we expect, so - * the test might break whenever the contacts schema changes. But we - * can at least make sure we handle all the URI patterns we claim to, - * and that the mime types match what we expect...) - */ - private static int getColumnIndexForPersonId(Uri contactRef, Cursor cursor) { - // TODO: This is pretty ugly now, see bug 2269240 for - // more details. The column to use depends upon the type of URL: - // - content://com.android.contacts/data/phones ==> use the "contact_id" column - // - content://com.android.contacts/phone_lookup ==> use the "_ID" column - // - content://com.android.contacts/data ==> use the "contact_id" column - // If it's none of the above, we leave columnIndex=-1 which means - // that the person_id field will be left unset. - // - // The logic here *used* to be based on the mime type of contactRef - // (for example Phone.CONTENT_ITEM_TYPE would tell us to use the - // RawContacts.CONTACT_ID column). But looking up the mime type requires - // a call to context.getContentResolver().getType(contactRef), which - // isn't safe to do from the UI thread since it can cause an ANR if - // the contacts provider is slow or blocked (like during a sync.) - // - // So instead, figure out the column to use for person_id by just - // looking at the URI itself. - - Log.v(TAG, "- getColumnIndexForPersonId: contactRef URI = '" - + contactRef + "'..."); - // Warning: Do not enable the following logging (due to ANR risk.) - // if (VDBG) Rlog.v(TAG, "- MIME type: " - // + context.getContentResolver().getType(contactRef)); - - String url = contactRef.toString(); - String columnName = null; - if (url.startsWith("content://com.android.contacts/data/phones")) { - // Direct lookup in the Phone table. - // MIME type: Phone.CONTENT_ITEM_TYPE (= "vnd.android.cursor.item/phone_v2") - Log.v(TAG, "'data/phones' URI; using RawContacts.CONTACT_ID"); - columnName = RawContacts.CONTACT_ID; - } else if (url.startsWith("content://com.android.contacts/data")) { - // Direct lookup in the Data table. - // MIME type: Data.CONTENT_TYPE (= "vnd.android.cursor.dir/data") - Log.v(TAG, "'data' URI; using Data.CONTACT_ID"); - // (Note Data.CONTACT_ID and RawContacts.CONTACT_ID are equivalent.) - columnName = Data.CONTACT_ID; - } else if (url.startsWith("content://com.android.contacts/phone_lookup")) { - // Lookup in the PhoneLookup table, which provides "fuzzy matching" - // for phone numbers. - // MIME type: PhoneLookup.CONTENT_TYPE (= "vnd.android.cursor.dir/phone_lookup") - Log.v(TAG, "'phone_lookup' URI; using PhoneLookup._ID"); - columnName = PhoneLookupUtil.getContactIdColumnNameForUri(contactRef); - } else { - Log.v(TAG, "Unexpected prefix for contactRef '" + url + "'"); - } - int columnIndex = (columnName != null) ? cursor.getColumnIndex(columnName) : -1; - Log.v(TAG, "==> Using column '" + columnName - + "' (columnIndex = " + columnIndex + ") for person_id lookup..."); - return columnIndex; - } - - /** - * Updates this CallerInfo's geoDescription field, based on the raw - * phone number in the phoneNumber field. - * - * (Note that the various getCallerInfo() methods do *not* set the - * geoDescription automatically; you need to call this method - * explicitly to get it.) - * - * @param context the context used to look up the current locale / country - * @param fallbackNumber if this CallerInfo's phoneNumber field is empty, - * this specifies a fallback number to use instead. - */ - public void updateGeoDescription(Context context, String fallbackNumber) { - String number = TextUtils.isEmpty(phoneNumber) ? fallbackNumber : phoneNumber; - geoDescription = com.android.dialer.util.PhoneNumberUtil.getGeoDescription(context, number); - } - - /** - * @return a string debug representation of this instance. - */ - @Override - public String toString() { - // Warning: never check in this file with VERBOSE_DEBUG = true - // because that will result in PII in the system log. - final boolean VERBOSE_DEBUG = false; - - if (VERBOSE_DEBUG) { - return new StringBuilder(384) - .append(super.toString() + " { ") - .append("\nname: " + name) - .append("\nphoneNumber: " + phoneNumber) - .append("\nnormalizedNumber: " + normalizedNumber) - .append("\forwardingNumber: " + forwardingNumber) - .append("\ngeoDescription: " + geoDescription) - .append("\ncnapName: " + cnapName) - .append("\nnumberPresentation: " + numberPresentation) - .append("\nnamePresentation: " + namePresentation) - .append("\ncontactExists: " + contactExists) - .append("\nphoneLabel: " + phoneLabel) - .append("\nnumberType: " + numberType) - .append("\nnumberLabel: " + numberLabel) - .append("\nphotoResource: " + photoResource) - .append("\ncontactIdOrZero: " + contactIdOrZero) - .append("\nneedUpdate: " + needUpdate) - .append("\ncontactRefUri: " + contactRefUri) - .append("\ncontactRingtoneUri: " + contactRingtoneUri) - .append("\ncontactDisplayPhotoUri: " + contactDisplayPhotoUri) - .append("\nshouldSendToVoicemail: " + shouldSendToVoicemail) - .append("\ncachedPhoto: " + cachedPhoto) - .append("\nisCachedPhotoCurrent: " + isCachedPhotoCurrent) - .append("\nemergency: " + mIsEmergency) - .append("\nvoicemail: " + mIsVoiceMail) - .append("\nuserType: " + userType) - .append(" }") - .toString(); - } else { - return new StringBuilder(128) - .append(super.toString() + " { ") - .append("name " + ((name == null) ? "null" : "non-null")) - .append(", phoneNumber " + ((phoneNumber == null) ? "null" : "non-null")) - .append(" }") - .toString(); - } - } -} diff --git a/InCallUI/src/com/android/incallui/CallerInfoAsyncQuery.java b/InCallUI/src/com/android/incallui/CallerInfoAsyncQuery.java deleted file mode 100644 index f7f0cbb5d..000000000 --- a/InCallUI/src/com/android/incallui/CallerInfoAsyncQuery.java +++ /dev/null @@ -1,599 +0,0 @@ -/* - * Copyright (C) 2006 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.incallui; - -import com.google.common.primitives.Longs; - -import android.Manifest; -import android.content.AsyncQueryHandler; -import android.content.ContentResolver; -import android.content.Context; -import android.database.Cursor; -import android.database.SQLException; -import android.net.Uri; -import android.os.Handler; -import android.os.Looper; -import android.os.Message; -import android.provider.ContactsContract; -import android.provider.ContactsContract.Directory; -import android.telephony.PhoneNumberUtils; -import android.text.TextUtils; - -import com.android.contacts.common.ContactsUtils; -import com.android.contacts.common.compat.DirectoryCompat; -import com.android.contacts.common.util.PermissionsUtil; -import com.android.contacts.common.util.TelephonyManagerUtils; -import com.android.dialer.R; -import com.android.dialer.calllog.ContactInfoHelper; -import com.android.dialer.service.CachedNumberLookupService; -import com.android.dialer.service.CachedNumberLookupService.CachedContactInfo; -import com.android.dialerbind.ObjectFactory; - -import java.io.IOException; -import java.io.InputStream; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Locale; - -/** - * Helper class to make it easier to run asynchronous caller-id lookup queries. - * @see CallerInfo - * - */ -public class CallerInfoAsyncQuery { - private static final boolean DBG = false; - private static final String LOG_TAG = "CallerInfoAsyncQuery"; - - private static final int EVENT_NEW_QUERY = 1; - private static final int EVENT_ADD_LISTENER = 2; - private static final int EVENT_END_OF_QUEUE = 3; - private static final int EVENT_EMERGENCY_NUMBER = 4; - private static final int EVENT_VOICEMAIL_NUMBER = 5; - - private CallerInfoAsyncQueryHandler mHandler; - - // If the CallerInfo query finds no contacts, should we use the - // PhoneNumberOfflineGeocoder to look up a "geo description"? - // (TODO: This could become a flag in config.xml if it ever needs to be - // configured on a per-product basis.) - private static final boolean ENABLE_UNKNOWN_NUMBER_GEO_DESCRIPTION = true; - - /** - * Interface for a CallerInfoAsyncQueryHandler result return. - */ - public interface OnQueryCompleteListener { - /** - * Called when the query is complete. - */ - public void onQueryComplete(int token, Object cookie, CallerInfo ci); - } - - - /** - * Wrap the cookie from the WorkerArgs with additional information needed by our - * classes. - */ - private static final class CookieWrapper { - public OnQueryCompleteListener listener; - public Object cookie; - public int event; - public String number; - } - - /** - * Simple exception used to communicate problems with the query pool. - */ - public static class QueryPoolException extends SQLException { - public QueryPoolException(String error) { - super(error); - } - } - - /** - * Our own implementation of the AsyncQueryHandler. - */ - private class CallerInfoAsyncQueryHandler extends AsyncQueryHandler { - - @Override - public void startQuery(int token, Object cookie, Uri uri, String[] projection, - String selection, String[] selectionArgs, String orderBy) { - if (DBG) { - // Show stack trace with the arguments. - android.util.Log.d(LOG_TAG, "InCall: startQuery: url=" + uri + - " projection=[" + Arrays.toString(projection) + "]" + - " selection=" + selection + " " + - " args=[" + Arrays.toString(selectionArgs) + "]", - new RuntimeException("STACKTRACE")); - } - super.startQuery(token, cookie, uri, projection, selection, selectionArgs, orderBy); - } - - /** - * The information relevant to each CallerInfo query. Each query may have multiple - * listeners, so each AsyncCursorInfo is associated with 2 or more CookieWrapper - * objects in the queue (one with a new query event, and one with a end event, with - * 0 or more additional listeners in between). - */ - private Context mQueryContext; - private Uri mQueryUri; - private CallerInfo mCallerInfo; - - /** - * Our own query worker thread. - * - * This thread handles the messages enqueued in the looper. The normal sequence - * of events is that a new query shows up in the looper queue, followed by 0 or - * more add listener requests, and then an end request. Of course, these requests - * can be interlaced with requests from other tokens, but is irrelevant to this - * handler since the handler has no state. - * - * Note that we depend on the queue to keep things in order; in other words, the - * looper queue must be FIFO with respect to input from the synchronous startQuery - * calls and output to this handleMessage call. - * - * This use of the queue is required because CallerInfo objects may be accessed - * multiple times before the query is complete. All accesses (listeners) must be - * queued up and informed in order when the query is complete. - */ - protected class CallerInfoWorkerHandler extends WorkerHandler { - public CallerInfoWorkerHandler(Looper looper) { - super(looper); - } - - @Override - public void handleMessage(Message msg) { - WorkerArgs args = (WorkerArgs) msg.obj; - CookieWrapper cw = (CookieWrapper) args.cookie; - - if (cw == null) { - // Normally, this should never be the case for calls originating - // from within this code. - // However, if there is any code that this Handler calls (such as in - // super.handleMessage) that DOES place unexpected messages on the - // queue, then we need pass these messages on. - Log.d(this, "Unexpected command (CookieWrapper is null): " + msg.what + - " ignored by CallerInfoWorkerHandler, passing onto parent."); - - super.handleMessage(msg); - } else { - Log.d(this, "Processing event: " + cw.event + " token (arg1): " + msg.arg1 + - " command: " + msg.what + " query URI: " + - sanitizeUriToString(args.uri)); - - switch (cw.event) { - case EVENT_NEW_QUERY: - //start the sql command. - super.handleMessage(msg); - break; - - // shortcuts to avoid query for recognized numbers. - case EVENT_EMERGENCY_NUMBER: - case EVENT_VOICEMAIL_NUMBER: - - case EVENT_ADD_LISTENER: - case EVENT_END_OF_QUEUE: - // query was already completed, so just send the reply. - // passing the original token value back to the caller - // on top of the event values in arg1. - Message reply = args.handler.obtainMessage(msg.what); - reply.obj = args; - reply.arg1 = msg.arg1; - - reply.sendToTarget(); - - break; - default: - } - } - } - } - - - /** - * Asynchronous query handler class for the contact / callerinfo object. - */ - private CallerInfoAsyncQueryHandler(Context context) { - super(context.getContentResolver()); - } - - @Override - protected Handler createHandler(Looper looper) { - return new CallerInfoWorkerHandler(looper); - } - - /** - * Overrides onQueryComplete from AsyncQueryHandler. - * - * This method takes into account the state of this class; we construct the CallerInfo - * object only once for each set of listeners. When the query thread has done its work - * and calls this method, we inform the remaining listeners in the queue, until we're - * out of listeners. Once we get the message indicating that we should expect no new - * listeners for this CallerInfo object, we release the AsyncCursorInfo back into the - * pool. - */ - @Override - protected void onQueryComplete(int token, Object cookie, Cursor cursor) { - try { - Log.d(this, "##### onQueryComplete() ##### query complete for token: " + token); - - //get the cookie and notify the listener. - CookieWrapper cw = (CookieWrapper) cookie; - if (cw == null) { - // Normally, this should never be the case for calls originating - // from within this code. - // However, if there is any code that calls this method, we should - // check the parameters to make sure they're viable. - Log.d(this, "Cookie is null, ignoring onQueryComplete() request."); - return; - } - - if (cw.event == EVENT_END_OF_QUEUE) { - release(); - return; - } - - // check the token and if needed, create the callerinfo object. - if (mCallerInfo == null) { - if ((mQueryContext == null) || (mQueryUri == null)) { - throw new QueryPoolException - ("Bad context or query uri, or CallerInfoAsyncQuery already released."); - } - - // adjust the callerInfo data as needed, and only if it was set from the - // initial query request. - // Change the callerInfo number ONLY if it is an emergency number or the - // voicemail number, and adjust other data (including photoResource) - // accordingly. - if (cw.event == EVENT_EMERGENCY_NUMBER) { - // Note we're setting the phone number here (refer to javadoc - // comments at the top of CallerInfo class). - mCallerInfo = new CallerInfo().markAsEmergency(mQueryContext); - } else if (cw.event == EVENT_VOICEMAIL_NUMBER) { - mCallerInfo = new CallerInfo().markAsVoiceMail(mQueryContext); - } else { - mCallerInfo = CallerInfo.getCallerInfo(mQueryContext, mQueryUri, cursor); - Log.d(this, "==> Got mCallerInfo: " + mCallerInfo); - - CallerInfo newCallerInfo = CallerInfo.doSecondaryLookupIfNecessary( - mQueryContext, cw.number, mCallerInfo); - if (newCallerInfo != mCallerInfo) { - mCallerInfo = newCallerInfo; - Log.d(this, "#####async contact look up with numeric username" - + mCallerInfo); - } - - // Final step: look up the geocoded description. - if (ENABLE_UNKNOWN_NUMBER_GEO_DESCRIPTION) { - // Note we do this only if we *don't* have a valid name (i.e. if - // no contacts matched the phone number of the incoming call), - // since that's the only case where the incoming-call UI cares - // about this field. - // - // (TODO: But if we ever want the UI to show the geoDescription - // even when we *do* match a contact, we'll need to either call - // updateGeoDescription() unconditionally here, or possibly add a - // new parameter to CallerInfoAsyncQuery.startQuery() to force - // the geoDescription field to be populated.) - - if (TextUtils.isEmpty(mCallerInfo.name)) { - // Actually when no contacts match the incoming phone number, - // the CallerInfo object is totally blank here (i.e. no name - // *or* phoneNumber). So we need to pass in cw.number as - // a fallback number. - mCallerInfo.updateGeoDescription(mQueryContext, cw.number); - } - } - - // Use the number entered by the user for display. - if (!TextUtils.isEmpty(cw.number)) { - mCallerInfo.phoneNumber = PhoneNumberUtils.formatNumber(cw.number, - mCallerInfo.normalizedNumber, - TelephonyManagerUtils.getCurrentCountryIso(mQueryContext, - Locale.getDefault())); - } - } - - Log.d(this, "constructing CallerInfo object for token: " + token); - - //notify that we can clean up the queue after this. - CookieWrapper endMarker = new CookieWrapper(); - endMarker.event = EVENT_END_OF_QUEUE; - startQuery(token, endMarker, null, null, null, null, null); - } - - //notify the listener that the query is complete. - if (cw.listener != null) { - Log.d(this, "notifying listener: " + cw.listener.getClass().toString() + - " for token: " + token + mCallerInfo); - cw.listener.onQueryComplete(token, cw.cookie, mCallerInfo); - } - } finally { - // The cursor may have been closed in CallerInfo.getCallerInfo() - if (cursor != null && !cursor.isClosed()) { - cursor.close(); - } - } - } - } - - /** - * Private constructor for factory methods. - */ - private CallerInfoAsyncQuery() { - } - - public static void startQuery(final int token, final Context context, final CallerInfo info, - final OnQueryCompleteListener listener, final Object cookie) { - Log.d(LOG_TAG, "##### CallerInfoAsyncQuery startContactProviderQuery()... #####"); - Log.d(LOG_TAG, "- number: " + info.phoneNumber); - Log.d(LOG_TAG, "- cookie: " + cookie); - if (!PermissionsUtil.hasPermission(context, Manifest.permission.READ_CONTACTS)) { - Log.w(LOG_TAG, "Dialer doesn't have permission to read contacts."); - listener.onQueryComplete(token, cookie, info); - return; - } - - OnQueryCompleteListener contactsProviderQueryCompleteListener = - new OnQueryCompleteListener() { - @Override - public void onQueryComplete(int token, Object cookie, CallerInfo ci) { - Log.d(LOG_TAG, "contactsProviderQueryCompleteListener done"); - // If there are no other directory queries, make sure that the listener is - // notified of this result. see b/27621628 - if ((ci != null && ci.contactExists) || - !startOtherDirectoriesQuery(token, context, info, listener, cookie)) { - if (listener != null && ci != null) { - listener.onQueryComplete(token, cookie, ci); - } - } - } - }; - startDefaultDirectoryQuery(token, context, info, contactsProviderQueryCompleteListener, - cookie); - } - - // Private methods - private static CallerInfoAsyncQuery startDefaultDirectoryQuery(int token, Context context, - CallerInfo info, OnQueryCompleteListener listener, Object cookie) { - // Construct the URI object and query params, and start the query. - Uri uri = ContactInfoHelper.getContactInfoLookupUri(info.phoneNumber); - return startQueryInternal(token, context, info, listener, cookie, uri); - } - - /** - * Factory method to start the query based on a CallerInfo object. - * - * Note: if the number contains an "@" character we treat it - * as a SIP address, and look it up directly in the Data table - * rather than using the PhoneLookup table. - * TODO: But eventually we should expose two separate methods, one for - * numbers and one for SIP addresses, and then have - * PhoneUtils.startGetCallerInfo() decide which one to call based on - * the phone type of the incoming connection. - */ - private static CallerInfoAsyncQuery startQueryInternal(int token, Context context, - CallerInfo info, OnQueryCompleteListener listener, Object cookie, Uri contactRef) { - if (DBG) { - Log.d(LOG_TAG, "==> contactRef: " + sanitizeUriToString(contactRef)); - } - - CallerInfoAsyncQuery c = new CallerInfoAsyncQuery(); - c.allocate(context, contactRef); - - //create cookieWrapper, start query - CookieWrapper cw = new CookieWrapper(); - cw.listener = listener; - cw.cookie = cookie; - cw.number = info.phoneNumber; - - // check to see if these are recognized numbers, and use shortcuts if we can. - if (PhoneNumberUtils.isLocalEmergencyNumber(context, info.phoneNumber)) { - cw.event = EVENT_EMERGENCY_NUMBER; - } else if (info.isVoiceMailNumber()) { - cw.event = EVENT_VOICEMAIL_NUMBER; - } else { - cw.event = EVENT_NEW_QUERY; - } - - - String[] proejection = CallerInfo.getDefaultPhoneLookupProjection(contactRef); - c.mHandler.startQuery(token, - cw, // cookie - contactRef, // uri - proejection, // projection - null, // selection - null, // selectionArgs - null); // orderBy - return c; - } - - // Return value indicates if listener was notified. - private static boolean startOtherDirectoriesQuery(int token, Context context, CallerInfo info, - OnQueryCompleteListener listener, Object cookie) { - long[] directoryIds = getDirectoryIds(context); - int size = directoryIds.length; - if (size == 0) { - return false; - } - - DirectoryQueryCompleteListenerFactory listenerFactory = - new DirectoryQueryCompleteListenerFactory(context, size, listener); - - // The current implementation of multiple async query runs in single handler thread - // in AsyncQueryHandler. - // intermediateListener.onQueryComplete is also called from the same caller thread. - // TODO(b/26019872): use thread pool instead of single thread. - for (int i = 0; i < size; i++) { - long directoryId = directoryIds[i]; - Uri uri = ContactInfoHelper.getContactInfoLookupUri(info.phoneNumber, directoryId); - if (DBG) { - Log.d(LOG_TAG, "directoryId: " + directoryId + " uri: " + uri); - } - OnQueryCompleteListener intermediateListener = - listenerFactory.newListener(directoryId); - startQueryInternal(token, context, info, intermediateListener, cookie, uri); - } - return true; - } - - /* Directory lookup related code - START */ - private static final String[] DIRECTORY_PROJECTION = new String[] {Directory._ID}; - - private static long[] getDirectoryIds(Context context) { - ArrayList results = new ArrayList<>(); - - Uri uri = Directory.CONTENT_URI; - if (ContactsUtils.FLAG_N_FEATURE) { - uri = Uri.withAppendedPath(ContactsContract.AUTHORITY_URI, "directories_enterprise"); - } - - ContentResolver cr = context.getContentResolver(); - Cursor cursor = cr.query(uri, DIRECTORY_PROJECTION, null, null, null); - addDirectoryIdsFromCursor(cursor, results); - - return Longs.toArray(results); - } - - private static void addDirectoryIdsFromCursor(Cursor cursor, ArrayList results) { - if (cursor != null) { - int idIndex = cursor.getColumnIndex(Directory._ID); - while (cursor.moveToNext()) { - long id = cursor.getLong(idIndex); - if (DirectoryCompat.isRemoteDirectoryId(id)) { - results.add(id); - } - } - cursor.close(); - } - } - - private static final class DirectoryQueryCompleteListenerFactory { - // Make sure listener to be called once and only once - private int mCount; - private boolean mIsListenerCalled; - private final OnQueryCompleteListener mListener; - private final Context mContext; - private final CachedNumberLookupService mCachedNumberLookupService = - ObjectFactory.newCachedNumberLookupService(); - - private class DirectoryQueryCompleteListener implements OnQueryCompleteListener { - private final long mDirectoryId; - - DirectoryQueryCompleteListener(long directoryId) { - mDirectoryId = directoryId; - } - - @Override - public void onQueryComplete(int token, Object cookie, CallerInfo ci) { - onDirectoryQueryComplete(token, cookie, ci, mDirectoryId); - } - } - - DirectoryQueryCompleteListenerFactory(Context context, int size, - OnQueryCompleteListener listener) { - mCount = size; - mListener = listener; - mIsListenerCalled = false; - mContext = context; - } - - private void onDirectoryQueryComplete(int token, Object cookie, CallerInfo ci, - long directoryId) { - boolean shouldCallListener = false; - synchronized (this) { - mCount = mCount - 1; - if (!mIsListenerCalled && (ci.contactExists || mCount == 0)) { - mIsListenerCalled = true; - shouldCallListener = true; - } - } - - // Don't call callback in synchronized block because mListener.onQueryComplete may - // take long time to complete - if (shouldCallListener && mListener != null) { - addCallerInfoIntoCache(ci, directoryId); - mListener.onQueryComplete(token, cookie, ci); - } - } - - private void addCallerInfoIntoCache(CallerInfo ci, long directoryId) { - if (ci.contactExists && mCachedNumberLookupService != null) { - // 1. Cache caller info - CachedContactInfo cachedContactInfo = CallerInfoUtils - .buildCachedContactInfo(mCachedNumberLookupService, ci); - String directoryLabel = mContext.getString(R.string.directory_search_label); - cachedContactInfo.setDirectorySource(directoryLabel, directoryId); - mCachedNumberLookupService.addContact(mContext, cachedContactInfo); - - // 2. Cache photo - if (ci.contactDisplayPhotoUri != null && ci.normalizedNumber != null) { - try (InputStream in = mContext.getContentResolver() - .openInputStream(ci.contactDisplayPhotoUri)) { - if (in != null) { - mCachedNumberLookupService.addPhoto(mContext, ci.normalizedNumber, in); - } - } catch (IOException e) { - Log.e(LOG_TAG, "failed to fetch directory contact photo", e); - } - - } - } - } - - public OnQueryCompleteListener newListener(long directoryId) { - return new DirectoryQueryCompleteListener(directoryId); - } - } - /* Directory lookup related code - END */ - - /** - * Method to create a new CallerInfoAsyncQueryHandler object, ensuring correct - * state of context and uri. - */ - private void allocate(Context context, Uri contactRef) { - if ((context == null) || (contactRef == null)){ - throw new QueryPoolException("Bad context or query uri."); - } - mHandler = new CallerInfoAsyncQueryHandler(context); - mHandler.mQueryContext = context; - mHandler.mQueryUri = contactRef; - } - - /** - * Releases the relevant data. - */ - private void release() { - mHandler.mQueryContext = null; - mHandler.mQueryUri = null; - mHandler.mCallerInfo = null; - mHandler = null; - } - - private static String sanitizeUriToString(Uri uri) { - if (uri != null) { - String uriString = uri.toString(); - int indexOfLastSlash = uriString.lastIndexOf('/'); - if (indexOfLastSlash > 0) { - return uriString.substring(0, indexOfLastSlash) + "/xxxxxxx"; - } else { - return uriString; - } - } else { - return ""; - } - } -} diff --git a/InCallUI/src/com/android/incallui/CallerInfoUtils.java b/InCallUI/src/com/android/incallui/CallerInfoUtils.java deleted file mode 100644 index 289b652fc..000000000 --- a/InCallUI/src/com/android/incallui/CallerInfoUtils.java +++ /dev/null @@ -1,234 +0,0 @@ -package com.android.incallui; - -import android.content.Context; -import android.content.Loader; -import android.content.Loader.OnLoadCompleteListener; -import android.net.Uri; -import android.telecom.PhoneAccount; -import android.telecom.TelecomManager; -import android.text.TextUtils; -import android.util.Log; - -import com.android.contacts.common.model.Contact; -import com.android.contacts.common.model.ContactLoader; -import com.android.dialer.R; -import com.android.dialer.calllog.ContactInfo; -import com.android.dialer.service.CachedNumberLookupService; -import com.android.dialer.service.CachedNumberLookupService.CachedContactInfo; -import com.android.dialer.util.TelecomUtil; - -import java.util.Arrays; - -/** - * Utility methods for contact and caller info related functionality - */ -public class CallerInfoUtils { - - private static final String TAG = CallerInfoUtils.class.getSimpleName(); - - /** Define for not a special CNAP string */ - private static final int CNAP_SPECIAL_CASE_NO = -1; - - public CallerInfoUtils() { - } - - private static final int QUERY_TOKEN = -1; - - /** - * This is called to get caller info for a call. This will return a CallerInfo - * object immediately based off information in the call, but - * more information is returned to the OnQueryCompleteListener (which contains - * information about the phone number label, user's name, etc). - */ - public static CallerInfo getCallerInfoForCall(Context context, Call call, - CallerInfoAsyncQuery.OnQueryCompleteListener listener) { - CallerInfo info = buildCallerInfo(context, call); - - // TODO: Have phoneapp send a Uri when it knows the contact that triggered this call. - - if (info.numberPresentation == TelecomManager.PRESENTATION_ALLOWED) { - // Start the query with the number provided from the call. - Log.d(TAG, "==> Actually starting CallerInfoAsyncQuery.startQuery()..."); - CallerInfoAsyncQuery.startQuery(QUERY_TOKEN, context, info, listener, call); - } - return info; - } - - public static CallerInfo buildCallerInfo(Context context, Call call) { - CallerInfo info = new CallerInfo(); - - // Store CNAP information retrieved from the Connection (we want to do this - // here regardless of whether the number is empty or not). - info.cnapName = call.getCnapName(); - info.name = info.cnapName; - info.numberPresentation = call.getNumberPresentation(); - info.namePresentation = call.getCnapNamePresentation(); - info.callSubject = call.getCallSubject(); - - String number = call.getNumber(); - if (!TextUtils.isEmpty(number)) { - final String[] numbers = number.split("&"); - number = numbers[0]; - if (numbers.length > 1) { - info.forwardingNumber = numbers[1]; - } - - number = modifyForSpecialCnapCases(context, info, number, info.numberPresentation); - info.phoneNumber = number; - } - - // Because the InCallUI is immediately launched before the call is connected, occasionally - // a voicemail call will be passed to InCallUI as a "voicemail:" URI without a number. - // This call should still be handled as a voicemail call. - if ((call.getHandle() != null && - PhoneAccount.SCHEME_VOICEMAIL.equals(call.getHandle().getScheme())) || - isVoiceMailNumber(context, call)) { - info.markAsVoiceMail(context); - } - - ContactInfoCache.getInstance(context).maybeInsertCnapInformationIntoCache(context, call, - info); - - return info; - } - - /** - * Creates a new {@link CachedContactInfo} from a {@link CallerInfo} - * - * @param lookupService the {@link CachedNumberLookupService} used to build a - * new {@link CachedContactInfo} - * @param {@link CallerInfo} object - * @return a CachedContactInfo object created from this CallerInfo - * @throws NullPointerException if lookupService or ci are null - */ - public static CachedContactInfo buildCachedContactInfo(CachedNumberLookupService lookupService, - CallerInfo ci) { - ContactInfo info = new ContactInfo(); - info.name = ci.name; - info.type = ci.numberType; - info.label = ci.phoneLabel; - info.number = ci.phoneNumber; - info.normalizedNumber = ci.normalizedNumber; - info.photoUri = ci.contactDisplayPhotoUri; - info.userType = ci.userType; - - CachedContactInfo cacheInfo = lookupService.buildCachedContactInfo(info); - cacheInfo.setLookupKey(ci.lookupKeyOrNull); - return cacheInfo; - } - - public static boolean isVoiceMailNumber(Context context, Call call) { - return TelecomUtil.isVoicemailNumber(context, - call.getTelecomCall().getDetails().getAccountHandle(), - call.getNumber()); - } - - /** - * Handles certain "corner cases" for CNAP. When we receive weird phone numbers - * from the network to indicate different number presentations, convert them to - * expected number and presentation values within the CallerInfo object. - * @param number number we use to verify if we are in a corner case - * @param presentation presentation value used to verify if we are in a corner case - * @return the new String that should be used for the phone number - */ - /* package */static String modifyForSpecialCnapCases(Context context, CallerInfo ci, - String number, int presentation) { - // Obviously we return number if ci == null, but still return number if - // number == null, because in these cases the correct string will still be - // displayed/logged after this function returns based on the presentation value. - if (ci == null || number == null) return number; - - Log.d(TAG, "modifyForSpecialCnapCases: initially, number=" - + toLogSafePhoneNumber(number) - + ", presentation=" + presentation + " ci " + ci); - - // "ABSENT NUMBER" is a possible value we could get from the network as the - // phone number, so if this happens, change it to "Unknown" in the CallerInfo - // and fix the presentation to be the same. - final String[] absentNumberValues = - context.getResources().getStringArray(R.array.absent_num); - if (Arrays.asList(absentNumberValues).contains(number) - && presentation == TelecomManager.PRESENTATION_ALLOWED) { - number = context.getString(R.string.unknown); - ci.numberPresentation = TelecomManager.PRESENTATION_UNKNOWN; - } - - // Check for other special "corner cases" for CNAP and fix them similarly. Corner - // cases only apply if we received an allowed presentation from the network, so check - // if we think we have an allowed presentation, or if the CallerInfo presentation doesn't - // match the presentation passed in for verification (meaning we changed it previously - // because it's a corner case and we're being called from a different entry point). - if (ci.numberPresentation == TelecomManager.PRESENTATION_ALLOWED - || (ci.numberPresentation != presentation - && presentation == TelecomManager.PRESENTATION_ALLOWED)) { - // For all special strings, change number & numberPrentation. - if (isCnapSpecialCaseRestricted(number)) { - number = context.getString(R.string.private_num); - ci.numberPresentation = TelecomManager.PRESENTATION_RESTRICTED; - } else if (isCnapSpecialCaseUnknown(number)) { - number = context.getString(R.string.unknown); - ci.numberPresentation = TelecomManager.PRESENTATION_UNKNOWN; - } - Log.d(TAG, "SpecialCnap: number=" + toLogSafePhoneNumber(number) - + "; presentation now=" + ci.numberPresentation); - } - Log.d(TAG, "modifyForSpecialCnapCases: returning number string=" - + toLogSafePhoneNumber(number)); - return number; - } - - private static boolean isCnapSpecialCaseRestricted(String n) { - return n.equals("PRIVATE") || n.equals("P") || n.equals("RES"); - } - - private static boolean isCnapSpecialCaseUnknown(String n) { - return n.equals("UNAVAILABLE") || n.equals("UNKNOWN") || n.equals("UNA") || n.equals("U"); - } - - /* package */static String toLogSafePhoneNumber(String number) { - // For unknown number, log empty string. - if (number == null) { - return ""; - } - - // Todo: Figure out an equivalent for VDBG - if (false) { - // When VDBG is true we emit PII. - return number; - } - - // Do exactly same thing as Uri#toSafeString() does, which will enable us to compare - // sanitized phone numbers. - StringBuilder builder = new StringBuilder(); - for (int i = 0; i < number.length(); i++) { - char c = number.charAt(i); - if (c == '-' || c == '@' || c == '.' || c == '&') { - builder.append(c); - } else { - builder.append('x'); - } - } - return builder.toString(); - } - - /** - * Send a notification using a {@link ContactLoader} to inform the sync adapter that we are - * viewing a particular contact, so that it can download the high-res photo. - */ - public static void sendViewNotification(Context context, Uri contactUri) { - final ContactLoader loader = new ContactLoader(context, contactUri, - true /* postViewNotification */); - loader.registerListener(0, new OnLoadCompleteListener() { - @Override - public void onLoadComplete( - Loader loader, Contact contact) { - try { - loader.reset(); - } catch (RuntimeException e) { - Log.e(TAG, "Error resetting loader", e); - } - } - }); - loader.startLoading(); - } -} diff --git a/InCallUI/src/com/android/incallui/CircularRevealFragment.java b/InCallUI/src/com/android/incallui/CircularRevealFragment.java deleted file mode 100644 index 01bd253ec..000000000 --- a/InCallUI/src/com/android/incallui/CircularRevealFragment.java +++ /dev/null @@ -1,170 +0,0 @@ -/* - * Copyright (C) 2014 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.animation.Animator; -import android.animation.AnimatorListenerAdapter; -import android.app.Activity; -import android.app.Fragment; -import android.app.FragmentManager; -import android.graphics.Outline; -import android.graphics.Point; -import android.os.Bundle; -import android.view.Display; -import android.view.LayoutInflater; -import android.view.View; -import android.view.ViewAnimationUtils; -import android.view.ViewGroup; -import android.view.ViewOutlineProvider; -import android.view.ViewTreeObserver; -import android.view.ViewTreeObserver.OnPreDrawListener; - -import com.android.contacts.common.util.MaterialColorMapUtils.MaterialPalette; -import com.android.dialer.R; - -public class CircularRevealFragment extends Fragment { - static final String TAG = "CircularRevealFragment"; - - private Point mTouchPoint; - private OnCircularRevealCompleteListener mListener; - private boolean mAnimationStarted; - - interface OnCircularRevealCompleteListener { - public void onCircularRevealComplete(FragmentManager fm); - } - - public static void startCircularReveal(FragmentManager fm, Point touchPoint, - OnCircularRevealCompleteListener listener) { - if (fm.findFragmentByTag(TAG) == null) { - fm.beginTransaction().add(R.id.main, - new CircularRevealFragment(touchPoint, listener), TAG) - .commitAllowingStateLoss(); - } else { - Log.w(TAG, "An instance of CircularRevealFragment already exists"); - } - } - - public static void endCircularReveal(FragmentManager fm) { - final Fragment fragment = fm.findFragmentByTag(TAG); - if (fragment != null) { - fm.beginTransaction().remove(fragment).commitAllowingStateLoss(); - } - } - - /** - * Empty constructor used only by the {@link FragmentManager}. - */ - public CircularRevealFragment() {} - - public CircularRevealFragment(Point touchPoint, OnCircularRevealCompleteListener listener) { - mTouchPoint = touchPoint; - mListener = listener; - } - - @Override - public void onResume() { - super.onResume(); - if (!mAnimationStarted) { - // Only run the animation once for each instance of the fragment - startOutgoingAnimation(InCallPresenter.getInstance().getThemeColors()); - } - mAnimationStarted = true; - } - - @Override - public View onCreateView(LayoutInflater inflater, ViewGroup container, - Bundle savedInstanceState) { - return inflater.inflate(R.layout.outgoing_call_animation, container, false); - } - - public void startOutgoingAnimation(MaterialPalette palette) { - final Activity activity = getActivity(); - if (activity == null) { - Log.w(this, "Asked to do outgoing call animation when not attached"); - return; - } - - final View view = activity.getWindow().getDecorView(); - - // The circle starts from an initial size of 0 so clip it such that it is invisible. - // Otherwise the first frame is drawn with a fully opaque screen which causes jank. When - // the animation later starts, this clip will be clobbered by the circular reveal clip. - // See ViewAnimationUtils.createCircularReveal. - view.setOutlineProvider(new ViewOutlineProvider() { - @Override - public void getOutline(View view, Outline outline) { - // Using (0, 0, 0, 0) will not work since the outline will simply be treated as - // an empty outline. - outline.setOval(-1, -1, 0, 0); - } - }); - view.setClipToOutline(true); - - if (palette != null) { - view.findViewById(R.id.outgoing_call_animation_circle).setBackgroundColor( - palette.mPrimaryColor); - activity.getWindow().setStatusBarColor(palette.mSecondaryColor); - } - - view.getViewTreeObserver().addOnPreDrawListener(new OnPreDrawListener() { - @Override - public boolean onPreDraw() { - final ViewTreeObserver vto = view.getViewTreeObserver(); - if (vto.isAlive()) { - vto.removeOnPreDrawListener(this); - } - final Animator animator = getRevealAnimator(mTouchPoint); - if (animator != null) { - animator.addListener(new AnimatorListenerAdapter() { - @Override - public void onAnimationEnd(Animator animation) { - view.setClipToOutline(false); - if (mListener != null) { - mListener.onCircularRevealComplete(getFragmentManager()); - } - } - }); - animator.start(); - } - return false; - } - }); - } - - private Animator getRevealAnimator(Point touchPoint) { - final Activity activity = getActivity(); - if (activity == null) { - return null; - } - final View view = activity.getWindow().getDecorView(); - final Display display = activity.getWindowManager().getDefaultDisplay(); - final Point size = new Point(); - display.getSize(size); - - int startX = size.x / 2; - int startY = size.y / 2; - if (touchPoint != null) { - startX = touchPoint.x; - startY = touchPoint.y; - } - - final Animator valueAnimator = ViewAnimationUtils.createCircularReveal(view, - startX, startY, 0, Math.max(size.x, size.y)); - valueAnimator.setDuration(getResources().getInteger(R.integer.reveal_animation_duration)); - return valueAnimator; - } -} diff --git a/InCallUI/src/com/android/incallui/ConferenceManagerFragment.java b/InCallUI/src/com/android/incallui/ConferenceManagerFragment.java deleted file mode 100644 index fe941c8c5..000000000 --- a/InCallUI/src/com/android/incallui/ConferenceManagerFragment.java +++ /dev/null @@ -1,139 +0,0 @@ -/* - * Copyright (C) 2013 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License - */ - -package com.android.incallui; - -import android.app.ActionBar; -import android.content.Context; -import android.os.Bundle; -import android.view.LayoutInflater; -import android.view.View; -import android.view.ViewGroup; -import android.widget.ListView; - -import com.android.contacts.common.ContactPhotoManager; -import com.android.dialer.R; - -import java.util.List; - -/** - * Fragment that allows the user to manage a conference call. - */ -public class ConferenceManagerFragment - extends BaseFragment - implements ConferenceManagerPresenter.ConferenceManagerUi { - - private static final String KEY_IS_VISIBLE = "key_conference_is_visible"; - - private ListView mConferenceParticipantList; - private int mActionBarElevation; - private ContactPhotoManager mContactPhotoManager; - private LayoutInflater mInflater; - private ConferenceParticipantListAdapter mConferenceParticipantListAdapter; - private boolean mIsVisible; - private boolean mIsRecreating; - - @Override - public ConferenceManagerPresenter createPresenter() { - return new ConferenceManagerPresenter(); - } - - @Override - public ConferenceManagerPresenter.ConferenceManagerUi getUi() { - return this; - } - - @Override - public void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - if (savedInstanceState != null) { - mIsRecreating = true; - mIsVisible = savedInstanceState.getBoolean(KEY_IS_VISIBLE); - } - } - - @Override - public View onCreateView(LayoutInflater inflater, ViewGroup container, - Bundle savedInstanceState) { - final View parent = - inflater.inflate(R.layout.conference_manager_fragment, container, false); - - mConferenceParticipantList = (ListView) parent.findViewById(R.id.participantList); - mContactPhotoManager = - ContactPhotoManager.getInstance(getActivity().getApplicationContext()); - mActionBarElevation = - (int) getResources().getDimension(R.dimen.incall_action_bar_elevation); - mInflater = LayoutInflater.from(getActivity().getApplicationContext()); - - return parent; - } - - @Override - public void onResume() { - super.onResume(); - if (mIsRecreating) { - onVisibilityChanged(mIsVisible); - } - } - - @Override - public void onSaveInstanceState(Bundle outState) { - outState.putBoolean(KEY_IS_VISIBLE, mIsVisible); - super.onSaveInstanceState(outState); - } - - public void onVisibilityChanged(boolean isVisible) { - mIsVisible = isVisible; - ActionBar actionBar = getActivity().getActionBar(); - if (isVisible) { - actionBar.setTitle(R.string.manageConferenceLabel); - actionBar.setElevation(mActionBarElevation); - actionBar.setHideOffset(0); - actionBar.show(); - - final CallList calls = CallList.getInstance(); - getPresenter().init(getActivity(), calls); - // Request focus on the list of participants for accessibility purposes. This ensures - // that once the list of participants is shown, the first participant is announced. - mConferenceParticipantList.requestFocus(); - } else { - actionBar.setElevation(0); - actionBar.setHideOffset(actionBar.getHeight()); - } - } - - @Override - public boolean isFragmentVisible() { - return isVisible(); - } - - @Override - public void update(Context context, List participants, boolean parentCanSeparate) { - if (mConferenceParticipantListAdapter == null) { - mConferenceParticipantListAdapter = new ConferenceParticipantListAdapter( - mConferenceParticipantList, context, mInflater, mContactPhotoManager); - - mConferenceParticipantList.setAdapter(mConferenceParticipantListAdapter); - } - mConferenceParticipantListAdapter.updateParticipants(participants, parentCanSeparate); - } - - @Override - public void refreshCall(Call call) { - mConferenceParticipantListAdapter.refreshCall(call); - } -} diff --git a/InCallUI/src/com/android/incallui/ConferenceManagerPresenter.java b/InCallUI/src/com/android/incallui/ConferenceManagerPresenter.java deleted file mode 100644 index 6fb6e5dda..000000000 --- a/InCallUI/src/com/android/incallui/ConferenceManagerPresenter.java +++ /dev/null @@ -1,144 +0,0 @@ -/* - * Copyright (C) 2013 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License - */ - -package com.android.incallui; - -import android.content.Context; - -import com.android.incallui.InCallPresenter.InCallDetailsListener; -import com.android.incallui.InCallPresenter.InCallState; -import com.android.incallui.InCallPresenter.InCallStateListener; -import com.android.incallui.InCallPresenter.IncomingCallListener; - -import com.google.common.base.Preconditions; - -import java.util.ArrayList; -import java.util.List; - -/** - * Logic for call buttons. - */ -public class ConferenceManagerPresenter - extends Presenter - implements InCallStateListener, InCallDetailsListener, IncomingCallListener { - - private Context mContext; - - @Override - public void onUiReady(ConferenceManagerUi ui) { - super.onUiReady(ui); - - // register for call state changes last - InCallPresenter.getInstance().addListener(this); - InCallPresenter.getInstance().addIncomingCallListener(this); - } - - @Override - public void onUiUnready(ConferenceManagerUi ui) { - super.onUiUnready(ui); - - InCallPresenter.getInstance().removeListener(this); - InCallPresenter.getInstance().removeIncomingCallListener(this); - } - - @Override - public void onStateChange(InCallState oldState, InCallState newState, CallList callList) { - if (getUi().isFragmentVisible()) { - Log.v(this, "onStateChange" + newState); - if (newState == InCallState.INCALL) { - final Call call = callList.getActiveOrBackgroundCall(); - if (call != null && call.isConferenceCall()) { - Log.v(this, "Number of existing calls is " + - String.valueOf(call.getChildCallIds().size())); - update(callList); - } else { - InCallPresenter.getInstance().showConferenceCallManager(false); - } - } else { - InCallPresenter.getInstance().showConferenceCallManager(false); - } - } - } - - @Override - public void onDetailsChanged(Call call, android.telecom.Call.Details details) { - boolean canDisconnect = details.can( - android.telecom.Call.Details.CAPABILITY_DISCONNECT_FROM_CONFERENCE); - boolean canSeparate = details.can( - android.telecom.Call.Details.CAPABILITY_SEPARATE_FROM_CONFERENCE); - - if (call.can(android.telecom.Call.Details.CAPABILITY_DISCONNECT_FROM_CONFERENCE) - != canDisconnect - || call.can(android.telecom.Call.Details.CAPABILITY_SEPARATE_FROM_CONFERENCE) - != canSeparate) { - getUi().refreshCall(call); - } - - if (!details.can( - android.telecom.Call.Details.CAPABILITY_MANAGE_CONFERENCE)) { - InCallPresenter.getInstance().showConferenceCallManager(false); - } - } - - @Override - public void onIncomingCall(InCallState oldState, InCallState newState, Call call) { - // When incoming call exists, set conference ui invisible. - if (getUi().isFragmentVisible()) { - Log.d(this, "onIncomingCall()... Conference ui is showing, hide it."); - InCallPresenter.getInstance().showConferenceCallManager(false); - } - } - - public void init(Context context, CallList callList) { - mContext = Preconditions.checkNotNull(context); - mContext = context; - update(callList); - } - - /** - * Updates the conference participant adapter. - * - * @param callList The callList. - */ - private void update(CallList callList) { - // callList is non null, but getActiveOrBackgroundCall() may return null - final Call currentCall = callList.getActiveOrBackgroundCall(); - if (currentCall == null) { - return; - } - - ArrayList calls = new ArrayList<>(currentCall.getChildCallIds().size()); - for (String callerId : currentCall.getChildCallIds()) { - calls.add(callList.getCallById(callerId)); - } - - Log.d(this, "Number of calls is " + String.valueOf(calls.size())); - - // Users can split out a call from the conference call if either the active call or the - // holding call is empty. If both are filled, users can not split out another call. - final boolean hasActiveCall = (callList.getActiveCall() != null); - final boolean hasHoldingCall = (callList.getBackgroundCall() != null); - boolean canSeparate = !(hasActiveCall && hasHoldingCall); - - getUi().update(mContext, calls, canSeparate); - } - - public interface ConferenceManagerUi extends Ui { - boolean isFragmentVisible(); - void update(Context context, List participants, boolean parentCanSeparate); - void refreshCall(Call call); - } -} diff --git a/InCallUI/src/com/android/incallui/ConferenceParticipantListAdapter.java b/InCallUI/src/com/android/incallui/ConferenceParticipantListAdapter.java deleted file mode 100644 index d68ae1f6f..000000000 --- a/InCallUI/src/com/android/incallui/ConferenceParticipantListAdapter.java +++ /dev/null @@ -1,533 +0,0 @@ -/* - * Copyright (C) 2014 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 com.google.common.base.MoreObjects; - -import android.content.Context; -import android.net.Uri; -import android.support.annotation.Nullable; -import android.text.BidiFormatter; -import android.text.TextDirectionHeuristics; -import android.text.TextUtils; -import android.view.LayoutInflater; -import android.view.View; -import android.view.ViewGroup; -import android.widget.BaseAdapter; -import android.widget.ImageView; -import android.widget.ListView; -import android.widget.TextView; - -import com.android.contacts.common.ContactPhotoManager; -import com.android.contacts.common.ContactPhotoManager.DefaultImageRequest; -import com.android.contacts.common.compat.PhoneNumberUtilsCompat; -import com.android.contacts.common.preference.ContactsPreferences; -import com.android.contacts.common.util.ContactDisplayUtils; -import com.android.dialer.R; -import com.android.incallui.ContactInfoCache.ContactCacheEntry; - -import java.lang.ref.WeakReference; -import java.util.ArrayList; -import java.util.Collections; -import java.util.Comparator; -import java.util.HashMap; -import java.util.HashSet; -import java.util.Iterator; -import java.util.List; -import java.util.Map; -import java.util.Objects; - -/** - * Adapter for a ListView containing conference call participant information. - */ -public class ConferenceParticipantListAdapter extends BaseAdapter { - - /** - * Internal class which represents a participant. Includes a reference to the {@link Call} and - * the corresponding {@link ContactCacheEntry} for the participant. - */ - private class ParticipantInfo { - private Call mCall; - private ContactCacheEntry mContactCacheEntry; - private boolean mCacheLookupComplete = false; - - public ParticipantInfo(Call call, ContactCacheEntry contactCacheEntry) { - mCall = call; - mContactCacheEntry = contactCacheEntry; - } - - public Call getCall() { - return mCall; - } - - public void setCall(Call call) { - mCall = call; - } - - public ContactCacheEntry getContactCacheEntry() { - return mContactCacheEntry; - } - - public void setContactCacheEntry(ContactCacheEntry entry) { - mContactCacheEntry = entry; - } - - public boolean isCacheLookupComplete() { - return mCacheLookupComplete; - } - - public void setCacheLookupComplete(boolean cacheLookupComplete) { - mCacheLookupComplete = cacheLookupComplete; - } - - @Override - public boolean equals(Object o) { - if (o instanceof ParticipantInfo) { - ParticipantInfo p = (ParticipantInfo) o; - return - Objects.equals(p.getCall().getId(), mCall.getId()); - } - return false; - } - - @Override - public int hashCode() { - return mCall.getId().hashCode(); - } - } - - /** - * Callback class used when making requests to the {@link ContactInfoCache} to resolve contact - * info and contact photos for conference participants. - */ - public static class ContactLookupCallback implements ContactInfoCache.ContactInfoCacheCallback { - private final WeakReference mListAdapter; - - public ContactLookupCallback(ConferenceParticipantListAdapter listAdapter) { - mListAdapter = new WeakReference(listAdapter); - } - - /** - * Called when contact info has been resolved. - * - * @param callId The call id. - * @param entry The new contact information. - */ - @Override - public void onContactInfoComplete(String callId, ContactCacheEntry entry) { - update(callId, entry); - } - - /** - * Called when contact photo has been loaded into the cache. - * - * @param callId The call id. - * @param entry The new contact information. - */ - @Override - public void onImageLoadComplete(String callId, ContactCacheEntry entry) { - update(callId, entry); - } - - @Override - public void onContactInteractionsInfoComplete(String callId, ContactCacheEntry entry) {} - - /** - * Updates the contact information for a participant. - * - * @param callId The call id. - * @param entry The new contact information. - */ - private void update(String callId, ContactCacheEntry entry) { - ConferenceParticipantListAdapter listAdapter = mListAdapter.get(); - if (listAdapter != null) { - listAdapter.updateContactInfo(callId, entry); - } - } - } - - /** - * Listener used to handle tap of the "disconnect' button for a participant. - */ - private View.OnClickListener mDisconnectListener = new View.OnClickListener() { - @Override - public void onClick(View v) { - View parent = (View) v.getParent(); - String callId = (String) parent.getTag(); - TelecomAdapter.getInstance().disconnectCall(callId); - } - }; - - /** - * Listener used to handle tap of the "separate' button for a participant. - */ - private View.OnClickListener mSeparateListener = new View.OnClickListener() { - @Override - public void onClick(View v) { - View parent = (View) v.getParent(); - String callId = (String) parent.getTag(); - TelecomAdapter.getInstance().separateCall(callId); - } - }; - - /** - * The ListView containing the participant information. - */ - private final ListView mListView; - - /** - * The conference participants to show in the ListView. - */ - private List mConferenceParticipants = new ArrayList<>(); - - /** - * Hashmap to make accessing participant info by call Id faster. - */ - private final HashMap mParticipantsByCallId = new HashMap<>(); - - /** - * The context. - */ - private final Context mContext; - - /** - * ContactsPreferences used to lookup displayName preferences - */ - @Nullable private final ContactsPreferences mContactsPreferences; - - /** - * The layout inflater used to inflate new views. - */ - private final LayoutInflater mLayoutInflater; - - /** - * Contact photo manager to retrieve cached contact photo information. - */ - private final ContactPhotoManager mContactPhotoManager; - - /** - * {@code True} if the conference parent supports separating calls from the conference. - */ - private boolean mParentCanSeparate; - - /** - * Creates an instance of the ConferenceParticipantListAdapter. - * - * @param listView The listview. - * @param context The context. - * @param layoutInflater The layout inflater. - * @param contactPhotoManager The contact photo manager, used to load contact photos. - */ - public ConferenceParticipantListAdapter(ListView listView, Context context, - LayoutInflater layoutInflater, ContactPhotoManager contactPhotoManager) { - - mListView = listView; - mContext = context; - mContactsPreferences = ContactsPreferencesFactory.newContactsPreferences(mContext); - mLayoutInflater = layoutInflater; - mContactPhotoManager = contactPhotoManager; - } - - /** - * Updates the adapter with the new conference participant information provided. - * - * @param conferenceParticipants The list of conference participants. - * @param parentCanSeparate {@code True} if the parent supports separating calls from the - * conference. - */ - public void updateParticipants(List conferenceParticipants, boolean parentCanSeparate) { - if (mContactsPreferences != null) { - mContactsPreferences.refreshValue(ContactsPreferences.DISPLAY_ORDER_KEY); - mContactsPreferences.refreshValue(ContactsPreferences.SORT_ORDER_KEY); - } - mParentCanSeparate = parentCanSeparate; - updateParticipantInfo(conferenceParticipants); - } - - /** - * Determines the number of participants in the conference. - * - * @return The number of participants. - */ - @Override - public int getCount() { - return mConferenceParticipants.size(); - } - - /** - * Retrieves an item from the list of participants. - * - * @param position Position of the item whose data we want within the adapter's - * data set. - * @return The {@link ParticipantInfo}. - */ - @Override - public Object getItem(int position) { - return mConferenceParticipants.get(position); - } - - /** - * Retreives the adapter-specific item id for an item at a specified position. - * - * @param position The position of the item within the adapter's data set whose row id we want. - * @return The item id. - */ - @Override - public long getItemId(int position) { - return position; - } - - /** - * Refreshes call information for the call passed in. - * - * @param call The new call information. - */ - public void refreshCall(Call call) { - String callId = call.getId(); - - if (mParticipantsByCallId.containsKey(callId)) { - ParticipantInfo participantInfo = mParticipantsByCallId.get(callId); - participantInfo.setCall(call); - refreshView(callId); - } - } - - /** - * Attempts to refresh the view for the specified call ID. This ensures the contact info and - * photo loaded from cache are updated. - * - * @param callId The call id. - */ - private void refreshView(String callId) { - int first = mListView.getFirstVisiblePosition(); - int last = mListView.getLastVisiblePosition(); - - for (int position = 0; position <= last - first; position++) { - View view = mListView.getChildAt(position); - String rowCallId = (String) view.getTag(); - if (rowCallId.equals(callId)) { - getView(position+first, view, mListView); - break; - } - } - } - - /** - * Creates or populates an existing conference participant row. - * - * @param position The position of the item within the adapter's data set of the item whose view - * we want. - * @param convertView The old view to reuse, if possible. - * @param parent The parent that this view will eventually be attached to - * @return The populated view. - */ - @Override - public View getView(int position, View convertView, ViewGroup parent) { - // Make sure we have a valid convertView to start with - final View result = convertView == null - ? mLayoutInflater.inflate(R.layout.caller_in_conference, parent, false) - : convertView; - - ParticipantInfo participantInfo = mConferenceParticipants.get(position); - Call call = participantInfo.getCall(); - ContactCacheEntry contactCache = participantInfo.getContactCacheEntry(); - - final ContactInfoCache cache = ContactInfoCache.getInstance(mContext); - - // If a cache lookup has not yet been performed to retrieve the contact information and - // photo, do it now. - if (!participantInfo.isCacheLookupComplete()) { - cache.findInfo(participantInfo.getCall(), - participantInfo.getCall().getState() == Call.State.INCOMING, - new ContactLookupCallback(this)); - } - - boolean thisRowCanSeparate = mParentCanSeparate && call.getTelecomCall().getDetails().can( - android.telecom.Call.Details.CAPABILITY_SEPARATE_FROM_CONFERENCE); - boolean thisRowCanDisconnect = call.getTelecomCall().getDetails().can( - android.telecom.Call.Details.CAPABILITY_DISCONNECT_FROM_CONFERENCE); - - setCallerInfoForRow(result, contactCache.namePrimary, - ContactDisplayUtils.getPreferredDisplayName(contactCache.namePrimary, - contactCache.nameAlternative, mContactsPreferences), - contactCache.number, contactCache.label, - contactCache.lookupKey, contactCache.displayPhotoUri, thisRowCanSeparate, - thisRowCanDisconnect); - - // Tag the row in the conference participant list with the call id to make it easier to - // find calls when contact cache information is loaded. - result.setTag(call.getId()); - - return result; - } - - /** - * Replaces the contact info for a participant and triggers a refresh of the UI. - * - * @param callId The call id. - * @param entry The new contact info. - */ - /* package */ void updateContactInfo(String callId, ContactCacheEntry entry) { - if (mParticipantsByCallId.containsKey(callId)) { - ParticipantInfo participantInfo = mParticipantsByCallId.get(callId); - participantInfo.setContactCacheEntry(entry); - participantInfo.setCacheLookupComplete(true); - refreshView(callId); - } - } - - /** - * Sets the caller information for a row in the conference participant list. - * - * @param view The view to set the details on. - * @param callerName The participant's name. - * @param callerNumber The participant's phone number. - * @param callerNumberType The participant's phone number typ.e - * @param lookupKey The lookup key for the participant (for photo lookup). - * @param photoUri The URI of the contact photo. - * @param thisRowCanSeparate {@code True} if this participant can separate from the conference. - * @param thisRowCanDisconnect {@code True} if this participant can be disconnected. - */ - private final void setCallerInfoForRow(View view, String callerName, String preferredName, - String callerNumber, String callerNumberType, String lookupKey, Uri photoUri, - boolean thisRowCanSeparate, boolean thisRowCanDisconnect) { - - final ImageView photoView = (ImageView) view.findViewById(R.id.callerPhoto); - final TextView nameTextView = (TextView) view.findViewById(R.id.conferenceCallerName); - final TextView numberTextView = (TextView) view.findViewById(R.id.conferenceCallerNumber); - final TextView numberTypeTextView = (TextView) view.findViewById( - R.id.conferenceCallerNumberType); - final View endButton = view.findViewById(R.id.conferenceCallerDisconnect); - final View separateButton = view.findViewById(R.id.conferenceCallerSeparate); - - endButton.setVisibility(thisRowCanDisconnect ? View.VISIBLE : View.GONE); - if (thisRowCanDisconnect) { - endButton.setOnClickListener(mDisconnectListener); - } else { - endButton.setOnClickListener(null); - } - - separateButton.setVisibility(thisRowCanSeparate ? View.VISIBLE : View.GONE); - if (thisRowCanSeparate) { - separateButton.setOnClickListener(mSeparateListener); - } else { - separateButton.setOnClickListener(null); - } - - DefaultImageRequest imageRequest = (photoUri != null) ? null : - new DefaultImageRequest(callerName, lookupKey, true /* isCircularPhoto */); - - mContactPhotoManager.loadDirectoryPhoto(photoView, photoUri, false, true, imageRequest); - - // set the caller name - nameTextView.setText(preferredName); - - // set the caller number in subscript, or make the field disappear. - if (TextUtils.isEmpty(callerNumber)) { - numberTextView.setVisibility(View.GONE); - numberTypeTextView.setVisibility(View.GONE); - } else { - numberTextView.setVisibility(View.VISIBLE); - numberTextView.setText(PhoneNumberUtilsCompat.createTtsSpannable( - BidiFormatter.getInstance().unicodeWrap( - callerNumber, TextDirectionHeuristics.LTR))); - numberTypeTextView.setVisibility(View.VISIBLE); - numberTypeTextView.setText(callerNumberType); - } - } - - /** - * Updates the participant info list which is bound to the ListView. Stores the call and - * contact info for all entries. The list is sorted alphabetically by participant name. - * - * @param conferenceParticipants The calls which make up the conference participants. - */ - private void updateParticipantInfo(List conferenceParticipants) { - final ContactInfoCache cache = ContactInfoCache.getInstance(mContext); - boolean newParticipantAdded = false; - HashSet newCallIds = new HashSet<>(conferenceParticipants.size()); - - // Update or add conference participant info. - for (Call call : conferenceParticipants) { - String callId = call.getId(); - newCallIds.add(callId); - ContactCacheEntry contactCache = cache.getInfo(callId); - if (contactCache == null) { - contactCache = ContactInfoCache.buildCacheEntryFromCall(mContext, call, - call.getState() == Call.State.INCOMING); - } - - if (mParticipantsByCallId.containsKey(callId)) { - ParticipantInfo participantInfo = mParticipantsByCallId.get(callId); - participantInfo.setCall(call); - participantInfo.setContactCacheEntry(contactCache); - } else { - newParticipantAdded = true; - ParticipantInfo participantInfo = new ParticipantInfo(call, contactCache); - mConferenceParticipants.add(participantInfo); - mParticipantsByCallId.put(call.getId(), participantInfo); - } - } - - // Remove any participants that no longer exist. - Iterator> it = - mParticipantsByCallId.entrySet().iterator(); - while (it.hasNext()) { - Map.Entry entry = it.next(); - String existingCallId = entry.getKey(); - if (!newCallIds.contains(existingCallId)) { - ParticipantInfo existingInfo = entry.getValue(); - mConferenceParticipants.remove(existingInfo); - it.remove(); - } - } - - if (newParticipantAdded) { - // Sort the list of participants by contact name. - sortParticipantList(); - } - notifyDataSetChanged(); - } - - /** - * Sorts the participant list by contact name. - */ - private void sortParticipantList() { - Collections.sort(mConferenceParticipants, new Comparator() { - public int compare(ParticipantInfo p1, ParticipantInfo p2) { - // Contact names might be null, so replace with empty string. - ContactCacheEntry c1 = p1.getContactCacheEntry(); - String p1Name = MoreObjects.firstNonNull( - ContactDisplayUtils.getPreferredSortName( - c1.namePrimary, - c1.nameAlternative, - mContactsPreferences), - ""); - - ContactCacheEntry c2 = p2.getContactCacheEntry(); - String p2Name = MoreObjects.firstNonNull( - ContactDisplayUtils.getPreferredSortName( - c2.namePrimary, - c2.nameAlternative, - mContactsPreferences), - ""); - - return p1Name.compareToIgnoreCase(p2Name); - } - }); - } -} diff --git a/InCallUI/src/com/android/incallui/ContactInfoCache.java b/InCallUI/src/com/android/incallui/ContactInfoCache.java deleted file mode 100644 index 9d6fc4627..000000000 --- a/InCallUI/src/com/android/incallui/ContactInfoCache.java +++ /dev/null @@ -1,699 +0,0 @@ -/* - * Copyright (C) 2013 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License - */ - -package com.android.incallui; - -import com.google.common.base.MoreObjects; -import com.google.common.base.Preconditions; -import com.google.common.collect.Maps; -import com.google.common.collect.Sets; - -import android.content.Context; -import android.graphics.Bitmap; -import android.graphics.drawable.BitmapDrawable; -import android.graphics.drawable.Drawable; -import android.location.Address; -import android.media.RingtoneManager; -import android.net.Uri; -import android.os.AsyncTask; -import android.os.Looper; -import android.provider.ContactsContract; -import android.provider.ContactsContract.CommonDataKinds.Phone; -import android.provider.ContactsContract.Contacts; -import android.provider.ContactsContract.DisplayNameSources; -import android.telecom.TelecomManager; -import android.text.TextUtils; -import android.util.Pair; - -import com.android.contacts.common.ContactsUtils; -import com.android.contacts.common.util.PhoneNumberHelper; -import com.android.dialer.R; -import com.android.dialer.calllog.ContactInfo; -import com.android.dialer.service.CachedNumberLookupService; -import com.android.dialer.service.CachedNumberLookupService.CachedContactInfo; -import com.android.dialer.util.MoreStrings; -import com.android.incallui.Call.LogState; -import com.android.incallui.service.PhoneNumberService; -import com.android.incalluibind.ObjectFactory; - -import org.json.JSONException; -import org.json.JSONObject; - -import java.util.Calendar; -import java.util.HashMap; -import java.util.List; -import java.util.Set; - -/** - * Class responsible for querying Contact Information for Call objects. Can perform asynchronous - * requests to the Contact Provider for information as well as respond synchronously for any data - * that it currently has cached from previous queries. This class always gets called from the UI - * thread so it does not need thread protection. - */ -public class ContactInfoCache implements ContactsAsyncHelper.OnImageLoadCompleteListener { - - private static final String TAG = ContactInfoCache.class.getSimpleName(); - private static final int TOKEN_UPDATE_PHOTO_FOR_CALL_STATE = 0; - - private final Context mContext; - private final PhoneNumberService mPhoneNumberService; - private final CachedNumberLookupService mCachedNumberLookupService; - private final HashMap mInfoMap = Maps.newHashMap(); - private final HashMap> mCallBacks = Maps.newHashMap(); - - private static ContactInfoCache sCache = null; - - private Drawable mDefaultContactPhotoDrawable; - private Drawable mConferencePhotoDrawable; - private ContactUtils mContactUtils; - - public static synchronized ContactInfoCache getInstance(Context mContext) { - if (sCache == null) { - sCache = new ContactInfoCache(mContext.getApplicationContext()); - } - return sCache; - } - - private ContactInfoCache(Context context) { - mContext = context; - mPhoneNumberService = ObjectFactory.newPhoneNumberService(context); - mCachedNumberLookupService = - com.android.dialerbind.ObjectFactory.newCachedNumberLookupService(); - mContactUtils = ObjectFactory.getContactUtilsInstance(context); - - } - - public ContactCacheEntry getInfo(String callId) { - return mInfoMap.get(callId); - } - - public static ContactCacheEntry buildCacheEntryFromCall(Context context, Call call, - boolean isIncoming) { - final ContactCacheEntry entry = new ContactCacheEntry(); - - // TODO: get rid of caller info. - final CallerInfo info = CallerInfoUtils.buildCallerInfo(context, call); - ContactInfoCache.populateCacheEntry(context, info, entry, call.getNumberPresentation(), - isIncoming); - return entry; - } - - public void maybeInsertCnapInformationIntoCache(Context context, final Call call, - final CallerInfo info) { - if (mCachedNumberLookupService == null || TextUtils.isEmpty(info.cnapName) - || mInfoMap.get(call.getId()) != null) { - return; - } - final Context applicationContext = context.getApplicationContext(); - Log.i(TAG, "Found contact with CNAP name - inserting into cache"); - new AsyncTask() { - @Override - protected Void doInBackground(Void... params) { - ContactInfo contactInfo = new ContactInfo(); - CachedContactInfo cacheInfo = mCachedNumberLookupService.buildCachedContactInfo( - contactInfo); - cacheInfo.setSource(CachedContactInfo.SOURCE_TYPE_CNAP, "CNAP", 0); - contactInfo.name = info.cnapName; - contactInfo.number = call.getNumber(); - contactInfo.type = ContactsContract.CommonDataKinds.Phone.TYPE_MAIN; - try { - final JSONObject contactRows = new JSONObject().put(Phone.CONTENT_ITEM_TYPE, - new JSONObject() - .put(Phone.NUMBER, contactInfo.number) - .put(Phone.TYPE, Phone.TYPE_MAIN)); - final String jsonString = new JSONObject() - .put(Contacts.DISPLAY_NAME, contactInfo.name) - .put(Contacts.DISPLAY_NAME_SOURCE, DisplayNameSources.STRUCTURED_NAME) - .put(Contacts.CONTENT_ITEM_TYPE, contactRows).toString(); - cacheInfo.setLookupKey(jsonString); - } catch (JSONException e) { - Log.w(TAG, "Creation of lookup key failed when caching CNAP information"); - } - mCachedNumberLookupService.addContact(applicationContext, cacheInfo); - return null; - } - }.execute(); - } - - private class FindInfoCallback implements CallerInfoAsyncQuery.OnQueryCompleteListener { - private final boolean mIsIncoming; - - public FindInfoCallback(boolean isIncoming) { - mIsIncoming = isIncoming; - } - - @Override - public void onQueryComplete(int token, Object cookie, CallerInfo callerInfo) { - findInfoQueryComplete((Call) cookie, callerInfo, mIsIncoming, true); - } - } - - /** - * Requests contact data for the Call object passed in. - * Returns the data through callback. If callback is null, no response is made, however the - * query is still performed and cached. - * - * @param callback The function to call back when the call is found. Can be null. - */ - public void findInfo(final Call call, final boolean isIncoming, - ContactInfoCacheCallback callback) { - Preconditions.checkState(Looper.getMainLooper().getThread() == Thread.currentThread()); - Preconditions.checkNotNull(callback); - - final String callId = call.getId(); - final ContactCacheEntry cacheEntry = mInfoMap.get(callId); - Set callBacks = mCallBacks.get(callId); - - // If we have a previously obtained intermediate result return that now - if (cacheEntry != null) { - Log.d(TAG, "Contact lookup. In memory cache hit; lookup " - + (callBacks == null ? "complete" : "still running")); - callback.onContactInfoComplete(callId, cacheEntry); - // If no other callbacks are in flight, we're done. - if (callBacks == null) { - return; - } - } - - // If the entry already exists, add callback - if (callBacks != null) { - callBacks.add(callback); - return; - } - Log.d(TAG, "Contact lookup. In memory cache miss; searching provider."); - // New lookup - callBacks = Sets.newHashSet(); - callBacks.add(callback); - mCallBacks.put(callId, callBacks); - - /** - * Performs a query for caller information. - * Save any immediate data we get from the query. An asynchronous query may also be made - * for any data that we do not already have. Some queries, such as those for voicemail and - * emergency call information, will not perform an additional asynchronous query. - */ - final CallerInfo callerInfo = CallerInfoUtils.getCallerInfoForCall( - mContext, call, new FindInfoCallback(isIncoming)); - - findInfoQueryComplete(call, callerInfo, isIncoming, false); - } - - private void findInfoQueryComplete(Call call, CallerInfo callerInfo, boolean isIncoming, - boolean didLocalLookup) { - final String callId = call.getId(); - int presentationMode = call.getNumberPresentation(); - if (callerInfo.contactExists || callerInfo.isEmergencyNumber() || - callerInfo.isVoiceMailNumber()) { - presentationMode = TelecomManager.PRESENTATION_ALLOWED; - } - - ContactCacheEntry cacheEntry = mInfoMap.get(callId); - // Ensure we always have a cacheEntry. Replace the existing entry if - // it has no name or if we found a local contact. - if (cacheEntry == null || TextUtils.isEmpty(cacheEntry.namePrimary) || - callerInfo.contactExists) { - cacheEntry = buildEntry(mContext, callId, callerInfo, presentationMode, isIncoming); - mInfoMap.put(callId, cacheEntry); - } - - sendInfoNotifications(callId, cacheEntry); - - if (didLocalLookup) { - // Before issuing a request for more data from other services, we only check that the - // contact wasn't found in the local DB. We don't check the if the cache entry already - // has a name because we allow overriding cnap data with data from other services. - if (!callerInfo.contactExists && mPhoneNumberService != null) { - Log.d(TAG, "Contact lookup. Local contacts miss, checking remote"); - final PhoneNumberServiceListener listener = new PhoneNumberServiceListener(callId); - mPhoneNumberService.getPhoneNumberInfo(cacheEntry.number, listener, listener, - isIncoming); - } else if (cacheEntry.displayPhotoUri != null) { - Log.d(TAG, "Contact lookup. Local contact found, starting image load"); - // Load the image with a callback to update the image state. - // When the load is finished, onImageLoadComplete() will be called. - cacheEntry.isLoadingPhoto = true; - ContactsAsyncHelper.startObtainPhotoAsync(TOKEN_UPDATE_PHOTO_FOR_CALL_STATE, - mContext, cacheEntry.displayPhotoUri, ContactInfoCache.this, callId); - } else { - if (callerInfo.contactExists) { - Log.d(TAG, "Contact lookup done. Local contact found, no image."); - } else { - Log.d(TAG, "Contact lookup done. Local contact not found and" - + " no remote lookup service available."); - } - clearCallbacks(callId); - } - } - } - - class PhoneNumberServiceListener implements PhoneNumberService.NumberLookupListener, - PhoneNumberService.ImageLookupListener, ContactUtils.Listener { - private final String mCallId; - - PhoneNumberServiceListener(String callId) { - mCallId = callId; - } - - @Override - public void onPhoneNumberInfoComplete( - final PhoneNumberService.PhoneNumberInfo info) { - // If we got a miss, this is the end of the lookup pipeline, - // so clear the callbacks and return. - if (info == null) { - Log.d(TAG, "Contact lookup done. Remote contact not found."); - clearCallbacks(mCallId); - return; - } - - ContactCacheEntry entry = new ContactCacheEntry(); - entry.namePrimary = info.getDisplayName(); - entry.number = info.getNumber(); - entry.contactLookupResult = info.getLookupSource(); - final int type = info.getPhoneType(); - final String label = info.getPhoneLabel(); - if (type == Phone.TYPE_CUSTOM) { - entry.label = label; - } else { - final CharSequence typeStr = Phone.getTypeLabel( - mContext.getResources(), type, label); - entry.label = typeStr == null ? null : typeStr.toString(); - } - final ContactCacheEntry oldEntry = mInfoMap.get(mCallId); - if (oldEntry != null) { - // Location is only obtained from local lookup so persist - // the value for remote lookups. Once we have a name this - // field is no longer used; it is persisted here in case - // the UI is ever changed to use it. - entry.location = oldEntry.location; - // Contact specific ringtone is obtained from local lookup. - entry.contactRingtoneUri = oldEntry.contactRingtoneUri; - } - - // If no image and it's a business, switch to using the default business avatar. - if (info.getImageUrl() == null && info.isBusiness()) { - Log.d(TAG, "Business has no image. Using default."); - entry.photo = mContext.getResources().getDrawable(R.drawable.img_business); - } - - mInfoMap.put(mCallId, entry); - sendInfoNotifications(mCallId, entry); - - if (mContactUtils != null) { - // This method will callback "onContactInteractionsFound". - entry.isLoadingContactInteractions = - mContactUtils.retrieveContactInteractionsFromLookupKey( - info.getLookupKey(), this); - } - - entry.isLoadingPhoto = info.getImageUrl() != null; - - // If there is no image or contact interactions then we should not expect another - // callback. - if (!entry.isLoadingPhoto && !entry.isLoadingContactInteractions) { - // We're done, so clear callbacks - clearCallbacks(mCallId); - } - } - - @Override - public void onImageFetchComplete(Bitmap bitmap) { - onImageLoadComplete(TOKEN_UPDATE_PHOTO_FOR_CALL_STATE, null, bitmap, mCallId); - } - - @Override - public void onContactInteractionsFound(Address address, - List> openingHours) { - final ContactCacheEntry entry = mInfoMap.get(mCallId); - if (entry == null) { - Log.e(this, "Contact context received for empty search entry."); - clearCallbacks(mCallId); - return; - } - - entry.isLoadingContactInteractions = false; - - Log.v(ContactInfoCache.this, "Setting contact interactions for entry: ", entry); - - entry.locationAddress = address; - entry.openingHours = openingHours; - sendContactInteractionsNotifications(mCallId, entry); - - if (!entry.isLoadingPhoto) { - clearCallbacks(mCallId); - } - } - } - - /** - * Implemented for ContactsAsyncHelper.OnImageLoadCompleteListener interface. - * make sure that the call state is reflected after the image is loaded. - */ - @Override - public void onImageLoadComplete(int token, Drawable photo, Bitmap photoIcon, Object cookie) { - Log.d(this, "Image load complete with context: ", mContext); - // TODO: may be nice to update the image view again once the newer one - // is available on contacts database. - - final String callId = (String) cookie; - final ContactCacheEntry entry = mInfoMap.get(callId); - - if (entry == null) { - Log.e(this, "Image Load received for empty search entry."); - clearCallbacks(callId); - return; - } - - entry.isLoadingPhoto = false; - - Log.d(this, "setting photo for entry: ", entry); - - // Conference call icons are being handled in CallCardPresenter. - if (photo != null) { - Log.v(this, "direct drawable: ", photo); - entry.photo = photo; - } else if (photoIcon != null) { - Log.v(this, "photo icon: ", photoIcon); - entry.photo = new BitmapDrawable(mContext.getResources(), photoIcon); - } else { - Log.v(this, "unknown photo"); - entry.photo = null; - } - - sendImageNotifications(callId, entry); - - if (!entry.isLoadingContactInteractions) { - clearCallbacks(callId); - } - } - - /** - * Blows away the stored cache values. - */ - public void clearCache() { - mInfoMap.clear(); - mCallBacks.clear(); - } - - private ContactCacheEntry buildEntry(Context context, String callId, - CallerInfo info, int presentation, boolean isIncoming) { - // The actual strings we're going to display onscreen: - Drawable photo = null; - - final ContactCacheEntry cce = new ContactCacheEntry(); - populateCacheEntry(context, info, cce, presentation, isIncoming); - - // This will only be true for emergency numbers - if (info.photoResource != 0) { - photo = context.getResources().getDrawable(info.photoResource); - } else if (info.isCachedPhotoCurrent) { - if (info.cachedPhoto != null) { - photo = info.cachedPhoto; - } else { - photo = getDefaultContactPhotoDrawable(); - } - } else if (info.contactDisplayPhotoUri == null) { - photo = getDefaultContactPhotoDrawable(); - } else { - cce.displayPhotoUri = info.contactDisplayPhotoUri; - } - - // Support any contact id in N because QuickContacts in N starts supporting enterprise - // contact id - if (info.lookupKeyOrNull != null - && (ContactsUtils.FLAG_N_FEATURE || info.contactIdOrZero != 0)) { - cce.lookupUri = Contacts.getLookupUri(info.contactIdOrZero, info.lookupKeyOrNull); - } else { - Log.v(TAG, "lookup key is null or contact ID is 0 on M. Don't create a lookup uri."); - cce.lookupUri = null; - } - - cce.photo = photo; - cce.lookupKey = info.lookupKeyOrNull; - cce.contactRingtoneUri = info.contactRingtoneUri; - if (cce.contactRingtoneUri == null || cce.contactRingtoneUri == Uri.EMPTY) { - cce.contactRingtoneUri = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_RINGTONE); - } - - return cce; - } - - /** - * Populate a cache entry from a call (which got converted into a caller info). - */ - public static void populateCacheEntry(Context context, CallerInfo info, ContactCacheEntry cce, - int presentation, boolean isIncoming) { - Preconditions.checkNotNull(info); - String displayName = null; - String displayNumber = null; - String displayLocation = null; - String label = null; - boolean isSipCall = false; - - // It appears that there is a small change in behaviour with the - // PhoneUtils' startGetCallerInfo whereby if we query with an - // empty number, we will get a valid CallerInfo object, but with - // fields that are all null, and the isTemporary boolean input - // parameter as true. - - // In the past, we would see a NULL callerinfo object, but this - // ends up causing null pointer exceptions elsewhere down the - // line in other cases, so we need to make this fix instead. It - // appears that this was the ONLY call to PhoneUtils - // .getCallerInfo() that relied on a NULL CallerInfo to indicate - // an unknown contact. - - // Currently, infi.phoneNumber may actually be a SIP address, and - // if so, it might sometimes include the "sip:" prefix. That - // prefix isn't really useful to the user, though, so strip it off - // if present. (For any other URI scheme, though, leave the - // prefix alone.) - // TODO: It would be cleaner for CallerInfo to explicitly support - // SIP addresses instead of overloading the "phoneNumber" field. - // Then we could remove this hack, and instead ask the CallerInfo - // for a "user visible" form of the SIP address. - String number = info.phoneNumber; - - if (!TextUtils.isEmpty(number)) { - isSipCall = PhoneNumberHelper.isUriNumber(number); - if (number.startsWith("sip:")) { - number = number.substring(4); - } - } - - if (TextUtils.isEmpty(info.name)) { - // No valid "name" in the CallerInfo, so fall back to - // something else. - // (Typically, we promote the phone number up to the "name" slot - // onscreen, and possibly display a descriptive string in the - // "number" slot.) - if (TextUtils.isEmpty(number)) { - // No name *or* number! Display a generic "unknown" string - // (or potentially some other default based on the presentation.) - displayName = getPresentationString(context, presentation, info.callSubject); - Log.d(TAG, " ==> no name *or* number! displayName = " + displayName); - } else if (presentation != TelecomManager.PRESENTATION_ALLOWED) { - // This case should never happen since the network should never send a phone # - // AND a restricted presentation. However we leave it here in case of weird - // network behavior - displayName = getPresentationString(context, presentation, info.callSubject); - Log.d(TAG, " ==> presentation not allowed! displayName = " + displayName); - } else if (!TextUtils.isEmpty(info.cnapName)) { - // No name, but we do have a valid CNAP name, so use that. - displayName = info.cnapName; - info.name = info.cnapName; - displayNumber = number; - Log.d(TAG, " ==> cnapName available: displayName '" + displayName + - "', displayNumber '" + displayNumber + "'"); - } else { - // No name; all we have is a number. This is the typical - // case when an incoming call doesn't match any contact, - // or if you manually dial an outgoing number using the - // dialpad. - displayNumber = number; - - // Display a geographical description string if available - // (but only for incoming calls.) - if (isIncoming) { - // TODO (CallerInfoAsyncQuery cleanup): Fix the CallerInfo - // query to only do the geoDescription lookup in the first - // place for incoming calls. - displayLocation = info.geoDescription; // may be null - Log.d(TAG, "Geodescrption: " + info.geoDescription); - } - - Log.d(TAG, " ==> no name; falling back to number:" - + " displayNumber '" + Log.pii(displayNumber) - + "', displayLocation '" + displayLocation + "'"); - } - } else { - // We do have a valid "name" in the CallerInfo. Display that - // in the "name" slot, and the phone number in the "number" slot. - if (presentation != TelecomManager.PRESENTATION_ALLOWED) { - // This case should never happen since the network should never send a name - // AND a restricted presentation. However we leave it here in case of weird - // network behavior - displayName = getPresentationString(context, presentation, info.callSubject); - Log.d(TAG, " ==> valid name, but presentation not allowed!" + - " displayName = " + displayName); - } else { - // Causes cce.namePrimary to be set as info.name below. CallCardPresenter will - // later determine whether to use the name or nameAlternative when presenting - displayName = info.name; - cce.nameAlternative = info.nameAlternative; - displayNumber = number; - label = info.phoneLabel; - Log.d(TAG, " ==> name is present in CallerInfo: displayName '" + displayName - + "', displayNumber '" + displayNumber + "'"); - } - } - - cce.namePrimary = displayName; - cce.number = displayNumber; - cce.location = displayLocation; - cce.label = label; - cce.isSipCall = isSipCall; - cce.userType = info.userType; - - if (info.contactExists) { - cce.contactLookupResult = LogState.LOOKUP_LOCAL_CONTACT; - } - } - - /** - * Sends the updated information to call the callbacks for the entry. - */ - private void sendInfoNotifications(String callId, ContactCacheEntry entry) { - final Set callBacks = mCallBacks.get(callId); - if (callBacks != null) { - for (ContactInfoCacheCallback callBack : callBacks) { - callBack.onContactInfoComplete(callId, entry); - } - } - } - - private void sendImageNotifications(String callId, ContactCacheEntry entry) { - final Set callBacks = mCallBacks.get(callId); - if (callBacks != null && entry.photo != null) { - for (ContactInfoCacheCallback callBack : callBacks) { - callBack.onImageLoadComplete(callId, entry); - } - } - } - - private void sendContactInteractionsNotifications(String callId, ContactCacheEntry entry) { - final Set callBacks = mCallBacks.get(callId); - if (callBacks != null) { - for (ContactInfoCacheCallback callBack : callBacks) { - callBack.onContactInteractionsInfoComplete(callId, entry); - } - } - } - - private void clearCallbacks(String callId) { - mCallBacks.remove(callId); - } - - /** - * Gets name strings based on some special presentation modes and the associated custom label. - */ - private static String getPresentationString(Context context, int presentation, - String customLabel) { - String name = context.getString(R.string.unknown); - if (!TextUtils.isEmpty(customLabel) && - ((presentation == TelecomManager.PRESENTATION_UNKNOWN) || - (presentation == TelecomManager.PRESENTATION_RESTRICTED))) { - name = customLabel; - return name; - } else { - if (presentation == TelecomManager.PRESENTATION_RESTRICTED) { - name = context.getString(R.string.private_num); - } else if (presentation == TelecomManager.PRESENTATION_PAYPHONE) { - name = context.getString(R.string.payphone); - } - } - return name; - } - - public Drawable getDefaultContactPhotoDrawable() { - if (mDefaultContactPhotoDrawable == null) { - mDefaultContactPhotoDrawable = - mContext.getResources().getDrawable(R.drawable.img_no_image_automirrored); - } - return mDefaultContactPhotoDrawable; - } - - public Drawable getConferenceDrawable() { - if (mConferencePhotoDrawable == null) { - mConferencePhotoDrawable = - mContext.getResources().getDrawable(R.drawable.img_conference_automirrored); - } - return mConferencePhotoDrawable; - } - - /** - * Callback interface for the contact query. - */ - public interface ContactInfoCacheCallback { - public void onContactInfoComplete(String callId, ContactCacheEntry entry); - public void onImageLoadComplete(String callId, ContactCacheEntry entry); - public void onContactInteractionsInfoComplete(String callId, ContactCacheEntry entry); - } - - public static class ContactCacheEntry { - public String namePrimary; - public String nameAlternative; - public String number; - public String location; - public String label; - public Drawable photo; - public boolean isSipCall; - // Note in cache entry whether this is a pending async loading action to know whether to - // wait for its callback or not. - public boolean isLoadingPhoto; - public boolean isLoadingContactInteractions; - /** This will be used for the "view" notification. */ - public Uri contactUri; - /** Either a display photo or a thumbnail URI. */ - public Uri displayPhotoUri; - public Uri lookupUri; // Sent to NotificationMananger - public String lookupKey; - public Address locationAddress; - public List> openingHours; - public int contactLookupResult = LogState.LOOKUP_NOT_FOUND; - public long userType = ContactsUtils.USER_TYPE_CURRENT; - public Uri contactRingtoneUri; - - @Override - public String toString() { - return MoreObjects.toStringHelper(this) - .add("name", MoreStrings.toSafeString(namePrimary)) - .add("nameAlternative", MoreStrings.toSafeString(nameAlternative)) - .add("number", MoreStrings.toSafeString(number)) - .add("location", MoreStrings.toSafeString(location)) - .add("label", label) - .add("photo", photo) - .add("isSipCall", isSipCall) - .add("contactUri", contactUri) - .add("displayPhotoUri", displayPhotoUri) - .add("locationAddress", locationAddress) - .add("openingHours", openingHours) - .add("contactLookupResult", contactLookupResult) - .add("userType", userType) - .add("contactRingtoneUri", contactRingtoneUri) - .toString(); - } - } -} diff --git a/InCallUI/src/com/android/incallui/ContactUtils.java b/InCallUI/src/com/android/incallui/ContactUtils.java deleted file mode 100644 index 0750af731..000000000 --- a/InCallUI/src/com/android/incallui/ContactUtils.java +++ /dev/null @@ -1,48 +0,0 @@ -/* - * Copyright (C) 2015 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.content.Context; -import android.location.Address; -import android.util.Pair; - -import com.android.incalluibind.ObjectFactory; - -import java.util.Calendar; -import java.util.List; - -/** - * Utility functions to help manipulate contact data. - */ -public abstract class ContactUtils { - protected Context mContext; - - public static ContactUtils getInstance(Context context) { - return ObjectFactory.getContactUtilsInstance(context); - } - - protected ContactUtils(Context context) { - mContext = context; - } - - public interface Listener { - public void onContactInteractionsFound(Address address, - List> openingHours); - } - - public abstract boolean retrieveContactInteractionsFromLookupKey(String lookupKey, - Listener listener); -} diff --git a/InCallUI/src/com/android/incallui/ContactsAsyncHelper.java b/InCallUI/src/com/android/incallui/ContactsAsyncHelper.java deleted file mode 100644 index d959fadd4..000000000 --- a/InCallUI/src/com/android/incallui/ContactsAsyncHelper.java +++ /dev/null @@ -1,258 +0,0 @@ -/* - * Copyright (C) 2008 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.incallui; - -import android.app.Notification; -import android.content.ContentUris; -import android.content.Context; -import android.content.res.AssetFileDescriptor; -import android.graphics.Bitmap; -import android.graphics.drawable.BitmapDrawable; -import android.graphics.drawable.Drawable; -import android.net.Uri; -import android.os.Handler; -import android.os.HandlerThread; -import android.os.Looper; -import android.os.Message; -import android.provider.ContactsContract.Contacts; - -import com.android.dialer.R; - -import java.io.IOException; -import java.io.InputStream; - -/** - * Helper class for loading contacts photo asynchronously. - */ -public class ContactsAsyncHelper { - - /** - * Interface for a WorkerHandler result return. - */ - public interface OnImageLoadCompleteListener { - /** - * Called when the image load is complete. - * - * @param token Integer passed in {@link ContactsAsyncHelper#startObtainPhotoAsync(int, - * Context, Uri, OnImageLoadCompleteListener, Object)}. - * @param photo Drawable object obtained by the async load. - * @param photoIcon Bitmap object obtained by the async load. - * @param cookie Object passed in {@link ContactsAsyncHelper#startObtainPhotoAsync(int, - * Context, Uri, OnImageLoadCompleteListener, Object)}. Can be null iff. the original - * cookie is null. - */ - public void onImageLoadComplete(int token, Drawable photo, Bitmap photoIcon, - Object cookie); - } - - // constants - private static final int EVENT_LOAD_IMAGE = 1; - - private final Handler mResultHandler = new Handler() { - /** Called when loading is done. */ - @Override - public void handleMessage(Message msg) { - WorkerArgs args = (WorkerArgs) msg.obj; - switch (msg.arg1) { - case EVENT_LOAD_IMAGE: - if (args.listener != null) { - Log.d(this, "Notifying listener: " + args.listener.toString() + - " image: " + args.displayPhotoUri + " completed"); - args.listener.onImageLoadComplete(msg.what, args.photo, args.photoIcon, - args.cookie); - } - break; - default: - } - } - }; - - /** Handler run on a worker thread to load photo asynchronously. */ - private static Handler sThreadHandler; - - /** For forcing the system to call its constructor */ - @SuppressWarnings("unused") - private static ContactsAsyncHelper sInstance; - - static { - sInstance = new ContactsAsyncHelper(); - } - - private static final class WorkerArgs { - public Context context; - public Uri displayPhotoUri; - public Drawable photo; - public Bitmap photoIcon; - public Object cookie; - public OnImageLoadCompleteListener listener; - } - - /** - * Thread worker class that handles the task of opening the stream and loading - * the images. - */ - private class WorkerHandler extends Handler { - public WorkerHandler(Looper looper) { - super(looper); - } - - @Override - public void handleMessage(Message msg) { - WorkerArgs args = (WorkerArgs) msg.obj; - - switch (msg.arg1) { - case EVENT_LOAD_IMAGE: - InputStream inputStream = null; - try { - try { - inputStream = args.context.getContentResolver() - .openInputStream(args.displayPhotoUri); - } catch (Exception e) { - Log.e(this, "Error opening photo input stream", e); - } - - if (inputStream != null) { - args.photo = Drawable.createFromStream(inputStream, - args.displayPhotoUri.toString()); - - // This assumes Drawable coming from contact database is usually - // BitmapDrawable and thus we can have (down)scaled version of it. - args.photoIcon = getPhotoIconWhenAppropriate(args.context, args.photo); - - Log.d(ContactsAsyncHelper.this, "Loading image: " + msg.arg1 + - " token: " + msg.what + " image URI: " + args.displayPhotoUri); - } else { - args.photo = null; - args.photoIcon = null; - Log.d(ContactsAsyncHelper.this, "Problem with image: " + msg.arg1 + - " token: " + msg.what + " image URI: " + args.displayPhotoUri + - ", using default image."); - } - } finally { - if (inputStream != null) { - try { - inputStream.close(); - } catch (IOException e) { - Log.e(this, "Unable to close input stream.", e); - } - } - } - break; - default: - } - - // send the reply to the enclosing class. - Message reply = ContactsAsyncHelper.this.mResultHandler.obtainMessage(msg.what); - reply.arg1 = msg.arg1; - reply.obj = msg.obj; - reply.sendToTarget(); - } - - /** - * Returns a Bitmap object suitable for {@link Notification}'s large icon. This might - * return null when the given Drawable isn't BitmapDrawable, or if the system fails to - * create a scaled Bitmap for the Drawable. - */ - private Bitmap getPhotoIconWhenAppropriate(Context context, Drawable photo) { - if (!(photo instanceof BitmapDrawable)) { - return null; - } - int iconSize = context.getResources() - .getDimensionPixelSize(R.dimen.notification_icon_size); - Bitmap orgBitmap = ((BitmapDrawable) photo).getBitmap(); - int orgWidth = orgBitmap.getWidth(); - int orgHeight = orgBitmap.getHeight(); - int longerEdge = orgWidth > orgHeight ? orgWidth : orgHeight; - // We want downscaled one only when the original icon is too big. - if (longerEdge > iconSize) { - float ratio = ((float) longerEdge) / iconSize; - int newWidth = (int) (orgWidth / ratio); - int newHeight = (int) (orgHeight / ratio); - // If the longer edge is much longer than the shorter edge, the latter may - // become 0 which will cause a crash. - if (newWidth <= 0 || newHeight <= 0) { - Log.w(this, "Photo icon's width or height become 0."); - return null; - } - - // It is sure ratio >= 1.0f in any case and thus the newly created Bitmap - // should be smaller than the original. - return Bitmap.createScaledBitmap(orgBitmap, newWidth, newHeight, true); - } else { - return orgBitmap; - } - } - } - - /** - * Private constructor for static class - */ - private ContactsAsyncHelper() { - HandlerThread thread = new HandlerThread("ContactsAsyncWorker"); - thread.start(); - sThreadHandler = new WorkerHandler(thread.getLooper()); - } - - /** - * Starts an asynchronous image load. After finishing the load, - * {@link OnImageLoadCompleteListener#onImageLoadComplete(int, Drawable, Bitmap, Object)} - * will be called. - * - * @param token Arbitrary integer which will be returned as the first argument of - * {@link OnImageLoadCompleteListener#onImageLoadComplete(int, Drawable, Bitmap, Object)} - * @param context Context object used to do the time-consuming operation. - * @param displayPhotoUri Uri to be used to fetch the photo - * @param listener Callback object which will be used when the asynchronous load is done. - * Can be null, which means only the asynchronous load is done while there's no way to - * obtain the loaded photos. - * @param cookie Arbitrary object the caller wants to remember, which will become the - * fourth argument of {@link OnImageLoadCompleteListener#onImageLoadComplete(int, Drawable, - * Bitmap, Object)}. Can be null, at which the callback will also has null for the argument. - */ - public static final void startObtainPhotoAsync(int token, Context context, Uri displayPhotoUri, - OnImageLoadCompleteListener listener, Object cookie) { - // in case the source caller info is null, the URI will be null as well. - // just update using the placeholder image in this case. - if (displayPhotoUri == null) { - Log.wtf("startObjectPhotoAsync", "Uri is missing"); - return; - } - - // Added additional Cookie field in the callee to handle arguments - // sent to the callback function. - - // setup arguments - WorkerArgs args = new WorkerArgs(); - args.cookie = cookie; - args.context = context; - args.displayPhotoUri = displayPhotoUri; - args.listener = listener; - - // setup message arguments - Message msg = sThreadHandler.obtainMessage(token); - msg.arg1 = EVENT_LOAD_IMAGE; - msg.obj = args; - - Log.d("startObjectPhotoAsync", "Begin loading image: " + args.displayPhotoUri + - ", displaying default image for now."); - - // notify the thread to begin working - sThreadHandler.sendMessage(msg); - } - - -} diff --git a/InCallUI/src/com/android/incallui/ContactsPreferencesFactory.java b/InCallUI/src/com/android/incallui/ContactsPreferencesFactory.java deleted file mode 100644 index a9cc93bda..000000000 --- a/InCallUI/src/com/android/incallui/ContactsPreferencesFactory.java +++ /dev/null @@ -1,61 +0,0 @@ -/* - * Copyright (C) 2016 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.content.Context; -import android.support.annotation.Nullable; -import com.android.dialer.compat.UserManagerCompat; - -import com.android.contacts.common.preference.ContactsPreferences; -import com.android.contacts.common.testing.NeededForTesting; - -/** - * Factory class for {@link ContactsPreferences}. - */ -public class ContactsPreferencesFactory { - - private static boolean sUseTestInstance; - private static ContactsPreferences sTestInstance; - - /** - * Creates a new {@link ContactsPreferences} object if possible. - * - * @param context the context to use when creating the ContactsPreferences. - * @return a new ContactsPreferences object or {@code null} if the user is locked. - */ - @Nullable - public static ContactsPreferences newContactsPreferences(Context context) { - if (sUseTestInstance) { - return sTestInstance; - } - if (UserManagerCompat.isUserUnlocked(context)) { - return new ContactsPreferences(context); - } - return null; - } - - /** - * Sets the instance to be returned by all calls to {@link #newContactsPreferences(Context)}. - * - * @param testInstance the instance to return. - */ - @NeededForTesting - static void setTestInstance(ContactsPreferences testInstance) { - sUseTestInstance = true; - sTestInstance = testInstance; - } -} diff --git a/InCallUI/src/com/android/incallui/DialpadFragment.java b/InCallUI/src/com/android/incallui/DialpadFragment.java deleted file mode 100644 index ad288bdc6..000000000 --- a/InCallUI/src/com/android/incallui/DialpadFragment.java +++ /dev/null @@ -1,563 +0,0 @@ -/* - * Copyright (C) 2013 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License - */ - -package com.android.incallui; - -import android.content.Context; -import android.os.Bundle; -import android.os.Handler; -import android.os.Looper; -import android.text.Editable; -import android.text.method.DialerKeyListener; -import android.util.AttributeSet; -import android.view.KeyEvent; -import android.view.LayoutInflater; -import android.view.MotionEvent; -import android.view.View; -import android.view.ViewGroup; -import android.view.accessibility.AccessibilityManager; -import android.widget.EditText; -import android.widget.LinearLayout; -import android.widget.TextView; - -import com.android.contacts.common.compat.PhoneNumberUtilsCompat; -import com.android.dialer.R; -import com.android.phone.common.dialpad.DialpadKeyButton; -import com.android.phone.common.dialpad.DialpadView; - -import java.util.HashMap; - -/** - * Fragment for call control buttons - */ -public class DialpadFragment extends BaseFragment - implements DialpadPresenter.DialpadUi, View.OnTouchListener, View.OnKeyListener, - View.OnHoverListener, View.OnClickListener { - - private static final int ACCESSIBILITY_DTMF_STOP_DELAY_MILLIS = 50; - - private final int[] mButtonIds = new int[] {R.id.zero, R.id.one, R.id.two, R.id.three, - R.id.four, R.id.five, R.id.six, R.id.seven, R.id.eight, R.id.nine, R.id.star, - R.id.pound}; - - /** - * LinearLayout with getter and setter methods for the translationY property using floats, - * for animation purposes. - */ - public static class DialpadSlidingLinearLayout extends LinearLayout { - - public DialpadSlidingLinearLayout(Context context) { - super(context); - } - - public DialpadSlidingLinearLayout(Context context, AttributeSet attrs) { - super(context, attrs); - } - - public DialpadSlidingLinearLayout(Context context, AttributeSet attrs, int defStyle) { - super(context, attrs, defStyle); - } - - public float getYFraction() { - final int height = getHeight(); - if (height == 0) return 0; - return getTranslationY() / height; - } - - public void setYFraction(float yFraction) { - setTranslationY(yFraction * getHeight()); - } - } - - private EditText mDtmfDialerField; - - /** Hash Map to map a view id to a character*/ - private static final HashMap mDisplayMap = - new HashMap(); - - private static final Handler sHandler = new Handler(Looper.getMainLooper()); - - - /** Set up the static maps*/ - static { - // Map the buttons to the display characters - mDisplayMap.put(R.id.one, '1'); - mDisplayMap.put(R.id.two, '2'); - mDisplayMap.put(R.id.three, '3'); - mDisplayMap.put(R.id.four, '4'); - mDisplayMap.put(R.id.five, '5'); - mDisplayMap.put(R.id.six, '6'); - mDisplayMap.put(R.id.seven, '7'); - mDisplayMap.put(R.id.eight, '8'); - mDisplayMap.put(R.id.nine, '9'); - mDisplayMap.put(R.id.zero, '0'); - mDisplayMap.put(R.id.pound, '#'); - mDisplayMap.put(R.id.star, '*'); - } - - // KeyListener used with the "dialpad digits" EditText widget. - private DTMFKeyListener mDialerKeyListener; - - private DialpadView mDialpadView; - - private int mCurrentTextColor; - - /** - * Our own key listener, specialized for dealing with DTMF codes. - * 1. Ignore the backspace since it is irrelevant. - * 2. Allow ONLY valid DTMF characters to generate a tone and be - * sent as a DTMF code. - * 3. All other remaining characters are handled by the superclass. - * - * This code is purely here to handle events from the hardware keyboard - * while the DTMF dialpad is up. - */ - private class DTMFKeyListener extends DialerKeyListener { - - private DTMFKeyListener() { - super(); - } - - /** - * Overriden to return correct DTMF-dialable characters. - */ - @Override - protected char[] getAcceptedChars(){ - return DTMF_CHARACTERS; - } - - /** special key listener ignores backspace. */ - @Override - public boolean backspace(View view, Editable content, int keyCode, - KeyEvent event) { - return false; - } - - /** - * Return true if the keyCode is an accepted modifier key for the - * dialer (ALT or SHIFT). - */ - private boolean isAcceptableModifierKey(int keyCode) { - switch (keyCode) { - case KeyEvent.KEYCODE_ALT_LEFT: - case KeyEvent.KEYCODE_ALT_RIGHT: - case KeyEvent.KEYCODE_SHIFT_LEFT: - case KeyEvent.KEYCODE_SHIFT_RIGHT: - return true; - default: - return false; - } - } - - /** - * Overriden so that with each valid button press, we start sending - * a dtmf code and play a local dtmf tone. - */ - @Override - public boolean onKeyDown(View view, Editable content, - int keyCode, KeyEvent event) { - // if (DBG) log("DTMFKeyListener.onKeyDown, keyCode " + keyCode + ", view " + view); - - // find the character - char c = (char) lookup(event, content); - - // if not a long press, and parent onKeyDown accepts the input - if (event.getRepeatCount() == 0 && super.onKeyDown(view, content, keyCode, event)) { - - boolean keyOK = ok(getAcceptedChars(), c); - - // if the character is a valid dtmf code, start playing the tone and send the - // code. - if (keyOK) { - Log.d(this, "DTMFKeyListener reading '" + c + "' from input."); - getPresenter().processDtmf(c); - } else { - Log.d(this, "DTMFKeyListener rejecting '" + c + "' from input."); - } - return true; - } - return false; - } - - /** - * Overriden so that with each valid button up, we stop sending - * a dtmf code and the dtmf tone. - */ - @Override - public boolean onKeyUp(View view, Editable content, - int keyCode, KeyEvent event) { - // if (DBG) log("DTMFKeyListener.onKeyUp, keyCode " + keyCode + ", view " + view); - - super.onKeyUp(view, content, keyCode, event); - - // find the character - char c = (char) lookup(event, content); - - boolean keyOK = ok(getAcceptedChars(), c); - - if (keyOK) { - Log.d(this, "Stopping the tone for '" + c + "'"); - getPresenter().stopDtmf(); - return true; - } - - return false; - } - - /** - * Handle individual keydown events when we DO NOT have an Editable handy. - */ - public boolean onKeyDown(KeyEvent event) { - char c = lookup(event); - Log.d(this, "DTMFKeyListener.onKeyDown: event '" + c + "'"); - - // if not a long press, and parent onKeyDown accepts the input - if (event.getRepeatCount() == 0 && c != 0) { - // if the character is a valid dtmf code, start playing the tone and send the - // code. - if (ok(getAcceptedChars(), c)) { - Log.d(this, "DTMFKeyListener reading '" + c + "' from input."); - getPresenter().processDtmf(c); - return true; - } else { - Log.d(this, "DTMFKeyListener rejecting '" + c + "' from input."); - } - } - return false; - } - - /** - * Handle individual keyup events. - * - * @param event is the event we are trying to stop. If this is null, - * then we just force-stop the last tone without checking if the event - * is an acceptable dialer event. - */ - public boolean onKeyUp(KeyEvent event) { - if (event == null) { - //the below piece of code sends stopDTMF event unnecessarily even when a null event - //is received, hence commenting it. - /*if (DBG) log("Stopping the last played tone."); - stopTone();*/ - return true; - } - - char c = lookup(event); - Log.d(this, "DTMFKeyListener.onKeyUp: event '" + c + "'"); - - // TODO: stopTone does not take in character input, we may want to - // consider checking for this ourselves. - if (ok(getAcceptedChars(), c)) { - Log.d(this, "Stopping the tone for '" + c + "'"); - getPresenter().stopDtmf(); - return true; - } - - return false; - } - - /** - * Find the Dialer Key mapped to this event. - * - * @return The char value of the input event, otherwise - * 0 if no matching character was found. - */ - private char lookup(KeyEvent event) { - // This code is similar to {@link DialerKeyListener#lookup(KeyEvent, Spannable) lookup} - int meta = event.getMetaState(); - int number = event.getNumber(); - - if (!((meta & (KeyEvent.META_ALT_ON | KeyEvent.META_SHIFT_ON)) == 0) || (number == 0)) { - int match = event.getMatch(getAcceptedChars(), meta); - number = (match != 0) ? match : number; - } - - return (char) number; - } - - /** - * Check to see if the keyEvent is dialable. - */ - boolean isKeyEventAcceptable (KeyEvent event) { - return (ok(getAcceptedChars(), lookup(event))); - } - - /** - * Overrides the characters used in {@link DialerKeyListener#CHARACTERS} - * These are the valid dtmf characters. - */ - public final char[] DTMF_CHARACTERS = new char[] { - '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '#', '*' - }; - } - - @Override - public void onClick(View v) { - final AccessibilityManager accessibilityManager = (AccessibilityManager) - v.getContext().getSystemService(Context.ACCESSIBILITY_SERVICE); - // When accessibility is on, simulate press and release to preserve the - // semantic meaning of performClick(). Required for Braille support. - if (accessibilityManager.isEnabled()) { - final int id = v.getId(); - // Checking the press state prevents double activation. - if (!v.isPressed() && mDisplayMap.containsKey(id)) { - getPresenter().processDtmf(mDisplayMap.get(id)); - sHandler.postDelayed(new Runnable() { - @Override - public void run() { - getPresenter().stopDtmf(); - } - }, ACCESSIBILITY_DTMF_STOP_DELAY_MILLIS); - } - } - if (v.getId() == R.id.dialpad_back) { - getActivity().onBackPressed(); - } - } - - @Override - public boolean onHover(View v, MotionEvent event) { - // When touch exploration is turned on, lifting a finger while inside - // the button's hover target bounds should perform a click action. - final AccessibilityManager accessibilityManager = (AccessibilityManager) - v.getContext().getSystemService(Context.ACCESSIBILITY_SERVICE); - - if (accessibilityManager.isEnabled() - && accessibilityManager.isTouchExplorationEnabled()) { - final int left = v.getPaddingLeft(); - final int right = (v.getWidth() - v.getPaddingRight()); - final int top = v.getPaddingTop(); - final int bottom = (v.getHeight() - v.getPaddingBottom()); - - switch (event.getActionMasked()) { - case MotionEvent.ACTION_HOVER_ENTER: - // Lift-to-type temporarily disables double-tap activation. - v.setClickable(false); - break; - case MotionEvent.ACTION_HOVER_EXIT: - final int x = (int) event.getX(); - final int y = (int) event.getY(); - if ((x > left) && (x < right) && (y > top) && (y < bottom)) { - v.performClick(); - } - v.setClickable(true); - break; - } - } - - return false; - } - - @Override - public boolean onKey(View v, int keyCode, KeyEvent event) { - Log.d(this, "onKey: keyCode " + keyCode + ", view " + v); - - if (keyCode == KeyEvent.KEYCODE_DPAD_CENTER || keyCode == KeyEvent.KEYCODE_ENTER) { - int viewId = v.getId(); - if (mDisplayMap.containsKey(viewId)) { - switch (event.getAction()) { - case KeyEvent.ACTION_DOWN: - if (event.getRepeatCount() == 0) { - getPresenter().processDtmf(mDisplayMap.get(viewId)); - } - break; - case KeyEvent.ACTION_UP: - getPresenter().stopDtmf(); - break; - } - // do not return true [handled] here, since we want the - // press / click animation to be handled by the framework. - } - } - return false; - } - - @Override - public boolean onTouch(View v, MotionEvent event) { - Log.d(this, "onTouch"); - int viewId = v.getId(); - - // if the button is recognized - if (mDisplayMap.containsKey(viewId)) { - switch (event.getAction()) { - case MotionEvent.ACTION_DOWN: - // Append the character mapped to this button, to the display. - // start the tone - getPresenter().processDtmf(mDisplayMap.get(viewId)); - break; - case MotionEvent.ACTION_UP: - case MotionEvent.ACTION_CANCEL: - // stop the tone on ANY other event, except for MOVE. - getPresenter().stopDtmf(); - break; - } - // do not return true [handled] here, since we want the - // press / click animation to be handled by the framework. - } - return false; - } - - // TODO(klp) Adds hardware keyboard listener - - @Override - public DialpadPresenter createPresenter() { - return new DialpadPresenter(); - } - - @Override - public DialpadPresenter.DialpadUi getUi() { - return this; - } - - @Override - public View onCreateView(LayoutInflater inflater, ViewGroup container, - Bundle savedInstanceState) { - final View parent = inflater.inflate( - R.layout.incall_dialpad_fragment, container, false); - mDialpadView = (DialpadView) parent.findViewById(R.id.dialpad_view); - mDialpadView.setCanDigitsBeEdited(false); - mDialpadView.setBackgroundResource(R.color.incall_dialpad_background); - mDtmfDialerField = (EditText) parent.findViewById(R.id.digits); - if (mDtmfDialerField != null) { - mDialerKeyListener = new DTMFKeyListener(); - mDtmfDialerField.setKeyListener(mDialerKeyListener); - // remove the long-press context menus that support - // the edit (copy / paste / select) functions. - mDtmfDialerField.setLongClickable(false); - mDtmfDialerField.setElegantTextHeight(false); - configureKeypadListeners(); - } - View backButton = mDialpadView.findViewById(R.id.dialpad_back); - backButton.setVisibility(View.VISIBLE); - backButton.setOnClickListener(this); - - return parent; - } - - @Override - public void onResume() { - super.onResume(); - updateColors(); - } - - public void updateColors() { - int textColor = InCallPresenter.getInstance().getThemeColors().mPrimaryColor; - - if (mCurrentTextColor == textColor) { - return; - } - - DialpadKeyButton dialpadKey; - for (int i = 0; i < mButtonIds.length; i++) { - dialpadKey = (DialpadKeyButton) mDialpadView.findViewById(mButtonIds[i]); - ((TextView) dialpadKey.findViewById(R.id.dialpad_key_number)).setTextColor(textColor); - } - - mCurrentTextColor = textColor; - } - - @Override - public void onDestroyView() { - mDialerKeyListener = null; - super.onDestroyView(); - } - - /** - * Getter for Dialpad text. - * - * @return String containing current Dialpad EditText text. - */ - public String getDtmfText() { - return mDtmfDialerField.getText().toString(); - } - - /** - * Sets the Dialpad text field with some text. - * - * @param text Text to set Dialpad EditText to. - */ - public void setDtmfText(String text) { - mDtmfDialerField.setText(PhoneNumberUtilsCompat.createTtsSpannable(text)); - } - - @Override - public void setVisible(boolean on) { - if (on) { - getView().setVisibility(View.VISIBLE); - } else { - getView().setVisibility(View.INVISIBLE); - } - } - - /** - * Starts the slide up animation for the Dialpad keys when the Dialpad is revealed. - */ - public void animateShowDialpad() { - final DialpadView dialpadView = (DialpadView) getView().findViewById(R.id.dialpad_view); - dialpadView.animateShow(); - } - - @Override - public void appendDigitsToField(char digit) { - if (mDtmfDialerField != null) { - // TODO: maybe *don't* manually append this digit if - // mDialpadDigits is focused and this key came from the HW - // keyboard, since in that case the EditText field will - // get the key event directly and automatically appends - // whetever the user types. - // (Or, a cleaner fix would be to just make mDialpadDigits - // *not* handle HW key presses. That seems to be more - // complicated than just setting focusable="false" on it, - // though.) - mDtmfDialerField.getText().append(digit); - } - } - - /** - * Called externally (from InCallScreen) to play a DTMF Tone. - */ - /* package */ boolean onDialerKeyDown(KeyEvent event) { - Log.d(this, "Notifying dtmf key down."); - if (mDialerKeyListener != null) { - return mDialerKeyListener.onKeyDown(event); - } else { - return false; - } - } - - /** - * Called externally (from InCallScreen) to cancel the last DTMF Tone played. - */ - public boolean onDialerKeyUp(KeyEvent event) { - Log.d(this, "Notifying dtmf key up."); - if (mDialerKeyListener != null) { - return mDialerKeyListener.onKeyUp(event); - } else { - return false; - } - } - - private void configureKeypadListeners() { - DialpadKeyButton dialpadKey; - for (int i = 0; i < mButtonIds.length; i++) { - dialpadKey = (DialpadKeyButton) mDialpadView.findViewById(mButtonIds[i]); - dialpadKey.setOnTouchListener(this); - dialpadKey.setOnKeyListener(this); - dialpadKey.setOnHoverListener(this); - dialpadKey.setOnClickListener(this); - } - } -} diff --git a/InCallUI/src/com/android/incallui/DialpadPresenter.java b/InCallUI/src/com/android/incallui/DialpadPresenter.java deleted file mode 100644 index 5e24bedef..000000000 --- a/InCallUI/src/com/android/incallui/DialpadPresenter.java +++ /dev/null @@ -1,84 +0,0 @@ -/* - * Copyright (C) 2013 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License - */ - -package com.android.incallui; - -import android.telephony.PhoneNumberUtils; - -/** - * Logic for call buttons. - */ -public class DialpadPresenter extends Presenter - implements InCallPresenter.InCallStateListener { - - private Call mCall; - - @Override - public void onUiReady(DialpadUi ui) { - super.onUiReady(ui); - InCallPresenter.getInstance().addListener(this); - mCall = CallList.getInstance().getOutgoingOrActive(); - } - - @Override - public void onUiUnready(DialpadUi ui) { - super.onUiUnready(ui); - InCallPresenter.getInstance().removeListener(this); - } - - @Override - public void onStateChange(InCallPresenter.InCallState oldState, - InCallPresenter.InCallState newState, CallList callList) { - mCall = callList.getOutgoingOrActive(); - Log.d(this, "DialpadPresenter mCall = " + mCall); - } - - /** - * Processes the specified digit as a DTMF key, by playing the - * appropriate DTMF tone, and appending the digit to the EditText - * field that displays the DTMF digits sent so far. - * - */ - public final void processDtmf(char c) { - Log.d(this, "Processing dtmf key " + c); - // if it is a valid key, then update the display and send the dtmf tone. - if (PhoneNumberUtils.is12Key(c) && mCall != null) { - Log.d(this, "updating display and sending dtmf tone for '" + c + "'"); - - // Append this key to the "digits" widget. - getUi().appendDigitsToField(c); - // Plays the tone through Telecom. - TelecomAdapter.getInstance().playDtmfTone(mCall.getId(), c); - } else { - Log.d(this, "ignoring dtmf request for '" + c + "'"); - } - } - - /** - * Stops the local tone based on the phone type. - */ - public void stopDtmf() { - if (mCall != null) { - Log.d(this, "stopping remote tone"); - TelecomAdapter.getInstance().stopDtmfTone(mCall.getId()); - } - } - - public interface DialpadUi extends Ui { - void setVisible(boolean on); - void appendDigitsToField(char digit); - } -} diff --git a/InCallUI/src/com/android/incallui/DistanceHelper.java b/InCallUI/src/com/android/incallui/DistanceHelper.java deleted file mode 100644 index a4db5fed3..000000000 --- a/InCallUI/src/com/android/incallui/DistanceHelper.java +++ /dev/null @@ -1,37 +0,0 @@ -/* - * Copyright (C) 2015 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.location.Address; - -/** - * Superclass for a helper class to get the current location and distance to other locations. - */ -public abstract class DistanceHelper { - public static final float DISTANCE_NOT_FOUND = -1; - public static final float MILES_PER_METER = (float) 0.000621371192; - public static final float KILOMETERS_PER_METER = (float) 0.001; - - public interface Listener { - public void onLocationReady(); - } - - public void cleanUp() {} - - public float calculateDistance(Address address) { - return DISTANCE_NOT_FOUND; - } -} diff --git a/InCallUI/src/com/android/incallui/ExternalCallList.java b/InCallUI/src/com/android/incallui/ExternalCallList.java deleted file mode 100644 index 06e0bb975..000000000 --- a/InCallUI/src/com/android/incallui/ExternalCallList.java +++ /dev/null @@ -1,105 +0,0 @@ -package com.android.incallui; - -import com.google.common.base.Preconditions; - -import com.android.contacts.common.compat.CallSdkCompat; - -import android.os.Handler; -import android.os.Looper; -import android.telecom.Call; -import android.util.ArraySet; - -import java.util.Collections; -import java.util.Set; -import java.util.concurrent.ConcurrentHashMap; - -/** - * Tracks the external calls known to the InCall UI. - * - * External calls are those with {@link android.telecom.Call.Details#PROPERTY_IS_EXTERNAL_CALL}. - */ -public class ExternalCallList { - - public interface ExternalCallListener { - void onExternalCallAdded(Call call); - void onExternalCallRemoved(Call call); - void onExternalCallUpdated(Call call); - } - - /** - * Handles {@link android.telecom.Call.Callback} callbacks. - */ - private final Call.Callback mTelecomCallCallback = new Call.Callback() { - @Override - public void onDetailsChanged(Call call, Call.Details details) { - notifyExternalCallUpdated(call); - } - }; - - private final Set mExternalCalls = new ArraySet<>(); - private final Set mExternalCallListeners = Collections.newSetFromMap( - new ConcurrentHashMap(8, 0.9f, 1)); - - /** - * Begins tracking an external call and notifies listeners of the new call. - */ - public void onCallAdded(Call telecomCall) { - Preconditions.checkArgument(telecomCall.getDetails() - .hasProperty(CallSdkCompat.Details.PROPERTY_IS_EXTERNAL_CALL)); - mExternalCalls.add(telecomCall); - telecomCall.registerCallback(mTelecomCallCallback, new Handler(Looper.getMainLooper())); - notifyExternalCallAdded(telecomCall); - } - - /** - * Stops tracking an external call and notifies listeners of the removal of the call. - */ - public void onCallRemoved(Call telecomCall) { - Preconditions.checkArgument(mExternalCalls.contains(telecomCall)); - mExternalCalls.remove(telecomCall); - telecomCall.unregisterCallback(mTelecomCallCallback); - notifyExternalCallRemoved(telecomCall); - } - - /** - * Adds a new listener to external call events. - */ - public void addExternalCallListener(ExternalCallListener listener) { - mExternalCallListeners.add(Preconditions.checkNotNull(listener)); - } - - /** - * Removes a listener to external call events. - */ - public void removeExternalCallListener(ExternalCallListener listener) { - Preconditions.checkArgument(mExternalCallListeners.contains(listener)); - mExternalCallListeners.remove(Preconditions.checkNotNull(listener)); - } - - /** - * Notifies listeners of the addition of a new external call. - */ - private void notifyExternalCallAdded(Call call) { - for (ExternalCallListener listener : mExternalCallListeners) { - listener.onExternalCallAdded(call); - } - } - - /** - * Notifies listeners of the removal of an external call. - */ - private void notifyExternalCallRemoved(Call call) { - for (ExternalCallListener listener : mExternalCallListeners) { - listener.onExternalCallRemoved(call); - } - } - - /** - * Notifies listeners of changes to an external call. - */ - private void notifyExternalCallUpdated(Call call) { - for (ExternalCallListener listener : mExternalCallListeners) { - listener.onExternalCallUpdated(call); - } - } -} diff --git a/InCallUI/src/com/android/incallui/ExternalCallNotifier.java b/InCallUI/src/com/android/incallui/ExternalCallNotifier.java deleted file mode 100644 index 639a46da0..000000000 --- a/InCallUI/src/com/android/incallui/ExternalCallNotifier.java +++ /dev/null @@ -1,406 +0,0 @@ -/* - * Copyright (C) 2016 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 com.google.common.base.Preconditions; - -import com.android.contacts.common.ContactsUtils; -import com.android.contacts.common.compat.CallSdkCompat; -import com.android.contacts.common.preference.ContactsPreferences; -import com.android.contacts.common.util.BitmapUtil; -import com.android.contacts.common.util.ContactDisplayUtils; -import com.android.dialer.R; -import com.android.incallui.util.TelecomCallUtil; - -import android.app.Notification; -import android.app.NotificationManager; -import android.app.PendingIntent; -import android.content.Context; -import android.content.Intent; -import android.graphics.Bitmap; -import android.graphics.BitmapFactory; -import android.graphics.drawable.BitmapDrawable; -import android.net.Uri; -import android.support.annotation.Nullable; -import android.telecom.Call; -import android.telecom.PhoneAccount; -import android.text.BidiFormatter; -import android.text.TextDirectionHeuristics; -import android.text.TextUtils; -import android.util.ArrayMap; - -import java.util.Map; - -/** - * Handles the display of notifications for "external calls". - * - * External calls are a representation of a call which is in progress on the user's other device - * (e.g. another phone, or a watch). - */ -public class ExternalCallNotifier implements ExternalCallList.ExternalCallListener { - - /** - * Tag used with the notification manager to uniquely identify external call notifications. - */ - private static final String NOTIFICATION_TAG = "EXTERNAL_CALL"; - - /** - * Represents a call and associated cached notification data. - */ - private static class NotificationInfo { - private final Call mCall; - private final int mNotificationId; - @Nullable private String mContentTitle; - @Nullable private Bitmap mLargeIcon; - @Nullable private String mPersonReference; - - public NotificationInfo(Call call, int notificationId) { - Preconditions.checkNotNull(call); - mCall = call; - mNotificationId = notificationId; - } - - public Call getCall() { - return mCall; - } - - public int getNotificationId() { - return mNotificationId; - } - - public @Nullable String getContentTitle() { - return mContentTitle; - } - - public @Nullable Bitmap getLargeIcon() { - return mLargeIcon; - } - - public @Nullable String getPersonReference() { - return mPersonReference; - } - - public void setContentTitle(@Nullable String contentTitle) { - mContentTitle = contentTitle; - } - - public void setLargeIcon(@Nullable Bitmap largeIcon) { - mLargeIcon = largeIcon; - } - - public void setPersonReference(@Nullable String personReference) { - mPersonReference = personReference; - } - } - - private final Context mContext; - private final ContactInfoCache mContactInfoCache; - private Map mNotifications = new ArrayMap<>(); - private int mNextUniqueNotificationId; - private ContactsPreferences mContactsPreferences; - - /** - * Initializes a new instance of the external call notifier. - */ - public ExternalCallNotifier(Context context, ContactInfoCache contactInfoCache) { - mContext = Preconditions.checkNotNull(context); - mContactsPreferences = ContactsPreferencesFactory.newContactsPreferences(mContext); - mContactInfoCache = Preconditions.checkNotNull(contactInfoCache); - } - - /** - * Handles the addition of a new external call by showing a new notification. - * Triggered by {@link CallList#onCallAdded(android.telecom.Call)}. - */ - @Override - public void onExternalCallAdded(android.telecom.Call call) { - Log.i(this, "onExternalCallAdded " + call); - Preconditions.checkArgument(!mNotifications.containsKey(call)); - NotificationInfo info = new NotificationInfo(call, mNextUniqueNotificationId++); - mNotifications.put(call, info); - - showNotifcation(info); - } - - /** - * Handles the removal of an external call by hiding its associated notification. - * Triggered by {@link CallList#onCallRemoved(android.telecom.Call)}. - */ - @Override - public void onExternalCallRemoved(android.telecom.Call call) { - Log.i(this, "onExternalCallRemoved " + call); - - dismissNotification(call); - } - - /** - * Handles updates to an external call. - */ - @Override - public void onExternalCallUpdated(Call call) { - Preconditions.checkArgument(mNotifications.containsKey(call)); - postNotification(mNotifications.get(call)); - } - - /** - * Initiates a call pull given a notification ID. - * - * @param notificationId The notification ID associated with the external call which is to be - * pulled. - */ - public void pullExternalCall(int notificationId) { - for (NotificationInfo info : mNotifications.values()) { - if (info.getNotificationId() == notificationId) { - CallSdkCompat.pullExternalCall(info.getCall()); - return; - } - } - } - - /** - * Shows a notification for a new external call. Performs a contact cache lookup to find any - * associated photo and information for the call. - */ - private void showNotifcation(final NotificationInfo info) { - // We make a call to the contact info cache to query for supplemental data to what the - // call provides. This includes the contact name and photo. - // This callback will always get called immediately and synchronously with whatever data - // it has available, and may make a subsequent call later (same thread) if it had to - // call into the contacts provider for more data. - com.android.incallui.Call incallCall = new com.android.incallui.Call(info.getCall(), - new LatencyReport(), false /* registerCallback */); - - mContactInfoCache.findInfo(incallCall, false /* isIncoming */, - new ContactInfoCache.ContactInfoCacheCallback() { - @Override - public void onContactInfoComplete(String callId, - ContactInfoCache.ContactCacheEntry entry) { - - // Ensure notification still exists as the external call could have been - // removed during async contact info lookup. - if (mNotifications.containsKey(info.getCall())) { - saveContactInfo(info, entry); - } - } - - @Override - public void onImageLoadComplete(String callId, - ContactInfoCache.ContactCacheEntry entry) { - - // Ensure notification still exists as the external call could have been - // removed during async contact info lookup. - if (mNotifications.containsKey(info.getCall())) { - savePhoto(info, entry); - } - } - - @Override - public void onContactInteractionsInfoComplete(String callId, - ContactInfoCache.ContactCacheEntry entry) { - } - }); - } - - /** - * Dismisses a notification for an external call. - */ - private void dismissNotification(Call call) { - Preconditions.checkArgument(mNotifications.containsKey(call)); - - NotificationManager notificationManager = - (NotificationManager) mContext.getSystemService(Context.NOTIFICATION_SERVICE); - notificationManager.cancel(NOTIFICATION_TAG, mNotifications.get(call).getNotificationId()); - - mNotifications.remove(call); - } - - /** - * Attempts to build a large icon to use for the notification based on the contact info and - * post the updated notification to the notification manager. - */ - private void savePhoto(NotificationInfo info, ContactInfoCache.ContactCacheEntry entry) { - Bitmap largeIcon = getLargeIconToDisplay(mContext, entry, info.getCall()); - if (largeIcon != null) { - largeIcon = getRoundedIcon(mContext, largeIcon); - } - info.setLargeIcon(largeIcon); - postNotification(info); - } - - /** - * Builds and stores the contact information the notification will display and posts the updated - * notification to the notification manager. - */ - private void saveContactInfo(NotificationInfo info, ContactInfoCache.ContactCacheEntry entry) { - info.setContentTitle(getContentTitle(mContext, mContactsPreferences, - entry, info.getCall())); - info.setPersonReference(getPersonReference(entry, info.getCall())); - postNotification(info); - } - - /** - * Rebuild an existing or show a new notification given {@link NotificationInfo}. - */ - private void postNotification(NotificationInfo info) { - Log.i(this, "postNotification : " + info.getContentTitle()); - Notification.Builder builder = new Notification.Builder(mContext); - // Set notification as ongoing since calls are long-running versus a point-in-time notice. - builder.setOngoing(true); - // Make the notification prioritized over the other normal notifications. - builder.setPriority(Notification.PRIORITY_HIGH); - // Set the content ("Ongoing call on another device") - builder.setContentText(mContext.getString(R.string.notification_external_call)); - builder.setSmallIcon(R.drawable.ic_call_white_24dp); - builder.setContentTitle(info.getContentTitle()); - builder.setLargeIcon(info.getLargeIcon()); - builder.setColor(mContext.getResources().getColor(R.color.dialer_theme_color)); - builder.addPerson(info.getPersonReference()); - - // Where the external call supports being transferred to the local device, add an action - // to the notification to initiate the call pull process. - if ((info.getCall().getDetails().getCallCapabilities() - & CallSdkCompat.Details.CAPABILITY_CAN_PULL_CALL) - == CallSdkCompat.Details.CAPABILITY_CAN_PULL_CALL) { - - Intent intent = new Intent( - NotificationBroadcastReceiver.ACTION_PULL_EXTERNAL_CALL, null, mContext, - NotificationBroadcastReceiver.class); - intent.putExtra(NotificationBroadcastReceiver.EXTRA_NOTIFICATION_ID, - info.getNotificationId()); - - builder.addAction(new Notification.Action.Builder(R.drawable.ic_call_white_24dp, - mContext.getText(R.string.notification_transfer_call), - PendingIntent.getBroadcast(mContext, 0, intent, 0)).build()); - } - - /** - * This builder is used for the notification shown when the device is locked and the user - * has set their notification settings to 'hide sensitive content' - * {@see Notification.Builder#setPublicVersion}. - */ - Notification.Builder publicBuilder = new Notification.Builder(mContext); - publicBuilder.setSmallIcon(R.drawable.ic_call_white_24dp); - publicBuilder.setColor(mContext.getResources().getColor(R.color.dialer_theme_color)); - - builder.setPublicVersion(publicBuilder.build()); - Notification notification = builder.build(); - - NotificationManager notificationManager = - (NotificationManager) mContext.getSystemService(Context.NOTIFICATION_SERVICE); - notificationManager.notify(NOTIFICATION_TAG, info.getNotificationId(), notification); - } - - /** - * Finds a large icon to display in a notification for a call. For conference calls, a - * conference call icon is used, otherwise if contact info is specified, the user's contact - * photo or avatar is used. - * - * @param context The context. - * @param contactInfo The contact cache info. - * @param call The call. - * @return The large icon to use for the notification. - */ - private @Nullable Bitmap getLargeIconToDisplay(Context context, - ContactInfoCache.ContactCacheEntry contactInfo, android.telecom.Call call) { - - Bitmap largeIcon = null; - if (call.getDetails().hasProperty(android.telecom.Call.Details.PROPERTY_CONFERENCE) && - !call.getDetails() - .hasProperty(android.telecom.Call.Details.PROPERTY_GENERIC_CONFERENCE)) { - - largeIcon = BitmapFactory.decodeResource(context.getResources(), - R.drawable.img_conference); - } - if (contactInfo.photo != null && (contactInfo.photo instanceof BitmapDrawable)) { - largeIcon = ((BitmapDrawable) contactInfo.photo).getBitmap(); - } - return largeIcon; - } - - /** - * Given a bitmap, returns a rounded version of the icon suitable for display in a notification. - * - * @param context The context. - * @param bitmap The bitmap to round. - * @return The rounded bitmap. - */ - private @Nullable Bitmap getRoundedIcon(Context context, @Nullable Bitmap bitmap) { - if (bitmap == null) { - return null; - } - final int height = (int) context.getResources().getDimension( - android.R.dimen.notification_large_icon_height); - final int width = (int) context.getResources().getDimension( - android.R.dimen.notification_large_icon_width); - return BitmapUtil.getRoundedBitmap(bitmap, width, height); - } - - /** - * Builds a notification content title for a call. If the call is a conference call, it is - * identified as such. Otherwise an attempt is made to show an associated contact name or - * phone number. - * - * @param context The context. - * @param contactsPreferences Contacts preferences, used to determine the preferred formatting - * for contact names. - * @param contactInfo The contact info which was looked up in the contact cache. - * @param call The call to generate a title for. - * @return The content title. - */ - private @Nullable String getContentTitle(Context context, - @Nullable ContactsPreferences contactsPreferences, - ContactInfoCache.ContactCacheEntry contactInfo, android.telecom.Call call) { - - if (call.getDetails().hasProperty(android.telecom.Call.Details.PROPERTY_CONFERENCE) && - !call.getDetails() - .hasProperty(android.telecom.Call.Details.PROPERTY_GENERIC_CONFERENCE)) { - - return context.getResources().getString(R.string.card_title_conf_call); - } - - String preferredName = ContactDisplayUtils.getPreferredDisplayName(contactInfo.namePrimary, - contactInfo.nameAlternative, contactsPreferences); - if (TextUtils.isEmpty(preferredName)) { - return TextUtils.isEmpty(contactInfo.number) ? null : BidiFormatter.getInstance() - .unicodeWrap(contactInfo.number, TextDirectionHeuristics.LTR); - } - return preferredName; - } - - /** - * Gets a "person reference" for a notification, used by the system to determine whether the - * notification should be allowed past notification interruption filters. - * - * @param contactInfo The contact info from cache. - * @param call The call. - * @return the person reference. - */ - private String getPersonReference(ContactInfoCache.ContactCacheEntry contactInfo, - Call call) { - - String number = TelecomCallUtil.getNumber(call); - // Query {@link Contacts#CONTENT_LOOKUP_URI} directly with work lookup key is not allowed. - // So, do not pass {@link Contacts#CONTENT_LOOKUP_URI} to NotificationManager to avoid - // NotificationManager using it. - if (contactInfo.lookupUri != null && contactInfo.userType != ContactsUtils.USER_TYPE_WORK) { - return contactInfo.lookupUri.toString(); - } else if (!TextUtils.isEmpty(number)) { - return Uri.fromParts(PhoneAccount.SCHEME_TEL, number, null).toString(); - } - return ""; - } -} diff --git a/InCallUI/src/com/android/incallui/FragmentDisplayManager.java b/InCallUI/src/com/android/incallui/FragmentDisplayManager.java deleted file mode 100644 index 045d999a0..000000000 --- a/InCallUI/src/com/android/incallui/FragmentDisplayManager.java +++ /dev/null @@ -1,23 +0,0 @@ -/* - * Copyright (C) 2015 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.Fragment; - -interface FragmentDisplayManager { - public void onFragmentAttached(Fragment fragment); -} diff --git a/InCallUI/src/com/android/incallui/GlowPadAnswerFragment.java b/InCallUI/src/com/android/incallui/GlowPadAnswerFragment.java deleted file mode 100644 index 62a8e7829..000000000 --- a/InCallUI/src/com/android/incallui/GlowPadAnswerFragment.java +++ /dev/null @@ -1,155 +0,0 @@ -/* - * Copyright (C) 2013 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License - */ - -package com.android.incallui; - -import android.os.Bundle; -import android.telecom.VideoProfile; -import android.view.LayoutInflater; -import android.view.View; -import android.view.ViewGroup; - -import com.android.dialer.R; - -public class GlowPadAnswerFragment extends AnswerFragment { - - private GlowPadWrapper mGlowpad; - - public GlowPadAnswerFragment() { - } - - @Override - public View onCreateView(LayoutInflater inflater, ViewGroup container, - Bundle savedInstanceState) { - mGlowpad = (GlowPadWrapper) inflater.inflate(R.layout.answer_fragment, - container, false); - - Log.d(this, "Creating view for answer fragment ", this); - Log.d(this, "Created from activity", getActivity()); - mGlowpad.setAnswerFragment(this); - - return mGlowpad; - } - - @Override - public void onResume() { - super.onResume(); - mGlowpad.requestFocus(); - } - - @Override - public void onDestroyView() { - Log.d(this, "onDestroyView"); - if (mGlowpad != null) { - mGlowpad.stopPing(); - mGlowpad = null; - } - super.onDestroyView(); - } - - @Override - public void onShowAnswerUi(boolean shown) { - Log.d(this, "Show answer UI: " + shown); - if (shown) { - mGlowpad.startPing(); - } else { - mGlowpad.stopPing(); - } - } - - /** - * Sets targets on the glowpad according to target set identified by the parameter. - * - * @param targetSet Integer identifying the set of targets to use. - */ - public void showTargets(int targetSet) { - showTargets(targetSet, VideoProfile.STATE_BIDIRECTIONAL); - } - - /** - * Sets targets on the glowpad according to target set identified by the parameter. - * - * @param targetSet Integer identifying the set of targets to use. - */ - @Override - public void showTargets(int targetSet, int videoState) { - final int targetResourceId; - final int targetDescriptionsResourceId; - final int directionDescriptionsResourceId; - final int handleDrawableResourceId; - mGlowpad.setVideoState(videoState); - - switch (targetSet) { - case TARGET_SET_FOR_AUDIO_WITH_SMS: - targetResourceId = R.array.incoming_call_widget_audio_with_sms_targets; - targetDescriptionsResourceId = - R.array.incoming_call_widget_audio_with_sms_target_descriptions; - directionDescriptionsResourceId = - R.array.incoming_call_widget_audio_with_sms_direction_descriptions; - handleDrawableResourceId = R.drawable.ic_incall_audio_handle; - break; - case TARGET_SET_FOR_VIDEO_WITHOUT_SMS: - targetResourceId = R.array.incoming_call_widget_video_without_sms_targets; - targetDescriptionsResourceId = - R.array.incoming_call_widget_video_without_sms_target_descriptions; - directionDescriptionsResourceId = - R.array.incoming_call_widget_video_without_sms_direction_descriptions; - handleDrawableResourceId = R.drawable.ic_incall_video_handle; - break; - case TARGET_SET_FOR_VIDEO_WITH_SMS: - targetResourceId = R.array.incoming_call_widget_video_with_sms_targets; - targetDescriptionsResourceId = - R.array.incoming_call_widget_video_with_sms_target_descriptions; - directionDescriptionsResourceId = - R.array.incoming_call_widget_video_with_sms_direction_descriptions; - handleDrawableResourceId = R.drawable.ic_incall_video_handle; - break; - case TARGET_SET_FOR_VIDEO_ACCEPT_REJECT_REQUEST: - targetResourceId = - R.array.incoming_call_widget_video_request_targets; - targetDescriptionsResourceId = - R.array.incoming_call_widget_video_request_target_descriptions; - directionDescriptionsResourceId = R.array - .incoming_call_widget_video_request_target_direction_descriptions; - handleDrawableResourceId = R.drawable.ic_incall_video_handle; - break; - case TARGET_SET_FOR_AUDIO_WITHOUT_SMS: - default: - targetResourceId = R.array.incoming_call_widget_audio_without_sms_targets; - targetDescriptionsResourceId = - R.array.incoming_call_widget_audio_without_sms_target_descriptions; - directionDescriptionsResourceId = - R.array.incoming_call_widget_audio_without_sms_direction_descriptions; - handleDrawableResourceId = R.drawable.ic_incall_audio_handle; - break; - } - - if (targetResourceId != mGlowpad.getTargetResourceId()) { - mGlowpad.setTargetResources(targetResourceId); - mGlowpad.setTargetDescriptionsResourceId(targetDescriptionsResourceId); - mGlowpad.setDirectionDescriptionsResourceId(directionDescriptionsResourceId); - mGlowpad.setHandleDrawable(handleDrawableResourceId); - mGlowpad.reset(false); - } - } - - @Override - protected void onMessageDialogCancel() { - if (mGlowpad != null) { - mGlowpad.startPing(); - } - } -} diff --git a/InCallUI/src/com/android/incallui/GlowPadWrapper.java b/InCallUI/src/com/android/incallui/GlowPadWrapper.java deleted file mode 100644 index 342f6b4fd..000000000 --- a/InCallUI/src/com/android/incallui/GlowPadWrapper.java +++ /dev/null @@ -1,158 +0,0 @@ -/* - * Copyright (C) 2013 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License - */ - -package com.android.incallui; - -import android.content.Context; -import android.os.Handler; -import android.os.Message; -import android.telecom.VideoProfile; -import android.util.AttributeSet; -import android.view.View; - -import com.android.dialer.R; -import com.android.incallui.widget.multiwaveview.GlowPadView; - -/** - * - */ -public class GlowPadWrapper extends GlowPadView implements GlowPadView.OnTriggerListener { - - // Parameters for the GlowPadView "ping" animation; see triggerPing(). - private static final int PING_MESSAGE_WHAT = 101; - private static final boolean ENABLE_PING_AUTO_REPEAT = true; - private static final long PING_REPEAT_DELAY_MS = 1200; - - private final Handler mPingHandler = new Handler() { - @Override - public void handleMessage(Message msg) { - switch (msg.what) { - case PING_MESSAGE_WHAT: - triggerPing(); - break; - } - } - }; - - private AnswerFragment mAnswerFragment; - private boolean mPingEnabled = true; - private boolean mTargetTriggered = false; - private int mVideoState = VideoProfile.STATE_BIDIRECTIONAL; - - public GlowPadWrapper(Context context) { - super(context); - Log.d(this, "class created " + this + " "); - } - - public GlowPadWrapper(Context context, AttributeSet attrs) { - super(context, attrs); - Log.d(this, "class created " + this); - } - - @Override - protected void onFinishInflate() { - Log.d(this, "onFinishInflate()"); - super.onFinishInflate(); - setOnTriggerListener(this); - } - - public void startPing() { - Log.d(this, "startPing"); - mPingEnabled = true; - triggerPing(); - } - - public void stopPing() { - Log.d(this, "stopPing"); - mPingEnabled = false; - mPingHandler.removeMessages(PING_MESSAGE_WHAT); - } - - private void triggerPing() { - Log.d(this, "triggerPing(): " + mPingEnabled + " " + this); - if (mPingEnabled && !mPingHandler.hasMessages(PING_MESSAGE_WHAT)) { - ping(); - - if (ENABLE_PING_AUTO_REPEAT) { - mPingHandler.sendEmptyMessageDelayed(PING_MESSAGE_WHAT, PING_REPEAT_DELAY_MS); - } - } - } - - @Override - public void onGrabbed(View v, int handle) { - Log.d(this, "onGrabbed()"); - stopPing(); - } - - @Override - public void onReleased(View v, int handle) { - Log.d(this, "onReleased()"); - if (mTargetTriggered) { - mTargetTriggered = false; - } else { - startPing(); - } - } - - @Override - public void onTrigger(View v, int target) { - Log.d(this, "onTrigger() view=" + v + " target=" + target); - final int resId = getResourceIdForTarget(target); - if (resId == R.drawable.ic_lockscreen_answer) { - mAnswerFragment.onAnswer(VideoProfile.STATE_AUDIO_ONLY, getContext()); - mTargetTriggered = true; - } else if (resId == R.drawable.ic_lockscreen_decline) { - mAnswerFragment.onDecline(getContext()); - mTargetTriggered = true; - } else if (resId == R.drawable.ic_lockscreen_text) { - mAnswerFragment.onText(); - mTargetTriggered = true; - } else if (resId == R.drawable.ic_videocam || resId == R.drawable.ic_lockscreen_answer_video) { - mAnswerFragment.onAnswer(mVideoState, getContext()); - mTargetTriggered = true; - } else if (resId == R.drawable.ic_lockscreen_decline_video) { - mAnswerFragment.onDeclineUpgradeRequest(getContext()); - mTargetTriggered = true; - } else { - // Code should never reach here. - Log.e(this, "Trigger detected on unhandled resource. Skipping."); - } - } - - @Override - public void onGrabbedStateChange(View v, int handle) { - - } - - @Override - public void onFinishFinalAnimation() { - - } - - public void setAnswerFragment(AnswerFragment fragment) { - mAnswerFragment = fragment; - } - - /** - * Sets the video state represented by the "video" icon on the glow pad. - * - * @param videoState The new video state. - */ - public void setVideoState(int videoState) { - mVideoState = videoState; - } -} diff --git a/InCallUI/src/com/android/incallui/InCallActivity.java b/InCallUI/src/com/android/incallui/InCallActivity.java deleted file mode 100644 index eaaedff2c..000000000 --- a/InCallUI/src/com/android/incallui/InCallActivity.java +++ /dev/null @@ -1,980 +0,0 @@ -/* - * Copyright (C) 2006 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.incallui; - -import android.app.ActionBar; -import android.app.Activity; -import android.app.ActivityManager; -import android.app.AlertDialog; -import android.app.DialogFragment; -import android.app.Fragment; -import android.app.FragmentManager; -import android.app.FragmentTransaction; -import android.content.Context; -import android.content.DialogInterface; -import android.content.DialogInterface.OnCancelListener; -import android.content.DialogInterface.OnClickListener; -import android.content.Intent; -import android.content.res.Configuration; -import android.graphics.Point; -import android.hardware.SensorManager; -import android.os.Bundle; -import android.os.Trace; -import android.telecom.DisconnectCause; -import android.telecom.PhoneAccountHandle; -import android.text.TextUtils; -import android.view.KeyEvent; -import android.view.MenuItem; -import android.view.MotionEvent; -import android.view.OrientationEventListener; -import android.view.Surface; -import android.view.View; -import android.view.View.OnTouchListener; -import android.view.Window; -import android.view.WindowManager; -import android.view.accessibility.AccessibilityEvent; -import android.view.animation.Animation; -import android.view.animation.AnimationUtils; - -import com.android.contacts.common.activity.TransactionSafeActivity; -import com.android.contacts.common.compat.CompatUtils; -import com.android.contacts.common.interactions.TouchPointManager; -import com.android.contacts.common.widget.SelectPhoneAccountDialogFragment; -import com.android.contacts.common.widget.SelectPhoneAccountDialogFragment.SelectPhoneAccountListener; -import com.android.dialer.R; -import com.android.dialer.logging.Logger; -import com.android.dialer.logging.ScreenEvent; -import com.android.incallui.Call.State; -import com.android.incallui.util.AccessibilityUtil; -import com.android.phone.common.animation.AnimUtils; -import com.android.phone.common.animation.AnimationListenerAdapter; - -import java.util.ArrayList; -import java.util.List; -import java.util.Locale; - -/** - * Main activity that the user interacts with while in a live call. - */ -public class InCallActivity extends TransactionSafeActivity implements FragmentDisplayManager { - - public static final String TAG = InCallActivity.class.getSimpleName(); - - public static final String SHOW_DIALPAD_EXTRA = "InCallActivity.show_dialpad"; - public static final String DIALPAD_TEXT_EXTRA = "InCallActivity.dialpad_text"; - public static final String NEW_OUTGOING_CALL_EXTRA = "InCallActivity.new_outgoing_call"; - public static final String FOR_FULL_SCREEN_INTENT = "InCallActivity.for_full_screen_intent"; - - private static final String TAG_DIALPAD_FRAGMENT = "tag_dialpad_fragment"; - private static final String TAG_CONFERENCE_FRAGMENT = "tag_conference_manager_fragment"; - private static final String TAG_CALLCARD_FRAGMENT = "tag_callcard_fragment"; - private static final String TAG_ANSWER_FRAGMENT = "tag_answer_fragment"; - private static final String TAG_SELECT_ACCT_FRAGMENT = "tag_select_acct_fragment"; - - private static final int DIALPAD_REQUEST_NONE = 1; - private static final int DIALPAD_REQUEST_SHOW = 2; - private static final int DIALPAD_REQUEST_HIDE = 3; - - /** - * This is used to relaunch the activity if resizing beyond which it needs to load different - * layout file. - */ - private static final int SCREEN_HEIGHT_RESIZE_THRESHOLD = 500; - - private CallButtonFragment mCallButtonFragment; - private CallCardFragment mCallCardFragment; - private AnswerFragment mAnswerFragment; - private DialpadFragment mDialpadFragment; - private ConferenceManagerFragment mConferenceManagerFragment; - private FragmentManager mChildFragmentManager; - - private AlertDialog mDialog; - private InCallOrientationEventListener mInCallOrientationEventListener; - - /** - * Used to indicate whether the dialpad should be hidden or shown {@link #onResume}. - * {@code #DIALPAD_REQUEST_SHOW} indicates that the dialpad should be shown. - * {@code #DIALPAD_REQUEST_HIDE} indicates that the dialpad should be hidden. - * {@code #DIALPAD_REQUEST_NONE} indicates no change should be made to dialpad visibility. - */ - private int mShowDialpadRequest = DIALPAD_REQUEST_NONE; - - /** - * Use to determine if the dialpad should be animated on show. - */ - private boolean mAnimateDialpadOnShow; - - /** - * Use to determine the DTMF Text which should be pre-populated in the dialpad. - */ - private String mDtmfText; - - /** - * Use to pass parameters for showing the PostCharDialog to {@link #onResume} - */ - private boolean mShowPostCharWaitDialogOnResume; - private String mShowPostCharWaitDialogCallId; - private String mShowPostCharWaitDialogChars; - - private boolean mIsLandscape; - private Animation mSlideIn; - private Animation mSlideOut; - private boolean mDismissKeyguard = false; - - AnimationListenerAdapter mSlideOutListener = new AnimationListenerAdapter() { - @Override - public void onAnimationEnd(Animation animation) { - showFragment(TAG_DIALPAD_FRAGMENT, false, true); - } - }; - - private OnTouchListener mDispatchTouchEventListener; - - private SelectPhoneAccountListener mSelectAcctListener = new SelectPhoneAccountListener() { - @Override - public void onPhoneAccountSelected(PhoneAccountHandle selectedAccountHandle, - boolean setDefault) { - InCallPresenter.getInstance().handleAccountSelection(selectedAccountHandle, - setDefault); - } - - @Override - public void onDialogDismissed() { - InCallPresenter.getInstance().cancelAccountSelection(); - } - }; - - @Override - protected void onCreate(Bundle icicle) { - Log.d(this, "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". - int flags = WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED - | WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON - | WindowManager.LayoutParams.FLAG_IGNORE_CHEEK_PRESSES; - - getWindow().addFlags(flags); - - // Setup action bar for the conference call manager. - requestWindowFeature(Window.FEATURE_ACTION_BAR_OVERLAY); - ActionBar actionBar = getActionBar(); - if (actionBar != null) { - actionBar.setDisplayHomeAsUpEnabled(true); - actionBar.setDisplayShowTitleEnabled(true); - actionBar.hide(); - } - - // TODO(klp): Do we need to add this back when prox sensor is not available? - // lp.inputFeatures |= WindowManager.LayoutParams.INPUT_FEATURE_DISABLE_USER_ACTIVITY; - - setContentView(R.layout.incall_screen); - - internalResolveIntent(getIntent()); - - mIsLandscape = getResources().getConfiguration().orientation == - Configuration.ORIENTATION_LANDSCAPE; - - final boolean isRtl = TextUtils.getLayoutDirectionFromLocale(Locale.getDefault()) == - View.LAYOUT_DIRECTION_RTL; - - if (mIsLandscape) { - mSlideIn = AnimationUtils.loadAnimation(this, - isRtl ? R.anim.dialpad_slide_in_left : R.anim.dialpad_slide_in_right); - mSlideOut = AnimationUtils.loadAnimation(this, - isRtl ? R.anim.dialpad_slide_out_left : R.anim.dialpad_slide_out_right); - } else { - mSlideIn = AnimationUtils.loadAnimation(this, R.anim.dialpad_slide_in_bottom); - mSlideOut = AnimationUtils.loadAnimation(this, R.anim.dialpad_slide_out_bottom); - } - - mSlideIn.setInterpolator(AnimUtils.EASE_IN); - mSlideOut.setInterpolator(AnimUtils.EASE_OUT); - - mSlideOut.setAnimationListener(mSlideOutListener); - - // If the dialpad fragment already exists, retrieve it. This is important when rotating as - // we will not be able to hide or show the dialpad after the rotation otherwise. - Fragment existingFragment = - getFragmentManager().findFragmentByTag(DialpadFragment.class.getName()); - if (existingFragment != null) { - mDialpadFragment = (DialpadFragment) existingFragment; - } - - if (icicle != null) { - // If the dialpad was shown before, set variables indicating it should be shown and - // populated with the previous DTMF text. The dialpad is actually shown and populated - // in onResume() to ensure the hosting CallCardFragment has been inflated and is ready - // to receive it. - if (icicle.containsKey(SHOW_DIALPAD_EXTRA)) { - boolean showDialpad = icicle.getBoolean(SHOW_DIALPAD_EXTRA); - mShowDialpadRequest = showDialpad ? DIALPAD_REQUEST_SHOW : DIALPAD_REQUEST_HIDE; - mAnimateDialpadOnShow = false; - } - mDtmfText = icicle.getString(DIALPAD_TEXT_EXTRA); - - SelectPhoneAccountDialogFragment dialogFragment = (SelectPhoneAccountDialogFragment) - getFragmentManager().findFragmentByTag(TAG_SELECT_ACCT_FRAGMENT); - if (dialogFragment != null) { - dialogFragment.setListener(mSelectAcctListener); - } - } - mInCallOrientationEventListener = new InCallOrientationEventListener(this); - - Log.d(this, "onCreate(): exit"); - } - - @Override - protected void onSaveInstanceState(Bundle out) { - // TODO: The dialpad fragment should handle this as part of its own state - out.putBoolean(SHOW_DIALPAD_EXTRA, - mCallButtonFragment != null && mCallButtonFragment.isDialpadVisible()); - if (mDialpadFragment != null) { - out.putString(DIALPAD_TEXT_EXTRA, mDialpadFragment.getDtmfText()); - } - super.onSaveInstanceState(out); - } - - @Override - protected void onStart() { - Log.d(this, "onStart()..."); - super.onStart(); - - // setting activity should be last thing in setup process - InCallPresenter.getInstance().setActivity(this); - enableInCallOrientationEventListener(getRequestedOrientation() == - InCallOrientationEventListener.FULL_SENSOR_SCREEN_ORIENTATION); - - InCallPresenter.getInstance().onActivityStarted(); - } - - @Override - protected void onResume() { - Log.i(this, "onResume()..."); - super.onResume(); - - InCallPresenter.getInstance().setThemeColors(); - InCallPresenter.getInstance().onUiShowing(true); - - // Clear fullscreen state onResume; the stored value may not match reality. - InCallPresenter.getInstance().clearFullscreen(); - - // If there is a pending request to show or hide the dialpad, handle that now. - if (mShowDialpadRequest != DIALPAD_REQUEST_NONE) { - if (mShowDialpadRequest == DIALPAD_REQUEST_SHOW) { - // Exit fullscreen so that the user has access to the dialpad hide/show button and - // can hide the dialpad. Important when showing the dialpad from within dialer. - InCallPresenter.getInstance().setFullScreen(false, true /* force */); - - mCallButtonFragment.displayDialpad(true /* show */, - mAnimateDialpadOnShow /* animate */); - mAnimateDialpadOnShow = false; - - if (mDialpadFragment != null) { - mDialpadFragment.setDtmfText(mDtmfText); - mDtmfText = null; - } - } else { - Log.v(this, "onResume : force hide dialpad"); - if (mDialpadFragment != null) { - mCallButtonFragment.displayDialpad(false /* show */, false /* animate */); - } - } - mShowDialpadRequest = DIALPAD_REQUEST_NONE; - } - - if (mShowPostCharWaitDialogOnResume) { - showPostCharWaitDialog(mShowPostCharWaitDialogCallId, mShowPostCharWaitDialogChars); - } - - CallList.getInstance().onInCallUiShown( - getIntent().getBooleanExtra(FOR_FULL_SCREEN_INTENT, false)); - } - - // onPause is guaranteed to be called when the InCallActivity goes - // in the background. - @Override - protected void onPause() { - Log.d(this, "onPause()..."); - if (mDialpadFragment != null) { - mDialpadFragment.onDialerKeyUp(null); - } - - InCallPresenter.getInstance().onUiShowing(false); - if (isFinishing()) { - InCallPresenter.getInstance().unsetActivity(this); - } - super.onPause(); - } - - @Override - protected void onStop() { - Log.d(this, "onStop()..."); - enableInCallOrientationEventListener(false); - InCallPresenter.getInstance().updateIsChangingConfigurations(); - InCallPresenter.getInstance().onActivityStopped(); - super.onStop(); - } - - @Override - protected void onDestroy() { - Log.d(this, "onDestroy()... this = " + this); - InCallPresenter.getInstance().unsetActivity(this); - InCallPresenter.getInstance().updateIsChangingConfigurations(); - super.onDestroy(); - } - - /** - * When fragments have a parent fragment, onAttachFragment is not called on the parent - * activity. To fix this, register our own callback instead that is always called for - * all fragments. - * - * @see {@link BaseFragment#onAttach(Activity)} - */ - @Override - public void onFragmentAttached(Fragment fragment) { - if (fragment instanceof DialpadFragment) { - mDialpadFragment = (DialpadFragment) fragment; - } else if (fragment instanceof AnswerFragment) { - mAnswerFragment = (AnswerFragment) fragment; - } else if (fragment instanceof CallCardFragment) { - mCallCardFragment = (CallCardFragment) fragment; - mChildFragmentManager = mCallCardFragment.getChildFragmentManager(); - } else if (fragment instanceof ConferenceManagerFragment) { - mConferenceManagerFragment = (ConferenceManagerFragment) fragment; - } else if (fragment instanceof CallButtonFragment) { - mCallButtonFragment = (CallButtonFragment) fragment; - } - } - - @Override - public void onConfigurationChanged(Configuration newConfig) { - super.onConfigurationChanged(newConfig); - Configuration oldConfig = getResources().getConfiguration(); - Log.v(this, String.format( - "incallui config changed, screen size: w%ddp x h%ddp old:w%ddp x h%ddp", - newConfig.screenWidthDp, newConfig.screenHeightDp, - oldConfig.screenWidthDp, oldConfig.screenHeightDp)); - // Recreate this activity if height is changing beyond the threshold to load different - // layout file. - if (oldConfig.screenHeightDp < SCREEN_HEIGHT_RESIZE_THRESHOLD && - newConfig.screenHeightDp > SCREEN_HEIGHT_RESIZE_THRESHOLD || - oldConfig.screenHeightDp > SCREEN_HEIGHT_RESIZE_THRESHOLD && - newConfig.screenHeightDp < SCREEN_HEIGHT_RESIZE_THRESHOLD) { - Log.i(this, String.format( - "Recreate activity due to resize beyond threshold: %d dp", - SCREEN_HEIGHT_RESIZE_THRESHOLD)); - recreate(); - } - } - - /** - * Returns true when the Activity is currently visible. - */ - /* package */ boolean isVisible() { - return isSafeToCommitTransactions(); - } - - private boolean hasPendingDialogs() { - return mDialog != null || (mAnswerFragment != null && mAnswerFragment.hasPendingDialogs()); - } - - @Override - public void finish() { - Log.i(this, "finish(). Dialog showing: " + (mDialog != null)); - - // skip finish if we are still showing a dialog. - if (!hasPendingDialogs()) { - super.finish(); - } - } - - @Override - protected void onNewIntent(Intent intent) { - Log.d(this, "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. - internalResolveIntent(intent); - } - - @Override - public void onBackPressed() { - Log.i(this, "onBackPressed"); - - // BACK is also used to exit out of any "special modes" of the - // in-call UI: - if (!isVisible()) { - return; - } - - if ((mConferenceManagerFragment == null || !mConferenceManagerFragment.isVisible()) - && (mCallCardFragment == null || !mCallCardFragment.isVisible())) { - return; - } - - if (mDialpadFragment != null && mDialpadFragment.isVisible()) { - mCallButtonFragment.displayDialpad(false /* show */, true /* animate */); - return; - } else if (mConferenceManagerFragment != null && mConferenceManagerFragment.isVisible()) { - showConferenceFragment(false); - return; - } - - // Always disable the Back key while an incoming call is ringing - final Call call = CallList.getInstance().getIncomingCall(); - if (call != null) { - Log.i(this, "Consume Back press for an incoming call"); - return; - } - - // Nothing special to do. Fall back to the default behavior. - super.onBackPressed(); - } - - @Override - public boolean onOptionsItemSelected(MenuItem item) { - final int itemId = item.getItemId(); - if (itemId == android.R.id.home) { - onBackPressed(); - return true; - } - return super.onOptionsItemSelected(item); - } - - @Override - public boolean onKeyUp(int keyCode, KeyEvent event) { - // push input to the dialer. - if (mDialpadFragment != null && (mDialpadFragment.isVisible()) && - (mDialpadFragment.onDialerKeyUp(event))) { - return true; - } else if (keyCode == KeyEvent.KEYCODE_CALL) { - // Always consume CALL to be sure the PhoneWindow won't do anything with it - return true; - } - return super.onKeyUp(keyCode, event); - } - - @Override - public boolean dispatchTouchEvent(MotionEvent ev) { - if (mDispatchTouchEventListener != null) { - boolean handled = mDispatchTouchEventListener.onTouch(null, ev); - if (handled) { - return true; - } - } - return super.dispatchTouchEvent(ev); - } - - @Override - public boolean onKeyDown(int keyCode, KeyEvent event) { - switch (keyCode) { - case KeyEvent.KEYCODE_CALL: - boolean handled = InCallPresenter.getInstance().handleCallKey(); - if (!handled) { - Log.w(this, "InCallActivity should always handle KEYCODE_CALL in onKeyDown"); - } - // Always consume CALL to be sure the PhoneWindow won't do anything with it - return true; - - // Note there's no KeyEvent.KEYCODE_ENDCALL case here. - // The standard system-wide handling of the ENDCALL key - // (see PhoneWindowManager's handling of KEYCODE_ENDCALL) - // already implements exactly what the UI spec wants, - // namely (1) "hang up" if there's a current active call, - // or (2) "don't answer" if there's a current ringing call. - - case KeyEvent.KEYCODE_CAMERA: - // Disable the CAMERA button while in-call since it's too - // easy to press accidentally. - return true; - - case KeyEvent.KEYCODE_VOLUME_UP: - case KeyEvent.KEYCODE_VOLUME_DOWN: - case KeyEvent.KEYCODE_VOLUME_MUTE: - // Ringer silencing handled by PhoneWindowManager. - break; - - case KeyEvent.KEYCODE_MUTE: - // toggle mute - TelecomAdapter.getInstance().mute(!AudioModeProvider.getInstance().getMute()); - return true; - - // Various testing/debugging features, enabled ONLY when VERBOSE == true. - case KeyEvent.KEYCODE_SLASH: - if (Log.VERBOSE) { - Log.v(this, "----------- InCallActivity View dump --------------"); - // Dump starting from the top-level view of the entire activity: - Window w = this.getWindow(); - View decorView = w.getDecorView(); - Log.d(this, "View dump:" + decorView); - return true; - } - break; - case KeyEvent.KEYCODE_EQUALS: - // TODO: Dump phone state? - break; - } - - if (event.getRepeatCount() == 0 && handleDialerKeyDown(keyCode, event)) { - return true; - } - return super.onKeyDown(keyCode, event); - } - - private boolean handleDialerKeyDown(int keyCode, KeyEvent event) { - Log.v(this, "handleDialerKeyDown: keyCode " + keyCode + ", event " + event + "..."); - - // As soon as the user starts typing valid dialable keys on the - // keyboard (presumably to type DTMF tones) we start passing the - // key events to the DTMFDialer's onDialerKeyDown. - if (mDialpadFragment != null && mDialpadFragment.isVisible()) { - return mDialpadFragment.onDialerKeyDown(event); - } - - return false; - } - - public CallButtonFragment getCallButtonFragment() { - return mCallButtonFragment; - } - - public CallCardFragment getCallCardFragment() { - return mCallCardFragment; - } - - public AnswerFragment getAnswerFragment() { - return mAnswerFragment; - } - - private void internalResolveIntent(Intent intent) { - final String action = intent.getAction(); - if (action.equals(Intent.ACTION_MAIN)) { - // This action is the normal way to bring up the in-call UI. - // - // But we do check here for one extra that can come along with the - // ACTION_MAIN intent: - - if (intent.hasExtra(SHOW_DIALPAD_EXTRA)) { - // SHOW_DIALPAD_EXTRA can be used here to specify whether the DTMF - // dialpad should be initially visible. If the extra isn't - // present at all, we just leave the dialpad in its previous state. - - final boolean showDialpad = intent.getBooleanExtra(SHOW_DIALPAD_EXTRA, false); - Log.d(this, "- internalResolveIntent: SHOW_DIALPAD_EXTRA: " + showDialpad); - - relaunchedFromDialer(showDialpad); - } - - boolean newOutgoingCall = false; - if (intent.getBooleanExtra(NEW_OUTGOING_CALL_EXTRA, false)) { - intent.removeExtra(NEW_OUTGOING_CALL_EXTRA); - Call call = CallList.getInstance().getOutgoingCall(); - if (call == null) { - call = CallList.getInstance().getPendingOutgoingCall(); - } - - Bundle extras = null; - if (call != null) { - extras = call.getTelecomCall().getDetails().getIntentExtras(); - } - if (extras == null) { - // Initialize the extras bundle to avoid NPE - extras = new Bundle(); - } - - Point touchPoint = null; - if (TouchPointManager.getInstance().hasValidPoint()) { - // Use the most immediate touch point in the InCallUi if available - touchPoint = TouchPointManager.getInstance().getPoint(); - } else { - // Otherwise retrieve the touch point from the call intent - if (call != null) { - touchPoint = (Point) extras.getParcelable(TouchPointManager.TOUCH_POINT); - } - } - - // Start animation for new outgoing call - CircularRevealFragment.startCircularReveal(getFragmentManager(), touchPoint, - InCallPresenter.getInstance()); - - // InCallActivity is responsible for disconnecting a new outgoing call if there - // is no way of making it (i.e. no valid call capable accounts). - // If the version is not MSIM compatible, then ignore this code. - if (CompatUtils.isMSIMCompatible() - && InCallPresenter.isCallWithNoValidAccounts(call)) { - TelecomAdapter.getInstance().disconnectCall(call.getId()); - } - - dismissKeyguard(true); - newOutgoingCall = true; - } - - Call pendingAccountSelectionCall = CallList.getInstance().getWaitingForAccountCall(); - if (pendingAccountSelectionCall != null) { - showCallCardFragment(false); - Bundle extras = - pendingAccountSelectionCall.getTelecomCall().getDetails().getIntentExtras(); - - final List phoneAccountHandles; - if (extras != null) { - phoneAccountHandles = extras.getParcelableArrayList( - android.telecom.Call.AVAILABLE_PHONE_ACCOUNTS); - } else { - phoneAccountHandles = new ArrayList<>(); - } - - DialogFragment dialogFragment = SelectPhoneAccountDialogFragment.newInstance( - R.string.select_phone_account_for_calls, true, phoneAccountHandles, - mSelectAcctListener); - dialogFragment.show(getFragmentManager(), TAG_SELECT_ACCT_FRAGMENT); - } else if (!newOutgoingCall) { - showCallCardFragment(true); - } - return; - } - } - - /** - * When relaunching from the dialer app, {@code showDialpad} indicates whether the dialpad - * should be shown on launch. - * - * @param showDialpad {@code true} to indicate the dialpad should be shown on launch, and - * {@code false} to indicate no change should be made to the - * dialpad visibility. - */ - private void relaunchedFromDialer(boolean showDialpad) { - mShowDialpadRequest = showDialpad ? DIALPAD_REQUEST_SHOW : DIALPAD_REQUEST_NONE; - mAnimateDialpadOnShow = true; - - if (mShowDialpadRequest == DIALPAD_REQUEST_SHOW) { - // If there's only one line in use, AND it's on hold, then we're sure the user - // wants to use the dialpad toward the exact line, so un-hold the holding line. - final Call call = CallList.getInstance().getActiveOrBackgroundCall(); - if (call != null && call.getState() == State.ONHOLD) { - TelecomAdapter.getInstance().unholdCall(call.getId()); - } - } - } - - public void dismissKeyguard(boolean dismiss) { - if (mDismissKeyguard == dismiss) { - return; - } - mDismissKeyguard = dismiss; - if (dismiss) { - getWindow().addFlags(WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD); - } else { - getWindow().clearFlags(WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD); - } - } - - private void showFragment(String tag, boolean show, boolean executeImmediately) { - Trace.beginSection("showFragment - " + tag); - final FragmentManager fm = getFragmentManagerForTag(tag); - - if (fm == null) { - Log.w(TAG, "Fragment manager is null for : " + tag); - return; - } - - Fragment fragment = fm.findFragmentByTag(tag); - if (!show && fragment == null) { - // Nothing to show, so bail early. - return; - } - - final FragmentTransaction transaction = fm.beginTransaction(); - if (show) { - if (fragment == null) { - fragment = createNewFragmentForTag(tag); - transaction.add(getContainerIdForFragment(tag), fragment, tag); - } else { - transaction.show(fragment); - } - Logger.logScreenView(getScreenTypeForTag(tag), this); - } else { - transaction.hide(fragment); - } - - transaction.commitAllowingStateLoss(); - if (executeImmediately) { - fm.executePendingTransactions(); - } - Trace.endSection(); - } - - private Fragment createNewFragmentForTag(String tag) { - if (TAG_DIALPAD_FRAGMENT.equals(tag)) { - mDialpadFragment = new DialpadFragment(); - return mDialpadFragment; - } else if (TAG_ANSWER_FRAGMENT.equals(tag)) { - if (AccessibilityUtil.isTalkBackEnabled(this)) { - mAnswerFragment = new AccessibleAnswerFragment(); - } else { - mAnswerFragment = new GlowPadAnswerFragment(); - } - return mAnswerFragment; - } else if (TAG_CONFERENCE_FRAGMENT.equals(tag)) { - mConferenceManagerFragment = new ConferenceManagerFragment(); - return mConferenceManagerFragment; - } else if (TAG_CALLCARD_FRAGMENT.equals(tag)) { - mCallCardFragment = new CallCardFragment(); - return mCallCardFragment; - } - throw new IllegalStateException("Unexpected fragment: " + tag); - } - - private FragmentManager getFragmentManagerForTag(String tag) { - if (TAG_DIALPAD_FRAGMENT.equals(tag)) { - return mChildFragmentManager; - } else if (TAG_ANSWER_FRAGMENT.equals(tag)) { - return mChildFragmentManager; - } else if (TAG_CONFERENCE_FRAGMENT.equals(tag)) { - return getFragmentManager(); - } else if (TAG_CALLCARD_FRAGMENT.equals(tag)) { - return getFragmentManager(); - } - throw new IllegalStateException("Unexpected fragment: " + tag); - } - - private int getScreenTypeForTag(String tag) { - switch (tag) { - case TAG_DIALPAD_FRAGMENT: - return ScreenEvent.INCALL_DIALPAD; - case TAG_CALLCARD_FRAGMENT: - return ScreenEvent.INCALL; - case TAG_CONFERENCE_FRAGMENT: - return ScreenEvent.CONFERENCE_MANAGEMENT; - case TAG_ANSWER_FRAGMENT: - return ScreenEvent.INCOMING_CALL; - default: - return ScreenEvent.UNKNOWN; - } - } - - private int getContainerIdForFragment(String tag) { - if (TAG_DIALPAD_FRAGMENT.equals(tag)) { - return R.id.answer_and_dialpad_container; - } else if (TAG_ANSWER_FRAGMENT.equals(tag)) { - return R.id.answer_and_dialpad_container; - } else if (TAG_CONFERENCE_FRAGMENT.equals(tag)) { - return R.id.main; - } else if (TAG_CALLCARD_FRAGMENT.equals(tag)) { - return R.id.main; - } - throw new IllegalStateException("Unexpected fragment: " + tag); - } - - /** - * @return {@code true} while the visibility of the dialpad has actually changed. - */ - public boolean showDialpadFragment(boolean show, boolean animate) { - // If the dialpad is already visible, don't animate in. If it's gone, don't animate out. - if ((show && isDialpadVisible()) || (!show && !isDialpadVisible())) { - return false; - } - // We don't do a FragmentTransaction on the hide case because it will be dealt with when - // the listener is fired after an animation finishes. - if (!animate) { - showFragment(TAG_DIALPAD_FRAGMENT, show, true); - } else { - if (show) { - showFragment(TAG_DIALPAD_FRAGMENT, true, true); - mDialpadFragment.animateShowDialpad(); - } - mDialpadFragment.getView().startAnimation(show ? mSlideIn : mSlideOut); - } - // Note: onDialpadVisibilityChange is called here to ensure that the dialpad FAB - // repositions itself. - mCallCardFragment.onDialpadVisibilityChange(show); - - final ProximitySensor sensor = InCallPresenter.getInstance().getProximitySensor(); - if (sensor != null) { - sensor.onDialpadVisible(show); - } - return true; - } - - public boolean isDialpadVisible() { - return mDialpadFragment != null && mDialpadFragment.isVisible(); - } - - public void showCallCardFragment(boolean show) { - showFragment(TAG_CALLCARD_FRAGMENT, show, true); - } - - /** - * Hides or shows the conference manager fragment. - * - * @param show {@code true} if the conference manager should be shown, {@code false} if it - * should be hidden. - */ - public void showConferenceFragment(boolean show) { - showFragment(TAG_CONFERENCE_FRAGMENT, show, true); - mConferenceManagerFragment.onVisibilityChanged(show); - - // Need to hide the call card fragment to ensure that accessibility service does not try to - // give focus to the call card when the conference manager is visible. - mCallCardFragment.getView().setVisibility(show ? View.GONE : View.VISIBLE); - } - - public void showAnswerFragment(boolean show) { - // CallCardFragment is the parent fragment of AnswerFragment. - // Must create the CallCardFragment first before creating - // AnswerFragment if CallCardFragment is null. - if (show && getCallCardFragment() == null) { - showCallCardFragment(true); - } - showFragment(TAG_ANSWER_FRAGMENT, show, true); - } - - public void showPostCharWaitDialog(String callId, String chars) { - if (isVisible()) { - final PostCharDialogFragment fragment = new PostCharDialogFragment(callId, chars); - fragment.show(getFragmentManager(), "postCharWait"); - - mShowPostCharWaitDialogOnResume = false; - mShowPostCharWaitDialogCallId = null; - mShowPostCharWaitDialogChars = null; - } else { - mShowPostCharWaitDialogOnResume = true; - mShowPostCharWaitDialogCallId = callId; - mShowPostCharWaitDialogChars = chars; - } - } - - @Override - public boolean dispatchPopulateAccessibilityEvent(AccessibilityEvent event) { - if (mCallCardFragment != null) { - mCallCardFragment.dispatchPopulateAccessibilityEvent(event); - } - return super.dispatchPopulateAccessibilityEvent(event); - } - - public void maybeShowErrorDialogOnDisconnect(DisconnectCause disconnectCause) { - Log.d(this, "maybeShowErrorDialogOnDisconnect"); - - if (!isFinishing() && !TextUtils.isEmpty(disconnectCause.getDescription()) - && (disconnectCause.getCode() == DisconnectCause.ERROR || - disconnectCause.getCode() == DisconnectCause.RESTRICTED)) { - showErrorDialog(disconnectCause.getDescription()); - } - } - - public void dismissPendingDialogs() { - if (mDialog != null) { - mDialog.dismiss(); - mDialog = null; - } - if (mAnswerFragment != null) { - mAnswerFragment.dismissPendingDialogs(); - } - - SelectPhoneAccountDialogFragment dialogFragment = (SelectPhoneAccountDialogFragment) - getFragmentManager().findFragmentByTag(TAG_SELECT_ACCT_FRAGMENT); - if (dialogFragment != null) { - dialogFragment.dismiss(); - } - } - - /** - * Utility function to bring up a generic "error" dialog. - */ - private void showErrorDialog(CharSequence msg) { - Log.i(this, "Show Dialog: " + msg); - - dismissPendingDialogs(); - - mDialog = new AlertDialog.Builder(this) - .setMessage(msg) - .setPositiveButton(android.R.string.ok, new OnClickListener() { - @Override - public void onClick(DialogInterface dialog, int which) { - onDialogDismissed(); - } - }) - .setOnCancelListener(new OnCancelListener() { - @Override - public void onCancel(DialogInterface dialog) { - onDialogDismissed(); - } - }) - .create(); - - mDialog.getWindow().addFlags(WindowManager.LayoutParams.FLAG_DIM_BEHIND); - mDialog.show(); - } - - private void onDialogDismissed() { - mDialog = null; - CallList.getInstance().onErrorDialogDismissed(); - InCallPresenter.getInstance().onDismissDialog(); - } - - public void setExcludeFromRecents(boolean exclude) { - ActivityManager am = (ActivityManager) getSystemService(Context.ACTIVITY_SERVICE); - List tasks = am.getAppTasks(); - int taskId = getTaskId(); - for (int i = 0; i < tasks.size(); i++) { - ActivityManager.AppTask task = tasks.get(i); - if (task.getTaskInfo().id == taskId) { - try { - task.setExcludeFromRecents(exclude); - } catch (RuntimeException e) { - Log.e(TAG, "RuntimeException when excluding task from recents.", e); - } - } - } - } - - - public OnTouchListener getDispatchTouchEventListener() { - return mDispatchTouchEventListener; - } - - public void setDispatchTouchEventListener(OnTouchListener mDispatchTouchEventListener) { - this.mDispatchTouchEventListener = mDispatchTouchEventListener; - } - - /** - * Enables the OrientationEventListener if enable flag is true. Disables it if enable is - * false - * @param enable true or false. - */ - public void enableInCallOrientationEventListener(boolean enable) { - if (enable) { - mInCallOrientationEventListener.enable(enable); - } else { - mInCallOrientationEventListener.disable(); - } - } -} diff --git a/InCallUI/src/com/android/incallui/InCallAnimationUtils.java b/InCallUI/src/com/android/incallui/InCallAnimationUtils.java deleted file mode 100644 index 44bb369e6..000000000 --- a/InCallUI/src/com/android/incallui/InCallAnimationUtils.java +++ /dev/null @@ -1,184 +0,0 @@ -/* - * Copyright (C) 2012 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.incallui; - -import android.animation.Animator; -import android.animation.AnimatorListenerAdapter; -import android.animation.ObjectAnimator; -import android.graphics.Canvas; -import android.graphics.drawable.BitmapDrawable; -import android.graphics.drawable.Drawable; -import android.graphics.drawable.LayerDrawable; -import android.view.ViewPropertyAnimator; -import android.widget.ImageView; - -/** - * Utilities for Animation. - */ -public class InCallAnimationUtils { - private static final String LOG_TAG = InCallAnimationUtils.class.getSimpleName(); - /** - * Turn on when you're interested in fading animation. Intentionally untied from other debug - * settings. - */ - private static final boolean FADE_DBG = false; - - /** - * Duration for animations in msec, which can be used with - * {@link ViewPropertyAnimator#setDuration(long)} for example. - */ - public static final int ANIMATION_DURATION = 250; - - private InCallAnimationUtils() { - } - - /** - * Drawable achieving cross-fade, just like TransitionDrawable. We can have - * call-backs via animator object (see also {@link CrossFadeDrawable#getAnimator()}). - */ - private static class CrossFadeDrawable extends LayerDrawable { - private final ObjectAnimator mAnimator; - - public CrossFadeDrawable(Drawable[] layers) { - super(layers); - mAnimator = ObjectAnimator.ofInt(this, "crossFadeAlpha", 0xff, 0); - } - - private int mCrossFadeAlpha; - - /** - * This will be used from ObjectAnimator. - * Note: this method is protected by proguard.flags so that it won't be removed - * automatically. - */ - @SuppressWarnings("unused") - public void setCrossFadeAlpha(int alpha) { - mCrossFadeAlpha = alpha; - invalidateSelf(); - } - - public ObjectAnimator getAnimator() { - return mAnimator; - } - - @Override - public void draw(Canvas canvas) { - Drawable first = getDrawable(0); - Drawable second = getDrawable(1); - - if (mCrossFadeAlpha > 0) { - first.setAlpha(mCrossFadeAlpha); - first.draw(canvas); - first.setAlpha(255); - } - - if (mCrossFadeAlpha < 0xff) { - second.setAlpha(0xff - mCrossFadeAlpha); - second.draw(canvas); - second.setAlpha(0xff); - } - } - } - - private static CrossFadeDrawable newCrossFadeDrawable(Drawable first, Drawable second) { - Drawable[] layers = new Drawable[2]; - layers[0] = first; - layers[1] = second; - return new CrossFadeDrawable(layers); - } - - /** - * Starts cross-fade animation using TransitionDrawable. Nothing will happen if "from" and "to" - * are the same. - */ - public static void startCrossFade( - final ImageView imageView, final Drawable from, final Drawable to) { - // We skip the cross-fade when those two Drawables are equal, or they are BitmapDrawables - // pointing to the same Bitmap. - final boolean drawableIsEqual = (from != null && to != null && from.equals(to)); - final boolean hasFromImage = ((from instanceof BitmapDrawable) && - ((BitmapDrawable) from).getBitmap() != null); - final boolean hasToImage = ((to instanceof BitmapDrawable) && - ((BitmapDrawable) to).getBitmap() != null); - final boolean areSameImage = drawableIsEqual || (hasFromImage && hasToImage && - ((BitmapDrawable) from).getBitmap().equals(((BitmapDrawable) to).getBitmap())); - - if (!areSameImage) { - if (FADE_DBG) { - log("Start cross-fade animation for " + imageView - + "(" + Integer.toHexString(from.hashCode()) + " -> " - + Integer.toHexString(to.hashCode()) + ")"); - } - - CrossFadeDrawable crossFadeDrawable = newCrossFadeDrawable(from, to); - ObjectAnimator animator = crossFadeDrawable.getAnimator(); - imageView.setImageDrawable(crossFadeDrawable); - animator.setDuration(ANIMATION_DURATION); - animator.addListener(new AnimatorListenerAdapter() { - @Override - public void onAnimationStart(Animator animation) { - if (FADE_DBG) { - log("cross-fade animation start (" - + Integer.toHexString(from.hashCode()) + " -> " - + Integer.toHexString(to.hashCode()) + ")"); - } - } - - @Override - public void onAnimationEnd(Animator animation) { - if (FADE_DBG) { - log("cross-fade animation ended (" - + Integer.toHexString(from.hashCode()) + " -> " - + Integer.toHexString(to.hashCode()) + ")"); - } - animation.removeAllListeners(); - // Workaround for issue 6300562; this will force the drawable to the - // resultant one regardless of animation glitch. - imageView.setImageDrawable(to); - } - }); - animator.start(); - - /* We could use TransitionDrawable here, but it may cause some weird animation in - * some corner cases. See issue 6300562 - * TODO: decide which to be used in the long run. TransitionDrawable is old but system - * one. Ours uses new animation framework and thus have callback (great for testing), - * while no framework support for the exact class. - - Drawable[] layers = new Drawable[2]; - layers[0] = from; - layers[1] = to; - TransitionDrawable transitionDrawable = new TransitionDrawable(layers); - imageView.setImageDrawable(transitionDrawable); - transitionDrawable.startTransition(ANIMATION_DURATION); */ - imageView.setTag(to); - } else if (!hasFromImage && hasToImage) { - imageView.setImageDrawable(to); - imageView.setTag(to); - } else { - if (FADE_DBG) { - log("*Not* start cross-fade. " + imageView); - } - } - } - - // Debugging / testing code - - private static void log(String msg) { - Log.d(LOG_TAG, msg); - } -} \ No newline at end of file diff --git a/InCallUI/src/com/android/incallui/InCallCameraManager.java b/InCallUI/src/com/android/incallui/InCallCameraManager.java deleted file mode 100644 index 53000f1dd..000000000 --- a/InCallUI/src/com/android/incallui/InCallCameraManager.java +++ /dev/null @@ -1,184 +0,0 @@ -/* - * Copyright (C) 2014 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.content.Context; -import android.graphics.SurfaceTexture; -import android.hardware.camera2.CameraAccessException; -import android.hardware.camera2.CameraCharacteristics; -import android.hardware.camera2.CameraManager; -import android.hardware.camera2.params.StreamConfigurationMap; -import android.util.Size; - -import java.lang.String; -import java.util.Collections; -import java.util.concurrent.ConcurrentHashMap; -import java.util.Set; - -/** - * Used to track which camera is used for outgoing video. - */ -public class InCallCameraManager { - - public interface Listener { - void onActiveCameraSelectionChanged(boolean isUsingFrontFacingCamera); - } - - private final Set mCameraSelectionListeners = Collections. - newSetFromMap(new ConcurrentHashMap(8,0.9f,1)); - - /** - * The camera ID for the front facing camera. - */ - private String mFrontFacingCameraId; - - /** - * The camera ID for the rear facing camera. - */ - private String mRearFacingCameraId; - - /** - * The currently active camera. - */ - private boolean mUseFrontFacingCamera; - - /** - * Indicates whether the list of cameras has been initialized yet. Initialization is delayed - * until a video call is present. - */ - private boolean mIsInitialized = false; - - /** - * The context. - */ - private Context mContext; - - /** - * Initializes the InCall CameraManager. - * - * @param context The current context. - */ - public InCallCameraManager(Context context) { - mUseFrontFacingCamera = true; - mContext = context; - } - - /** - * Sets whether the front facing camera should be used or not. - * - * @param useFrontFacingCamera {@code True} if the front facing camera is to be used. - */ - public void setUseFrontFacingCamera(boolean useFrontFacingCamera) { - mUseFrontFacingCamera = useFrontFacingCamera; - for (Listener listener : mCameraSelectionListeners) { - listener.onActiveCameraSelectionChanged(mUseFrontFacingCamera); - } - } - - /** - * Determines whether the front facing camera is currently in use. - * - * @return {@code True} if the front facing camera is in use. - */ - public boolean isUsingFrontFacingCamera() { - return mUseFrontFacingCamera; - } - - /** - * Determines the active camera ID. - * - * @return The active camera ID. - */ - public String getActiveCameraId() { - maybeInitializeCameraList(mContext); - - if (mUseFrontFacingCamera) { - return mFrontFacingCameraId; - } else { - return mRearFacingCameraId; - } - } - - /** - * Get the list of cameras available for use. - * - * @param context The context. - */ - private void maybeInitializeCameraList(Context context) { - if (mIsInitialized || context == null) { - return; - } - - Log.v(this, "initializeCameraList"); - - CameraManager cameraManager = null; - try { - cameraManager = (CameraManager) context.getSystemService( - Context.CAMERA_SERVICE); - } catch (Exception e) { - Log.e(this, "Could not get camera service."); - return; - } - - if (cameraManager == null) { - return; - } - - String[] cameraIds = {}; - try { - cameraIds = cameraManager.getCameraIdList(); - } catch (CameraAccessException e) { - Log.d(this, "Could not access camera: "+e); - // Camera disabled by device policy. - return; - } - - for (int i = 0; i < cameraIds.length; i++) { - CameraCharacteristics c = null; - try { - c = cameraManager.getCameraCharacteristics(cameraIds[i]); - } catch (IllegalArgumentException e) { - // Device Id is unknown. - } catch (CameraAccessException e) { - // Camera disabled by device policy. - } - if (c != null) { - int facingCharacteristic = c.get(CameraCharacteristics.LENS_FACING); - if (facingCharacteristic == CameraCharacteristics.LENS_FACING_FRONT) { - mFrontFacingCameraId = cameraIds[i]; - } else if (facingCharacteristic == CameraCharacteristics.LENS_FACING_BACK) { - mRearFacingCameraId = cameraIds[i]; - } - } - } - - mIsInitialized = true; - Log.v(this, "initializeCameraList : done"); - } - - public void addCameraSelectionListener(Listener listener) { - if (listener != null) { - mCameraSelectionListeners.add(listener); - } - } - - public void removeCameraSelectionListener(Listener listener) { - if (listener != null) { - mCameraSelectionListeners.remove(listener); - } - } -} diff --git a/InCallUI/src/com/android/incallui/InCallContactInteractions.java b/InCallUI/src/com/android/incallui/InCallContactInteractions.java deleted file mode 100644 index 88070fe37..000000000 --- a/InCallUI/src/com/android/incallui/InCallContactInteractions.java +++ /dev/null @@ -1,399 +0,0 @@ -/* - * Copyright (C) 2015 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 com.google.common.annotations.VisibleForTesting; - -import android.content.Context; -import android.location.Address; -import android.text.TextUtils; -import android.text.format.DateFormat; -import android.util.Pair; -import android.view.LayoutInflater; -import android.view.View; -import android.view.ViewGroup; -import android.widget.ArrayAdapter; -import android.widget.ImageView; -import android.widget.ListAdapter; -import android.widget.RelativeLayout; -import android.widget.RelativeLayout.LayoutParams; -import android.widget.TextView; - -import com.android.dialer.R; - -import java.text.ParseException; -import java.text.SimpleDateFormat; -import java.util.ArrayList; -import java.util.Calendar; -import java.util.Date; -import java.util.List; -import java.util.Locale; - -/** - * Wrapper class for objects that are used in generating the context about the contact in the InCall - * screen. - * - * This handles generating the appropriate resource for the ListAdapter based on whether the contact - * is a business contact or not and logic for the manipulation of data for the call context. - */ -public class InCallContactInteractions { - private static final String TAG = InCallContactInteractions.class.getSimpleName(); - - private Context mContext; - private InCallContactInteractionsListAdapter mListAdapter; - private boolean mIsBusiness; - private View mBusinessHeaderView; - private LayoutInflater mInflater; - - public InCallContactInteractions(Context context, boolean isBusiness) { - mContext = context; - mInflater = (LayoutInflater) - context.getSystemService(Context.LAYOUT_INFLATER_SERVICE); - switchContactType(isBusiness); - } - - public InCallContactInteractionsListAdapter getListAdapter() { - return mListAdapter; - } - - /** - * Switches the "isBusiness" value, if applicable. Recreates the list adapter with the resource - * corresponding to the new isBusiness value if the "isBusiness" value is switched. - * - * @param isBusiness Whether or not the contact is a business. - * - * @return {@code true} if a new list adapter was created, {@code} otherwise. - */ - public boolean switchContactType(boolean isBusiness) { - if (mIsBusiness != isBusiness || mListAdapter == null) { - mIsBusiness = isBusiness; - mListAdapter = new InCallContactInteractionsListAdapter(mContext, - mIsBusiness ? R.layout.business_context_info_list_item - : R.layout.person_context_info_list_item); - return true; - } - return false; - } - - public View getBusinessListHeaderView() { - if (mBusinessHeaderView == null) { - mBusinessHeaderView = mInflater.inflate( - R.layout.business_contact_context_list_header, null); - } - return mBusinessHeaderView; - } - - public void setBusinessInfo(Address address, float distance, - List> openingHours) { - mListAdapter.clear(); - List info = new ArrayList(); - - // Hours of operation - if (openingHours != null) { - BusinessContextInfo hoursInfo = constructHoursInfo(openingHours); - if (hoursInfo != null) { - info.add(hoursInfo); - } - } - - // Location information - if (address != null) { - BusinessContextInfo locationInfo = constructLocationInfo(address, distance); - info.add(locationInfo); - } - - mListAdapter.addAll(info); - } - - /** - * Construct a BusinessContextInfo object containing hours of operation information. - * The format is: - * [Open now/Closed now] - * [Hours] - * - * @param openingHours - * @return BusinessContextInfo object with the schedule icon, the heading set to whether the - * business is open or not and the details set to the hours of operation. - */ - private BusinessContextInfo constructHoursInfo(List> openingHours) { - try { - return constructHoursInfo(Calendar.getInstance(), openingHours); - } catch (Exception e) { - // Catch all exceptions here because we don't want any crashes if something goes wrong. - Log.e(TAG, "Error constructing hours info: ", e); - } - return null; - } - - /** - * Pass in arbitrary current calendar time. - */ - @VisibleForTesting - BusinessContextInfo constructHoursInfo(Calendar currentTime, - List> openingHours) { - if (currentTime == null || openingHours == null || openingHours.size() == 0) { - return null; - } - - BusinessContextInfo hoursInfo = new BusinessContextInfo(); - hoursInfo.iconId = R.drawable.ic_schedule_white_24dp; - - boolean isOpenNow = false; - // This variable records which interval the current time is after. 0 denotes none of the - // intervals, 1 after the first interval, etc. It is also the index of the interval the - // current time is in (if open) or the next interval (if closed). - int afterInterval = 0; - // This variable counts the number of time intervals in today's opening hours. - int todaysIntervalCount = 0; - - for (Pair hours : openingHours) { - if (hours.first.compareTo(currentTime) <= 0 - && currentTime.compareTo(hours.second) < 0) { - // If the current time is on or after the opening time and strictly before the - // closing time, then this business is open. - isOpenNow = true; - } - - if (currentTime.get(Calendar.DAY_OF_YEAR) == hours.first.get(Calendar.DAY_OF_YEAR)) { - todaysIntervalCount += 1; - } - - if (currentTime.compareTo(hours.second) > 0) { - // This assumes that the list of intervals is sorted by time. - afterInterval += 1; - } - } - - hoursInfo.heading = isOpenNow ? mContext.getString(R.string.open_now) - : mContext.getString(R.string.closed_now); - - /* - * The following logic determines what to display in various cases for hours of operation. - * - * - Display all intervals if open now and number of intervals is <=2. - * - Display next closing time if open now and number of intervals is >2. - * - Display next opening time if currently closed but opens later today. - * - Display last time it closed today if closed now and tomorrow's hours are unknown. - * - Display tomorrow's first open time if closed today and tomorrow's hours are known. - * - * NOTE: The logic below assumes that the intervals are sorted by ascending time. Possible - * TODO to modify the logic above and ensure this is true. - */ - if (isOpenNow) { - if (todaysIntervalCount == 1) { - hoursInfo.detail = getTimeSpanStringForHours(openingHours.get(0)); - } else if (todaysIntervalCount == 2) { - hoursInfo.detail = mContext.getString( - R.string.opening_hours, - getTimeSpanStringForHours(openingHours.get(0)), - getTimeSpanStringForHours(openingHours.get(1))); - } else if (afterInterval < openingHours.size()) { - // This check should not be necessary since if it is currently open, we should not - // be after the last interval, but just in case, we don't want to crash. - hoursInfo.detail = mContext.getString( - R.string.closes_today_at, - getFormattedTimeForCalendar(openingHours.get(afterInterval).second)); - } - } else { // Currently closed - final int lastIntervalToday = todaysIntervalCount - 1; - if (todaysIntervalCount == 0) { // closed today - hoursInfo.detail = mContext.getString( - R.string.opens_tomorrow_at, - getFormattedTimeForCalendar(openingHours.get(0).first)); - } else if (currentTime.after(openingHours.get(lastIntervalToday).second)) { - // Passed hours for today - if (todaysIntervalCount < openingHours.size()) { - // If all of today's intervals are exhausted, assume the next are tomorrow's. - hoursInfo.detail = mContext.getString( - R.string.opens_tomorrow_at, - getFormattedTimeForCalendar( - openingHours.get(todaysIntervalCount).first)); - } else { - // Grab the last time it was open today. - hoursInfo.detail = mContext.getString( - R.string.closed_today_at, - getFormattedTimeForCalendar( - openingHours.get(lastIntervalToday).second)); - } - } else if (afterInterval < openingHours.size()) { - // This check should not be necessary since if it is currently before the last - // interval, afterInterval should be less than the count of intervals, but just in - // case, we don't want to crash. - hoursInfo.detail = mContext.getString( - R.string.opens_today_at, - getFormattedTimeForCalendar(openingHours.get(afterInterval).first)); - } - } - - return hoursInfo; - } - - String getFormattedTimeForCalendar(Calendar calendar) { - return DateFormat.getTimeFormat(mContext).format(calendar.getTime()); - } - - String getTimeSpanStringForHours(Pair hours) { - return mContext.getString(R.string.open_time_span, - getFormattedTimeForCalendar(hours.first), - getFormattedTimeForCalendar(hours.second)); - } - - /** - * Construct a BusinessContextInfo object with the location information of the business. - * The format is: - * [Straight line distance in miles or kilometers] - * [Address without state/country/etc.] - * - * @param address An Address object containing address details of the business - * @param distance The distance to the location in meters - * @return A BusinessContextInfo object with the location icon, the heading as the distance to - * the business and the details containing the address. - */ - private BusinessContextInfo constructLocationInfo(Address address, float distance) { - return constructLocationInfo(Locale.getDefault(), address, distance); - } - - @VisibleForTesting - BusinessContextInfo constructLocationInfo(Locale locale, Address address, - float distance) { - if (address == null) { - return null; - } - - BusinessContextInfo locationInfo = new BusinessContextInfo(); - locationInfo.iconId = R.drawable.ic_location_on_white_24dp; - if (distance != DistanceHelper.DISTANCE_NOT_FOUND) { - //TODO: add a setting to allow the user to select "KM" or "MI" as their distance units. - if (Locale.US.equals(locale)) { - locationInfo.heading = mContext.getString(R.string.distance_imperial_away, - distance * DistanceHelper.MILES_PER_METER); - } else { - locationInfo.heading = mContext.getString(R.string.distance_metric_away, - distance * DistanceHelper.KILOMETERS_PER_METER); - } - } - if (address.getLocality() != null) { - locationInfo.detail = mContext.getString( - R.string.display_address, - address.getAddressLine(0), - address.getLocality()); - } else { - locationInfo.detail = address.getAddressLine(0); - } - return locationInfo; - } - - /** - * Get the appropriate title for the context. - * @return The "Business info" title for a business contact and the "Recent messages" title for - * personal contacts. - */ - public String getContactContextTitle() { - return mIsBusiness - ? mContext.getResources().getString(R.string.business_contact_context_title) - : mContext.getResources().getString(R.string.person_contact_context_title); - } - - public static abstract class ContactContextInfo { - public abstract void bindView(View listItem); - } - - public static class BusinessContextInfo extends ContactContextInfo { - int iconId; - String heading; - String detail; - - @Override - public void bindView(View listItem) { - ImageView imageView = (ImageView) listItem.findViewById(R.id.icon); - TextView headingTextView = (TextView) listItem.findViewById(R.id.heading); - TextView detailTextView = (TextView) listItem.findViewById(R.id.detail); - - if (this.iconId == 0 || (this.heading == null && this.detail == null)) { - return; - } - - imageView.setImageDrawable(listItem.getContext().getDrawable(this.iconId)); - - headingTextView.setText(this.heading); - headingTextView.setVisibility(TextUtils.isEmpty(this.heading) - ? View.GONE : View.VISIBLE); - - detailTextView.setText(this.detail); - detailTextView.setVisibility(TextUtils.isEmpty(this.detail) - ? View.GONE : View.VISIBLE); - - } - } - - public static class PersonContextInfo extends ContactContextInfo { - boolean isIncoming; - String message; - String detail; - - @Override - public void bindView(View listItem) { - TextView messageTextView = (TextView) listItem.findViewById(R.id.message); - TextView detailTextView = (TextView) listItem.findViewById(R.id.detail); - - if (this.message == null || this.detail == null) { - return; - } - - messageTextView.setBackgroundResource(this.isIncoming ? - R.drawable.incoming_sms_background : R.drawable.outgoing_sms_background); - messageTextView.setText(this.message); - LayoutParams messageLayoutParams = (LayoutParams) messageTextView.getLayoutParams(); - messageLayoutParams.addRule(this.isIncoming? - RelativeLayout.ALIGN_PARENT_START : RelativeLayout.ALIGN_PARENT_END); - messageTextView.setLayoutParams(messageLayoutParams); - - LayoutParams detailLayoutParams = (LayoutParams) detailTextView.getLayoutParams(); - detailLayoutParams.addRule(this.isIncoming ? - RelativeLayout.ALIGN_PARENT_START : RelativeLayout.ALIGN_PARENT_END); - detailTextView.setLayoutParams(detailLayoutParams); - detailTextView.setText(this.detail); - } - } - - /** - * A list adapter for call context information. We use the same adapter for both business and - * contact context. - */ - private class InCallContactInteractionsListAdapter extends ArrayAdapter { - // The resource id of the list item layout. - int mResId; - - public InCallContactInteractionsListAdapter(Context context, int resource) { - super(context, resource); - mResId = resource; - } - - @Override - public View getView(int position, View convertView, ViewGroup parent) { - View listItem = mInflater.inflate(mResId, null); - ContactContextInfo item = getItem(position); - - if (item == null) { - return listItem; - } - - item.bindView(listItem); - return listItem; - } - } -} diff --git a/InCallUI/src/com/android/incallui/InCallDateUtils.java b/InCallUI/src/com/android/incallui/InCallDateUtils.java deleted file mode 100644 index 3401692ea..000000000 --- a/InCallUI/src/com/android/incallui/InCallDateUtils.java +++ /dev/null @@ -1,53 +0,0 @@ -package com.android.incallui; - -import android.icu.text.MeasureFormat; -import android.icu.text.MeasureFormat.FormatWidth; -import android.icu.util.Measure; -import android.icu.util.MeasureUnit; - -import java.util.ArrayList; -import java.util.Locale; - -/** - * Methods to parse time and date information in the InCallUi - */ -public class InCallDateUtils { - - /** - * Return given duration in a human-friendly format. For example, "4 minutes 3 seconds" or - * "3 hours 1 second". Returns the hours, minutes and seconds in that order if they exist. - */ - public static String formatDuration(long millis) { - int hours = 0; - int minutes = 0; - int seconds = 0; - int elapsedSeconds = (int) (millis / 1000); - if (elapsedSeconds >= 3600) { - hours = elapsedSeconds / 3600; - elapsedSeconds -= hours * 3600; - } - if (elapsedSeconds >= 60) { - minutes = elapsedSeconds / 60; - elapsedSeconds -= minutes * 60; - } - seconds = elapsedSeconds; - - final ArrayList measures = new ArrayList(); - if (hours > 0) { - measures.add(new Measure(hours, MeasureUnit.HOUR)); - } - if (minutes > 0) { - measures.add(new Measure(minutes, MeasureUnit.MINUTE)); - } - if (seconds > 0) { - measures.add(new Measure(seconds, MeasureUnit.SECOND)); - } - - if (measures.isEmpty()) { - return ""; - } else { - return MeasureFormat.getInstance(Locale.getDefault(), FormatWidth.WIDE) - .formatMeasures(measures.toArray(new Measure[measures.size()])); - } - } -} diff --git a/InCallUI/src/com/android/incallui/InCallOrientationEventListener.java b/InCallUI/src/com/android/incallui/InCallOrientationEventListener.java deleted file mode 100644 index 3cab6dc3b..000000000 --- a/InCallUI/src/com/android/incallui/InCallOrientationEventListener.java +++ /dev/null @@ -1,178 +0,0 @@ -/* - * Copyright (C) 2015 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.content.Context; -import android.content.res.Configuration; -import android.view.OrientationEventListener; -import android.hardware.SensorManager; -import android.view.Surface; -import android.content.pm.ActivityInfo; - -/** - * This class listens to Orientation events and overrides onOrientationChanged which gets - * invoked when an orientation change occurs. When that happens, we notify InCallUI registrants - * of the change. - */ -public class InCallOrientationEventListener extends OrientationEventListener { - - /** - * Screen orientation angles one of 0, 90, 180, 270, 360 in degrees. - */ - public static int SCREEN_ORIENTATION_0 = 0; - public static int SCREEN_ORIENTATION_90 = 90; - public static int SCREEN_ORIENTATION_180 = 180; - public static int SCREEN_ORIENTATION_270 = 270; - public static int SCREEN_ORIENTATION_360 = 360; - - public static int FULL_SENSOR_SCREEN_ORIENTATION = - ActivityInfo.SCREEN_ORIENTATION_FULL_SENSOR; - - public static int NO_SENSOR_SCREEN_ORIENTATION = - ActivityInfo.SCREEN_ORIENTATION_NOSENSOR; - - /** - * This is to identify dead zones where we won't notify others of orientation changed. - * Say for e.g our threshold is x degrees. We will only notify UI when our current rotation is - * within x degrees right or left of the screen orientation angles. If it's not within those - * ranges, we return SCREEN_ORIENTATION_UNKNOWN and ignore it. - */ - private static int SCREEN_ORIENTATION_UNKNOWN = -1; - - // Rotation threshold is 10 degrees. So if the rotation angle is within 10 degrees of any of - // the above angles, we will notify orientation changed. - private static int ROTATION_THRESHOLD = 10; - - - /** - * Cache the current rotation of the device. - */ - private static int sCurrentOrientation = SCREEN_ORIENTATION_0; - private boolean mEnabled = false; - - public InCallOrientationEventListener(Context context) { - super(context); - } - - /** - * Handles changes in device orientation. Notifies InCallPresenter of orientation changes. - * - * Note that this API receives sensor rotation in degrees as a param and we convert that to - * one of our screen orientation constants - (one of: {@link SCREEN_ORIENTATION_0}, - * {@link SCREEN_ORIENTATION_90}, {@link SCREEN_ORIENTATION_180}, - * {@link SCREEN_ORIENTATION_270}). - * - * @param rotation The new device sensor rotation in degrees - */ - @Override - public void onOrientationChanged(int rotation) { - if (rotation == OrientationEventListener.ORIENTATION_UNKNOWN) { - return; - } - - final int orientation = toScreenOrientation(rotation); - - if (orientation != SCREEN_ORIENTATION_UNKNOWN && sCurrentOrientation != orientation) { - sCurrentOrientation = orientation; - InCallPresenter.getInstance().onDeviceOrientationChange(sCurrentOrientation); - } - } - - /** - * Enables the OrientationEventListener and notifies listeners of current orientation if - * notify flag is true - * @param notify true or false. Notify device orientation changed if true. - */ - public void enable(boolean notify) { - if (mEnabled) { - Log.v(this, "enable: Orientation listener is already enabled. Ignoring..."); - return; - } - - super.enable(); - mEnabled = true; - if (notify) { - InCallPresenter.getInstance().onDeviceOrientationChange(sCurrentOrientation); - } - } - - /** - * Enables the OrientationEventListener with notify flag defaulting to false. - */ - public void enable() { - enable(false); - } - - /** - * Disables the OrientationEventListener. - */ - public void disable() { - if (!mEnabled) { - Log.v(this, "enable: Orientation listener is already disabled. Ignoring..."); - return; - } - - mEnabled = false; - super.disable(); - } - - /** - * Returns true the OrientationEventListener is enabled, false otherwise. - */ - public boolean isEnabled() { - return mEnabled; - } - - /** - * Converts sensor rotation in degrees to screen orientation constants. - * @param rotation sensor rotation angle in degrees - * @return Screen orientation angle in degrees (0, 90, 180, 270). Returns -1 for degrees not - * within threshold to identify zones where orientation change should not be trigerred. - */ - private int toScreenOrientation(int rotation) { - // Sensor orientation 90 is equivalent to screen orientation 270 and vice versa. This - // function returns the screen orientation. So we convert sensor rotation 90 to 270 and - // vice versa here. - if (isInLeftRange(rotation, SCREEN_ORIENTATION_360, ROTATION_THRESHOLD) || - isInRightRange(rotation, SCREEN_ORIENTATION_0, ROTATION_THRESHOLD)) { - return SCREEN_ORIENTATION_0; - } else if (isWithinThreshold(rotation, SCREEN_ORIENTATION_90, ROTATION_THRESHOLD)) { - return SCREEN_ORIENTATION_270; - } else if (isWithinThreshold(rotation, SCREEN_ORIENTATION_180, ROTATION_THRESHOLD)) { - return SCREEN_ORIENTATION_180; - } else if (isWithinThreshold(rotation, SCREEN_ORIENTATION_270, ROTATION_THRESHOLD)) { - return SCREEN_ORIENTATION_90; - } - return SCREEN_ORIENTATION_UNKNOWN; - } - - private static boolean isWithinRange(int value, int begin, int end) { - return value >= begin && value < end; - } - - private static boolean isWithinThreshold(int value, int center, int threshold) { - return isWithinRange(value, center - threshold, center + threshold); - } - - private static boolean isInLeftRange(int value, int center, int threshold) { - return isWithinRange(value, center - threshold, center); - } - - private static boolean isInRightRange(int value, int center, int threshold) { - return isWithinRange(value, center, center + threshold); - } -} diff --git a/InCallUI/src/com/android/incallui/InCallPresenter.java b/InCallUI/src/com/android/incallui/InCallPresenter.java deleted file mode 100644 index 0103f61ed..000000000 --- a/InCallUI/src/com/android/incallui/InCallPresenter.java +++ /dev/null @@ -1,1938 +0,0 @@ -/* - * Copyright (C) 2013 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.incallui; - -import com.google.common.base.Preconditions; - -import android.app.ActivityManager.TaskDescription; -import android.app.FragmentManager; -import android.content.Context; -import android.content.Intent; -import android.content.res.Resources; -import android.database.ContentObserver; -import android.graphics.Point; -import android.os.Bundle; -import android.os.Handler; -import android.os.SystemClock; -import android.provider.CallLog; -import android.telecom.DisconnectCause; -import android.telecom.PhoneAccount; -import android.telecom.PhoneAccountHandle; -import android.telecom.TelecomManager; -import android.telecom.VideoProfile; -import android.telephony.PhoneStateListener; -import android.telephony.TelephonyManager; -import android.text.TextUtils; -import android.view.View; -import android.view.Window; -import android.view.WindowManager; - -import com.android.contacts.common.GeoUtil; -import com.android.contacts.common.compat.CallSdkCompat; -import com.android.contacts.common.compat.CompatUtils; -import com.android.contacts.common.compat.telecom.TelecomManagerCompat; -import com.android.contacts.common.interactions.TouchPointManager; -import com.android.contacts.common.testing.NeededForTesting; -import com.android.contacts.common.util.MaterialColorMapUtils.MaterialPalette; -import com.android.dialer.R; -import com.android.dialer.calllog.CallLogAsyncTaskUtil; -import com.android.dialer.calllog.CallLogAsyncTaskUtil.OnCallLogQueryFinishedListener; -import com.android.dialer.database.FilteredNumberAsyncQueryHandler; -import com.android.dialer.database.FilteredNumberAsyncQueryHandler.OnCheckBlockedListener; -import com.android.dialer.filterednumber.FilteredNumbersUtil; -import com.android.dialer.logging.InteractionEvent; -import com.android.dialer.logging.Logger; -import com.android.dialer.util.TelecomUtil; -import com.android.incallui.spam.SpamCallListListener; -import com.android.incallui.util.TelecomCallUtil; -import com.android.incalluibind.ObjectFactory; - -import java.util.Collections; -import java.util.List; -import java.util.Locale; -import java.util.Set; -import java.util.concurrent.ConcurrentHashMap; -import java.util.concurrent.CopyOnWriteArrayList; -import java.util.concurrent.atomic.AtomicBoolean; - -/** - * Takes updates from the CallList and notifies the InCallActivity (UI) - * of the changes. - * Responsible for starting the activity for a new call and finishing the activity when all calls - * are disconnected. - * Creates and manages the in-call state and provides a listener pattern for the presenters - * that want to listen in on the in-call state changes. - * TODO: This class has become more of a state machine at this point. Consider renaming. - */ -public class InCallPresenter implements CallList.Listener, - CircularRevealFragment.OnCircularRevealCompleteListener, - InCallVideoCallCallbackNotifier.SessionModificationListener { - - private static final String EXTRA_FIRST_TIME_SHOWN = - "com.android.incallui.intent.extra.FIRST_TIME_SHOWN"; - - private static final long BLOCK_QUERY_TIMEOUT_MS = 1000; - - private static final Bundle EMPTY_EXTRAS = new Bundle(); - - private static InCallPresenter sInCallPresenter; - - /** - * ConcurrentHashMap constructor params: 8 is initial table size, 0.9f is - * load factor before resizing, 1 means we only expect a single thread to - * access the map so make only a single shard - */ - private final Set mListeners = Collections.newSetFromMap( - new ConcurrentHashMap(8, 0.9f, 1)); - private final List mIncomingCallListeners = new CopyOnWriteArrayList<>(); - private final Set mDetailsListeners = Collections.newSetFromMap( - new ConcurrentHashMap(8, 0.9f, 1)); - private final Set mCanAddCallListeners = Collections.newSetFromMap( - new ConcurrentHashMap(8, 0.9f, 1)); - private final Set mInCallUiListeners = Collections.newSetFromMap( - new ConcurrentHashMap(8, 0.9f, 1)); - private final Set mOrientationListeners = Collections.newSetFromMap( - new ConcurrentHashMap(8, 0.9f, 1)); - private final Set mInCallEventListeners = Collections.newSetFromMap( - new ConcurrentHashMap(8, 0.9f, 1)); - - private AudioModeProvider mAudioModeProvider; - private StatusBarNotifier mStatusBarNotifier; - private ExternalCallNotifier mExternalCallNotifier; - private ContactInfoCache mContactInfoCache; - private Context mContext; - private CallList mCallList; - private ExternalCallList mExternalCallList; - private InCallActivity mInCallActivity; - private InCallState mInCallState = InCallState.NO_CALLS; - private ProximitySensor mProximitySensor; - private boolean mServiceConnected = false; - private boolean mAccountSelectionCancelled = false; - private InCallCameraManager mInCallCameraManager = null; - private AnswerPresenter mAnswerPresenter = new AnswerPresenter(); - private FilteredNumberAsyncQueryHandler mFilteredQueryHandler; - private CallList.Listener mSpamCallListListener; - - /** - * Whether or not we are currently bound and waiting for Telecom to send us a new call. - */ - private boolean mBoundAndWaitingForOutgoingCall; - - /** - * If there is no actual call currently in the call list, this will be used as a fallback - * to determine the theme color for InCallUI. - */ - private PhoneAccountHandle mPendingPhoneAccountHandle; - - /** - * Determines if the InCall UI is in fullscreen mode or not. - */ - private boolean mIsFullScreen = false; - - private final android.telecom.Call.Callback mCallCallback = new android.telecom.Call.Callback() { - @Override - public void onPostDialWait(android.telecom.Call telecomCall, - String remainingPostDialSequence) { - final Call call = mCallList.getCallByTelecomCall(telecomCall); - if (call == null) { - Log.w(this, "Call not found in call list: " + telecomCall); - return; - } - onPostDialCharWait(call.getId(), remainingPostDialSequence); - } - - @Override - public void onDetailsChanged(android.telecom.Call telecomCall, - android.telecom.Call.Details details) { - final Call call = mCallList.getCallByTelecomCall(telecomCall); - if (call == null) { - Log.w(this, "Call not found in call list: " + telecomCall); - return; - } - for (InCallDetailsListener listener : mDetailsListeners) { - listener.onDetailsChanged(call, details); - } - } - - @Override - public void onConferenceableCallsChanged(android.telecom.Call telecomCall, - List conferenceableCalls) { - Log.i(this, "onConferenceableCallsChanged: " + telecomCall); - onDetailsChanged(telecomCall, telecomCall.getDetails()); - } - }; - - private PhoneStateListener mPhoneStateListener = new PhoneStateListener() { - public void onCallStateChanged(int state, String incomingNumber) { - if (state == TelephonyManager.CALL_STATE_RINGING) { - if (FilteredNumbersUtil.hasRecentEmergencyCall(mContext)) { - return; - } - // Check if the number is blocked, to silence the ringer. - String countryIso = GeoUtil.getCurrentCountryIso(mContext); - mFilteredQueryHandler.isBlockedNumber( - mOnCheckBlockedListener, incomingNumber, countryIso); - } - } - }; - - private final OnCheckBlockedListener mOnCheckBlockedListener = new OnCheckBlockedListener() { - @Override - public void onCheckComplete(final Integer id) { - if (id != null) { - // Silence the ringer now to prevent ringing and vibration before the call is - // terminated when Telecom attempts to add it. - TelecomUtil.silenceRinger(mContext); - } - } - }; - - /** - * Observes the CallLog to delete the call log entry for the blocked call after it is added. - * Times out if too much time has passed. - */ - private class BlockedNumberContentObserver extends ContentObserver { - private static final int TIMEOUT_MS = 5000; - - private Handler mHandler; - private String mNumber; - private long mTimeAddedMs; - - private Runnable mTimeoutRunnable = new Runnable() { - @Override - public void run() { - unregister(); - } - }; - - public BlockedNumberContentObserver(Handler handler, String number, long timeAddedMs) { - super(handler); - - mHandler = handler; - mNumber = number; - mTimeAddedMs = timeAddedMs; - } - - @Override - public void onChange(boolean selfChange) { - CallLogAsyncTaskUtil.deleteBlockedCall(mContext, mNumber, mTimeAddedMs, - new OnCallLogQueryFinishedListener() { - @Override - public void onQueryFinished(boolean hasEntry) { - if (mContext != null && hasEntry) { - unregister(); - } - } - }); - } - - public void register() { - if (mContext != null) { - mContext.getContentResolver().registerContentObserver( - CallLog.CONTENT_URI, true, this); - mHandler.postDelayed(mTimeoutRunnable, TIMEOUT_MS); - } - } - - private void unregister() { - if (mContext != null) { - mHandler.removeCallbacks(mTimeoutRunnable); - mContext.getContentResolver().unregisterContentObserver(this); - } - } - }; - - /** - * Is true when the activity has been previously started. Some code needs to know not just if - * the activity is currently up, but if it had been previously shown in foreground for this - * in-call session (e.g., StatusBarNotifier). This gets reset when the session ends in the - * tear-down method. - */ - private boolean mIsActivityPreviouslyStarted = false; - - /** - * Whether or not InCallService is bound to Telecom. - */ - private boolean mServiceBound = false; - - /** - * When configuration changes Android kills the current activity and starts a new one. - * The flag is used to check if full clean up is necessary (activity is stopped and new - * activity won't be started), or if a new activity will be started right after the current one - * is destroyed, and therefore no need in release all resources. - */ - private boolean mIsChangingConfigurations = false; - - /** Display colors for the UI. Consists of a primary color and secondary (darker) color */ - private MaterialPalette mThemeColors; - - private TelecomManager mTelecomManager; - private TelephonyManager mTelephonyManager; - - public static synchronized InCallPresenter getInstance() { - if (sInCallPresenter == null) { - sInCallPresenter = new InCallPresenter(); - } - return sInCallPresenter; - } - - @NeededForTesting - static synchronized void setInstance(InCallPresenter inCallPresenter) { - sInCallPresenter = inCallPresenter; - } - - public InCallState getInCallState() { - return mInCallState; - } - - public CallList getCallList() { - return mCallList; - } - - public void setUp(Context context, - CallList callList, - ExternalCallList externalCallList, - AudioModeProvider audioModeProvider, - StatusBarNotifier statusBarNotifier, - ExternalCallNotifier externalCallNotifier, - ContactInfoCache contactInfoCache, - ProximitySensor proximitySensor) { - if (mServiceConnected) { - Log.i(this, "New service connection replacing existing one."); - // retain the current resources, no need to create new ones. - Preconditions.checkState(context == mContext); - Preconditions.checkState(callList == mCallList); - Preconditions.checkState(audioModeProvider == mAudioModeProvider); - return; - } - - Preconditions.checkNotNull(context); - mContext = context; - - mContactInfoCache = contactInfoCache; - - mStatusBarNotifier = statusBarNotifier; - mExternalCallNotifier = externalCallNotifier; - addListener(mStatusBarNotifier); - - mAudioModeProvider = audioModeProvider; - - mProximitySensor = proximitySensor; - addListener(mProximitySensor); - - addIncomingCallListener(mAnswerPresenter); - addInCallUiListener(mAnswerPresenter); - - mCallList = callList; - mExternalCallList = externalCallList; - externalCallList.addExternalCallListener(mExternalCallNotifier); - - // This only gets called by the service so this is okay. - mServiceConnected = true; - - // The final thing we do in this set up is add ourselves as a listener to CallList. This - // will kick off an update and the whole process can start. - mCallList.addListener(this); - - // Create spam call list listener and add it to the list of listeners - mSpamCallListListener = new SpamCallListListener(context); - mCallList.addListener(mSpamCallListListener); - - VideoPauseController.getInstance().setUp(this); - InCallVideoCallCallbackNotifier.getInstance().addSessionModificationListener(this); - - mFilteredQueryHandler = new FilteredNumberAsyncQueryHandler(context.getContentResolver()); - mTelephonyManager = (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE); - mTelephonyManager.listen(mPhoneStateListener, PhoneStateListener.LISTEN_CALL_STATE); - mCallList.setExtendedCallInfoService( - com.android.dialerbind.ObjectFactory.newExtendedCallInfoService(context)); - - Log.d(this, "Finished InCallPresenter.setUp"); - } - - /** - * Called when the telephony service has disconnected from us. This will happen when there are - * no more active calls. However, we may still want to continue showing the UI for - * certain cases like showing "Call Ended". - * What we really want is to wait for the activity and the service to both disconnect before we - * tear things down. This method sets a serviceConnected boolean and calls a secondary method - * that performs the aforementioned logic. - */ - public void tearDown() { - Log.d(this, "tearDown"); - mCallList.clearOnDisconnect(); - - mServiceConnected = false; - attemptCleanup(); - - mTelephonyManager.listen(mPhoneStateListener, PhoneStateListener.LISTEN_NONE); - VideoPauseController.getInstance().tearDown(); - InCallVideoCallCallbackNotifier.getInstance().removeSessionModificationListener(this); - } - - private void attemptFinishActivity() { - final boolean doFinish = (mInCallActivity != null && isActivityStarted()); - Log.i(this, "Hide in call UI: " + doFinish); - if (doFinish) { - mInCallActivity.setExcludeFromRecents(true); - mInCallActivity.finish(); - - if (mAccountSelectionCancelled) { - // This finish is a result of account selection cancellation - // do not include activity ending transition - mInCallActivity.overridePendingTransition(0, 0); - } - } - } - - /** - * Called when the UI begins, and starts the callstate callbacks if necessary. - */ - public void setActivity(InCallActivity inCallActivity) { - if (inCallActivity == null) { - throw new IllegalArgumentException("registerActivity cannot be called with null"); - } - if (mInCallActivity != null && mInCallActivity != inCallActivity) { - Log.w(this, "Setting a second activity before destroying the first."); - } - updateActivity(inCallActivity); - } - - /** - * Called when the UI ends. Attempts to tear down everything if necessary. See - * {@link #tearDown()} for more insight on the tear-down process. - */ - public void unsetActivity(InCallActivity inCallActivity) { - if (inCallActivity == null) { - throw new IllegalArgumentException("unregisterActivity cannot be called with null"); - } - if (mInCallActivity == null) { - Log.i(this, "No InCallActivity currently set, no need to unset."); - return; - } - if (mInCallActivity != inCallActivity) { - Log.w(this, "Second instance of InCallActivity is trying to unregister when another" - + " instance is active. Ignoring."); - return; - } - updateActivity(null); - } - - /** - * Updates the current instance of {@link InCallActivity} with the provided one. If a - * {@code null} activity is provided, it means that the activity was finished and we should - * attempt to cleanup. - */ - private void updateActivity(InCallActivity inCallActivity) { - boolean updateListeners = false; - boolean doAttemptCleanup = false; - - if (inCallActivity != null) { - if (mInCallActivity == null) { - updateListeners = true; - Log.i(this, "UI Initialized"); - } else { - // since setActivity is called onStart(), it can be called multiple times. - // This is fine and ignorable, but we do not want to update the world every time - // this happens (like going to/from background) so we do not set updateListeners. - } - - mInCallActivity = inCallActivity; - mInCallActivity.setExcludeFromRecents(false); - - // By the time the UI finally comes up, the call may already be disconnected. - // If that's the case, we may need to show an error dialog. - if (mCallList != null && mCallList.getDisconnectedCall() != null) { - maybeShowErrorDialogOnDisconnect(mCallList.getDisconnectedCall()); - } - - // When the UI comes up, we need to first check the in-call state. - // If we are showing NO_CALLS, that means that a call probably connected and - // then immediately disconnected before the UI was able to come up. - // If we dont have any calls, start tearing down the UI instead. - // NOTE: This code relies on {@link #mInCallActivity} being set so we run it after - // it has been set. - if (mInCallState == InCallState.NO_CALLS) { - Log.i(this, "UI Initialized, but no calls left. shut down."); - attemptFinishActivity(); - return; - } - } else { - Log.i(this, "UI Destroyed"); - updateListeners = true; - mInCallActivity = null; - - // We attempt cleanup for the destroy case but only after we recalculate the state - // to see if we need to come back up or stay shut down. This is why we do the - // cleanup after the call to onCallListChange() instead of directly here. - doAttemptCleanup = true; - } - - // Messages can come from the telephony layer while the activity is coming up - // and while the activity is going down. So in both cases we need to recalculate what - // state we should be in after they complete. - // Examples: (1) A new incoming call could come in and then get disconnected before - // the activity is created. - // (2) All calls could disconnect and then get a new incoming call before the - // activity is destroyed. - // - // b/1122139 - We previously had a check for mServiceConnected here as well, but there are - // cases where we need to recalculate the current state even if the service in not - // connected. In particular the case where startOrFinish() is called while the app is - // already finish()ing. In that case, we skip updating the state with the knowledge that - // we will check again once the activity has finished. That means we have to recalculate the - // state here even if the service is disconnected since we may not have finished a state - // transition while finish()ing. - if (updateListeners) { - onCallListChange(mCallList); - } - - if (doAttemptCleanup) { - attemptCleanup(); - } - } - - private boolean mAwaitingCallListUpdate = false; - - public void onBringToForeground(boolean showDialpad) { - Log.i(this, "Bringing UI to foreground."); - bringToForeground(showDialpad); - } - - public void onCallAdded(final android.telecom.Call call) { - LatencyReport latencyReport = new LatencyReport(call); - if (shouldAttemptBlocking(call)) { - maybeBlockCall(call, latencyReport); - } else { - latencyReport.onCallBlockingDone(); - if (call.getDetails() - .hasProperty(CallSdkCompat.Details.PROPERTY_IS_EXTERNAL_CALL)) { - mExternalCallList.onCallAdded(call); - } else { - mCallList.onCallAdded(call, latencyReport); - } - } - - // Since a call has been added we are no longer waiting for Telecom to send us a call. - setBoundAndWaitingForOutgoingCall(false, null); - call.registerCallback(mCallCallback); - } - - private boolean shouldAttemptBlocking(android.telecom.Call call) { - if (call.getState() != android.telecom.Call.STATE_RINGING) { - return false; - } - if (TelecomCallUtil.isEmergencyCall(call)) { - Log.i(this, "Not attempting to block incoming emergency call"); - return false; - } - if (FilteredNumbersUtil.hasRecentEmergencyCall(mContext)) { - Log.i(this, "Not attempting to block incoming call due to recent emergency call"); - return false; - } - if (call.getDetails().hasProperty(CallSdkCompat.Details.PROPERTY_IS_EXTERNAL_CALL)) { - return false; - } - - return true; - } - - /** - * Checks whether a call should be blocked, and blocks it if so. Otherwise, it adds the call - * to the CallList so it can proceed as normal. There is a timeout, so if the function for - * checking whether a function is blocked does not return in a reasonable time, we proceed - * with adding the call anyways. - */ - private void maybeBlockCall(final android.telecom.Call call, - final LatencyReport latencyReport) { - final String countryIso = GeoUtil.getCurrentCountryIso(mContext); - final String number = TelecomCallUtil.getNumber(call); - final long timeAdded = System.currentTimeMillis(); - - // Though AtomicBoolean's can be scary, don't fear, as in this case it is only used on the - // main UI thread. It is needed so we can change its value within different scopes, since - // that cannot be done with a final boolean. - final AtomicBoolean hasTimedOut = new AtomicBoolean(false); - - final Handler handler = new Handler(); - - // Proceed if the query is slow; the call may still be blocked after the query returns. - final Runnable runnable = new Runnable() { - public void run() { - hasTimedOut.set(true); - latencyReport.onCallBlockingDone(); - mCallList.onCallAdded(call, latencyReport); - } - }; - handler.postDelayed(runnable, BLOCK_QUERY_TIMEOUT_MS); - - OnCheckBlockedListener onCheckBlockedListener = new OnCheckBlockedListener() { - @Override - public void onCheckComplete(final Integer id) { - if (!hasTimedOut.get()) { - handler.removeCallbacks(runnable); - } - if (id == null) { - if (!hasTimedOut.get()) { - latencyReport.onCallBlockingDone(); - mCallList.onCallAdded(call, latencyReport); - } - } else { - Log.i(this, "Rejecting incoming call from blocked number"); - call.reject(false, null); - Logger.logInteraction(InteractionEvent.CALL_BLOCKED); - - mFilteredQueryHandler.incrementFilteredCount(id); - - // Register observer to update the call log. - // BlockedNumberContentObserver will unregister after successful log or timeout. - BlockedNumberContentObserver contentObserver = - new BlockedNumberContentObserver(new Handler(), number, timeAdded); - contentObserver.register(); - } - } - }; - - final boolean success = mFilteredQueryHandler.isBlockedNumber( - onCheckBlockedListener, number, countryIso); - if (!success) { - Log.d(this, "checkForBlockedCall: invalid number, skipping block checking"); - if (!hasTimedOut.get()) { - handler.removeCallbacks(runnable); - - latencyReport.onCallBlockingDone(); - mCallList.onCallAdded(call, latencyReport); - } - } - } - - public void onCallRemoved(android.telecom.Call call) { - if (call.getDetails() - .hasProperty(CallSdkCompat.Details.PROPERTY_IS_EXTERNAL_CALL)) { - mExternalCallList.onCallRemoved(call); - } else { - mCallList.onCallRemoved(call); - call.unregisterCallback(mCallCallback); - } - } - - public void onCanAddCallChanged(boolean canAddCall) { - for (CanAddCallListener listener : mCanAddCallListeners) { - listener.onCanAddCallChanged(canAddCall); - } - } - - /** - * Called when there is a change to the call list. - * Sets the In-Call state for the entire in-call app based on the information it gets from - * CallList. Dispatches the in-call state to all listeners. Can trigger the creation or - * destruction of the UI based on the states that is calculates. - */ - @Override - public void onCallListChange(CallList callList) { - if (mInCallActivity != null && mInCallActivity.getCallCardFragment() != null && - mInCallActivity.getCallCardFragment().isAnimating()) { - mAwaitingCallListUpdate = true; - return; - } - if (callList == null) { - return; - } - - mAwaitingCallListUpdate = false; - - InCallState newState = getPotentialStateFromCallList(callList); - InCallState oldState = mInCallState; - Log.d(this, "onCallListChange oldState= " + oldState + " newState=" + newState); - newState = startOrFinishUi(newState); - Log.d(this, "onCallListChange newState changed to " + newState); - - // Set the new state before announcing it to the world - Log.i(this, "Phone switching state: " + oldState + " -> " + newState); - mInCallState = newState; - - // notify listeners of new state - for (InCallStateListener listener : mListeners) { - Log.d(this, "Notify " + listener + " of state " + mInCallState.toString()); - listener.onStateChange(oldState, mInCallState, callList); - } - - if (isActivityStarted()) { - final boolean hasCall = callList.getActiveOrBackgroundCall() != null || - callList.getOutgoingCall() != null; - mInCallActivity.dismissKeyguard(hasCall); - } - } - - /** - * Called when there is a new incoming call. - * - * @param call - */ - @Override - public void onIncomingCall(Call call) { - InCallState newState = startOrFinishUi(InCallState.INCOMING); - InCallState oldState = mInCallState; - - Log.i(this, "Phone switching state: " + oldState + " -> " + newState); - mInCallState = newState; - - for (IncomingCallListener listener : mIncomingCallListeners) { - listener.onIncomingCall(oldState, mInCallState, call); - } - } - - @Override - public void onUpgradeToVideo(Call call) { - //NO-OP - } - /** - * Called when a call becomes disconnected. Called everytime an existing call - * changes from being connected (incoming/outgoing/active) to disconnected. - */ - @Override - public void onDisconnect(Call call) { - maybeShowErrorDialogOnDisconnect(call); - - // We need to do the run the same code as onCallListChange. - onCallListChange(mCallList); - - if (isActivityStarted()) { - mInCallActivity.dismissKeyguard(false); - } - - if (call.isEmergencyCall()) { - FilteredNumbersUtil.recordLastEmergencyCallTime(mContext); - } - } - - @Override - public void onUpgradeToVideoRequest(Call call, int videoState) { - Log.d(this, "onUpgradeToVideoRequest call = " + call + " video state = " + videoState); - - if (call == null) { - return; - } - - call.setRequestedVideoState(videoState); - } - - /** - * Given the call list, return the state in which the in-call screen should be. - */ - public InCallState getPotentialStateFromCallList(CallList callList) { - - InCallState newState = InCallState.NO_CALLS; - - if (callList == null) { - return newState; - } - if (callList.getIncomingCall() != null) { - newState = InCallState.INCOMING; - } else if (callList.getWaitingForAccountCall() != null) { - newState = InCallState.WAITING_FOR_ACCOUNT; - } else if (callList.getPendingOutgoingCall() != null) { - newState = InCallState.PENDING_OUTGOING; - } else if (callList.getOutgoingCall() != null) { - newState = InCallState.OUTGOING; - } else if (callList.getActiveCall() != null || - callList.getBackgroundCall() != null || - callList.getDisconnectedCall() != null || - callList.getDisconnectingCall() != null) { - newState = InCallState.INCALL; - } - - if (newState == InCallState.NO_CALLS) { - if (mBoundAndWaitingForOutgoingCall) { - return InCallState.OUTGOING; - } - } - - return newState; - } - - public boolean isBoundAndWaitingForOutgoingCall() { - return mBoundAndWaitingForOutgoingCall; - } - - public void setBoundAndWaitingForOutgoingCall(boolean isBound, PhoneAccountHandle handle) { - // NOTE: It is possible for there to be a race and have handle become null before - // the circular reveal starts. This should not cause any problems because CallCardFragment - // should fallback to the actual call in the CallList at that point in time to determine - // the theme color. - Log.i(this, "setBoundAndWaitingForOutgoingCall: " + isBound); - mBoundAndWaitingForOutgoingCall = isBound; - mPendingPhoneAccountHandle = handle; - if (isBound && mInCallState == InCallState.NO_CALLS) { - mInCallState = InCallState.OUTGOING; - } - } - - @Override - public void onCircularRevealComplete(FragmentManager fm) { - if (mInCallActivity != null) { - mInCallActivity.showCallCardFragment(true); - mInCallActivity.getCallCardFragment().animateForNewOutgoingCall(); - CircularRevealFragment.endCircularReveal(mInCallActivity.getFragmentManager()); - } - } - - public void onShrinkAnimationComplete() { - if (mAwaitingCallListUpdate) { - onCallListChange(mCallList); - } - } - - public void addIncomingCallListener(IncomingCallListener listener) { - Preconditions.checkNotNull(listener); - mIncomingCallListeners.add(listener); - } - - public void removeIncomingCallListener(IncomingCallListener listener) { - if (listener != null) { - mIncomingCallListeners.remove(listener); - } - } - - public void addListener(InCallStateListener listener) { - Preconditions.checkNotNull(listener); - mListeners.add(listener); - } - - public void removeListener(InCallStateListener listener) { - if (listener != null) { - mListeners.remove(listener); - } - } - - public void addDetailsListener(InCallDetailsListener listener) { - Preconditions.checkNotNull(listener); - mDetailsListeners.add(listener); - } - - public void removeDetailsListener(InCallDetailsListener listener) { - if (listener != null) { - mDetailsListeners.remove(listener); - } - } - - public void addCanAddCallListener(CanAddCallListener listener) { - Preconditions.checkNotNull(listener); - mCanAddCallListeners.add(listener); - } - - public void removeCanAddCallListener(CanAddCallListener listener) { - if (listener != null) { - mCanAddCallListeners.remove(listener); - } - } - - public void addOrientationListener(InCallOrientationListener listener) { - Preconditions.checkNotNull(listener); - mOrientationListeners.add(listener); - } - - public void removeOrientationListener(InCallOrientationListener listener) { - if (listener != null) { - mOrientationListeners.remove(listener); - } - } - - public void addInCallEventListener(InCallEventListener listener) { - Preconditions.checkNotNull(listener); - mInCallEventListeners.add(listener); - } - - public void removeInCallEventListener(InCallEventListener listener) { - if (listener != null) { - mInCallEventListeners.remove(listener); - } - } - - public ProximitySensor getProximitySensor() { - return mProximitySensor; - } - - public void handleAccountSelection(PhoneAccountHandle accountHandle, boolean setDefault) { - if (mCallList != null) { - Call call = mCallList.getWaitingForAccountCall(); - if (call != null) { - String callId = call.getId(); - TelecomAdapter.getInstance().phoneAccountSelected(callId, accountHandle, setDefault); - } - } - } - - public void cancelAccountSelection() { - mAccountSelectionCancelled = true; - if (mCallList != null) { - Call call = mCallList.getWaitingForAccountCall(); - if (call != null) { - String callId = call.getId(); - TelecomAdapter.getInstance().disconnectCall(callId); - } - } - } - - /** - * Hangs up any active or outgoing calls. - */ - public void hangUpOngoingCall(Context context) { - // By the time we receive this intent, we could be shut down and call list - // could be null. Bail in those cases. - if (mCallList == null) { - if (mStatusBarNotifier == null) { - // The In Call UI has crashed but the notification still stayed up. We should not - // come to this stage. - StatusBarNotifier.clearAllCallNotifications(context); - } - return; - } - - Call call = mCallList.getOutgoingCall(); - if (call == null) { - call = mCallList.getActiveOrBackgroundCall(); - } - - if (call != null) { - TelecomAdapter.getInstance().disconnectCall(call.getId()); - call.setState(Call.State.DISCONNECTING); - mCallList.onUpdate(call); - } - } - - /** - * Answers any incoming call. - */ - public void answerIncomingCall(Context context, int videoState) { - // By the time we receive this intent, we could be shut down and call list - // could be null. Bail in those cases. - if (mCallList == null) { - StatusBarNotifier.clearAllCallNotifications(context); - return; - } - - Call call = mCallList.getIncomingCall(); - if (call != null) { - TelecomAdapter.getInstance().answerCall(call.getId(), videoState); - showInCall(false, false/* newOutgoingCall */); - } - } - - /** - * Declines any incoming call. - */ - public void declineIncomingCall(Context context) { - // By the time we receive this intent, we could be shut down and call list - // could be null. Bail in those cases. - if (mCallList == null) { - StatusBarNotifier.clearAllCallNotifications(context); - return; - } - - Call call = mCallList.getIncomingCall(); - if (call != null) { - TelecomAdapter.getInstance().rejectCall(call.getId(), false, null); - } - } - - public void acceptUpgradeRequest(int videoState, Context context) { - Log.d(this, " acceptUpgradeRequest videoState " + videoState); - // Bail if we have been shut down and the call list is null. - if (mCallList == null) { - StatusBarNotifier.clearAllCallNotifications(context); - Log.e(this, " acceptUpgradeRequest mCallList is empty so returning"); - return; - } - - Call call = mCallList.getVideoUpgradeRequestCall(); - if (call != null) { - VideoProfile videoProfile = new VideoProfile(videoState); - call.getVideoCall().sendSessionModifyResponse(videoProfile); - call.setSessionModificationState(Call.SessionModificationState.NO_REQUEST); - } - } - - public void declineUpgradeRequest(Context context) { - Log.d(this, " declineUpgradeRequest"); - // Bail if we have been shut down and the call list is null. - if (mCallList == null) { - StatusBarNotifier.clearAllCallNotifications(context); - Log.e(this, " declineUpgradeRequest mCallList is empty so returning"); - return; - } - - Call call = mCallList.getVideoUpgradeRequestCall(); - if (call != null) { - VideoProfile videoProfile = - new VideoProfile(call.getVideoState()); - call.getVideoCall().sendSessionModifyResponse(videoProfile); - call.setSessionModificationState(Call.SessionModificationState.NO_REQUEST); - } - } - - /*package*/ - void declineUpgradeRequest() { - // Pass mContext if InCallActivity is destroyed. - // Ex: When user pressed back key while in active call and - // then modify request is received followed by MT call. - declineUpgradeRequest(mInCallActivity != null ? mInCallActivity : mContext); - } - - /** - * Returns true if the incall app is the foreground application. - */ - public boolean isShowingInCallUi() { - return (isActivityStarted() && mInCallActivity.isVisible()); - } - - /** - * Returns true if the activity has been created and is running. - * Returns true as long as activity is not destroyed or finishing. This ensures that we return - * true even if the activity is paused (not in foreground). - */ - public boolean isActivityStarted() { - return (mInCallActivity != null && - !mInCallActivity.isDestroyed() && - !mInCallActivity.isFinishing()); - } - - public boolean isActivityPreviouslyStarted() { - return mIsActivityPreviouslyStarted; - } - - /** - * Determines if the In-Call app is currently changing configuration. - * - * @return {@code true} if the In-Call app is changing configuration. - */ - public boolean isChangingConfigurations() { - return mIsChangingConfigurations; - } - - /** - * Tracks whether the In-Call app is currently in the process of changing configuration (i.e. - * screen orientation). - */ - /*package*/ - void updateIsChangingConfigurations() { - mIsChangingConfigurations = false; - if (mInCallActivity != null) { - mIsChangingConfigurations = mInCallActivity.isChangingConfigurations(); - } - Log.v(this, "updateIsChangingConfigurations = " + mIsChangingConfigurations); - } - - - /** - * Called when the activity goes in/out of the foreground. - */ - public void onUiShowing(boolean showing) { - // We need to update the notification bar when we leave the UI because that - // could trigger it to show again. - if (mStatusBarNotifier != null) { - mStatusBarNotifier.updateNotification(mInCallState, mCallList); - } - - if (mProximitySensor != null) { - mProximitySensor.onInCallShowing(showing); - } - - Intent broadcastIntent = ObjectFactory.getUiReadyBroadcastIntent(mContext); - if (broadcastIntent != null) { - broadcastIntent.putExtra(EXTRA_FIRST_TIME_SHOWN, !mIsActivityPreviouslyStarted); - - if (showing) { - Log.d(this, "Sending sticky broadcast: ", broadcastIntent); - mContext.sendStickyBroadcast(broadcastIntent); - } else { - Log.d(this, "Removing sticky broadcast: ", broadcastIntent); - mContext.removeStickyBroadcast(broadcastIntent); - } - } - - if (showing) { - mIsActivityPreviouslyStarted = true; - } else { - updateIsChangingConfigurations(); - } - - for (InCallUiListener listener : mInCallUiListeners) { - listener.onUiShowing(showing); - } - } - - public void addInCallUiListener(InCallUiListener listener) { - mInCallUiListeners.add(listener); - } - - public boolean removeInCallUiListener(InCallUiListener listener) { - return mInCallUiListeners.remove(listener); - } - - /*package*/ - void onActivityStarted() { - Log.d(this, "onActivityStarted"); - notifyVideoPauseController(true); - } - - /*package*/ - void onActivityStopped() { - Log.d(this, "onActivityStopped"); - notifyVideoPauseController(false); - } - - private void notifyVideoPauseController(boolean showing) { - Log.d(this, "notifyVideoPauseController: mIsChangingConfigurations=" + - mIsChangingConfigurations); - if (!mIsChangingConfigurations) { - VideoPauseController.getInstance().onUiShowing(showing); - } - } - - /** - * Brings the app into the foreground if possible. - */ - public void bringToForeground(boolean showDialpad) { - // Before we bring the incall UI to the foreground, we check to see if: - // 1. It is not currently in the foreground - // 2. We are in a state where we want to show the incall ui (i.e. there are calls to - // be displayed) - // If the activity hadn't actually been started previously, yet there are still calls - // present (e.g. a call was accepted by a bluetooth or wired headset), we want to - // bring it up the UI regardless. - if (!isShowingInCallUi() && mInCallState != InCallState.NO_CALLS) { - showInCall(showDialpad, false /* newOutgoingCall */); - } - } - - public void onPostDialCharWait(String callId, String chars) { - if (isActivityStarted()) { - mInCallActivity.showPostCharWaitDialog(callId, chars); - } - } - - /** - * Handles the green CALL key while in-call. - * @return true if we consumed the event. - */ - public boolean handleCallKey() { - Log.v(this, "handleCallKey"); - - // The green CALL button means either "Answer", "Unhold", or - // "Swap calls", or can be a no-op, depending on the current state - // of the Phone. - - /** - * INCOMING CALL - */ - final CallList calls = mCallList; - final Call incomingCall = calls.getIncomingCall(); - Log.v(this, "incomingCall: " + incomingCall); - - // (1) Attempt to answer a call - if (incomingCall != null) { - TelecomAdapter.getInstance().answerCall( - incomingCall.getId(), VideoProfile.STATE_AUDIO_ONLY); - return true; - } - - /** - * STATE_ACTIVE CALL - */ - final Call activeCall = calls.getActiveCall(); - if (activeCall != null) { - // TODO: This logic is repeated from CallButtonPresenter.java. We should - // consolidate this logic. - final boolean canMerge = activeCall.can( - android.telecom.Call.Details.CAPABILITY_MERGE_CONFERENCE); - final boolean canSwap = activeCall.can( - android.telecom.Call.Details.CAPABILITY_SWAP_CONFERENCE); - - Log.v(this, "activeCall: " + activeCall + ", canMerge: " + canMerge + - ", canSwap: " + canSwap); - - // (2) Attempt actions on conference calls - if (canMerge) { - TelecomAdapter.getInstance().merge(activeCall.getId()); - return true; - } else if (canSwap) { - TelecomAdapter.getInstance().swap(activeCall.getId()); - return true; - } - } - - /** - * BACKGROUND CALL - */ - final Call heldCall = calls.getBackgroundCall(); - if (heldCall != null) { - // We have a hold call so presumeable it will always support HOLD...but - // there is no harm in double checking. - final boolean canHold = heldCall.can(android.telecom.Call.Details.CAPABILITY_HOLD); - - Log.v(this, "heldCall: " + heldCall + ", canHold: " + canHold); - - // (4) unhold call - if (heldCall.getState() == Call.State.ONHOLD && canHold) { - TelecomAdapter.getInstance().unholdCall(heldCall.getId()); - return true; - } - } - - // Always consume hard keys - return true; - } - - /** - * A dialog could have prevented in-call screen from being previously finished. - * This function checks to see if there should be any UI left and if not attempts - * to tear down the UI. - */ - public void onDismissDialog() { - Log.i(this, "Dialog dismissed"); - if (mInCallState == InCallState.NO_CALLS) { - attemptFinishActivity(); - attemptCleanup(); - } - } - - /** - * Toggles whether the application is in fullscreen mode or not. - * - * @return {@code true} if in-call is now in fullscreen mode. - */ - public boolean toggleFullscreenMode() { - boolean isFullScreen = !mIsFullScreen; - Log.v(this, "toggleFullscreenMode = " + isFullScreen); - setFullScreen(isFullScreen); - return mIsFullScreen; - } - - /** - * Clears the previous fullscreen state. - */ - public void clearFullscreen() { - mIsFullScreen = false; - } - - /** - * Changes the fullscreen mode of the in-call UI. - * - * @param isFullScreen {@code true} if in-call should be in fullscreen mode, {@code false} - * otherwise. - */ - public void setFullScreen(boolean isFullScreen) { - setFullScreen(isFullScreen, false /* force */); - } - - /** - * Changes the fullscreen mode of the in-call UI. - * - * @param isFullScreen {@code true} if in-call should be in fullscreen mode, {@code false} - * otherwise. - * @param force {@code true} if fullscreen mode should be set regardless of its current state. - */ - public void setFullScreen(boolean isFullScreen, boolean force) { - Log.v(this, "setFullScreen = " + isFullScreen); - - // As a safeguard, ensure we cannot enter fullscreen if the dialpad is shown. - if (isDialpadVisible()) { - isFullScreen = false; - Log.v(this, "setFullScreen overridden as dialpad is shown = " + isFullScreen); - } - - if (mIsFullScreen == isFullScreen && !force) { - Log.v(this, "setFullScreen ignored as already in that state."); - return; - } - mIsFullScreen = isFullScreen; - notifyFullscreenModeChange(mIsFullScreen); - } - - /** - * @return {@code true} if the in-call ui is currently in fullscreen mode, {@code false} - * otherwise. - */ - public boolean isFullscreen() { - return mIsFullScreen; - } - - - /** - * Called by the {@link VideoCallPresenter} to inform of a change in full screen video status. - * - * @param isFullscreenMode {@code True} if entering full screen mode. - */ - public void notifyFullscreenModeChange(boolean isFullscreenMode) { - for (InCallEventListener listener : mInCallEventListeners) { - listener.onFullscreenModeChanged(isFullscreenMode); - } - } - - /** - * Called by the {@link CallCardPresenter} to inform of a change in visibility of the secondary - * caller info bar. - * - * @param isVisible {@code true} if the secondary caller info is visible, {@code false} - * otherwise. - * @param height the height of the secondary caller info bar. - */ - public void notifySecondaryCallerInfoVisibilityChanged(boolean isVisible, int height) { - for (InCallEventListener listener : mInCallEventListeners) { - listener.onSecondaryCallerInfoVisibilityChanged(isVisible, height); - } - } - - - /** - * For some disconnected causes, we show a dialog. This calls into the activity to show - * the dialog if appropriate for the call. - */ - private void maybeShowErrorDialogOnDisconnect(Call call) { - // For newly disconnected calls, we may want to show a dialog on specific error conditions - if (isActivityStarted() && call.getState() == Call.State.DISCONNECTED) { - if (call.getAccountHandle() == null && !call.isConferenceCall()) { - setDisconnectCauseForMissingAccounts(call); - } - mInCallActivity.maybeShowErrorDialogOnDisconnect(call.getDisconnectCause()); - } - } - - /** - * When the state of in-call changes, this is the first method to get called. It determines if - * the UI needs to be started or finished depending on the new state and does it. - */ - private InCallState startOrFinishUi(InCallState newState) { - Log.d(this, "startOrFinishUi: " + mInCallState + " -> " + newState); - - // TODO: Consider a proper state machine implementation - - // If the state isn't changing we have already done any starting/stopping of activities in - // a previous pass...so lets cut out early - if (newState == mInCallState) { - return newState; - } - - // A new Incoming call means that the user needs to be notified of the the call (since - // it wasn't them who initiated it). We do this through full screen notifications and - // happens indirectly through {@link StatusBarNotifier}. - // - // The process for incoming calls is as follows: - // - // 1) CallList - Announces existence of new INCOMING call - // 2) InCallPresenter - Gets announcement and calculates that the new InCallState - // - should be set to INCOMING. - // 3) InCallPresenter - This method is called to see if we need to start or finish - // the app given the new state. - // 4) StatusBarNotifier - Listens to InCallState changes. InCallPresenter calls - // StatusBarNotifier explicitly to issue a FullScreen Notification - // that will either start the InCallActivity or show the user a - // top-level notification dialog if the user is in an immersive app. - // That notification can also start the InCallActivity. - // 5) InCallActivity - Main activity starts up and at the end of its onCreate will - // call InCallPresenter::setActivity() to let the presenter - // know that start-up is complete. - // - // [ AND NOW YOU'RE IN THE CALL. voila! ] - // - // Our app is started using a fullScreen notification. We need to do this whenever - // we get an incoming call. Depending on the current context of the device, either a - // incoming call HUN or the actual InCallActivity will be shown. - final boolean startIncomingCallSequence = (InCallState.INCOMING == newState); - - // A dialog to show on top of the InCallUI to select a PhoneAccount - final boolean showAccountPicker = (InCallState.WAITING_FOR_ACCOUNT == newState); - - // A new outgoing call indicates that the user just now dialed a number and when that - // happens we need to display the screen immediately or show an account picker dialog if - // no default is set. However, if the main InCallUI is already visible, we do not want to - // re-initiate the start-up animation, so we do not need to do anything here. - // - // It is also possible to go into an intermediate state where the call has been initiated - // but Telecom has not yet returned with the details of the call (handle, gateway, etc.). - // This pending outgoing state can also launch the call screen. - // - // This is different from the incoming call sequence because we do not need to shock the - // user with a top-level notification. Just show the call UI normally. - final boolean mainUiNotVisible = !isShowingInCallUi() || !getCallCardFragmentVisible(); - boolean showCallUi = InCallState.OUTGOING == newState && mainUiNotVisible; - - // Direct transition from PENDING_OUTGOING -> INCALL means that there was an error in the - // outgoing call process, so the UI should be brought up to show an error dialog. - showCallUi |= (InCallState.PENDING_OUTGOING == mInCallState - && InCallState.INCALL == newState && !isShowingInCallUi()); - - // Another exception - InCallActivity is in charge of disconnecting a call with no - // valid accounts set. Bring the UI up if this is true for the current pending outgoing - // call so that: - // 1) The call can be disconnected correctly - // 2) The UI comes up and correctly displays the error dialog. - // TODO: Remove these special case conditions by making InCallPresenter a true state - // machine. Telecom should also be the component responsible for disconnecting a call - // with no valid accounts. - showCallUi |= InCallState.PENDING_OUTGOING == newState && mainUiNotVisible - && isCallWithNoValidAccounts(mCallList.getPendingOutgoingCall()); - - // The only time that we have an instance of mInCallActivity and it isn't started is - // when it is being destroyed. In that case, lets avoid bringing up another instance of - // the activity. When it is finally destroyed, we double check if we should bring it back - // up so we aren't going to lose anything by avoiding a second startup here. - boolean activityIsFinishing = mInCallActivity != null && !isActivityStarted(); - if (activityIsFinishing) { - Log.i(this, "Undo the state change: " + newState + " -> " + mInCallState); - return mInCallState; - } - - if (showCallUi || showAccountPicker) { - Log.i(this, "Start in call UI"); - showInCall(false /* showDialpad */, !showAccountPicker /* newOutgoingCall */); - } else if (startIncomingCallSequence) { - Log.i(this, "Start Full Screen in call UI"); - - // We're about the bring up the in-call UI for an incoming call. If we still have - // dialogs up, we need to clear them out before showing incoming screen. - if (isActivityStarted()) { - mInCallActivity.dismissPendingDialogs(); - } - if (!startUi(newState)) { - // startUI refused to start the UI. This indicates that it needed to restart the - // activity. When it finally restarts, it will call us back, so we do not actually - // change the state yet (we return mInCallState instead of newState). - return mInCallState; - } - } else if (newState == InCallState.NO_CALLS) { - // The new state is the no calls state. Tear everything down. - attemptFinishActivity(); - attemptCleanup(); - } - - return newState; - } - - /** - * Determines whether or not a call has no valid phone accounts that can be used to make the - * call with. Emergency calls do not require a phone account. - * - * @param call to check accounts for. - * @return {@code true} if the call has no call capable phone accounts set, {@code false} if - * the call contains a phone account that could be used to initiate it with, or is an emergency - * call. - */ - public static boolean isCallWithNoValidAccounts(Call call) { - if (call != null && !call.isEmergencyCall()) { - Bundle extras = call.getIntentExtras(); - - if (extras == null) { - extras = EMPTY_EXTRAS; - } - - final List phoneAccountHandles = extras - .getParcelableArrayList(android.telecom.Call.AVAILABLE_PHONE_ACCOUNTS); - - if ((call.getAccountHandle() == null && - (phoneAccountHandles == null || phoneAccountHandles.isEmpty()))) { - Log.i(InCallPresenter.getInstance(), "No valid accounts for call " + call); - return true; - } - } - return false; - } - - /** - * Sets the DisconnectCause for a call that was disconnected because it was missing a - * PhoneAccount or PhoneAccounts to select from. - * @param call - */ - private void setDisconnectCauseForMissingAccounts(Call call) { - android.telecom.Call telecomCall = call.getTelecomCall(); - - Bundle extras = telecomCall.getDetails().getIntentExtras(); - // Initialize the extras bundle to avoid NPE - if (extras == null) { - extras = new Bundle(); - } - - final List phoneAccountHandles = extras.getParcelableArrayList( - android.telecom.Call.AVAILABLE_PHONE_ACCOUNTS); - - if (phoneAccountHandles == null || phoneAccountHandles.isEmpty()) { - String scheme = telecomCall.getDetails().getHandle().getScheme(); - final String errorMsg = PhoneAccount.SCHEME_TEL.equals(scheme) ? - mContext.getString(R.string.callFailed_simError) : - mContext.getString(R.string.incall_error_supp_service_unknown); - DisconnectCause disconnectCause = - new DisconnectCause(DisconnectCause.ERROR, null, errorMsg, errorMsg); - call.setDisconnectCause(disconnectCause); - } - } - - private boolean startUi(InCallState inCallState) { - boolean isCallWaiting = mCallList.getActiveCall() != null && - mCallList.getIncomingCall() != null; - - // If the screen is off, we need to make sure it gets turned on for incoming calls. - // This normally works just fine thanks to FLAG_TURN_SCREEN_ON but that only works - // when the activity is first created. Therefore, to ensure the screen is turned on - // for the call waiting case, we finish() the current activity and start a new one. - // There should be no jank from this since the screen is already off and will remain so - // until our new activity is up. - - if (isCallWaiting) { - if (mProximitySensor.isScreenReallyOff() && isActivityStarted()) { - Log.i(this, "Restarting InCallActivity to turn screen on for call waiting"); - mInCallActivity.finish(); - // When the activity actually finishes, we will start it again if there are - // any active calls, so we do not need to start it explicitly here. Note, we - // actually get called back on this function to restart it. - - // We return false to indicate that we did not actually start the UI. - return false; - } else { - showInCall(false, false); - } - } else { - mStatusBarNotifier.updateNotification(inCallState, mCallList); - } - return true; - } - - /** - * Checks to see if both the UI is gone and the service is disconnected. If so, tear it all - * down. - */ - private void attemptCleanup() { - boolean shouldCleanup = (mInCallActivity == null && !mServiceConnected && - mInCallState == InCallState.NO_CALLS); - Log.i(this, "attemptCleanup? " + shouldCleanup); - - if (shouldCleanup) { - mIsActivityPreviouslyStarted = false; - mIsChangingConfigurations = false; - - // blow away stale contact info so that we get fresh data on - // the next set of calls - if (mContactInfoCache != null) { - mContactInfoCache.clearCache(); - } - mContactInfoCache = null; - - if (mProximitySensor != null) { - removeListener(mProximitySensor); - mProximitySensor.tearDown(); - } - mProximitySensor = null; - - mAudioModeProvider = null; - - if (mStatusBarNotifier != null) { - removeListener(mStatusBarNotifier); - } - if (mExternalCallNotifier != null && mExternalCallList != null) { - mExternalCallList.removeExternalCallListener(mExternalCallNotifier); - } - mStatusBarNotifier = null; - - if (mCallList != null) { - mCallList.removeListener(this); - mCallList.removeListener(mSpamCallListListener); - } - mCallList = null; - - mContext = null; - mInCallActivity = null; - - mListeners.clear(); - mIncomingCallListeners.clear(); - mDetailsListeners.clear(); - mCanAddCallListeners.clear(); - mOrientationListeners.clear(); - mInCallEventListeners.clear(); - - Log.d(this, "Finished InCallPresenter.CleanUp"); - } - } - - public void showInCall(final boolean showDialpad, final boolean newOutgoingCall) { - Log.i(this, "Showing InCallActivity"); - mContext.startActivity(getInCallIntent(showDialpad, newOutgoingCall)); - } - - public void onServiceBind() { - mServiceBound = true; - } - - public void onServiceUnbind() { - InCallPresenter.getInstance().setBoundAndWaitingForOutgoingCall(false, null); - mServiceBound = false; - } - - public boolean isServiceBound() { - return mServiceBound; - } - - public void maybeStartRevealAnimation(Intent intent) { - if (intent == null || mInCallActivity != null) { - return; - } - final Bundle extras = intent.getBundleExtra(TelecomManager.EXTRA_OUTGOING_CALL_EXTRAS); - if (extras == null) { - // Incoming call, just show the in-call UI directly. - return; - } - - if (extras.containsKey(android.telecom.Call.AVAILABLE_PHONE_ACCOUNTS)) { - // Account selection dialog will show up so don't show the animation. - return; - } - - final PhoneAccountHandle accountHandle = - intent.getParcelableExtra(TelecomManager.EXTRA_PHONE_ACCOUNT_HANDLE); - final Point touchPoint = extras.getParcelable(TouchPointManager.TOUCH_POINT); - - InCallPresenter.getInstance().setBoundAndWaitingForOutgoingCall(true, accountHandle); - - final Intent incallIntent = getInCallIntent(false, true); - incallIntent.putExtra(TouchPointManager.TOUCH_POINT, touchPoint); - mContext.startActivity(incallIntent); - } - - public Intent getInCallIntent(boolean showDialpad, boolean newOutgoingCall) { - final Intent intent = new Intent(Intent.ACTION_MAIN, null); - intent.setFlags(Intent.FLAG_ACTIVITY_NO_USER_ACTION | Intent.FLAG_ACTIVITY_NEW_TASK); - - intent.setClass(mContext, InCallActivity.class); - if (showDialpad) { - intent.putExtra(InCallActivity.SHOW_DIALPAD_EXTRA, true); - } - intent.putExtra(InCallActivity.NEW_OUTGOING_CALL_EXTRA, newOutgoingCall); - return intent; - } - - /** - * Retrieves the current in-call camera manager instance, creating if necessary. - * - * @return The {@link InCallCameraManager}. - */ - public InCallCameraManager getInCallCameraManager() { - synchronized(this) { - if (mInCallCameraManager == null) { - mInCallCameraManager = new InCallCameraManager(mContext); - } - - return mInCallCameraManager; - } - } - - /** - * Notifies listeners of changes in orientation and notify calls of rotation angle change. - * - * @param orientation The screen orientation of the device (one of: - * {@link InCallOrientationEventListener#SCREEN_ORIENTATION_0}, - * {@link InCallOrientationEventListener#SCREEN_ORIENTATION_90}, - * {@link InCallOrientationEventListener#SCREEN_ORIENTATION_180}, - * {@link InCallOrientationEventListener#SCREEN_ORIENTATION_270}). - */ - public void onDeviceOrientationChange(int orientation) { - Log.d(this, "onDeviceOrientationChange: orientation= " + orientation); - - if (mCallList != null) { - mCallList.notifyCallsOfDeviceRotation(orientation); - } else { - Log.w(this, "onDeviceOrientationChange: CallList is null."); - } - - // Notify listeners of device orientation changed. - for (InCallOrientationListener listener : mOrientationListeners) { - listener.onDeviceOrientationChanged(orientation); - } - } - - /** - * Configures the in-call UI activity so it can change orientations or not. Enables the - * orientation event listener if allowOrientationChange is true, disables it if false. - * - * @param allowOrientationChange {@code True} if the in-call UI can change between portrait - * and landscape. {@Code False} if the in-call UI should be locked in portrait. - */ - public void setInCallAllowsOrientationChange(boolean allowOrientationChange) { - if (mInCallActivity == null) { - Log.e(this, "InCallActivity is null. Can't set requested orientation."); - return; - } - - if (!allowOrientationChange) { - mInCallActivity.setRequestedOrientation( - InCallOrientationEventListener.NO_SENSOR_SCREEN_ORIENTATION); - } else { - // Using SCREEN_ORIENTATION_FULL_SENSOR allows for reverse-portrait orientation, where - // SCREEN_ORIENTATION_SENSOR does not. - mInCallActivity.setRequestedOrientation( - InCallOrientationEventListener.FULL_SENSOR_SCREEN_ORIENTATION); - } - mInCallActivity.enableInCallOrientationEventListener(allowOrientationChange); - } - - public void enableScreenTimeout(boolean enable) { - Log.v(this, "enableScreenTimeout: value=" + enable); - if (mInCallActivity == null) { - Log.e(this, "enableScreenTimeout: InCallActivity is null."); - return; - } - - final Window window = mInCallActivity.getWindow(); - if (enable) { - window.clearFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON); - } else { - window.addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON); - } - } - - /** - * Returns the space available beside the call card. - * - * @return The space beside the call card. - */ - public float getSpaceBesideCallCard() { - if (mInCallActivity != null && mInCallActivity.getCallCardFragment() != null) { - return mInCallActivity.getCallCardFragment().getSpaceBesideCallCard(); - } - return 0; - } - - /** - * Returns whether the call card fragment is currently visible. - * - * @return True if the call card fragment is visible. - */ - public boolean getCallCardFragmentVisible() { - if (mInCallActivity != null && mInCallActivity.getCallCardFragment() != null) { - return mInCallActivity.getCallCardFragment().isVisible(); - } - return false; - } - - /** - * Hides or shows the conference manager fragment. - * - * @param show {@code true} if the conference manager should be shown, {@code false} if it - * should be hidden. - */ - public void showConferenceCallManager(boolean show) { - if (mInCallActivity == null) { - return; - } - - mInCallActivity.showConferenceFragment(show); - } - - /** - * Determines if the dialpad is visible. - * - * @return {@code true} if the dialpad is visible, {@code false} otherwise. - */ - public boolean isDialpadVisible() { - if (mInCallActivity == null) { - return false; - } - return mInCallActivity.isDialpadVisible(); - } - - /** - * @return True if the application is currently running in a right-to-left locale. - */ - public static boolean isRtl() { - return TextUtils.getLayoutDirectionFromLocale(Locale.getDefault()) == - View.LAYOUT_DIRECTION_RTL; - } - - /** - * Extract background color from call object. The theme colors will include a primary color - * and a secondary color. - */ - public void setThemeColors() { - // This method will set the background to default if the color is PhoneAccount.NO_COLOR. - mThemeColors = getColorsFromCall(mCallList.getFirstCall()); - - if (mInCallActivity == null) { - return; - } - - final Resources resources = mInCallActivity.getResources(); - final int color; - if (resources.getBoolean(R.bool.is_layout_landscape)) { - // TODO use ResourcesCompat.getColor(Resources, int, Resources.Theme) when available - // {@link Resources#getColor(int)} used for compatibility - color = resources.getColor(R.color.statusbar_background_color); - } else { - color = mThemeColors.mSecondaryColor; - } - - mInCallActivity.getWindow().setStatusBarColor(color); - final TaskDescription td = new TaskDescription( - resources.getString(R.string.notification_ongoing_call), null, color); - mInCallActivity.setTaskDescription(td); - } - - /** - * @return A palette for colors to display in the UI. - */ - public MaterialPalette getThemeColors() { - return mThemeColors; - } - - private MaterialPalette getColorsFromCall(Call call) { - if (call == null) { - return getColorsFromPhoneAccountHandle(mPendingPhoneAccountHandle); - } else { - if (call.isSpam()) { - Resources resources = mContext.getResources(); - return new InCallUIMaterialColorMapUtils( - resources).calculatePrimaryAndSecondaryColor( - resources.getColor(R.color.incall_call_spam_background_color)); - } else { - return getColorsFromPhoneAccountHandle(call.getAccountHandle()); - } - } - } - - private MaterialPalette getColorsFromPhoneAccountHandle(PhoneAccountHandle phoneAccountHandle) { - int highlightColor = PhoneAccount.NO_HIGHLIGHT_COLOR; - if (phoneAccountHandle != null) { - final TelecomManager tm = getTelecomManager(); - - if (tm != null) { - final PhoneAccount account = - TelecomManagerCompat.getPhoneAccount(tm, phoneAccountHandle); - // For single-sim devices, there will be no selected highlight color, so the phone - // account will default to NO_HIGHLIGHT_COLOR. - if (account != null && CompatUtils.isLollipopMr1Compatible()) { - highlightColor = account.getHighlightColor(); - } - } - } - return new InCallUIMaterialColorMapUtils( - mContext.getResources()).calculatePrimaryAndSecondaryColor(highlightColor); - } - - /** - * @return An instance of TelecomManager. - */ - public TelecomManager getTelecomManager() { - if (mTelecomManager == null) { - mTelecomManager = (TelecomManager) - mContext.getSystemService(Context.TELECOM_SERVICE); - } - return mTelecomManager; - } - - /** - * @return An instance of TelephonyManager - */ - public TelephonyManager getTelephonyManager() { - return mTelephonyManager; - } - - InCallActivity getActivity() { - return mInCallActivity; - } - - AnswerPresenter getAnswerPresenter() { - return mAnswerPresenter; - } - - ExternalCallNotifier getExternalCallNotifier() { - return mExternalCallNotifier; - } - - /** - * Private constructor. Must use getInstance() to get this singleton. - */ - private InCallPresenter() { - } - - /** - * All the main states of InCallActivity. - */ - public enum InCallState { - // InCall Screen is off and there are no calls - NO_CALLS, - - // Incoming-call screen is up - INCOMING, - - // In-call experience is showing - INCALL, - - // Waiting for user input before placing outgoing call - WAITING_FOR_ACCOUNT, - - // UI is starting up but no call has been initiated yet. - // The UI is waiting for Telecom to respond. - PENDING_OUTGOING, - - // User is dialing out - OUTGOING; - - public boolean isIncoming() { - return (this == INCOMING); - } - - public boolean isConnectingOrConnected() { - return (this == INCOMING || - this == OUTGOING || - this == INCALL); - } - } - - /** - * Interface implemented by classes that need to know about the InCall State. - */ - public interface InCallStateListener { - // TODO: Enhance state to contain the call objects instead of passing CallList - public void onStateChange(InCallState oldState, InCallState newState, CallList callList); - } - - public interface IncomingCallListener { - public void onIncomingCall(InCallState oldState, InCallState newState, Call call); - } - - public interface CanAddCallListener { - public void onCanAddCallChanged(boolean canAddCall); - } - - public interface InCallDetailsListener { - public void onDetailsChanged(Call call, android.telecom.Call.Details details); - } - - public interface InCallOrientationListener { - public void onDeviceOrientationChanged(int orientation); - } - - /** - * Interface implemented by classes that need to know about events which occur within the - * In-Call UI. Used as a means of communicating between fragments that make up the UI. - */ - public interface InCallEventListener { - public void onFullscreenModeChanged(boolean isFullscreenMode); - public void onSecondaryCallerInfoVisibilityChanged(boolean isVisible, int height); - } - - public interface InCallUiListener { - void onUiShowing(boolean showing); - } -} diff --git a/InCallUI/src/com/android/incallui/InCallServiceImpl.java b/InCallUI/src/com/android/incallui/InCallServiceImpl.java deleted file mode 100644 index 1414bc51d..000000000 --- a/InCallUI/src/com/android/incallui/InCallServiceImpl.java +++ /dev/null @@ -1,100 +0,0 @@ -/* - * Copyright (C) 2014 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.content.Context; -import android.content.Intent; -import android.os.IBinder; -import android.telecom.Call; -import android.telecom.CallAudioState; -import android.telecom.InCallService; - -/** - * Used to receive updates about calls from the Telecom component. This service is bound to - * Telecom while there exist calls which potentially require UI. This includes ringing (incoming), - * dialing (outgoing), and active calls. When the last call is disconnected, Telecom will unbind to - * the service triggering InCallActivity (via CallList) to finish soon after. - */ -public class InCallServiceImpl extends InCallService { - - @Override - public void onCallAudioStateChanged(CallAudioState audioState) { - AudioModeProvider.getInstance().onAudioStateChanged(audioState.isMuted(), - audioState.getRoute(), audioState.getSupportedRouteMask()); - } - - @Override - public void onBringToForeground(boolean showDialpad) { - InCallPresenter.getInstance().onBringToForeground(showDialpad); - } - - @Override - public void onCallAdded(Call call) { - InCallPresenter.getInstance().onCallAdded(call); - } - - @Override - public void onCallRemoved(Call call) { - InCallPresenter.getInstance().onCallRemoved(call); - } - - @Override - public void onCanAddCallChanged(boolean canAddCall) { - InCallPresenter.getInstance().onCanAddCallChanged(canAddCall); - } - - @Override - public IBinder onBind(Intent intent) { - final Context context = getApplicationContext(); - final ContactInfoCache contactInfoCache = ContactInfoCache.getInstance(context); - InCallPresenter.getInstance().setUp( - getApplicationContext(), - CallList.getInstance(), - new ExternalCallList(), - AudioModeProvider.getInstance(), - new StatusBarNotifier(context, contactInfoCache), - new ExternalCallNotifier(context, contactInfoCache), - contactInfoCache, - new ProximitySensor( - context, - AudioModeProvider.getInstance(), - new AccelerometerListener(context)) - ); - InCallPresenter.getInstance().onServiceBind(); - InCallPresenter.getInstance().maybeStartRevealAnimation(intent); - TelecomAdapter.getInstance().setInCallService(this); - - return super.onBind(intent); - } - - @Override - public boolean onUnbind(Intent intent) { - super.onUnbind(intent); - - InCallPresenter.getInstance().onServiceUnbind(); - tearDown(); - - return false; - } - - private void tearDown() { - Log.v(this, "tearDown"); - // Tear down the InCall system - TelecomAdapter.getInstance().clearInCallService(); - InCallPresenter.getInstance().tearDown(); - } -} diff --git a/InCallUI/src/com/android/incallui/InCallServiceListener.java b/InCallUI/src/com/android/incallui/InCallServiceListener.java deleted file mode 100644 index 11a5b08ef..000000000 --- a/InCallUI/src/com/android/incallui/InCallServiceListener.java +++ /dev/null @@ -1,41 +0,0 @@ -/* - * Copyright (C) 2014 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.telecom.InCallService; - -/** - * Interface implemented by In-Call components that maintain a reference to the Telecom API - * {@code InCallService} object. Clarifies the expectations associated with the relevant method - * calls. - */ -public interface InCallServiceListener { - - /** - * Called once at {@code InCallService} startup time with a valid instance. At - * that time, there will be no existing {@code Call}s. - * - * @param inCallService The {@code InCallService} object. - */ - void setInCallService(InCallService inCallService); - - /** - * Called once at {@code InCallService} shutdown time. At that time, any {@code Call}s - * will have transitioned through the disconnected state and will no longer exist. - */ - void clearInCallService(); -} diff --git a/InCallUI/src/com/android/incallui/InCallUIMaterialColorMapUtils.java b/InCallUI/src/com/android/incallui/InCallUIMaterialColorMapUtils.java deleted file mode 100644 index 9c108b855..000000000 --- a/InCallUI/src/com/android/incallui/InCallUIMaterialColorMapUtils.java +++ /dev/null @@ -1,55 +0,0 @@ -package com.android.incallui; - -import android.content.res.Resources; -import android.content.res.TypedArray; -import android.telecom.PhoneAccount; - -import com.android.contacts.common.util.MaterialColorMapUtils; -import com.android.contacts.common.util.MaterialColorMapUtils.MaterialPalette; -import com.android.dialer.R; - -public class InCallUIMaterialColorMapUtils extends MaterialColorMapUtils { - private final TypedArray sPrimaryColors; - private final TypedArray sSecondaryColors; - private final Resources mResources; - - public InCallUIMaterialColorMapUtils(Resources resources) { - super(resources); - sPrimaryColors = resources.obtainTypedArray(R.array.background_colors); - sSecondaryColors = resources.obtainTypedArray(R.array.background_colors_dark); - mResources = resources; - } - - /** - * Currently the InCallUI color will only vary by SIM color which is a list of colors - * defined in the background_colors array, so first search the list for the matching color and - * fall back to the closest matching color if an exact match does not exist. - */ - @Override - public MaterialPalette calculatePrimaryAndSecondaryColor(int color) { - if (color == PhoneAccount.NO_HIGHLIGHT_COLOR) { - return getDefaultPrimaryAndSecondaryColors(mResources); - } - - for (int i = 0; i < sPrimaryColors.length(); i++) { - if (sPrimaryColors.getColor(i, 0) == color) { - return new MaterialPalette( - sPrimaryColors.getColor(i, 0), - sSecondaryColors.getColor(i, 0)); - } - } - - // The color isn't in the list, so use the superclass to find an approximate color. - return super.calculatePrimaryAndSecondaryColor(color); - } - - /** - * {@link Resources#getColor(int) used for compatibility - */ - @SuppressWarnings("deprecation") - public static MaterialPalette getDefaultPrimaryAndSecondaryColors(Resources resources) { - final int primaryColor = resources.getColor(R.color.dialer_theme_color); - final int secondaryColor = resources.getColor(R.color.dialer_theme_color_dark); - return new MaterialPalette(primaryColor, secondaryColor); - } -} diff --git a/InCallUI/src/com/android/incallui/InCallVideoCallCallback.java b/InCallUI/src/com/android/incallui/InCallVideoCallCallback.java deleted file mode 100644 index 99e6d5129..000000000 --- a/InCallUI/src/com/android/incallui/InCallVideoCallCallback.java +++ /dev/null @@ -1,156 +0,0 @@ -/* - * Copyright (C) 2014 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.telecom.Connection; -import android.telecom.Connection.VideoProvider; -import android.telecom.InCallService.VideoCall; -import android.telecom.VideoProfile; -import android.telecom.VideoProfile.CameraCapabilities; - -/** - * Implements the InCallUI VideoCall Callback. - */ -public class InCallVideoCallCallback extends VideoCall.Callback { - - /** - * The call associated with this {@link InCallVideoCallCallback}. - */ - private Call mCall; - - /** - * Creates an instance of the call video client, specifying the call it is related to. - * - * @param call The call. - */ - public InCallVideoCallCallback(Call call) { - mCall = call; - } - - /** - * Handles an incoming session modification request. - * - * @param videoProfile The requested video call profile. - */ - @Override - public void onSessionModifyRequestReceived(VideoProfile videoProfile) { - Log.d(this, " onSessionModifyRequestReceived videoProfile=" + videoProfile); - int previousVideoState = VideoUtils.getUnPausedVideoState(mCall.getVideoState()); - int newVideoState = VideoUtils.getUnPausedVideoState(videoProfile.getVideoState()); - - boolean wasVideoCall = VideoUtils.isVideoCall(previousVideoState); - boolean isVideoCall = VideoUtils.isVideoCall(newVideoState); - - // Check for upgrades to video. - if (!wasVideoCall && isVideoCall && previousVideoState != newVideoState) { - InCallVideoCallCallbackNotifier.getInstance().upgradeToVideoRequest(mCall, - newVideoState); - } - } - - /** - * Handles a session modification response. - * - * @param status Status of the session modify request. Valid values are - * {@link Connection.VideoProvider#SESSION_MODIFY_REQUEST_SUCCESS}, - * {@link Connection.VideoProvider#SESSION_MODIFY_REQUEST_FAIL}, - * {@link Connection.VideoProvider#SESSION_MODIFY_REQUEST_INVALID} - * @param requestedProfile - * @param responseProfile The actual profile changes made by the peer device. - */ - @Override - public void onSessionModifyResponseReceived(int status, VideoProfile requestedProfile, - VideoProfile responseProfile) { - Log.d(this, "onSessionModifyResponseReceived status=" + status + " requestedProfile=" - + requestedProfile + " responseProfile=" + responseProfile); - if (status != VideoProvider.SESSION_MODIFY_REQUEST_SUCCESS) { - // Report the reason the upgrade failed as the new session modification state. - if (status == VideoProvider.SESSION_MODIFY_REQUEST_TIMED_OUT) { - mCall.setSessionModificationState( - Call.SessionModificationState.UPGRADE_TO_VIDEO_REQUEST_TIMED_OUT); - } else { - if (status == VideoProvider.SESSION_MODIFY_REQUEST_REJECTED_BY_REMOTE) { - mCall.setSessionModificationState( - Call.SessionModificationState.REQUEST_REJECTED); - } else { - mCall.setSessionModificationState( - Call.SessionModificationState.REQUEST_FAILED); - } - } - } - - // Finally clear the outstanding request. - mCall.setSessionModificationState(Call.SessionModificationState.NO_REQUEST); - } - - /** - * Handles a call session event. - * - * @param event The event. - */ - @Override - public void onCallSessionEvent(int event) { - InCallVideoCallCallbackNotifier.getInstance().callSessionEvent(event); - } - - /** - * Handles a change to the peer video dimensions. - * - * @param width The updated peer video width. - * @param height The updated peer video height. - */ - @Override - public void onPeerDimensionsChanged(int width, int height) { - InCallVideoCallCallbackNotifier.getInstance().peerDimensionsChanged(mCall, width, height); - } - - /** - * Handles a change to the video quality of the call. - * - * @param videoQuality The updated video call quality. - */ - @Override - public void onVideoQualityChanged(int videoQuality) { - InCallVideoCallCallbackNotifier.getInstance().videoQualityChanged(mCall, videoQuality); - } - - /** - * Handles a change to the call data usage. No implementation as the in-call UI does not - * display data usage. - * - * @param dataUsage The updated data usage. - */ - @Override - public void onCallDataUsageChanged(long dataUsage) { - Log.d(this, "onCallDataUsageChanged: dataUsage = " + dataUsage); - InCallVideoCallCallbackNotifier.getInstance().callDataUsageChanged(dataUsage); - } - - /** - * Handles changes to the camera capabilities. No implementation as the in-call UI does not - * make use of camera capabilities. - * - * @param cameraCapabilities The changed camera capabilities. - */ - @Override - public void onCameraCapabilitiesChanged(CameraCapabilities cameraCapabilities) { - if (cameraCapabilities != null) { - InCallVideoCallCallbackNotifier.getInstance().cameraDimensionsChanged( - mCall, cameraCapabilities.getWidth(), cameraCapabilities.getHeight()); - } - } -} diff --git a/InCallUI/src/com/android/incallui/InCallVideoCallCallbackNotifier.java b/InCallUI/src/com/android/incallui/InCallVideoCallCallbackNotifier.java deleted file mode 100644 index bb7529205..000000000 --- a/InCallUI/src/com/android/incallui/InCallVideoCallCallbackNotifier.java +++ /dev/null @@ -1,284 +0,0 @@ -/* - * Copyright (C) 2014 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 com.google.common.base.Preconditions; - -import java.util.Collections; -import java.util.Set; -import java.util.concurrent.ConcurrentHashMap; - -/** - * Class used by {@link InCallService.VideoCallCallback} to notify interested parties of incoming - * events. - */ -public class InCallVideoCallCallbackNotifier { - /** - * Singleton instance of this class. - */ - private static InCallVideoCallCallbackNotifier sInstance = - new InCallVideoCallCallbackNotifier(); - - /** - * ConcurrentHashMap constructor params: 8 is initial table size, 0.9f is - * load factor before resizing, 1 means we only expect a single thread to - * access the map so make only a single shard - */ - private final Set mSessionModificationListeners = - Collections.newSetFromMap(new ConcurrentHashMap - (8, 0.9f, 1)); - private final Set mVideoEventListeners = Collections.newSetFromMap( - new ConcurrentHashMap(8, 0.9f, 1)); - private final Set mSurfaceChangeListeners = Collections.newSetFromMap( - new ConcurrentHashMap(8, 0.9f, 1)); - - /** - * Static singleton accessor method. - */ - public static InCallVideoCallCallbackNotifier getInstance() { - return sInstance; - } - - /** - * Private constructor. Instance should only be acquired through getInstance(). - */ - private InCallVideoCallCallbackNotifier() { - } - - /** - * Adds a new {@link SessionModificationListener}. - * - * @param listener The listener. - */ - public void addSessionModificationListener(SessionModificationListener listener) { - Preconditions.checkNotNull(listener); - mSessionModificationListeners.add(listener); - } - - /** - * Remove a {@link SessionModificationListener}. - * - * @param listener The listener. - */ - public void removeSessionModificationListener(SessionModificationListener listener) { - if (listener != null) { - mSessionModificationListeners.remove(listener); - } - } - - /** - * Adds a new {@link VideoEventListener}. - * - * @param listener The listener. - */ - public void addVideoEventListener(VideoEventListener listener) { - Preconditions.checkNotNull(listener); - mVideoEventListeners.add(listener); - } - - /** - * Remove a {@link VideoEventListener}. - * - * @param listener The listener. - */ - public void removeVideoEventListener(VideoEventListener listener) { - if (listener != null) { - mVideoEventListeners.remove(listener); - } - } - - /** - * Adds a new {@link SurfaceChangeListener}. - * - * @param listener The listener. - */ - public void addSurfaceChangeListener(SurfaceChangeListener listener) { - Preconditions.checkNotNull(listener); - mSurfaceChangeListeners.add(listener); - } - - /** - * Remove a {@link SurfaceChangeListener}. - * - * @param listener The listener. - */ - public void removeSurfaceChangeListener(SurfaceChangeListener listener) { - if (listener != null) { - mSurfaceChangeListeners.remove(listener); - } - } - - /** - * Inform listeners of an upgrade to video request for a call. - * @param call The call. - * @param videoState The video state we want to upgrade to. - */ - public void upgradeToVideoRequest(Call call, int videoState) { - Log.d(this, "upgradeToVideoRequest call = " + call + " new video state = " + videoState); - for (SessionModificationListener listener : mSessionModificationListeners) { - listener.onUpgradeToVideoRequest(call, videoState); - } - } - - /** - * Inform listeners of a call session event. - * - * @param event The call session event. - */ - public void callSessionEvent(int event) { - for (VideoEventListener listener : mVideoEventListeners) { - listener.onCallSessionEvent(event); - } - } - - /** - * Inform listeners of a downgrade to audio. - * - * @param call The call. - * @param paused The paused state. - */ - public void peerPausedStateChanged(Call call, boolean paused) { - for (VideoEventListener listener : mVideoEventListeners) { - listener.onPeerPauseStateChanged(call, paused); - } - } - - /** - * Inform listeners of any change in the video quality of the call - * - * @param call The call. - * @param videoQuality The updated video quality of the call. - */ - public void videoQualityChanged(Call call, int videoQuality) { - for (VideoEventListener listener : mVideoEventListeners) { - listener.onVideoQualityChanged(call, videoQuality); - } - } - - /** - * Inform listeners of a change to peer dimensions. - * - * @param call The call. - * @param width New peer width. - * @param height New peer height. - */ - public void peerDimensionsChanged(Call call, int width, int height) { - for (SurfaceChangeListener listener : mSurfaceChangeListeners) { - listener.onUpdatePeerDimensions(call, width, height); - } - } - - /** - * Inform listeners of a change to camera dimensions. - * - * @param call The call. - * @param width The new camera video width. - * @param height The new camera video height. - */ - public void cameraDimensionsChanged(Call call, int width, int height) { - for (SurfaceChangeListener listener : mSurfaceChangeListeners) { - listener.onCameraDimensionsChange(call, width, height); - } - } - - /** - * Inform listeners of a change to call data usage. - * - * @param dataUsage data usage value - */ - public void callDataUsageChanged(long dataUsage) { - for (VideoEventListener listener : mVideoEventListeners) { - listener.onCallDataUsageChange(dataUsage); - } - } - - /** - * Listener interface for any class that wants to be notified of upgrade to video request. - */ - public interface SessionModificationListener { - /** - * Called when a peer request is received to upgrade an audio-only call to a video call. - * - * @param call The call the request was received for. - * @param videoState The requested video state. - */ - public void onUpgradeToVideoRequest(Call call, int videoState); - } - - /** - * Listener interface for any class that wants to be notified of video events, including pause - * and un-pause of peer video, video quality changes. - */ - public interface VideoEventListener { - /** - * Called when the peer pauses or un-pauses video transmission. - * - * @param call The call which paused or un-paused video transmission. - * @param paused {@code True} when the video transmission is paused, {@code false} - * otherwise. - */ - public void onPeerPauseStateChanged(Call call, boolean paused); - - /** - * Called when the video quality changes. - * - * @param call The call whose video quality changes. - * @param videoCallQuality - values are QUALITY_HIGH, MEDIUM, LOW and UNKNOWN. - */ - public void onVideoQualityChanged(Call call, int videoCallQuality); - - /* - * Called when call data usage value is requested or when call data usage value is updated - * because of a call state change - * - * @param dataUsage call data usage value - */ - public void onCallDataUsageChange(long dataUsage); - - /** - * Called when call session event is raised. - * - * @param event The call session event. - */ - public void onCallSessionEvent(int event); - } - - /** - * Listener interface for any class that wants to be notified of changes to the video surfaces. - */ - public interface SurfaceChangeListener { - /** - * Called when the peer video feed changes dimensions. This can occur when the peer rotates - * their device, changing the aspect ratio of the video signal. - * - * @param call The call which experienced a peer video - * @param width - * @param height - */ - public void onUpdatePeerDimensions(Call call, int width, int height); - - /** - * Called when the local camera changes dimensions. This occurs when a change in camera - * occurs. - * - * @param call The call which experienced the camera dimension change. - * @param width The new camera video width. - * @param height The new camera video height. - */ - public void onCameraDimensionsChange(Call call, int width, int height); - } -} diff --git a/InCallUI/src/com/android/incallui/LatencyReport.java b/InCallUI/src/com/android/incallui/LatencyReport.java deleted file mode 100644 index 655372a8f..000000000 --- a/InCallUI/src/com/android/incallui/LatencyReport.java +++ /dev/null @@ -1,145 +0,0 @@ -/* - * Copyright (C) 2016 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.os.Bundle; -import android.os.SystemClock; - -import com.android.incalluibind.ObjectFactory; - -/** - * Tracks latency information for a call. - */ -public class LatencyReport { - // The following are hidden constants from android.telecom.TelecomManager. - private static final String EXTRA_CALL_CREATED_TIME_MILLIS = - "android.telecom.extra.CALL_CREATED_TIME_MILLIS"; - private static final String EXTRA_CALL_TELECOM_ROUTING_START_TIME_MILLIS = - "android.telecom.extra.CALL_TELECOM_ROUTING_START_TIME_MILLIS"; - private static final String EXTRA_CALL_TELECOM_ROUTING_END_TIME_MILLIS = - "android.telecom.extra.CALL_TELECOM_ROUTING_END_TIME_MILLIS"; - - public static final long INVALID_TIME = -1; - - private final boolean mWasIncoming; - - // Time elapsed since boot when the call was created by the connection service. - private final long mCreatedTimeMillis; - - // Time elapsed since boot when telecom began processing the call. - private final long mTelecomRoutingStartTimeMillis; - - // Time elapsed since boot when telecom finished processing the call. This includes things like - // looking up contact info and call blocking but before showing any UI. - private final long mTelecomRoutingEndTimeMillis; - - // Time elapsed since boot when the call was added to the InCallUi. - private final long mCallAddedTimeMillis; - - // Time elapsed since boot when the call was added and call blocking evaluation was completed. - private long mCallBlockingTimeMillis = INVALID_TIME; - - // Time elapsed since boot when the call notification was shown. - private long mCallNotificationTimeMillis = INVALID_TIME; - - // Time elapsed since boot when the InCallUI was shown. - private long mInCallUiShownTimeMillis = INVALID_TIME; - - // Whether the call was shown to the user as a heads up notification instead of a full screen - // UI. - private boolean mDidDisplayHeadsUpNotification; - - public LatencyReport() { - mWasIncoming = false; - mCreatedTimeMillis = INVALID_TIME; - mTelecomRoutingStartTimeMillis = INVALID_TIME; - mTelecomRoutingEndTimeMillis = INVALID_TIME; - mCallAddedTimeMillis = SystemClock.elapsedRealtime(); - } - - public LatencyReport(android.telecom.Call telecomCall) { - mWasIncoming = telecomCall.getState() == android.telecom.Call.STATE_RINGING; - Bundle extras = telecomCall.getDetails().getIntentExtras(); - if (extras == null) { - mCreatedTimeMillis = INVALID_TIME; - mTelecomRoutingStartTimeMillis = INVALID_TIME; - mTelecomRoutingEndTimeMillis = INVALID_TIME; - } else { - mCreatedTimeMillis = extras.getLong(EXTRA_CALL_CREATED_TIME_MILLIS, INVALID_TIME); - mTelecomRoutingStartTimeMillis = extras.getLong( - EXTRA_CALL_TELECOM_ROUTING_START_TIME_MILLIS, INVALID_TIME); - mTelecomRoutingEndTimeMillis = extras.getLong( - EXTRA_CALL_TELECOM_ROUTING_END_TIME_MILLIS, INVALID_TIME); - } - mCallAddedTimeMillis = SystemClock.elapsedRealtime(); - } - - public boolean getWasIncoming() { - return mWasIncoming; - } - - public long getCreatedTimeMillis() { - return mCreatedTimeMillis; - } - - public long getTelecomRoutingStartTimeMillis() { - return mTelecomRoutingStartTimeMillis; - } - - public long getTelecomRoutingEndTimeMillis() { - return mTelecomRoutingEndTimeMillis; - } - - public long getCallAddedTimeMillis() { - return mCallAddedTimeMillis; - } - - public long getCallBlockingTimeMillis() { - return mCallBlockingTimeMillis; - } - - public void onCallBlockingDone() { - if (mCallBlockingTimeMillis == INVALID_TIME) { - mCallBlockingTimeMillis = SystemClock.elapsedRealtime(); - } - } - - public long getCallNotificationTimeMillis() { - return mCallNotificationTimeMillis; - } - - public void onNotificationShown() { - if (mCallNotificationTimeMillis == INVALID_TIME) { - mCallNotificationTimeMillis = SystemClock.elapsedRealtime(); - } - } - - public long getInCallUiShownTimeMillis() { - return mInCallUiShownTimeMillis; - } - - public void onInCallUiShown(boolean forFullScreenIntent) { - if (mInCallUiShownTimeMillis == INVALID_TIME) { - mInCallUiShownTimeMillis = SystemClock.elapsedRealtime(); - mDidDisplayHeadsUpNotification = mWasIncoming && !forFullScreenIntent; - } - } - - public boolean getDidDisplayHeadsUpNotification() { - return mDidDisplayHeadsUpNotification; - } -} diff --git a/InCallUI/src/com/android/incallui/Log.java b/InCallUI/src/com/android/incallui/Log.java deleted file mode 100644 index 07a0e61ca..000000000 --- a/InCallUI/src/com/android/incallui/Log.java +++ /dev/null @@ -1,176 +0,0 @@ -/* - * Copyright (C) 2013 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.incallui; - -import android.net.Uri; -import android.telecom.PhoneAccount; -import android.telephony.PhoneNumberUtils; - -import java.security.MessageDigest; -import java.security.NoSuchAlgorithmException; - -/** - * Manages logging for the entire class. - */ -public class Log { - - // Generic tag for all In Call logging - public static final String TAG = "InCall"; - - public static final boolean FORCE_DEBUG = false; /* STOPSHIP if true */ - public static final boolean DEBUG = FORCE_DEBUG || - android.util.Log.isLoggable(TAG, android.util.Log.DEBUG); - public static final boolean VERBOSE = FORCE_DEBUG || - android.util.Log.isLoggable(TAG, android.util.Log.VERBOSE); - public static final String TAG_DELIMETER = " - "; - - public static void d(String tag, String msg) { - if (DEBUG) { - android.util.Log.d(TAG, delimit(tag) + msg); - } - } - - public static void d(Object obj, String msg) { - if (DEBUG) { - android.util.Log.d(TAG, getPrefix(obj) + msg); - } - } - - public static void d(Object obj, String str1, Object str2) { - if (DEBUG) { - android.util.Log.d(TAG, getPrefix(obj) + str1 + str2); - } - } - - public static void v(Object obj, String msg) { - if (VERBOSE) { - android.util.Log.v(TAG, getPrefix(obj) + msg); - } - } - - public static void v(Object obj, String str1, Object str2) { - if (VERBOSE) { - android.util.Log.d(TAG, getPrefix(obj) + str1 + str2); - } - } - - public static void e(String tag, String msg, Exception e) { - android.util.Log.e(TAG, delimit(tag) + msg, e); - } - - public static void e(String tag, String msg) { - android.util.Log.e(TAG, delimit(tag) + msg); - } - - public static void e(Object obj, String msg, Exception e) { - android.util.Log.e(TAG, getPrefix(obj) + msg, e); - } - - public static void e(Object obj, String msg) { - android.util.Log.e(TAG, getPrefix(obj) + msg); - } - - public static void i(String tag, String msg) { - android.util.Log.i(TAG, delimit(tag) + msg); - } - - public static void i(Object obj, String msg) { - android.util.Log.i(TAG, getPrefix(obj) + msg); - } - - public static void w(Object obj, String msg) { - android.util.Log.w(TAG, getPrefix(obj) + msg); - } - - public static void wtf(Object obj, String msg) { - android.util.Log.wtf(TAG, getPrefix(obj) + msg); - } - - public static String piiHandle(Object pii) { - if (pii == null || VERBOSE) { - return String.valueOf(pii); - } - - if (pii instanceof Uri) { - Uri uri = (Uri) pii; - - // All Uri's which are not "tel" go through normal pii() method. - if (!PhoneAccount.SCHEME_TEL.equals(uri.getScheme())) { - return pii(pii); - } else { - pii = uri.getSchemeSpecificPart(); - } - } - - String originalString = String.valueOf(pii); - StringBuilder stringBuilder = new StringBuilder(originalString.length()); - for (char c : originalString.toCharArray()) { - if (PhoneNumberUtils.isDialable(c)) { - stringBuilder.append('*'); - } else { - stringBuilder.append(c); - } - } - return stringBuilder.toString(); - } - - /** - * Redact personally identifiable information for production users. - * If we are running in verbose mode, return the original string, otherwise - * return a SHA-1 hash of the input string. - */ - public static String pii(Object pii) { - if (pii == null || VERBOSE) { - return String.valueOf(pii); - } - return "[" + secureHash(String.valueOf(pii).getBytes()) + "]"; - } - - private static String secureHash(byte[] input) { - MessageDigest messageDigest; - try { - messageDigest = MessageDigest.getInstance("SHA-1"); - } catch (NoSuchAlgorithmException e) { - return null; - } - messageDigest.update(input); - byte[] result = messageDigest.digest(); - return encodeHex(result); - } - - private static String encodeHex(byte[] bytes) { - StringBuffer hex = new StringBuffer(bytes.length * 2); - - for (int i = 0; i < bytes.length; i++) { - int byteIntValue = bytes[i] & 0xff; - if (byteIntValue < 0x10) { - hex.append("0"); - } - hex.append(Integer.toString(byteIntValue, 16)); - } - - return hex.toString(); - } - - private static String getPrefix(Object obj) { - return (obj == null ? "" : (obj.getClass().getSimpleName() + TAG_DELIMETER)); - } - - private static String delimit(String tag) { - return tag + TAG_DELIMETER; - } -} diff --git a/InCallUI/src/com/android/incallui/NeededForReflection.java b/InCallUI/src/com/android/incallui/NeededForReflection.java deleted file mode 100644 index 363a0a548..000000000 --- a/InCallUI/src/com/android/incallui/NeededForReflection.java +++ /dev/null @@ -1,30 +0,0 @@ -/* - * Copyright (C) 2014 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 java.lang.annotation.ElementType; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.lang.annotation.Target; - -/** - * Denotes that the class, constructor, method or field is used for reflection and therefore cannot - * be removed by tools like ProGuard. - */ -@Retention(RetentionPolicy.CLASS) -@Target({ElementType.TYPE, ElementType.CONSTRUCTOR, ElementType.METHOD, ElementType.FIELD}) -public @interface NeededForReflection {} diff --git a/InCallUI/src/com/android/incallui/NotificationBroadcastReceiver.java b/InCallUI/src/com/android/incallui/NotificationBroadcastReceiver.java deleted file mode 100644 index 27f71159d..000000000 --- a/InCallUI/src/com/android/incallui/NotificationBroadcastReceiver.java +++ /dev/null @@ -1,82 +0,0 @@ -/* - * Copyright (C) 2015 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.content.BroadcastReceiver; -import android.content.Context; -import android.content.Intent; -import android.telecom.VideoProfile; - -/** - * Accepts broadcast Intents which will be prepared by {@link StatusBarNotifier} and thus - * sent from the notification manager. - * This should be visible from outside, but shouldn't be exported. - */ -public class NotificationBroadcastReceiver extends BroadcastReceiver { - - /** - * Intent Action used for hanging up the current call from Notification bar. This will - * choose first ringing call, first active call, or first background call (typically in - * STATE_HOLDING state). - */ - public static final String ACTION_DECLINE_INCOMING_CALL = - "com.android.incallui.ACTION_DECLINE_INCOMING_CALL"; - public static final String ACTION_HANG_UP_ONGOING_CALL = - "com.android.incallui.ACTION_HANG_UP_ONGOING_CALL"; - public static final String ACTION_ANSWER_VIDEO_INCOMING_CALL = - "com.android.incallui.ACTION_ANSWER_VIDEO_INCOMING_CALL"; - public static final String ACTION_ANSWER_VOICE_INCOMING_CALL = - "com.android.incallui.ACTION_ANSWER_VOICE_INCOMING_CALL"; - public static final String ACTION_ACCEPT_VIDEO_UPGRADE_REQUEST = - "com.android.incallui.ACTION_ACCEPT_VIDEO_UPGRADE_REQUEST"; - public static final String ACTION_DECLINE_VIDEO_UPGRADE_REQUEST = - "com.android.incallui.ACTION_DECLINE_VIDEO_UPGRADE_REQUEST"; - public static final String ACTION_PULL_EXTERNAL_CALL = - "com.android.incallui.ACTION_PULL_EXTERNAL_CALL"; - public static final String EXTRA_NOTIFICATION_ID = - "com.android.incallui.extra.EXTRA_NOTIFICATION_ID"; - - @Override - public void onReceive(Context context, Intent intent) { - final String action = intent.getAction(); - Log.i(this, "Broadcast from Notification: " + action); - - // TODO: Commands of this nature should exist in the CallList. - if (action.equals(ACTION_ANSWER_VIDEO_INCOMING_CALL)) { - InCallPresenter.getInstance().answerIncomingCall( - context, VideoProfile.STATE_BIDIRECTIONAL); - } else if (action.equals(ACTION_ANSWER_VOICE_INCOMING_CALL)) { - InCallPresenter.getInstance().answerIncomingCall( - context, VideoProfile.STATE_AUDIO_ONLY); - } else if (action.equals(ACTION_DECLINE_INCOMING_CALL)) { - InCallPresenter.getInstance().declineIncomingCall(context); - } else if (action.equals(ACTION_HANG_UP_ONGOING_CALL)) { - InCallPresenter.getInstance().hangUpOngoingCall(context); - } else if (action.equals(ACTION_ACCEPT_VIDEO_UPGRADE_REQUEST)) { - //TODO: Change calltype after adding support for TX and RX - InCallPresenter.getInstance().acceptUpgradeRequest( - VideoProfile.STATE_BIDIRECTIONAL, context); - } else if (action.equals(ACTION_DECLINE_VIDEO_UPGRADE_REQUEST)) { - InCallPresenter.getInstance().declineUpgradeRequest(context); - } else if (action.equals(ACTION_PULL_EXTERNAL_CALL)) { - int notificationId = intent.getIntExtra(EXTRA_NOTIFICATION_ID, -1); - InCallPresenter.getInstance().getExternalCallNotifier() - .pullExternalCall(notificationId); - } - } - -} diff --git a/InCallUI/src/com/android/incallui/PostCharDialogFragment.java b/InCallUI/src/com/android/incallui/PostCharDialogFragment.java deleted file mode 100644 index 6f904ad9e..000000000 --- a/InCallUI/src/com/android/incallui/PostCharDialogFragment.java +++ /dev/null @@ -1,95 +0,0 @@ -/* - * Copyright (C) 2013 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.incallui; - -import android.app.AlertDialog; -import android.app.Dialog; -import android.app.DialogFragment; -import android.content.DialogInterface; -import android.os.Bundle; -import android.view.WindowManager; - -import com.android.dialer.R; - -/** - * Pop up an alert dialog with OK and Cancel buttons to allow user to Accept or Reject the WAIT - * inserted as part of the Dial string. - */ -public class PostCharDialogFragment extends DialogFragment { - - private static final String STATE_CALL_ID = "CALL_ID"; - private static final String STATE_POST_CHARS = "POST_CHARS"; - - private String mCallId; - private String mPostDialStr; - - public PostCharDialogFragment() { - } - - public PostCharDialogFragment(String callId, String postDialStr) { - mCallId = callId; - mPostDialStr = postDialStr; - } - - @Override - public Dialog onCreateDialog(Bundle savedInstanceState) { - super.onCreateDialog(savedInstanceState); - - if (mPostDialStr == null && savedInstanceState != null) { - mCallId = savedInstanceState.getString(STATE_CALL_ID); - mPostDialStr = savedInstanceState.getString(STATE_POST_CHARS); - } - - final StringBuilder buf = new StringBuilder(); - buf.append(getResources().getText(R.string.wait_prompt_str)); - buf.append(mPostDialStr); - - final AlertDialog.Builder builder = new AlertDialog.Builder(getActivity()); - builder.setMessage(buf.toString()); - - builder.setPositiveButton(R.string.pause_prompt_yes, new DialogInterface.OnClickListener() { - @Override - public void onClick(DialogInterface dialog, int whichButton) { - TelecomAdapter.getInstance().postDialContinue(mCallId, true); - } - }); - builder.setNegativeButton(R.string.pause_prompt_no, new DialogInterface.OnClickListener() { - @Override - public void onClick(DialogInterface dialog, int whichButton) { - dialog.cancel(); - } - }); - - final AlertDialog dialog = builder.create(); - return dialog; - } - - @Override - public void onCancel(DialogInterface dialog) { - super.onCancel(dialog); - - TelecomAdapter.getInstance().postDialContinue(mCallId, false); - } - - @Override - public void onSaveInstanceState(Bundle outState) { - super.onSaveInstanceState(outState); - - outState.putString(STATE_CALL_ID, mCallId); - outState.putString(STATE_POST_CHARS, mPostDialStr); - } -} diff --git a/InCallUI/src/com/android/incallui/Presenter.java b/InCallUI/src/com/android/incallui/Presenter.java deleted file mode 100644 index 4e1fa978d..000000000 --- a/InCallUI/src/com/android/incallui/Presenter.java +++ /dev/null @@ -1,59 +0,0 @@ -/* - * Copyright (C) 2013 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License - */ - -package com.android.incallui; - -import android.os.Bundle; - -/** - * Base class for Presenters. - */ -public abstract class Presenter { - - private U mUi; - - /** - * Called after the UI view has been created. That is when fragment.onViewCreated() is called. - * - * @param ui The Ui implementation that is now ready to be used. - */ - public void onUiReady(U ui) { - mUi = ui; - } - - /** - * Called when the UI view is destroyed in Fragment.onDestroyView(). - */ - public final void onUiDestroy(U ui) { - onUiUnready(ui); - mUi = null; - } - - /** - * To be overriden by Presenter implementations. Called when the fragment is being - * destroyed but before ui is set to null. - */ - public void onUiUnready(U ui) { - } - - public void onSaveInstanceState(Bundle outState) {} - - public void onRestoreInstanceState(Bundle savedInstanceState) {} - - public U getUi() { - return mUi; - } -} diff --git a/InCallUI/src/com/android/incallui/ProximitySensor.java b/InCallUI/src/com/android/incallui/ProximitySensor.java deleted file mode 100644 index 3c9fd9370..000000000 --- a/InCallUI/src/com/android/incallui/ProximitySensor.java +++ /dev/null @@ -1,317 +0,0 @@ -/* - * Copyright (C) 2013 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License - */ - -package com.android.incallui; - -import com.google.common.base.Objects; - -import android.content.Context; -import android.content.res.Configuration; -import android.hardware.display.DisplayManager; -import android.hardware.display.DisplayManager.DisplayListener; -import android.os.PowerManager; -import android.telecom.CallAudioState; -import android.view.Display; - -import com.android.incallui.AudioModeProvider.AudioModeListener; -import com.android.incallui.InCallPresenter.InCallState; -import com.android.incallui.InCallPresenter.InCallStateListener; - -/** - * Class manages the proximity sensor for the in-call UI. - * We enable the proximity sensor while the user in a phone call. The Proximity sensor turns off - * the touchscreen and display when the user is close to the screen to prevent user's cheek from - * causing touch events. - * The class requires special knowledge of the activity and device state to know when the proximity - * sensor should be enabled and disabled. Most of that state is fed into this class through - * public methods. - */ -public class ProximitySensor implements AccelerometerListener.OrientationListener, - InCallStateListener, AudioModeListener { - private static final String TAG = ProximitySensor.class.getSimpleName(); - - private final PowerManager mPowerManager; - private final PowerManager.WakeLock mProximityWakeLock; - private final AudioModeProvider mAudioModeProvider; - private final AccelerometerListener mAccelerometerListener; - private final ProximityDisplayListener mDisplayListener; - private int mOrientation = AccelerometerListener.ORIENTATION_UNKNOWN; - private boolean mUiShowing = false; - private boolean mIsPhoneOffhook = false; - private boolean mDialpadVisible; - - // True if the keyboard is currently *not* hidden - // Gets updated whenever there is a Configuration change - private boolean mIsHardKeyboardOpen; - - public ProximitySensor(Context context, AudioModeProvider audioModeProvider, - AccelerometerListener accelerometerListener) { - mPowerManager = (PowerManager) context.getSystemService(Context.POWER_SERVICE); - if (mPowerManager.isWakeLockLevelSupported(PowerManager.PROXIMITY_SCREEN_OFF_WAKE_LOCK)) { - mProximityWakeLock = mPowerManager.newWakeLock( - PowerManager.PROXIMITY_SCREEN_OFF_WAKE_LOCK, TAG); - } else { - Log.w(TAG, "Device does not support proximity wake lock."); - mProximityWakeLock = null; - } - mAccelerometerListener = accelerometerListener; - mAccelerometerListener.setListener(this); - - mDisplayListener = new ProximityDisplayListener( - (DisplayManager) context.getSystemService(Context.DISPLAY_SERVICE)); - mDisplayListener.register(); - - mAudioModeProvider = audioModeProvider; - mAudioModeProvider.addListener(this); - } - - public void tearDown() { - mAudioModeProvider.removeListener(this); - - mAccelerometerListener.enable(false); - mDisplayListener.unregister(); - - turnOffProximitySensor(true); - } - - /** - * Called to identify when the device is laid down flat. - */ - @Override - public void orientationChanged(int orientation) { - mOrientation = orientation; - updateProximitySensorMode(); - } - - /** - * Called to keep track of the overall UI state. - */ - @Override - public void onStateChange(InCallState oldState, InCallState newState, CallList callList) { - // We ignore incoming state because we do not want to enable proximity - // sensor during incoming call screen. We check hasLiveCall() because a disconnected call - // can also put the in-call screen in the INCALL state. - boolean hasOngoingCall = InCallState.INCALL == newState && callList.hasLiveCall(); - boolean isOffhook = (InCallState.OUTGOING == newState) || hasOngoingCall; - - if (isOffhook != mIsPhoneOffhook) { - mIsPhoneOffhook = isOffhook; - - mOrientation = AccelerometerListener.ORIENTATION_UNKNOWN; - mAccelerometerListener.enable(mIsPhoneOffhook); - - updateProximitySensorMode(); - } - } - - @Override - public void onSupportedAudioMode(int modeMask) { - } - - @Override - public void onMute(boolean muted) { - } - - /** - * Called when the audio mode changes during a call. - */ - @Override - public void onAudioMode(int mode) { - updateProximitySensorMode(); - } - - public void onDialpadVisible(boolean visible) { - mDialpadVisible = visible; - updateProximitySensorMode(); - } - - /** - * Called by InCallActivity to listen for hard keyboard events. - */ - public void onConfigurationChanged(Configuration newConfig) { - mIsHardKeyboardOpen = newConfig.hardKeyboardHidden == Configuration.HARDKEYBOARDHIDDEN_NO; - - // Update the Proximity sensor based on keyboard state - updateProximitySensorMode(); - } - - /** - * Used to save when the UI goes in and out of the foreground. - */ - public void onInCallShowing(boolean showing) { - if (showing) { - mUiShowing = true; - - // We only consider the UI not showing for instances where another app took the foreground. - // If we stopped showing because the screen is off, we still consider that showing. - } else if (mPowerManager.isScreenOn()) { - mUiShowing = false; - } - updateProximitySensorMode(); - } - - void onDisplayStateChanged(boolean isDisplayOn) { - Log.i(this, "isDisplayOn: " + isDisplayOn); - mAccelerometerListener.enable(isDisplayOn); - } - - /** - * TODO: There is no way to determine if a screen is off due to proximity or if it is - * legitimately off, but if ever we can do that in the future, it would be useful here. - * Until then, this function will simply return true of the screen is off. - * TODO: Investigate whether this can be replaced with the ProximityDisplayListener. - */ - public boolean isScreenReallyOff() { - return !mPowerManager.isScreenOn(); - } - - private void turnOnProximitySensor() { - if (mProximityWakeLock != null) { - if (!mProximityWakeLock.isHeld()) { - Log.i(this, "Acquiring proximity wake lock"); - mProximityWakeLock.acquire(); - } else { - Log.i(this, "Proximity wake lock already acquired"); - } - } - } - - private void turnOffProximitySensor(boolean screenOnImmediately) { - if (mProximityWakeLock != null) { - if (mProximityWakeLock.isHeld()) { - Log.i(this, "Releasing proximity wake lock"); - int flags = - (screenOnImmediately ? 0 : PowerManager.RELEASE_FLAG_WAIT_FOR_NO_PROXIMITY); - mProximityWakeLock.release(flags); - } else { - Log.i(this, "Proximity wake lock already released"); - } - } - } - - /** - * Updates the wake lock used to control proximity sensor behavior, - * based on the current state of the phone. - * - * On devices that have a proximity sensor, to avoid false touches - * during a call, we hold a PROXIMITY_SCREEN_OFF_WAKE_LOCK wake lock - * whenever the phone is off hook. (When held, that wake lock causes - * the screen to turn off automatically when the sensor detects an - * object close to the screen.) - * - * This method is a no-op for devices that don't have a proximity - * sensor. - * - * Proximity wake lock will *not* be held if any one of the - * conditions is true while on a call: - * 1) If the audio is routed via Bluetooth - * 2) If a wired headset is connected - * 3) if the speaker is ON - * 4) If the slider is open(i.e. the hardkeyboard is *not* hidden) - */ - private synchronized void updateProximitySensorMode() { - final int audioMode = mAudioModeProvider.getAudioMode(); - - // turn proximity sensor off and turn screen on immediately if - // we are using a headset, the keyboard is open, or the device - // is being held in a horizontal position. - boolean screenOnImmediately = (CallAudioState.ROUTE_WIRED_HEADSET == audioMode - || CallAudioState.ROUTE_SPEAKER == audioMode - || CallAudioState.ROUTE_BLUETOOTH == audioMode - || mIsHardKeyboardOpen); - - // We do not keep the screen off when the user is outside in-call screen and we are - // horizontal, but we do not force it on when we become horizontal until the - // proximity sensor goes negative. - final boolean horizontal = - (mOrientation == AccelerometerListener.ORIENTATION_HORIZONTAL); - screenOnImmediately |= !mUiShowing && horizontal; - - // We do not keep the screen off when dialpad is visible, we are horizontal, and - // the in-call screen is being shown. - // At that moment we're pretty sure users want to use it, instead of letting the - // proximity sensor turn off the screen by their hands. - screenOnImmediately |= mDialpadVisible && horizontal; - - Log.v(this, "screenonImmediately: ", screenOnImmediately); - - Log.i(this, Objects.toStringHelper(this) - .add("keybrd", mIsHardKeyboardOpen ? 1 : 0) - .add("dpad", mDialpadVisible ? 1 : 0) - .add("offhook", mIsPhoneOffhook ? 1 : 0) - .add("hor", horizontal ? 1 : 0) - .add("ui", mUiShowing ? 1 : 0) - .add("aud", CallAudioState.audioRouteToString(audioMode)) - .toString()); - - if (mIsPhoneOffhook && !screenOnImmediately) { - Log.d(this, "Turning on proximity sensor"); - // Phone is in use! Arrange for the screen to turn off - // automatically when the sensor detects a close object. - turnOnProximitySensor(); - } else { - Log.d(this, "Turning off proximity sensor"); - // Phone is either idle, or ringing. We don't want any special proximity sensor - // behavior in either case. - turnOffProximitySensor(screenOnImmediately); - } - } - - /** - * Implementation of a {@link DisplayListener} that maintains a binary state: - * Screen on vs screen off. Used by the proximity sensor manager to decide whether or not - * it needs to listen to accelerometer events. - */ - public class ProximityDisplayListener implements DisplayListener { - private DisplayManager mDisplayManager; - private boolean mIsDisplayOn = true; - - ProximityDisplayListener(DisplayManager displayManager) { - mDisplayManager = displayManager; - } - - void register() { - mDisplayManager.registerDisplayListener(this, null); - } - - void unregister() { - mDisplayManager.unregisterDisplayListener(this); - } - - @Override - public void onDisplayRemoved(int displayId) { - } - - @Override - public void onDisplayChanged(int displayId) { - if (displayId == Display.DEFAULT_DISPLAY) { - final Display display = mDisplayManager.getDisplay(displayId); - - final boolean isDisplayOn = display.getState() != Display.STATE_OFF; - // For call purposes, we assume that as long as the screen is not truly off, it is - // considered on, even if it is in an unknown or low power idle state. - if (isDisplayOn != mIsDisplayOn) { - mIsDisplayOn = isDisplayOn; - onDisplayStateChanged(mIsDisplayOn); - } - } - } - - @Override - public void onDisplayAdded(int displayId) { - } - } -} diff --git a/InCallUI/src/com/android/incallui/StatusBarNotifier.java b/InCallUI/src/com/android/incallui/StatusBarNotifier.java deleted file mode 100644 index cc87dd414..000000000 --- a/InCallUI/src/com/android/incallui/StatusBarNotifier.java +++ /dev/null @@ -1,793 +0,0 @@ -/* - * Copyright (C) 2013 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.incallui; - -import static com.android.contacts.common.compat.CallSdkCompat.Details.PROPERTY_ENTERPRISE_CALL; -import static com.android.incallui.NotificationBroadcastReceiver.ACTION_ACCEPT_VIDEO_UPGRADE_REQUEST; -import static com.android.incallui.NotificationBroadcastReceiver.ACTION_ANSWER_VIDEO_INCOMING_CALL; -import static com.android.incallui.NotificationBroadcastReceiver.ACTION_ANSWER_VOICE_INCOMING_CALL; -import static com.android.incallui.NotificationBroadcastReceiver.ACTION_DECLINE_INCOMING_CALL; -import static com.android.incallui.NotificationBroadcastReceiver.ACTION_DECLINE_VIDEO_UPGRADE_REQUEST; -import static com.android.incallui.NotificationBroadcastReceiver.ACTION_HANG_UP_ONGOING_CALL; - -import com.google.common.base.Preconditions; - -import android.app.Notification; -import android.app.NotificationManager; -import android.app.PendingIntent; -import android.content.Context; -import android.content.Intent; -import android.graphics.Bitmap; -import android.graphics.BitmapFactory; -import android.graphics.Canvas; -import android.graphics.drawable.BitmapDrawable; -import android.graphics.drawable.Drawable; -import android.media.AudioAttributes; -import android.net.Uri; -import android.provider.ContactsContract.Contacts; -import android.support.annotation.Nullable; -import android.telecom.Call.Details; -import android.telecom.PhoneAccount; -import android.telecom.TelecomManager; -import android.text.BidiFormatter; -import android.text.TextDirectionHeuristics; -import android.text.TextUtils; - -import com.android.contacts.common.ContactsUtils; -import com.android.contacts.common.ContactsUtils.UserType; -import com.android.contacts.common.preference.ContactsPreferences; -import com.android.contacts.common.testing.NeededForTesting; -import com.android.contacts.common.util.BitmapUtil; -import com.android.contacts.common.util.ContactDisplayUtils; -import com.android.dialer.R; -import com.android.dialer.service.ExtendedCallInfoService; -import com.android.incallui.ContactInfoCache.ContactCacheEntry; -import com.android.incallui.ContactInfoCache.ContactInfoCacheCallback; -import com.android.incallui.InCallPresenter.InCallState; -import com.android.incallui.async.PausableExecutorImpl; -import com.android.incallui.ringtone.DialerRingtoneManager; -import com.android.incallui.ringtone.InCallTonePlayer; -import com.android.incallui.ringtone.ToneGeneratorFactory; - -import java.util.Objects; - -/** - * This class adds Notifications to the status bar for the in-call experience. - */ -public class StatusBarNotifier implements InCallPresenter.InCallStateListener, - CallList.CallUpdateListener { - - // Notification types - // Indicates that no notification is currently showing. - private static final int NOTIFICATION_NONE = 0; - // Notification for an active call. This is non-interruptive, but cannot be dismissed. - private static final int NOTIFICATION_IN_CALL = 1; - // Notification for incoming calls. This is interruptive and will show up as a HUN. - private static final int NOTIFICATION_INCOMING_CALL = 2; - - private static final int PENDING_INTENT_REQUEST_CODE_NON_FULL_SCREEN = 0; - private static final int PENDING_INTENT_REQUEST_CODE_FULL_SCREEN = 1; - - private static final long[] VIBRATE_PATTERN = new long[] {0, 1000, 1000}; - - private final Context mContext; - @Nullable private ContactsPreferences mContactsPreferences; - private final ContactInfoCache mContactInfoCache; - private final NotificationManager mNotificationManager; - private final DialerRingtoneManager mDialerRingtoneManager; - private int mCurrentNotification = NOTIFICATION_NONE; - private int mCallState = Call.State.INVALID; - private int mSavedIcon = 0; - private String mSavedContent = null; - private Bitmap mSavedLargeIcon; - private String mSavedContentTitle; - private String mCallId = null; - private InCallState mInCallState; - private Uri mRingtone; - - public StatusBarNotifier(Context context, ContactInfoCache contactInfoCache) { - Preconditions.checkNotNull(context); - mContext = context; - mContactsPreferences = ContactsPreferencesFactory.newContactsPreferences(mContext); - mContactInfoCache = contactInfoCache; - mNotificationManager = - (NotificationManager) mContext.getSystemService(Context.NOTIFICATION_SERVICE); - mDialerRingtoneManager = new DialerRingtoneManager( - new InCallTonePlayer(new ToneGeneratorFactory(), new PausableExecutorImpl()), - CallList.getInstance()); - mCurrentNotification = NOTIFICATION_NONE; - } - - /** - * Creates notifications according to the state we receive from {@link InCallPresenter}. - */ - @Override - public void onStateChange(InCallState oldState, InCallState newState, CallList callList) { - Log.d(this, "onStateChange"); - mInCallState = newState; - updateNotification(newState, callList); - } - - /** - * Updates the phone app's status bar notification *and* launches the - * incoming call UI in response to a new incoming call. - * - * If an incoming call is ringing (or call-waiting), the notification - * will also include a "fullScreenIntent" that will cause the - * InCallScreen to be launched, unless the current foreground activity - * is marked as "immersive". - * - * (This is the mechanism that actually brings up the incoming call UI - * when we receive a "new ringing connection" event from the telephony - * layer.) - * - * Also note that this method is safe to call even if the phone isn't - * actually ringing (or, more likely, if an incoming call *was* - * ringing briefly but then disconnected). In that case, we'll simply - * update or cancel the in-call notification based on the current - * phone state. - * - * @see #updateInCallNotification(InCallState,CallList) - */ - public void updateNotification(InCallState state, CallList callList) { - updateInCallNotification(state, callList); - } - - /** - * Take down the in-call notification. - * @see #updateInCallNotification(InCallState,CallList) - */ - private void cancelNotification() { - if (!TextUtils.isEmpty(mCallId)) { - CallList.getInstance().removeCallUpdateListener(mCallId, this); - mCallId = null; - } - if (mCurrentNotification != NOTIFICATION_NONE) { - Log.d(this, "cancelInCall()..."); - mNotificationManager.cancel(mCurrentNotification); - } - mCurrentNotification = NOTIFICATION_NONE; - } - - /** - * Should only be called from a irrecoverable state where it is necessary to dismiss all - * notifications. - */ - static void clearAllCallNotifications(Context backupContext) { - Log.i(StatusBarNotifier.class.getSimpleName(), - "Something terrible happened. Clear all InCall notifications"); - - NotificationManager notificationManager = - (NotificationManager) backupContext.getSystemService(Context.NOTIFICATION_SERVICE); - notificationManager.cancel(NOTIFICATION_IN_CALL); - notificationManager.cancel(NOTIFICATION_INCOMING_CALL); - } - - /** - * Helper method for updateInCallNotification() and - * updateNotification(): Update the phone app's - * status bar notification based on the current telephony state, or - * cancels the notification if the phone is totally idle. - */ - private void updateInCallNotification(final InCallState state, CallList callList) { - Log.d(this, "updateInCallNotification..."); - - final Call call = getCallToShow(callList); - - if (call != null) { - showNotification(call); - } else { - cancelNotification(); - } - } - - private void showNotification(final Call call) { - final boolean isIncoming = (call.getState() == Call.State.INCOMING || - call.getState() == Call.State.CALL_WAITING); - if (!TextUtils.isEmpty(mCallId)) { - CallList.getInstance().removeCallUpdateListener(mCallId, this); - } - mCallId = call.getId(); - CallList.getInstance().addCallUpdateListener(call.getId(), this); - - // we make a call to the contact info cache to query for supplemental data to what the - // call provides. This includes the contact name and photo. - // This callback will always get called immediately and synchronously with whatever data - // it has available, and may make a subsequent call later (same thread) if it had to - // call into the contacts provider for more data. - mContactInfoCache.findInfo(call, isIncoming, new ContactInfoCacheCallback() { - @Override - public void onContactInfoComplete(String callId, ContactCacheEntry entry) { - Call call = CallList.getInstance().getCallById(callId); - if (call != null) { - call.getLogState().contactLookupResult = entry.contactLookupResult; - buildAndSendNotification(call, entry); - } - } - - @Override - public void onImageLoadComplete(String callId, ContactCacheEntry entry) { - Call call = CallList.getInstance().getCallById(callId); - if (call != null) { - buildAndSendNotification(call, entry); - } - } - - @Override - public void onContactInteractionsInfoComplete(String callId, ContactCacheEntry entry) {} - }); - } - - /** - * Sets up the main Ui for the notification - */ - private void buildAndSendNotification(Call originalCall, ContactCacheEntry contactInfo) { - // This can get called to update an existing notification after contact information has come - // back. However, it can happen much later. Before we continue, we need to make sure that - // the call being passed in is still the one we want to show in the notification. - final Call call = getCallToShow(CallList.getInstance()); - if (call == null || !call.getId().equals(originalCall.getId())) { - return; - } - - final int callState = call.getState(); - // Dont' show as spam if the number is in local contact. - if (contactInfo.contactLookupResult == Call.LogState.LOOKUP_LOCAL_CONTACT) { - call.setSpam(false); - } - - // Check if data has changed; if nothing is different, don't issue another notification. - final int iconResId = getIconToDisplay(call); - Bitmap largeIcon = getLargeIconToDisplay(contactInfo, call); - final String content = - getContentString(call, contactInfo.userType); - final String contentTitle = getContentTitle(contactInfo, call); - - final boolean isVideoUpgradeRequest = call.getSessionModificationState() - == Call.SessionModificationState.RECEIVED_UPGRADE_TO_VIDEO_REQUEST; - final int notificationType; - if (callState == Call.State.INCOMING || callState == Call.State.CALL_WAITING - || isVideoUpgradeRequest) { - notificationType = NOTIFICATION_INCOMING_CALL; - } else { - notificationType = NOTIFICATION_IN_CALL; - } - - if (!checkForChangeAndSaveData(iconResId, content, largeIcon, contentTitle, callState, - notificationType, contactInfo.contactRingtoneUri)) { - return; - } - - if (largeIcon != null) { - largeIcon = getRoundedIcon(largeIcon); - } - - /* - * This builder is used for the notification shown when the device is locked and the user - * has set their notification settings to 'hide sensitive content' - * {@see Notification.Builder#setPublicVersion}. - */ - Notification.Builder publicBuilder = new Notification.Builder(mContext); - publicBuilder.setSmallIcon(iconResId) - .setColor(mContext.getResources().getColor(R.color.dialer_theme_color)) - // Hide work call state for the lock screen notification - .setContentTitle(getContentString(call, ContactsUtils.USER_TYPE_CURRENT)); - setNotificationWhen(call, callState, publicBuilder); - - /* - * Builder for the notification shown when the device is unlocked or the user has set their - * notification settings to 'show all notification content'. - */ - final Notification.Builder builder = getNotificationBuilder(); - builder.setPublicVersion(publicBuilder.build()); - - // Set up the main intent to send the user to the in-call screen - builder.setContentIntent(createLaunchPendingIntent(false /* isFullScreen */)); - - // Set the intent as a full screen intent as well if a call is incoming - if (notificationType == NOTIFICATION_INCOMING_CALL - && !InCallPresenter.getInstance().isShowingInCallUi()) { - configureFullScreenIntent( - builder, createLaunchPendingIntent(true /* isFullScreen */), call); - // Set the notification category for incoming calls - builder.setCategory(Notification.CATEGORY_CALL); - } - - // Set the content - builder.setContentText(content); - builder.setSmallIcon(iconResId); - builder.setContentTitle(contentTitle); - builder.setLargeIcon(largeIcon); - builder.setColor(mContext.getResources().getColor(R.color.dialer_theme_color)); - - if (isVideoUpgradeRequest) { - builder.setUsesChronometer(false); - addDismissUpgradeRequestAction(builder); - addAcceptUpgradeRequestAction(builder); - } else { - createIncomingCallNotification(call, callState, builder); - } - - addPersonReference(builder, contactInfo, call); - - /* - * Fire off the notification - */ - Notification notification = builder.build(); - - if (mDialerRingtoneManager.shouldPlayRingtone(callState, contactInfo.contactRingtoneUri)) { - notification.flags |= Notification.FLAG_INSISTENT; - notification.sound = contactInfo.contactRingtoneUri; - AudioAttributes.Builder audioAttributes = new AudioAttributes.Builder(); - audioAttributes.setContentType(AudioAttributes.CONTENT_TYPE_MUSIC); - audioAttributes.setUsage(AudioAttributes.USAGE_NOTIFICATION_RINGTONE); - notification.audioAttributes = audioAttributes.build(); - if (mDialerRingtoneManager.shouldVibrate(mContext.getContentResolver())) { - notification.vibrate = VIBRATE_PATTERN; - } - } - if (mDialerRingtoneManager.shouldPlayCallWaitingTone(callState)) { - Log.v(this, "Playing call waiting tone"); - mDialerRingtoneManager.playCallWaitingTone(); - } - if (mCurrentNotification != notificationType && mCurrentNotification != NOTIFICATION_NONE) { - Log.i(this, "Previous notification already showing - cancelling " - + mCurrentNotification); - mNotificationManager.cancel(mCurrentNotification); - } - - Log.i(this, "Displaying notification for " + notificationType); - mNotificationManager.notify(notificationType, notification); - call.getLatencyReport().onNotificationShown(); - mCurrentNotification = notificationType; - } - - private void createIncomingCallNotification( - Call call, int state, Notification.Builder builder) { - setNotificationWhen(call, state, builder); - - // Add hang up option for any active calls (active | onhold), outgoing calls (dialing). - if (state == Call.State.ACTIVE || - state == Call.State.ONHOLD || - Call.State.isDialing(state)) { - addHangupAction(builder); - } else if (state == Call.State.INCOMING || state == Call.State.CALL_WAITING) { - addDismissAction(builder); - if (call.isVideoCall(mContext)) { - addVoiceAction(builder); - addVideoCallAction(builder); - } else { - addAnswerAction(builder); - } - } - } - - /* - * Sets the notification's when section as needed. For active calls, this is explicitly set as - * the duration of the call. For all other states, the notification will automatically show the - * time at which the notification was created. - */ - private void setNotificationWhen(Call call, int state, Notification.Builder builder) { - if (state == Call.State.ACTIVE) { - builder.setUsesChronometer(true); - builder.setWhen(call.getConnectTimeMillis()); - } else { - builder.setUsesChronometer(false); - } - } - - /** - * Checks the new notification data and compares it against any notification that we - * are already displaying. If the data is exactly the same, we return false so that - * we do not issue a new notification for the exact same data. - */ - private boolean checkForChangeAndSaveData(int icon, String content, Bitmap largeIcon, - String contentTitle, int state, int notificationType, Uri ringtone) { - - // The two are different: - // if new title is not null, it should be different from saved version OR - // if new title is null, the saved version should not be null - final boolean contentTitleChanged = - (contentTitle != null && !contentTitle.equals(mSavedContentTitle)) || - (contentTitle == null && mSavedContentTitle != null); - - // any change means we are definitely updating - boolean retval = (mSavedIcon != icon) || !Objects.equals(mSavedContent, content) - || (mCallState != state) || (mSavedLargeIcon != largeIcon) - || contentTitleChanged || !Objects.equals(mRingtone, ringtone); - - // If we aren't showing a notification right now or the notification type is changing, - // definitely do an update. - if (mCurrentNotification != notificationType) { - if (mCurrentNotification == NOTIFICATION_NONE) { - Log.d(this, "Showing notification for first time."); - } - retval = true; - } - - mSavedIcon = icon; - mSavedContent = content; - mCallState = state; - mSavedLargeIcon = largeIcon; - mSavedContentTitle = contentTitle; - mRingtone = ringtone; - - if (retval) { - Log.d(this, "Data changed. Showing notification"); - } - - return retval; - } - - /** - * Returns the main string to use in the notification. - */ - @NeededForTesting - String getContentTitle(ContactCacheEntry contactInfo, Call call) { - if (call.isConferenceCall() && !call.hasProperty(Details.PROPERTY_GENERIC_CONFERENCE)) { - return mContext.getResources().getString(R.string.card_title_conf_call); - } - - String preferredName = ContactDisplayUtils.getPreferredDisplayName(contactInfo.namePrimary, - contactInfo.nameAlternative, mContactsPreferences); - if (TextUtils.isEmpty(preferredName)) { - return TextUtils.isEmpty(contactInfo.number) ? null : BidiFormatter.getInstance() - .unicodeWrap(contactInfo.number, TextDirectionHeuristics.LTR); - } - return preferredName; - } - - private void addPersonReference(Notification.Builder builder, ContactCacheEntry contactInfo, - Call call) { - // Query {@link Contacts#CONTENT_LOOKUP_URI} directly with work lookup key is not allowed. - // So, do not pass {@link Contacts#CONTENT_LOOKUP_URI} to NotificationManager to avoid - // NotificationManager using it. - if (contactInfo.lookupUri != null && contactInfo.userType != ContactsUtils.USER_TYPE_WORK) { - builder.addPerson(contactInfo.lookupUri.toString()); - } else if (!TextUtils.isEmpty(call.getNumber())) { - builder.addPerson(Uri.fromParts(PhoneAccount.SCHEME_TEL, - call.getNumber(), null).toString()); - } - } - - /** - * Gets a large icon from the contact info object to display in the notification. - */ - private Bitmap getLargeIconToDisplay(ContactCacheEntry contactInfo, Call call) { - Bitmap largeIcon = null; - if (call.isConferenceCall() && !call.hasProperty(Details.PROPERTY_GENERIC_CONFERENCE)) { - largeIcon = BitmapFactory.decodeResource(mContext.getResources(), - R.drawable.img_conference); - } - if (contactInfo.photo != null && (contactInfo.photo instanceof BitmapDrawable)) { - largeIcon = ((BitmapDrawable) contactInfo.photo).getBitmap(); - } - if (call.isSpam()) { - Drawable drawable = mContext.getResources().getDrawable(R.drawable.blocked_contact); - largeIcon = CallCardFragment.drawableToBitmap(drawable); - } - return largeIcon; - } - - private Bitmap getRoundedIcon(Bitmap bitmap) { - if (bitmap == null) { - return null; - } - final int height = (int) mContext.getResources().getDimension( - android.R.dimen.notification_large_icon_height); - final int width = (int) mContext.getResources().getDimension( - android.R.dimen.notification_large_icon_width); - return BitmapUtil.getRoundedBitmap(bitmap, width, height); - } - - /** - * Returns the appropriate icon res Id to display based on the call for which - * we want to display information. - */ - private int getIconToDisplay(Call call) { - // Even if both lines are in use, we only show a single item in - // the expanded Notifications UI. It's labeled "Ongoing call" - // (or "On hold" if there's only one call, and it's on hold.) - // Also, we don't have room to display caller-id info from two - // different calls. So if both lines are in use, display info - // from the foreground call. And if there's a ringing call, - // display that regardless of the state of the other calls. - if (call.getState() == Call.State.ONHOLD) { - return R.drawable.ic_phone_paused_white_24dp; - } else if (call.getSessionModificationState() - == Call.SessionModificationState.RECEIVED_UPGRADE_TO_VIDEO_REQUEST) { - return R.drawable.ic_videocam; - } - return R.drawable.ic_call_white_24dp; - } - - /** - * Returns the message to use with the notification. - */ - private String getContentString(Call call, @UserType long userType) { - boolean isIncomingOrWaiting = call.getState() == Call.State.INCOMING || - call.getState() == Call.State.CALL_WAITING; - - if (isIncomingOrWaiting && - call.getNumberPresentation() == TelecomManager.PRESENTATION_ALLOWED) { - - if (!TextUtils.isEmpty(call.getChildNumber())) { - return mContext.getString(R.string.child_number, call.getChildNumber()); - } else if (!TextUtils.isEmpty(call.getCallSubject()) && call.isCallSubjectSupported()) { - return call.getCallSubject(); - } - } - - int resId = R.string.notification_ongoing_call; - if (call.hasProperty(Details.PROPERTY_WIFI)) { - resId = R.string.notification_ongoing_call_wifi; - } - - if (isIncomingOrWaiting) { - if (call.hasProperty(Details.PROPERTY_WIFI)) { - resId = R.string.notification_incoming_call_wifi; - } else { - if (call.isSpam()) { - resId = R.string.notification_incoming_spam_call; - } else { - resId = R.string.notification_incoming_call; - } - } - } else if (call.getState() == Call.State.ONHOLD) { - resId = R.string.notification_on_hold; - } else if (Call.State.isDialing(call.getState())) { - resId = R.string.notification_dialing; - } else if (call.getSessionModificationState() - == Call.SessionModificationState.RECEIVED_UPGRADE_TO_VIDEO_REQUEST) { - resId = R.string.notification_requesting_video_call; - } - - // Is the call placed through work connection service. - boolean isWorkCall = call.hasProperty(PROPERTY_ENTERPRISE_CALL); - if(userType == ContactsUtils.USER_TYPE_WORK || isWorkCall) { - resId = getWorkStringFromPersonalString(resId); - } - - return mContext.getString(resId); - } - - private static int getWorkStringFromPersonalString(int resId) { - if (resId == R.string.notification_ongoing_call) { - return R.string.notification_ongoing_work_call; - } else if (resId == R.string.notification_ongoing_call_wifi) { - return R.string.notification_ongoing_work_call_wifi; - } else if (resId == R.string.notification_incoming_call_wifi) { - return R.string.notification_incoming_work_call_wifi; - } else if (resId == R.string.notification_incoming_call) { - return R.string.notification_incoming_work_call; - } else { - return resId; - } - } - - /** - * Gets the most relevant call to display in the notification. - */ - private Call getCallToShow(CallList callList) { - if (callList == null) { - return null; - } - Call call = callList.getIncomingCall(); - if (call == null) { - call = callList.getOutgoingCall(); - } - if (call == null) { - call = callList.getVideoUpgradeRequestCall(); - } - if (call == null) { - call = callList.getActiveOrBackgroundCall(); - } - return call; - } - - private void addAnswerAction(Notification.Builder builder) { - Log.d(this, "Will show \"answer\" action in the incoming call Notification"); - - PendingIntent answerVoicePendingIntent = createNotificationPendingIntent( - mContext, ACTION_ANSWER_VOICE_INCOMING_CALL); - builder.addAction(R.drawable.ic_call_white_24dp, - mContext.getText(R.string.notification_action_answer), - answerVoicePendingIntent); - } - - private void addDismissAction(Notification.Builder builder) { - Log.d(this, "Will show \"dismiss\" action in the incoming call Notification"); - - PendingIntent declinePendingIntent = - createNotificationPendingIntent(mContext, ACTION_DECLINE_INCOMING_CALL); - builder.addAction(R.drawable.ic_close_dk, - mContext.getText(R.string.notification_action_dismiss), - declinePendingIntent); - } - - private void addHangupAction(Notification.Builder builder) { - Log.d(this, "Will show \"hang-up\" action in the ongoing active call Notification"); - - PendingIntent hangupPendingIntent = - createNotificationPendingIntent(mContext, ACTION_HANG_UP_ONGOING_CALL); - builder.addAction(R.drawable.ic_call_end_white_24dp, - mContext.getText(R.string.notification_action_end_call), - hangupPendingIntent); - } - - private void addVideoCallAction(Notification.Builder builder) { - Log.i(this, "Will show \"video\" action in the incoming call Notification"); - - PendingIntent answerVideoPendingIntent = createNotificationPendingIntent( - mContext, ACTION_ANSWER_VIDEO_INCOMING_CALL); - builder.addAction(R.drawable.ic_videocam, - mContext.getText(R.string.notification_action_answer_video), - answerVideoPendingIntent); - } - - private void addVoiceAction(Notification.Builder builder) { - Log.d(this, "Will show \"voice\" action in the incoming call Notification"); - - PendingIntent answerVoicePendingIntent = createNotificationPendingIntent( - mContext, ACTION_ANSWER_VOICE_INCOMING_CALL); - builder.addAction(R.drawable.ic_call_white_24dp, - mContext.getText(R.string.notification_action_answer_voice), - answerVoicePendingIntent); - } - - private void addAcceptUpgradeRequestAction(Notification.Builder builder) { - Log.i(this, "Will show \"accept upgrade\" action in the incoming call Notification"); - - PendingIntent acceptVideoPendingIntent = createNotificationPendingIntent( - mContext, ACTION_ACCEPT_VIDEO_UPGRADE_REQUEST); - builder.addAction(0, mContext.getText(R.string.notification_action_accept), - acceptVideoPendingIntent); - } - - private void addDismissUpgradeRequestAction(Notification.Builder builder) { - Log.i(this, "Will show \"dismiss upgrade\" action in the incoming call Notification"); - - PendingIntent declineVideoPendingIntent = createNotificationPendingIntent( - mContext, ACTION_DECLINE_VIDEO_UPGRADE_REQUEST); - builder.addAction(0, mContext.getText(R.string.notification_action_dismiss), - declineVideoPendingIntent); - } - - /** - * Adds fullscreen intent to the builder. - */ - private void configureFullScreenIntent(Notification.Builder builder, PendingIntent intent, - Call call) { - // Ok, we actually want to launch the incoming call - // UI at this point (in addition to simply posting a notification - // to the status bar). Setting fullScreenIntent will cause - // the InCallScreen to be launched immediately *unless* the - // current foreground activity is marked as "immersive". - Log.d(this, "- Setting fullScreenIntent: " + intent); - builder.setFullScreenIntent(intent, true); - - // Ugly hack alert: - // - // The NotificationManager has the (undocumented) behavior - // that it will *ignore* the fullScreenIntent field if you - // post a new Notification that matches the ID of one that's - // already active. Unfortunately this is exactly what happens - // when you get an incoming call-waiting call: the - // "ongoing call" notification is already visible, so the - // InCallScreen won't get launched in this case! - // (The result: if you bail out of the in-call UI while on a - // call and then get a call-waiting call, the incoming call UI - // won't come up automatically.) - // - // The workaround is to just notice this exact case (this is a - // call-waiting call *and* the InCallScreen is not in the - // foreground) and manually cancel the in-call notification - // before (re)posting it. - // - // TODO: there should be a cleaner way of avoiding this - // problem (see discussion in bug 3184149.) - - // If a call is onhold during an incoming call, the call actually comes in as - // INCOMING. For that case *and* traditional call-waiting, we want to - // cancel the notification. - boolean isCallWaiting = (call.getState() == Call.State.CALL_WAITING || - (call.getState() == Call.State.INCOMING && - CallList.getInstance().getBackgroundCall() != null)); - - if (isCallWaiting) { - Log.i(this, "updateInCallNotification: call-waiting! force relaunch..."); - // Cancel the IN_CALL_NOTIFICATION immediately before - // (re)posting it; this seems to force the - // NotificationManager to launch the fullScreenIntent. - mNotificationManager.cancel(NOTIFICATION_IN_CALL); - } - } - - private Notification.Builder getNotificationBuilder() { - final Notification.Builder builder = new Notification.Builder(mContext); - builder.setOngoing(true); - - // Make the notification prioritized over the other normal notifications. - builder.setPriority(Notification.PRIORITY_HIGH); - - return builder; - } - - private PendingIntent createLaunchPendingIntent(boolean isFullScreen) { - Intent intent = InCallPresenter.getInstance().getInCallIntent( - false /* showDialpad */, false /* newOutgoingCall */); - - int requestCode = PENDING_INTENT_REQUEST_CODE_NON_FULL_SCREEN; - if (isFullScreen) { - intent.putExtra(InCallActivity.FOR_FULL_SCREEN_INTENT, true); - // Use a unique request code so that the pending intent isn't clobbered by the - // non-full screen pending intent. - requestCode = PENDING_INTENT_REQUEST_CODE_FULL_SCREEN; - } - - // PendingIntent that can be used to launch the InCallActivity. The - // system fires off this intent if the user pulls down the windowshade - // and clicks the notification's expanded view. It's also used to - // launch the InCallActivity immediately when when there's an incoming - // call (see the "fullScreenIntent" field below). - return PendingIntent.getActivity(mContext, requestCode, intent, 0); - } - - /** - * Returns PendingIntent for answering a phone call. This will typically be used from - * Notification context. - */ - private static PendingIntent createNotificationPendingIntent(Context context, String action) { - final Intent intent = new Intent(action, null, - context, NotificationBroadcastReceiver.class); - return PendingIntent.getBroadcast(context, 0, intent, 0); - } - - @Override - public void onCallChanged(Call call) { - if (CallList.getInstance().getIncomingCall() == null) { - mDialerRingtoneManager.stopCallWaitingTone(); - } - } - - /** - * Responds to changes in the session modification state for the call by dismissing the - * status bar notification as required. - * - * @param sessionModificationState The new session modification state. - */ - @Override - public void onSessionModificationStateChange(int sessionModificationState) { - if (sessionModificationState == Call.SessionModificationState.NO_REQUEST) { - if (mCallId != null) { - CallList.getInstance().removeCallUpdateListener(mCallId, this); - } - - updateNotification(mInCallState, CallList.getInstance()); - } - } - - @Override - public void onLastForwardedNumberChange() { - // no-op - } - - @Override - public void onChildNumberChange() { - // no-op - } -} diff --git a/InCallUI/src/com/android/incallui/TelecomAdapter.java b/InCallUI/src/com/android/incallui/TelecomAdapter.java deleted file mode 100644 index f172270dd..000000000 --- a/InCallUI/src/com/android/incallui/TelecomAdapter.java +++ /dev/null @@ -1,226 +0,0 @@ -/* - * Copyright (C) 2014 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 com.google.common.base.Preconditions; - -import android.content.ActivityNotFoundException; -import android.content.Intent; -import android.os.Looper; -import android.telecom.InCallService; -import android.telecom.PhoneAccountHandle; - -import java.util.List; - -final class TelecomAdapter implements InCallServiceListener { - private static final String ADD_CALL_MODE_KEY = "add_call_mode"; - - private static TelecomAdapter sInstance; - private InCallService mInCallService; - - static TelecomAdapter getInstance() { - Preconditions.checkState(Looper.getMainLooper().getThread() == Thread.currentThread()); - if (sInstance == null) { - sInstance = new TelecomAdapter(); - } - return sInstance; - } - - private TelecomAdapter() { - } - - @Override - public void setInCallService(InCallService inCallService) { - mInCallService = inCallService; - } - - @Override - public void clearInCallService() { - mInCallService = null; - } - - private android.telecom.Call getTelecomCallById(String callId) { - Call call = CallList.getInstance().getCallById(callId); - return call == null ? null : call.getTelecomCall(); - } - - void answerCall(String callId, int videoState) { - android.telecom.Call call = getTelecomCallById(callId); - if (call != null) { - call.answer(videoState); - } else { - Log.e(this, "error answerCall, call not in call list: " + callId); - } - } - - void rejectCall(String callId, boolean rejectWithMessage, String message) { - android.telecom.Call call = getTelecomCallById(callId); - if (call != null) { - call.reject(rejectWithMessage, message); - } else { - Log.e(this, "error rejectCall, call not in call list: " + callId); - } - } - - void disconnectCall(String callId) { - android.telecom.Call call = getTelecomCallById(callId); - if (call != null) { - call.disconnect(); - } else { - Log.e(this, "error disconnectCall, call not in call list " + callId); - } - } - - void holdCall(String callId) { - android.telecom.Call call = getTelecomCallById(callId); - if (call != null) { - call.hold(); - } else { - Log.e(this, "error holdCall, call not in call list " + callId); - } - } - - void unholdCall(String callId) { - android.telecom.Call call = getTelecomCallById(callId); - if (call != null) { - call.unhold(); - } else { - Log.e(this, "error unholdCall, call not in call list " + callId); - } - } - - void mute(boolean shouldMute) { - if (mInCallService != null) { - mInCallService.setMuted(shouldMute); - } else { - Log.e(this, "error mute, mInCallService is null"); - } - } - - void setAudioRoute(int route) { - if (mInCallService != null) { - mInCallService.setAudioRoute(route); - } else { - Log.e(this, "error setAudioRoute, mInCallService is null"); - } - } - - void separateCall(String callId) { - android.telecom.Call call = getTelecomCallById(callId); - if (call != null) { - call.splitFromConference(); - } else { - Log.e(this, "error separateCall, call not in call list " + callId); - } - } - - void merge(String callId) { - android.telecom.Call call = getTelecomCallById(callId); - if (call != null) { - List conferenceable = call.getConferenceableCalls(); - if (!conferenceable.isEmpty()) { - call.conference(conferenceable.get(0)); - } else { - if (call.getDetails().can(android.telecom.Call.Details.CAPABILITY_MERGE_CONFERENCE)) { - call.mergeConference(); - } - } - } else { - Log.e(this, "error merge, call not in call list " + callId); - } - } - - void swap(String callId) { - android.telecom.Call call = getTelecomCallById(callId); - if (call != null) { - if (call.getDetails().can(android.telecom.Call.Details.CAPABILITY_SWAP_CONFERENCE)) { - call.swapConference(); - } - } else { - Log.e(this, "error swap, call not in call list " + callId); - } - } - - void addCall() { - if (mInCallService != null) { - Intent intent = new Intent(Intent.ACTION_DIAL); - intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); - - // when we request the dialer come up, we also want to inform - // it that we're going through the "add call" option from the - // InCallScreen / PhoneUtils. - intent.putExtra(ADD_CALL_MODE_KEY, true); - try { - Log.d(this, "Sending the add Call intent"); - mInCallService.startActivity(intent); - } catch (ActivityNotFoundException e) { - // This is rather rare but possible. - // Note: this method is used even when the phone is encrypted. At that moment - // the system may not find any Activity which can accept this Intent. - Log.e(this, "Activity for adding calls isn't found.", e); - } - } - } - - void playDtmfTone(String callId, char digit) { - android.telecom.Call call = getTelecomCallById(callId); - if (call != null) { - call.playDtmfTone(digit); - } else { - Log.e(this, "error playDtmfTone, call not in call list " + callId); - } - } - - void stopDtmfTone(String callId) { - android.telecom.Call call = getTelecomCallById(callId); - if (call != null) { - call.stopDtmfTone(); - } else { - Log.e(this, "error stopDtmfTone, call not in call list " + callId); - } - } - - void postDialContinue(String callId, boolean proceed) { - android.telecom.Call call = getTelecomCallById(callId); - if (call != null) { - call.postDialContinue(proceed); - } else { - Log.e(this, "error postDialContinue, call not in call list " + callId); - } - } - - void phoneAccountSelected(String callId, PhoneAccountHandle accountHandle, boolean setDefault) { - if (accountHandle == null) { - Log.e(this, "error phoneAccountSelected, accountHandle is null"); - // TODO: Do we really want to send null accountHandle? - } - - android.telecom.Call call = getTelecomCallById(callId); - if (call != null) { - call.phoneAccountSelected(accountHandle, setDefault); - } else { - Log.e(this, "error phoneAccountSelected, call not in call list " + callId); - } - } - - boolean canAddCall() { - if (mInCallService != null) { - return mInCallService.canAddCall(); - } - return false; - } -} diff --git a/InCallUI/src/com/android/incallui/Ui.java b/InCallUI/src/com/android/incallui/Ui.java deleted file mode 100644 index e453ccb1c..000000000 --- a/InCallUI/src/com/android/incallui/Ui.java +++ /dev/null @@ -1,24 +0,0 @@ -/* - * Copyright (C) 2013 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License - */ - -package com.android.incallui; - -/** - * Base class for all presenter ui. - */ -public interface Ui { - -} diff --git a/InCallUI/src/com/android/incallui/VideoCallFragment.java b/InCallUI/src/com/android/incallui/VideoCallFragment.java deleted file mode 100644 index 6a46a423d..000000000 --- a/InCallUI/src/com/android/incallui/VideoCallFragment.java +++ /dev/null @@ -1,901 +0,0 @@ -/* - * Copyright (C) 2014 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.graphics.Matrix; -import android.graphics.Point; -import android.graphics.SurfaceTexture; -import android.os.Bundle; -import android.view.Display; -import android.view.LayoutInflater; -import android.view.Surface; -import android.view.TextureView; -import android.view.View; -import android.view.ViewGroup; -import android.view.ViewStub; -import android.view.ViewTreeObserver; -import android.widget.FrameLayout; -import android.widget.ImageView; - -import com.android.dialer.R; -import com.android.phone.common.animation.AnimUtils; -import com.google.common.base.Objects; - -/** - * Fragment containing video calling surfaces. - */ -public class VideoCallFragment extends BaseFragment implements VideoCallPresenter.VideoCallUi { - private static final String TAG = VideoCallFragment.class.getSimpleName(); - private static final boolean DEBUG = false; - - /** - * Used to indicate that the surface dimensions are not set. - */ - private static final int DIMENSIONS_NOT_SET = -1; - - /** - * Surface ID for the display surface. - */ - public static final int SURFACE_DISPLAY = 1; - - /** - * Surface ID for the preview surface. - */ - public static final int SURFACE_PREVIEW = 2; - - /** - * Used to indicate that the UI rotation is unknown. - */ - public static final int ORIENTATION_UNKNOWN = -1; - - // Static storage used to retain the video surfaces across Activity restart. - // TextureViews are not parcelable, so it is not possible to store them in the saved state. - private static boolean sVideoSurfacesInUse = false; - private static VideoCallSurface sPreviewSurface = null; - private static VideoCallSurface sDisplaySurface = null; - private static Point sDisplaySize = null; - - /** - * {@link ViewStub} holding the video call surfaces. This is the parent for the - * {@link VideoCallFragment}. Used to ensure that the video surfaces are only inflated when - * required. - */ - private ViewStub mVideoViewsStub; - - /** - * Inflated view containing the video call surfaces represented by the {@link ViewStub}. - */ - private View mVideoViews; - - /** - * The {@link FrameLayout} containing the preview surface. - */ - private View mPreviewVideoContainer; - - /** - * Icon shown to indicate that the outgoing camera has been turned off. - */ - private View mCameraOff; - - /** - * {@link ImageView} containing the user's profile photo. - */ - private ImageView mPreviewPhoto; - - /** - * {@code True} when the layout of the activity has been completed. - */ - private boolean mIsLayoutComplete = false; - - /** - * {@code True} if in landscape mode. - */ - private boolean mIsLandscape; - - private int mAnimationDuration; - - /** - * Inner-class representing a {@link TextureView} and its associated {@link SurfaceTexture} and - * {@link Surface}. Used to manage the lifecycle of these objects across device orientation - * changes. - */ - private static class VideoCallSurface implements TextureView.SurfaceTextureListener, - View.OnClickListener, View.OnAttachStateChangeListener { - private int mSurfaceId; - private VideoCallPresenter mPresenter; - private TextureView mTextureView; - private SurfaceTexture mSavedSurfaceTexture; - private Surface mSavedSurface; - private boolean mIsDoneWithSurface; - private int mWidth = DIMENSIONS_NOT_SET; - private int mHeight = DIMENSIONS_NOT_SET; - - /** - * Creates an instance of a {@link VideoCallSurface}. - * - * @param surfaceId The surface ID of the surface. - * @param textureView The {@link TextureView} for the surface. - */ - public VideoCallSurface(VideoCallPresenter presenter, int surfaceId, - TextureView textureView) { - this(presenter, surfaceId, textureView, DIMENSIONS_NOT_SET, DIMENSIONS_NOT_SET); - } - - /** - * Creates an instance of a {@link VideoCallSurface}. - * - * @param surfaceId The surface ID of the surface. - * @param textureView The {@link TextureView} for the surface. - * @param width The width of the surface. - * @param height The height of the surface. - */ - public VideoCallSurface(VideoCallPresenter presenter,int surfaceId, TextureView textureView, - int width, int height) { - Log.d(this, "VideoCallSurface: surfaceId=" + surfaceId + - " width=" + width + " height=" + height); - mPresenter = presenter; - mWidth = width; - mHeight = height; - mSurfaceId = surfaceId; - - recreateView(textureView); - } - - /** - * Recreates a {@link VideoCallSurface} after a device orientation change. Re-applies the - * saved {@link SurfaceTexture} to the - * - * @param view The {@link TextureView}. - */ - public void recreateView(TextureView view) { - if (DEBUG) { - Log.i(TAG, "recreateView: " + view); - } - - if (mTextureView == view) { - return; - } - - mTextureView = view; - mTextureView.setSurfaceTextureListener(this); - mTextureView.setOnClickListener(this); - - final boolean areSameSurfaces = - Objects.equal(mSavedSurfaceTexture, mTextureView.getSurfaceTexture()); - Log.d(this, "recreateView: SavedSurfaceTexture=" + mSavedSurfaceTexture - + " areSameSurfaces=" + areSameSurfaces); - if (mSavedSurfaceTexture != null && !areSameSurfaces) { - mTextureView.setSurfaceTexture(mSavedSurfaceTexture); - if (createSurface(mWidth, mHeight)) { - onSurfaceCreated(); - } - } - mIsDoneWithSurface = false; - } - - public void resetPresenter(VideoCallPresenter presenter) { - Log.d(this, "resetPresenter: CurrentPresenter=" + mPresenter + " NewPresenter=" - + presenter); - mPresenter = presenter; - } - - /** - * Handles {@link SurfaceTexture} callback to indicate that a {@link SurfaceTexture} has - * been successfully created. - * - * @param surfaceTexture The {@link SurfaceTexture} which has been created. - * @param width The width of the {@link SurfaceTexture}. - * @param height The height of the {@link SurfaceTexture}. - */ - @Override - public void onSurfaceTextureAvailable(SurfaceTexture surfaceTexture, int width, - int height) { - boolean surfaceCreated; - if (DEBUG) { - Log.i(TAG, "onSurfaceTextureAvailable: " + surfaceTexture); - } - // Where there is no saved {@link SurfaceTexture} available, use the newly created one. - // If a saved {@link SurfaceTexture} is available, we are re-creating after an - // orientation change. - Log.d(this, " onSurfaceTextureAvailable mSurfaceId=" + mSurfaceId + " surfaceTexture=" - + surfaceTexture + " width=" + width - + " height=" + height + " mSavedSurfaceTexture=" + mSavedSurfaceTexture); - Log.d(this, " onSurfaceTextureAvailable VideoCallPresenter=" + mPresenter); - if (mSavedSurfaceTexture == null) { - mSavedSurfaceTexture = surfaceTexture; - surfaceCreated = createSurface(width, height); - } else { - // A saved SurfaceTexture was found. - Log.d(this, " onSurfaceTextureAvailable: Replacing with cached surface..."); - mTextureView.setSurfaceTexture(mSavedSurfaceTexture); - surfaceCreated = true; - } - - // Inform presenter that the surface is available. - if (surfaceCreated) { - onSurfaceCreated(); - } - } - - private void onSurfaceCreated() { - if (mPresenter != null) { - mPresenter.onSurfaceCreated(mSurfaceId); - } else { - Log.e(this, "onSurfaceTextureAvailable: Presenter is null"); - } - } - - /** - * Handles a change in the {@link SurfaceTexture}'s size. - * - * @param surfaceTexture The {@link SurfaceTexture}. - * @param width The new width. - * @param height The new height. - */ - @Override - public void onSurfaceTextureSizeChanged(SurfaceTexture surfaceTexture, int width, - int height) { - // Not handled - } - - /** - * Handles {@link SurfaceTexture} destruct callback, indicating that it has been destroyed. - * - * @param surfaceTexture The {@link SurfaceTexture}. - * @return {@code True} if the {@link TextureView} can release the {@link SurfaceTexture}. - */ - @Override - public boolean onSurfaceTextureDestroyed(SurfaceTexture surfaceTexture) { - /** - * Destroying the surface texture; inform the presenter so it can null the surfaces. - */ - Log.d(this, " onSurfaceTextureDestroyed mSurfaceId=" + mSurfaceId + " surfaceTexture=" - + surfaceTexture + " SavedSurfaceTexture=" + mSavedSurfaceTexture - + " SavedSurface=" + mSavedSurface); - Log.d(this, " onSurfaceTextureDestroyed VideoCallPresenter=" + mPresenter); - - // Notify presenter if it is not null. - onSurfaceDestroyed(); - - if (mIsDoneWithSurface) { - onSurfaceReleased(); - if (mSavedSurface != null) { - mSavedSurface.release(); - mSavedSurface = null; - } - } - return mIsDoneWithSurface; - } - - private void onSurfaceDestroyed() { - if (mPresenter != null) { - mPresenter.onSurfaceDestroyed(mSurfaceId); - } else { - Log.e(this, "onSurfaceTextureDestroyed: Presenter is null."); - } - } - - /** - * Handles {@link SurfaceTexture} update callback. - * @param surface - */ - @Override - public void onSurfaceTextureUpdated(SurfaceTexture surface) { - // Not Handled - } - - @Override - public void onViewAttachedToWindow(View v) { - if (DEBUG) { - Log.i(TAG, "OnViewAttachedToWindow"); - } - if (mSavedSurfaceTexture != null) { - mTextureView.setSurfaceTexture(mSavedSurfaceTexture); - } - } - - @Override - public void onViewDetachedFromWindow(View v) {} - - /** - * Retrieves the current {@link TextureView}. - * - * @return The {@link TextureView}. - */ - public TextureView getTextureView() { - return mTextureView; - } - - /** - * Called by the user presenter to indicate that the surface is no longer required due to a - * change in video state. Releases and clears out the saved surface and surface textures. - */ - public void setDoneWithSurface() { - Log.d(this, "setDoneWithSurface: SavedSurface=" + mSavedSurface - + " SavedSurfaceTexture=" + mSavedSurfaceTexture); - mIsDoneWithSurface = true; - if (mTextureView != null && mTextureView.isAvailable()) { - return; - } - - if (mSavedSurface != null) { - onSurfaceReleased(); - mSavedSurface.release(); - mSavedSurface = null; - } - if (mSavedSurfaceTexture != null) { - mSavedSurfaceTexture.release(); - mSavedSurfaceTexture = null; - } - } - - private void onSurfaceReleased() { - if (mPresenter != null) { - mPresenter.onSurfaceReleased(mSurfaceId); - } else { - Log.d(this, "setDoneWithSurface: Presenter is null."); - } - } - - /** - * Retrieves the saved surface instance. - * - * @return The surface. - */ - public Surface getSurface() { - return mSavedSurface; - } - - /** - * Sets the dimensions of the surface. - * - * @param width The width of the surface, in pixels. - * @param height The height of the surface, in pixels. - */ - public void setSurfaceDimensions(int width, int height) { - Log.d(this, "setSurfaceDimensions, width=" + width + " height=" + height); - mWidth = width; - mHeight = height; - - if (width != DIMENSIONS_NOT_SET && height != DIMENSIONS_NOT_SET - && mSavedSurfaceTexture != null) { - Log.d(this, "setSurfaceDimensions, mSavedSurfaceTexture is NOT equal to null."); - mSavedSurfaceTexture.setDefaultBufferSize(width, height); - } - } - - /** - * Creates the {@link Surface}, adjusting the {@link SurfaceTexture} buffer size. - * @param width The width of the surface to create. - * @param height The height of the surface to create. - */ - private boolean createSurface(int width, int height) { - Log.d(this, "createSurface mSavedSurfaceTexture=" + mSavedSurfaceTexture - + " mSurfaceId =" + mSurfaceId + " mWidth " + width + " mHeight=" + height); - if (width != DIMENSIONS_NOT_SET && height != DIMENSIONS_NOT_SET - && mSavedSurfaceTexture != null) { - mSavedSurfaceTexture.setDefaultBufferSize(width, height); - mSavedSurface = new Surface(mSavedSurfaceTexture); - return true; - } - return false; - } - - /** - * Handles a user clicking the surface, which is the trigger to toggle the full screen - * Video UI. - * - * @param view The view receiving the click. - */ - @Override - public void onClick(View view) { - if (mPresenter != null) { - mPresenter.onSurfaceClick(mSurfaceId); - } else { - Log.e(this, "onClick: Presenter is null."); - } - } - - /** - * Returns the dimensions of the surface. - * - * @return The dimensions of the surface. - */ - public Point getSurfaceDimensions() { - return new Point(mWidth, mHeight); - } - }; - - @Override - public void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - - mAnimationDuration = getResources().getInteger(R.integer.video_animation_duration); - } - - /** - * Handles creation of the activity and initialization of the presenter. - * - * @param savedInstanceState The saved instance state. - */ - @Override - public void onActivityCreated(Bundle savedInstanceState) { - mIsLandscape = getResources().getBoolean(R.bool.is_layout_landscape); - Log.d(this, "onActivityCreated: IsLandscape=" + mIsLandscape); - getPresenter().init(getActivity()); - - super.onActivityCreated(savedInstanceState); - } - - @Override - public View onCreateView(LayoutInflater inflater, ViewGroup container, - Bundle savedInstanceState) { - super.onCreateView(inflater, container, savedInstanceState); - - final View view = inflater.inflate(R.layout.video_call_fragment, container, false); - - return view; - } - - /** - * Centers the display view vertically for portrait orientations. The view is centered within - * the available space not occupied by the call card. This is a no-op for landscape mode. - * - * @param displayVideo The video view to center. - */ - private void centerDisplayView(View displayVideo) { - if (!mIsLandscape) { - ViewGroup.LayoutParams p = displayVideo.getLayoutParams(); - int height = p.height; - - float spaceBesideCallCard = InCallPresenter.getInstance().getSpaceBesideCallCard(); - // If space beside call card is zeo, layout hasn't happened yet so there is no point - // in attempting to center the view. - if (Math.abs(spaceBesideCallCard - 0.0f) < 0.0001) { - return; - } - float videoViewTranslation = height / 2 - spaceBesideCallCard / 2; - displayVideo.setTranslationY(videoViewTranslation); - } - } - - /** - * After creation of the fragment view, retrieves the required views. - * - * @param view The fragment view. - * @param savedInstanceState The saved instance state. - */ - @Override - public void onViewCreated(View view, Bundle savedInstanceState) { - super.onViewCreated(view, savedInstanceState); - Log.d(this, "onViewCreated: VideoSurfacesInUse=" + sVideoSurfacesInUse); - - mVideoViewsStub = (ViewStub) view.findViewById(R.id.videoCallViewsStub); - } - - @Override - public void onStop() { - super.onStop(); - Log.d(this, "onStop:"); - } - - @Override - public void onPause() { - super.onPause(); - Log.d(this, "onPause:"); - getPresenter().cancelAutoFullScreen(); - } - - @Override - public void onDestroyView() { - super.onDestroyView(); - Log.d(this, "onDestroyView:"); - } - - /** - * Creates the presenter for the {@link VideoCallFragment}. - * @return The presenter instance. - */ - @Override - public VideoCallPresenter createPresenter() { - Log.d(this, "createPresenter"); - VideoCallPresenter presenter = new VideoCallPresenter(); - onPresenterChanged(presenter); - return presenter; - } - - /** - * @return The user interface for the presenter, which is this fragment. - */ - @Override - public VideoCallPresenter.VideoCallUi getUi() { - return this; - } - - /** - * Inflate video surfaces. - * - * @param show {@code True} if the video surfaces should be shown. - */ - private void inflateVideoUi(boolean show) { - int visibility = show ? View.VISIBLE : View.GONE; - getView().setVisibility(visibility); - - if (show) { - inflateVideoCallViews(); - } - - if (mVideoViews != null) { - mVideoViews.setVisibility(visibility); - } - } - - /** - * Hides and shows the incoming video view and changes the outgoing video view's state based on - * whether outgoing view is enabled or not. - */ - @Override - public void showVideoViews(boolean previewPaused, boolean showIncoming) { - inflateVideoUi(true); - - View incomingVideoView = mVideoViews.findViewById(R.id.incomingVideo); - if (incomingVideoView != null) { - incomingVideoView.setVisibility(showIncoming ? View.VISIBLE : View.INVISIBLE); - } - if (mCameraOff != null) { - mCameraOff.setVisibility(!previewPaused ? View.VISIBLE : View.INVISIBLE); - } - if (mPreviewPhoto != null) { - mPreviewPhoto.setVisibility(!previewPaused ? View.VISIBLE : View.INVISIBLE); - } - } - - /** - * Hide all video views. - */ - @Override - public void hideVideoUi() { - inflateVideoUi(false); - } - - /** - * Cleans up the video telephony surfaces. Used when the presenter indicates a change to an - * audio-only state. Since the surfaces are static, it is important to ensure they are cleaned - * up promptly. - */ - @Override - public void cleanupSurfaces() { - Log.d(this, "cleanupSurfaces"); - if (sDisplaySurface != null) { - sDisplaySurface.setDoneWithSurface(); - sDisplaySurface = null; - } - if (sPreviewSurface != null) { - sPreviewSurface.setDoneWithSurface(); - sPreviewSurface = null; - } - sVideoSurfacesInUse = false; - } - - @Override - public ImageView getPreviewPhotoView() { - return mPreviewPhoto; - } - - /** - * Adjusts the location of the video preview view by the specified offset. - * - * @param shiftUp {@code true} if the preview should shift up, {@code false} if it should shift - * down. - * @param offset The offset. - */ - @Override - public void adjustPreviewLocation(boolean shiftUp, int offset) { - if (sPreviewSurface == null || mPreviewVideoContainer == null) { - return; - } - - // Set the position of the secondary call info card to its starting location. - mPreviewVideoContainer.setTranslationY(shiftUp ? 0 : -offset); - - // Animate the secondary card info slide up/down as it appears and disappears. - mPreviewVideoContainer.animate() - .setInterpolator(AnimUtils.EASE_OUT_EASE_IN) - .setDuration(mAnimationDuration) - .translationY(shiftUp ? -offset : 0) - .start(); - } - - private void onPresenterChanged(VideoCallPresenter presenter) { - Log.d(this, "onPresenterChanged: Presenter=" + presenter); - if (sDisplaySurface != null) { - sDisplaySurface.resetPresenter(presenter);; - } - if (sPreviewSurface != null) { - sPreviewSurface.resetPresenter(presenter); - } - } - - /** - * @return {@code True} if the display video surface has been created. - */ - @Override - public boolean isDisplayVideoSurfaceCreated() { - boolean ret = sDisplaySurface != null && sDisplaySurface.getSurface() != null; - Log.d(this, " isDisplayVideoSurfaceCreated returns " + ret); - return ret; - } - - /** - * @return {@code True} if the preview video surface has been created. - */ - @Override - public boolean isPreviewVideoSurfaceCreated() { - boolean ret = sPreviewSurface != null && sPreviewSurface.getSurface() != null; - Log.d(this, " isPreviewVideoSurfaceCreated returns " + ret); - return ret; - } - - /** - * {@link android.view.Surface} on which incoming video for a video call is displayed. - * {@code Null} until the video views {@link android.view.ViewStub} is inflated. - */ - @Override - public Surface getDisplayVideoSurface() { - return sDisplaySurface == null ? null : sDisplaySurface.getSurface(); - } - - /** - * {@link android.view.Surface} on which a preview of the outgoing video for a video call is - * displayed. {@code Null} until the video views {@link android.view.ViewStub} is inflated. - */ - @Override - public Surface getPreviewVideoSurface() { - return sPreviewSurface == null ? null : sPreviewSurface.getSurface(); - } - - /** - * Changes the dimensions of the preview surface. Called when the dimensions change due to a - * device orientation change. - * - * @param width The new width. - * @param height The new height. - */ - @Override - public void setPreviewSize(int width, int height) { - Log.d(this, "setPreviewSize: width=" + width + " height=" + height); - if (sPreviewSurface != null) { - TextureView preview = sPreviewSurface.getTextureView(); - - if (preview == null ) { - return; - } - - // Set the dimensions of both the video surface and the FrameLayout containing it. - ViewGroup.LayoutParams params = preview.getLayoutParams(); - params.width = width; - params.height = height; - preview.setLayoutParams(params); - - if (mPreviewVideoContainer != null) { - ViewGroup.LayoutParams containerParams = mPreviewVideoContainer.getLayoutParams(); - containerParams.width = width; - containerParams.height = height; - mPreviewVideoContainer.setLayoutParams(containerParams); - } - - // The width and height are interchanged outside of this method based on the current - // orientation, so we can transform using "width", which will be either the width or - // the height. - Matrix transform = new Matrix(); - transform.setScale(-1, 1, width/2, 0); - preview.setTransform(transform); - } - } - - /** - * Sets the rotation of the preview surface. Called when the dimensions change due to a - * device orientation change. - * - * Please note that the screen orientation passed in is subtracted from 360 to get the actual - * preview rotation values. - * - * @param rotation The screen orientation. One of - - * {@link InCallOrientationEventListener#SCREEN_ORIENTATION_0}, - * {@link InCallOrientationEventListener#SCREEN_ORIENTATION_90}, - * {@link InCallOrientationEventListener#SCREEN_ORIENTATION_180}, - * {@link InCallOrientationEventListener#SCREEN_ORIENTATION_270}). - */ - @Override - public void setPreviewRotation(int orientation) { - Log.d(this, "setPreviewRotation: orientation=" + orientation); - if (sPreviewSurface != null) { - TextureView preview = sPreviewSurface.getTextureView(); - - if (preview == null ) { - return; - } - - preview.setRotation(orientation); - } - } - - @Override - public void setPreviewSurfaceSize(int width, int height) { - final boolean isPreviewSurfaceAvailable = sPreviewSurface != null; - Log.d(this, "setPreviewSurfaceSize: width=" + width + " height=" + height + - " isPreviewSurfaceAvailable=" + isPreviewSurfaceAvailable); - if (isPreviewSurfaceAvailable) { - sPreviewSurface.setSurfaceDimensions(width, height); - } - } - - /** - * returns UI's current orientation. - */ - @Override - public int getCurrentRotation() { - try { - return getActivity().getWindowManager().getDefaultDisplay().getRotation(); - } catch (Exception e) { - Log.e(this, "getCurrentRotation: Retrieving current rotation failed. Ex=" + e); - } - return ORIENTATION_UNKNOWN; - } - - /** - * Changes the dimensions of the display video surface. Called when the dimensions change due to - * a peer resolution update - * - * @param width The new width. - * @param height The new height. - */ - @Override - public void setDisplayVideoSize(int width, int height) { - Log.v(this, "setDisplayVideoSize: width=" + width + " height=" + height); - if (sDisplaySurface != null) { - TextureView displayVideo = sDisplaySurface.getTextureView(); - if (displayVideo == null) { - Log.e(this, "Display Video texture view is null. Bail out"); - return; - } - sDisplaySize = new Point(width, height); - setSurfaceSizeAndTranslation(displayVideo, sDisplaySize); - } else { - Log.e(this, "Display Video Surface is null. Bail out"); - } - } - - /** - * Determines the size of the device screen. - * - * @return {@link Point} specifying the width and height of the screen. - */ - @Override - public Point getScreenSize() { - // Get current screen size. - Display display = getActivity().getWindowManager().getDefaultDisplay(); - Point size = new Point(); - display.getSize(size); - - return size; - } - - /** - * Determines the size of the preview surface. - * - * @return {@link Point} specifying the width and height of the preview surface. - */ - @Override - public Point getPreviewSize() { - if (sPreviewSurface == null) { - return null; - } - return sPreviewSurface.getSurfaceDimensions(); - } - - /** - * Inflates the {@link ViewStub} containing the incoming and outgoing surfaces, if necessary, - * and creates {@link VideoCallSurface} instances to track the surfaces. - */ - private void inflateVideoCallViews() { - Log.d(this, "inflateVideoCallViews"); - if (mVideoViews == null ) { - mVideoViews = mVideoViewsStub.inflate(); - } - - if (mVideoViews != null) { - mPreviewVideoContainer = mVideoViews.findViewById(R.id.previewVideoContainer); - mCameraOff = mVideoViews.findViewById(R.id.previewCameraOff); - mPreviewPhoto = (ImageView) mVideoViews.findViewById(R.id.previewProfilePhoto); - - TextureView displaySurface = (TextureView) mVideoViews.findViewById(R.id.incomingVideo); - - Log.d(this, "inflateVideoCallViews: sVideoSurfacesInUse=" + sVideoSurfacesInUse); - //If peer adjusted screen size is not available, set screen size to default display size - Point screenSize = sDisplaySize == null ? getScreenSize() : sDisplaySize; - setSurfaceSizeAndTranslation(displaySurface, screenSize); - - if (!sVideoSurfacesInUse) { - // Where the video surfaces are not already in use (first time creating them), - // setup new VideoCallSurface instances to track them. - Log.d(this, " inflateVideoCallViews screenSize" + screenSize); - - sDisplaySurface = new VideoCallSurface(getPresenter(), SURFACE_DISPLAY, - (TextureView) mVideoViews.findViewById(R.id.incomingVideo), screenSize.x, - screenSize.y); - sPreviewSurface = new VideoCallSurface(getPresenter(), SURFACE_PREVIEW, - (TextureView) mVideoViews.findViewById(R.id.previewVideo)); - sVideoSurfacesInUse = true; - } else { - // In this case, the video surfaces are already in use (we are recreating the - // Fragment after a destroy/create cycle resulting from a rotation. - sDisplaySurface.recreateView((TextureView) mVideoViews.findViewById( - R.id.incomingVideo)); - sPreviewSurface.recreateView((TextureView) mVideoViews.findViewById( - R.id.previewVideo)); - } - - // Attempt to center the incoming video view, if it is in the layout. - final ViewTreeObserver observer = mVideoViews.getViewTreeObserver(); - observer.addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() { - @Override - public void onGlobalLayout() { - // Check if the layout includes the incoming video surface -- this will only be the - // case for a video call. - View displayVideo = mVideoViews.findViewById(R.id.incomingVideo); - if (displayVideo != null) { - centerDisplayView(displayVideo); - } - mIsLayoutComplete = true; - - // Remove the listener so we don't continually re-layout. - ViewTreeObserver observer = mVideoViews.getViewTreeObserver(); - if (observer.isAlive()) { - observer.removeOnGlobalLayoutListener(this); - } - } - }); - } - } - - /** - * Resizes a surface so that it has the same size as the full screen and so that it is - * centered vertically below the call card. - * - * @param textureView The {@link TextureView} to resize and position. - * @param size The size of the screen. - */ - private void setSurfaceSizeAndTranslation(TextureView textureView, Point size) { - // Set the surface to have that size. - ViewGroup.LayoutParams params = textureView.getLayoutParams(); - params.width = size.x; - params.height = size.y; - textureView.setLayoutParams(params); - Log.d(this, "setSurfaceSizeAndTranslation: Size=" + size + "IsLayoutComplete=" + - mIsLayoutComplete + "IsLandscape=" + mIsLandscape); - - // It is only possible to center the display view if layout of the views has completed. - // It is only after layout is complete that the dimensions of the Call Card has been - // established, which is a prerequisite to centering the view. - // Incoming video calls will center the view - if (mIsLayoutComplete) { - centerDisplayView(textureView); - } - } -} diff --git a/InCallUI/src/com/android/incallui/VideoCallPresenter.java b/InCallUI/src/com/android/incallui/VideoCallPresenter.java deleted file mode 100644 index 06e3e4440..000000000 --- a/InCallUI/src/com/android/incallui/VideoCallPresenter.java +++ /dev/null @@ -1,1306 +0,0 @@ -/* - * Copyright (C) 2014 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.content.Context; -import android.database.Cursor; -import android.graphics.Point; -import android.net.Uri; -import android.os.AsyncTask; -import android.os.Handler; -import android.os.Looper; -import android.provider.ContactsContract; -import android.telecom.Connection; -import android.telecom.InCallService.VideoCall; -import android.telecom.VideoProfile; -import android.telecom.VideoProfile.CameraCapabilities; -import android.view.Surface; -import android.widget.ImageView; - -import com.android.contacts.common.ContactPhotoManager; -import com.android.contacts.common.compat.CompatUtils; -import com.android.dialer.R; -import com.android.incallui.InCallPresenter.InCallDetailsListener; -import com.android.incallui.InCallPresenter.InCallOrientationListener; -import com.android.incallui.InCallPresenter.InCallStateListener; -import com.android.incallui.InCallPresenter.IncomingCallListener; -import com.android.incallui.InCallVideoCallCallbackNotifier.SurfaceChangeListener; -import com.android.incallui.InCallVideoCallCallbackNotifier.VideoEventListener; - -import java.util.Objects; - -/** - * Logic related to the {@link VideoCallFragment} and for managing changes to the video calling - * surfaces based on other user interface events and incoming events from the - * {@class VideoCallListener}. - *

- * When a call's video state changes to bi-directional video, the - * {@link com.android.incallui.VideoCallPresenter} performs the following negotiation with the - * telephony layer: - *

    - *
  • {@code VideoCallPresenter} creates and informs telephony of the display surface.
  • - *
  • {@code VideoCallPresenter} creates the preview surface.
  • - *
  • {@code VideoCallPresenter} informs telephony of the currently selected camera.
  • - *
  • Telephony layer sends {@link CameraCapabilities}, including the - * dimensions of the video for the current camera.
  • - *
  • {@code VideoCallPresenter} adjusts size of the preview surface to match the aspect - * ratio of the camera.
  • - *
  • {@code VideoCallPresenter} informs telephony of the new preview surface.
  • - *
- *

- * When downgrading to an audio-only video state, the {@code VideoCallPresenter} nulls both - * surfaces. - */ -public class VideoCallPresenter extends Presenter implements - IncomingCallListener, InCallOrientationListener, InCallStateListener, - InCallDetailsListener, SurfaceChangeListener, VideoEventListener, - InCallPresenter.InCallEventListener { - public static final String TAG = "VideoCallPresenter"; - - public static final boolean DEBUG = false; - - /** - * Runnable which is posted to schedule automatically entering fullscreen mode. Will not auto - * enter fullscreen mode if the dialpad is visible (doing so would make it impossible to exit - * the dialpad). - */ - private Runnable mAutoFullscreenRunnable = new Runnable() { - @Override - public void run() { - if (mAutoFullScreenPending && !InCallPresenter.getInstance().isDialpadVisible() - && mIsVideoMode) { - - Log.v(this, "Automatically entering fullscreen mode."); - InCallPresenter.getInstance().setFullScreen(true); - mAutoFullScreenPending = false; - } else { - Log.v(this, "Skipping scheduled fullscreen mode."); - } - } - }; - - /** - * Defines the state of the preview surface negotiation with the telephony layer. - */ - private class PreviewSurfaceState { - /** - * The camera has not yet been set on the {@link VideoCall}; negotiation has not yet - * started. - */ - private static final int NONE = 0; - - /** - * The camera has been set on the {@link VideoCall}, but camera capabilities have not yet - * been received. - */ - private static final int CAMERA_SET = 1; - - /** - * The camera capabilties have been received from telephony, but the surface has not yet - * been set on the {@link VideoCall}. - */ - private static final int CAPABILITIES_RECEIVED = 2; - - /** - * The surface has been set on the {@link VideoCall}. - */ - private static final int SURFACE_SET = 3; - } - - /** - * The minimum width or height of the preview surface. Used when re-sizing the preview surface - * to match the aspect ratio of the currently selected camera. - */ - private float mMinimumVideoDimension; - - /** - * The current context. - */ - private Context mContext; - - /** - * The call the video surfaces are currently related to - */ - private Call mPrimaryCall; - - /** - * The {@link VideoCall} used to inform the video telephony layer of changes to the video - * surfaces. - */ - private VideoCall mVideoCall; - - /** - * Determines if the current UI state represents a video call. - */ - private int mCurrentVideoState; - - /** - * Call's current state - */ - private int mCurrentCallState = Call.State.INVALID; - - /** - * Determines the device orientation (portrait/lanscape). - */ - private int mDeviceOrientation = InCallOrientationEventListener.SCREEN_ORIENTATION_0; - - /** - * Tracks the state of the preview surface negotiation with the telephony layer. - */ - private int mPreviewSurfaceState = PreviewSurfaceState.NONE; - - private static boolean mIsVideoMode = false; - - /** - * Contact photo manager to retrieve cached contact photo information. - */ - private ContactPhotoManager mContactPhotoManager = null; - - /** - * The URI for the user's profile photo, or {@code null} if not specified. - */ - private ContactInfoCache.ContactCacheEntry mProfileInfo = null; - - /** - * UI thread handler used for delayed task execution. - */ - private Handler mHandler; - - /** - * Determines whether video calls should automatically enter full screen mode after - * {@link #mAutoFullscreenTimeoutMillis} milliseconds. - */ - private boolean mIsAutoFullscreenEnabled = false; - - /** - * Determines the number of milliseconds after which a video call will automatically enter - * fullscreen mode. Requires {@link #mIsAutoFullscreenEnabled} to be {@code true}. - */ - private int mAutoFullscreenTimeoutMillis = 0; - - /** - * Determines if the countdown is currently running to automatically enter full screen video - * mode. - */ - private boolean mAutoFullScreenPending = false; - - /** - * Initializes the presenter. - * - * @param context The current context. - */ - public void init(Context context) { - mContext = context; - mMinimumVideoDimension = mContext.getResources().getDimension( - R.dimen.video_preview_small_dimension); - mHandler = new Handler(Looper.getMainLooper()); - mIsAutoFullscreenEnabled = mContext.getResources() - .getBoolean(R.bool.video_call_auto_fullscreen); - mAutoFullscreenTimeoutMillis = mContext.getResources().getInteger( - R.integer.video_call_auto_fullscreen_timeout); - } - - /** - * Called when the user interface is ready to be used. - * - * @param ui The Ui implementation that is now ready to be used. - */ - @Override - public void onUiReady(VideoCallUi ui) { - super.onUiReady(ui); - Log.d(this, "onUiReady:"); - - // Do not register any listeners if video calling is not compatible to safeguard against - // any accidental calls of video calling code. - if (!CompatUtils.isVideoCompatible()) { - return; - } - - // Register for call state changes last - InCallPresenter.getInstance().addListener(this); - InCallPresenter.getInstance().addDetailsListener(this); - InCallPresenter.getInstance().addIncomingCallListener(this); - InCallPresenter.getInstance().addOrientationListener(this); - // To get updates of video call details changes - InCallPresenter.getInstance().addDetailsListener(this); - InCallPresenter.getInstance().addInCallEventListener(this); - - // Register for surface and video events from {@link InCallVideoCallListener}s. - InCallVideoCallCallbackNotifier.getInstance().addSurfaceChangeListener(this); - InCallVideoCallCallbackNotifier.getInstance().addVideoEventListener(this); - mCurrentVideoState = VideoProfile.STATE_AUDIO_ONLY; - mCurrentCallState = Call.State.INVALID; - - final InCallPresenter.InCallState inCallState = - InCallPresenter.getInstance().getInCallState(); - onStateChange(inCallState, inCallState, CallList.getInstance()); - } - - /** - * Called when the user interface is no longer ready to be used. - * - * @param ui The Ui implementation that is no longer ready to be used. - */ - @Override - public void onUiUnready(VideoCallUi ui) { - super.onUiUnready(ui); - Log.d(this, "onUiUnready:"); - - if (!CompatUtils.isVideoCompatible()) { - return; - } - - cancelAutoFullScreen(); - - InCallPresenter.getInstance().removeListener(this); - InCallPresenter.getInstance().removeDetailsListener(this); - InCallPresenter.getInstance().removeIncomingCallListener(this); - InCallPresenter.getInstance().removeOrientationListener(this); - InCallPresenter.getInstance().removeInCallEventListener(this); - - InCallVideoCallCallbackNotifier.getInstance().removeSurfaceChangeListener(this); - InCallVideoCallCallbackNotifier.getInstance().removeVideoEventListener(this); - } - - /** - * Handles the creation of a surface in the {@link VideoCallFragment}. - * - * @param surface The surface which was created. - */ - public void onSurfaceCreated(int surface) { - Log.d(this, "onSurfaceCreated surface=" + surface + " mVideoCall=" + mVideoCall); - Log.d(this, "onSurfaceCreated PreviewSurfaceState=" + mPreviewSurfaceState); - Log.d(this, "onSurfaceCreated presenter=" + this); - - final VideoCallUi ui = getUi(); - if (ui == null || mVideoCall == null) { - Log.w(this, "onSurfaceCreated: Error bad state VideoCallUi=" + ui + " mVideoCall=" - + mVideoCall); - return; - } - - // If the preview surface has just been created and we have already received camera - // capabilities, but not yet set the surface, we will set the surface now. - if (surface == VideoCallFragment.SURFACE_PREVIEW ) { - if (mPreviewSurfaceState == PreviewSurfaceState.CAPABILITIES_RECEIVED) { - mPreviewSurfaceState = PreviewSurfaceState.SURFACE_SET; - mVideoCall.setPreviewSurface(ui.getPreviewVideoSurface()); - } else if (mPreviewSurfaceState == PreviewSurfaceState.NONE && isCameraRequired()){ - enableCamera(mVideoCall, true); - } - } else if (surface == VideoCallFragment.SURFACE_DISPLAY) { - mVideoCall.setDisplaySurface(ui.getDisplayVideoSurface()); - } - } - - /** - * Handles structural changes (format or size) to a surface. - * - * @param surface The surface which changed. - * @param format The new PixelFormat of the surface. - * @param width The new width of the surface. - * @param height The new height of the surface. - */ - public void onSurfaceChanged(int surface, int format, int width, int height) { - //Do stuff - } - - /** - * Handles the destruction of a surface in the {@link VideoCallFragment}. - * Note: The surface is being released, that is, it is no longer valid. - * - * @param surface The surface which was destroyed. - */ - public void onSurfaceReleased(int surface) { - Log.d(this, "onSurfaceReleased: mSurfaceId=" + surface); - if ( mVideoCall == null) { - Log.w(this, "onSurfaceReleased: VideoCall is null. mSurfaceId=" + - surface); - return; - } - - if (surface == VideoCallFragment.SURFACE_DISPLAY) { - mVideoCall.setDisplaySurface(null); - } else if (surface == VideoCallFragment.SURFACE_PREVIEW) { - mVideoCall.setPreviewSurface(null); - enableCamera(mVideoCall, false); - } - } - - /** - * Called by {@link VideoCallFragment} when the surface is detached from UI (TextureView). - * Note: The surface will be cached by {@link VideoCallFragment}, so we don't immediately - * null out incoming video surface. - * @see VideoCallPresenter#onSurfaceReleased(int) - * - * @param surface The surface which was detached. - */ - public void onSurfaceDestroyed(int surface) { - Log.d(this, "onSurfaceDestroyed: mSurfaceId=" + surface); - if (mVideoCall == null) { - return; - } - - final boolean isChangingConfigurations = - InCallPresenter.getInstance().isChangingConfigurations(); - Log.d(this, "onSurfaceDestroyed: isChangingConfigurations=" + isChangingConfigurations); - - if (surface == VideoCallFragment.SURFACE_PREVIEW) { - if (!isChangingConfigurations) { - enableCamera(mVideoCall, false); - } else { - Log.w(this, "onSurfaceDestroyed: Activity is being destroyed due " - + "to configuration changes. Not closing the camera."); - } - } - } - - /** - * Handles clicks on the video surfaces by toggling full screen state. - * Informs the {@link InCallPresenter} of the change so that it can inform the - * {@link CallCardPresenter} of the change. - * - * @param surfaceId The video surface receiving the click. - */ - public void onSurfaceClick(int surfaceId) { - boolean isFullscreen = InCallPresenter.getInstance().toggleFullscreenMode(); - Log.v(this, "toggleFullScreen = " + isFullscreen); - } - - /** - * Handles incoming calls. - * - * @param oldState The old in call state. - * @param newState The new in call state. - * @param call The call. - */ - @Override - public void onIncomingCall(InCallPresenter.InCallState oldState, - InCallPresenter.InCallState newState, Call call) { - // same logic should happen as with onStateChange() - onStateChange(oldState, newState, CallList.getInstance()); - } - - /** - * Handles state changes (including incoming calls) - * - * @param newState The in call state. - * @param callList The call list. - */ - @Override - public void onStateChange(InCallPresenter.InCallState oldState, - InCallPresenter.InCallState newState, CallList callList) { - Log.d(this, "onStateChange oldState" + oldState + " newState=" + newState + - " isVideoMode=" + isVideoMode()); - - if (newState == InCallPresenter.InCallState.NO_CALLS) { - if (isVideoMode()) { - exitVideoMode(); - } - - cleanupSurfaces(); - } - - // Determine the primary active call). - Call primary = null; - - // Determine the call which is the focus of the user's attention. In the case of an - // incoming call waiting call, the primary call is still the active video call, however - // the determination of whether we should be in fullscreen mode is based on the type of the - // incoming call, not the active video call. - Call currentCall = null; - - if (newState == InCallPresenter.InCallState.INCOMING) { - // We don't want to replace active video call (primary call) - // with a waiting call, since user may choose to ignore/decline the waiting call and - // this should have no impact on current active video call, that is, we should not - // change the camera or UI unless the waiting VT call becomes active. - primary = callList.getActiveCall(); - currentCall = callList.getIncomingCall(); - if (!VideoUtils.isActiveVideoCall(primary)) { - primary = callList.getIncomingCall(); - } - } else if (newState == InCallPresenter.InCallState.OUTGOING) { - currentCall = primary = callList.getOutgoingCall(); - } else if (newState == InCallPresenter.InCallState.PENDING_OUTGOING) { - currentCall = primary = callList.getPendingOutgoingCall(); - } else if (newState == InCallPresenter.InCallState.INCALL) { - currentCall = primary = callList.getActiveCall(); - } - - final boolean primaryChanged = !Objects.equals(mPrimaryCall, primary); - Log.d(this, "onStateChange primaryChanged=" + primaryChanged); - Log.d(this, "onStateChange primary= " + primary); - Log.d(this, "onStateChange mPrimaryCall = " + mPrimaryCall); - if (primaryChanged) { - onPrimaryCallChanged(primary); - } else if (mPrimaryCall != null) { - updateVideoCall(primary); - } - updateCallCache(primary); - - // If the call context changed, potentially exit fullscreen or schedule auto enter of - // fullscreen mode. - // If the current call context is no longer a video call, exit fullscreen mode. - maybeExitFullscreen(currentCall); - // Schedule auto-enter of fullscreen mode if the current call context is a video call - maybeAutoEnterFullscreen(currentCall); - } - - /** - * Handles a change to the fullscreen mode of the app. - * - * @param isFullscreenMode {@code true} if the app is now fullscreen, {@code false} otherwise. - */ - @Override - public void onFullscreenModeChanged(boolean isFullscreenMode) { - cancelAutoFullScreen(); - } - - /** - * Handles changes to the visibility of the secondary caller info bar. - * - * @param isVisible {@code true} if the secondary caller info is showing, {@code false} - * otherwise. - * @param height the height of the secondary caller info bar. - */ - @Override - public void onSecondaryCallerInfoVisibilityChanged(boolean isVisible, int height) { - Log.d(this, - "onSecondaryCallerInfoVisibilityChanged : isVisible = " + isVisible + " height = " - + height); - getUi().adjustPreviewLocation(isVisible /* shiftUp */, height); - } - - private void checkForVideoStateChange(Call call) { - final boolean isVideoCall = VideoUtils.isVideoCall(call); - final boolean hasVideoStateChanged = mCurrentVideoState != call.getVideoState(); - - Log.d(this, "checkForVideoStateChange: isVideoCall= " + isVideoCall - + " hasVideoStateChanged=" + hasVideoStateChanged + " isVideoMode=" - + isVideoMode() + " previousVideoState: " + - VideoProfile.videoStateToString(mCurrentVideoState) + " newVideoState: " - + VideoProfile.videoStateToString(call.getVideoState())); - - if (!hasVideoStateChanged) { - return; - } - - updateCameraSelection(call); - - if (isVideoCall) { - adjustVideoMode(call); - } else if (isVideoMode()) { - exitVideoMode(); - } - } - - private void checkForCallStateChange(Call call) { - final boolean isVideoCall = VideoUtils.isVideoCall(call); - final boolean hasCallStateChanged = mCurrentCallState != call.getState(); - - Log.d(this, "checkForCallStateChange: isVideoCall= " + isVideoCall - + " hasCallStateChanged=" + - hasCallStateChanged + " isVideoMode=" + isVideoMode()); - - if (!hasCallStateChanged) { - return; - } - - if (isVideoCall) { - final InCallCameraManager cameraManager = InCallPresenter.getInstance(). - getInCallCameraManager(); - - String prevCameraId = cameraManager.getActiveCameraId(); - updateCameraSelection(call); - String newCameraId = cameraManager.getActiveCameraId(); - - if (!Objects.equals(prevCameraId, newCameraId) && VideoUtils.isActiveVideoCall(call)) { - enableCamera(call.getVideoCall(), true); - } - } - - // Make sure we hide or show the video UI if needed. - showVideoUi(call.getVideoState(), call.getState()); - } - - private void cleanupSurfaces() { - final VideoCallUi ui = getUi(); - if (ui == null) { - Log.w(this, "cleanupSurfaces"); - return; - } - ui.cleanupSurfaces(); - } - - private void onPrimaryCallChanged(Call newPrimaryCall) { - final boolean isVideoCall = VideoUtils.isVideoCall(newPrimaryCall); - final boolean isVideoMode = isVideoMode(); - - Log.d(this, "onPrimaryCallChanged: isVideoCall=" + isVideoCall + " isVideoMode=" - + isVideoMode); - - if (!isVideoCall && isVideoMode) { - // Terminate video mode if new primary call is not a video call - // and we are currently in video mode. - Log.d(this, "onPrimaryCallChanged: Exiting video mode..."); - exitVideoMode(); - } else if (isVideoCall) { - Log.d(this, "onPrimaryCallChanged: Entering video mode..."); - - updateCameraSelection(newPrimaryCall); - adjustVideoMode(newPrimaryCall); - } - checkForOrientationAllowedChange(newPrimaryCall); - } - - private boolean isVideoMode() { - return mIsVideoMode; - } - - private void updateCallCache(Call call) { - if (call == null) { - mCurrentVideoState = VideoProfile.STATE_AUDIO_ONLY; - mCurrentCallState = Call.State.INVALID; - mVideoCall = null; - mPrimaryCall = null; - } else { - mCurrentVideoState = call.getVideoState(); - mVideoCall = call.getVideoCall(); - mCurrentCallState = call.getState(); - mPrimaryCall = call; - } - } - - /** - * Handles changes to the details of the call. The {@link VideoCallPresenter} is interested in - * changes to the video state. - * - * @param call The call for which the details changed. - * @param details The new call details. - */ - @Override - public void onDetailsChanged(Call call, android.telecom.Call.Details details) { - Log.d(this, " onDetailsChanged call=" + call + " details=" + details + " mPrimaryCall=" - + mPrimaryCall); - if (call == null) { - return; - } - // If the details change is not for the currently active call no update is required. - if (!call.equals(mPrimaryCall)) { - Log.d(this, " onDetailsChanged: Details not for current active call so returning. "); - return; - } - - updateVideoCall(call); - - updateCallCache(call); - } - - private void updateVideoCall(Call call) { - checkForVideoCallChange(call); - checkForVideoStateChange(call); - checkForCallStateChange(call); - checkForOrientationAllowedChange(call); - } - - private void checkForOrientationAllowedChange(Call call) { - InCallPresenter.getInstance().setInCallAllowsOrientationChange( - VideoUtils.isVideoCall(call)); - } - - /** - * Checks for a change to the video call and changes it if required. - */ - private void checkForVideoCallChange(Call call) { - final VideoCall videoCall = call.getTelecomCall().getVideoCall(); - Log.d(this, "checkForVideoCallChange: videoCall=" + videoCall + " mVideoCall=" - + mVideoCall); - if (!Objects.equals(videoCall, mVideoCall)) { - changeVideoCall(call); - } - } - - /** - * Handles a change to the video call. Sets the surfaces on the previous call to null and sets - * the surfaces on the new video call accordingly. - * - * @param call The new video call. - */ - private void changeVideoCall(Call call) { - final VideoCall videoCall = call.getTelecomCall().getVideoCall(); - Log.d(this, "changeVideoCall to videoCall=" + videoCall + " mVideoCall=" + mVideoCall); - // Null out the surfaces on the previous video call. - if (mVideoCall != null) { - // Log.d(this, "Null out the surfaces on the previous video call."); - // mVideoCall.setDisplaySurface(null); - // mVideoCall.setPreviewSurface(null); - } - - final boolean hasChanged = mVideoCall == null && videoCall != null; - - mVideoCall = videoCall; - if (mVideoCall == null || call == null) { - Log.d(this, "Video call or primary call is null. Return"); - return; - } - - if (VideoUtils.isVideoCall(call) && hasChanged) { - adjustVideoMode(call); - } - } - - private static boolean isCameraRequired(int videoState) { - return VideoProfile.isBidirectional(videoState) - || VideoProfile.isTransmissionEnabled(videoState); - } - - private boolean isCameraRequired() { - return mPrimaryCall != null && isCameraRequired(mPrimaryCall.getVideoState()); - } - - /** - * Adjusts the current video mode by setting up the preview and display surfaces as necessary. - * Expected to be called whenever the video state associated with a call changes (e.g. a user - * turns their camera on or off) to ensure the correct surfaces are shown/hidden. - * TODO(vt): Need to adjust size and orientation of preview surface here. - */ - private void adjustVideoMode(Call call) { - VideoCall videoCall = call.getVideoCall(); - int newVideoState = call.getVideoState(); - - Log.d(this, "adjustVideoMode videoCall= " + videoCall + " videoState: " + newVideoState); - VideoCallUi ui = getUi(); - if (ui == null) { - Log.e(this, "Error VideoCallUi is null so returning"); - return; - } - - showVideoUi(newVideoState, call.getState()); - - // Communicate the current camera to telephony and make a request for the camera - // capabilities. - if (videoCall != null) { - if (ui.isDisplayVideoSurfaceCreated()) { - Log.d(this, "Calling setDisplaySurface with " + ui.getDisplayVideoSurface()); - videoCall.setDisplaySurface(ui.getDisplayVideoSurface()); - } - - videoCall.setDeviceOrientation(mDeviceOrientation); - enableCamera(videoCall, isCameraRequired(newVideoState)); - } - int previousVideoState = mCurrentVideoState; - mCurrentVideoState = newVideoState; - mIsVideoMode = true; - - // adjustVideoMode may be called if we are already in a 1-way video state. In this case - // we do not want to trigger auto-fullscreen mode. - if (!VideoUtils.isVideoCall(previousVideoState) && VideoUtils.isVideoCall(newVideoState)) { - maybeAutoEnterFullscreen(call); - } - } - - private void enableCamera(VideoCall videoCall, boolean isCameraRequired) { - Log.d(this, "enableCamera: VideoCall=" + videoCall + " enabling=" + isCameraRequired); - if (videoCall == null) { - Log.w(this, "enableCamera: VideoCall is null."); - return; - } - - if (isCameraRequired) { - InCallCameraManager cameraManager = InCallPresenter.getInstance(). - getInCallCameraManager(); - videoCall.setCamera(cameraManager.getActiveCameraId()); - mPreviewSurfaceState = PreviewSurfaceState.CAMERA_SET; - - videoCall.requestCameraCapabilities(); - } else { - mPreviewSurfaceState = PreviewSurfaceState.NONE; - videoCall.setCamera(null); - } - } - - /** - * Exits video mode by hiding the video surfaces and making other adjustments (eg. audio). - */ - private void exitVideoMode() { - Log.d(this, "exitVideoMode"); - - showVideoUi(VideoProfile.STATE_AUDIO_ONLY, Call.State.ACTIVE); - enableCamera(mVideoCall, false); - InCallPresenter.getInstance().setFullScreen(false); - - mIsVideoMode = false; - } - - /** - * Based on the current video state and call state, show or hide the incoming and - * outgoing video surfaces. The outgoing video surface is shown any time video is transmitting. - * The incoming video surface is shown whenever the video is un-paused and active. - * - * @param videoState The video state. - * @param callState The call state. - */ - private void showVideoUi(int videoState, int callState) { - VideoCallUi ui = getUi(); - if (ui == null) { - Log.e(this, "showVideoUi, VideoCallUi is null returning"); - return; - } - boolean showIncomingVideo = showIncomingVideo(videoState, callState); - boolean showOutgoingVideo = showOutgoingVideo(videoState); - Log.v(this, "showVideoUi : showIncoming = " + showIncomingVideo + " showOutgoing = " - + showOutgoingVideo); - if (showIncomingVideo || showOutgoingVideo) { - ui.showVideoViews(showOutgoingVideo, showIncomingVideo); - - if (VideoProfile.isReceptionEnabled(videoState)) { - loadProfilePhotoAsync(); - } - } else { - ui.hideVideoUi(); - } - - InCallPresenter.getInstance().enableScreenTimeout( - VideoProfile.isAudioOnly(videoState)); - } - - /** - * Determines if the incoming video surface should be shown based on the current videoState and - * callState. The video surface is shown when incoming video is not paused, the call is active, - * and video reception is enabled. - * - * @param videoState The current video state. - * @param callState The current call state. - * @return {@code true} if the incoming video surface should be shown, {@code false} otherwise. - */ - public static boolean showIncomingVideo(int videoState, int callState) { - if (!CompatUtils.isVideoCompatible()) { - return false; - } - - boolean isPaused = VideoProfile.isPaused(videoState); - boolean isCallActive = callState == Call.State.ACTIVE; - - return !isPaused && isCallActive && VideoProfile.isReceptionEnabled(videoState); - } - - /** - * Determines if the outgoing video surface should be shown based on the current videoState. - * The video surface is shown if video transmission is enabled. - * - * @param videoState The current video state. - * @return {@code true} if the the outgoing video surface should be shown, {@code false} - * otherwise. - */ - public static boolean showOutgoingVideo(int videoState) { - if (!CompatUtils.isVideoCompatible()) { - return false; - } - - return VideoProfile.isTransmissionEnabled(videoState); - } - - /** - * Handles peer video pause state changes. - * - * @param call The call which paused or un-pausedvideo transmission. - * @param paused {@code True} when the video transmission is paused, {@code false} when video - * transmission resumes. - */ - @Override - public void onPeerPauseStateChanged(Call call, boolean paused) { - if (!call.equals(mPrimaryCall)) { - return; - } - - // TODO(vt): Show/hide the peer contact photo. - } - - /** - * Handles peer video dimension changes. - * - * @param call The call which experienced a peer video dimension change. - * @param width The new peer video width . - * @param height The new peer video height. - */ - @Override - public void onUpdatePeerDimensions(Call call, int width, int height) { - Log.d(this, "onUpdatePeerDimensions: width= " + width + " height= " + height); - VideoCallUi ui = getUi(); - if (ui == null) { - Log.e(this, "VideoCallUi is null. Bail out"); - return; - } - if (!call.equals(mPrimaryCall)) { - Log.e(this, "Current call is not equal to primary call. Bail out"); - return; - } - - // Change size of display surface to match the peer aspect ratio - if (width > 0 && height > 0) { - setDisplayVideoSize(width, height); - } - } - - /** - * Handles any video quality changes in the call. - * - * @param call The call which experienced a video quality change. - * @param videoQuality The new video call quality. - */ - @Override - public void onVideoQualityChanged(Call call, int videoQuality) { - // No-op - } - - /** - * Handles a change to the dimensions of the local camera. Receiving the camera capabilities - * triggers the creation of the video - * - * @param call The call which experienced the camera dimension change. - * @param width The new camera video width. - * @param height The new camera video height. - */ - @Override - public void onCameraDimensionsChange(Call call, int width, int height) { - Log.d(this, "onCameraDimensionsChange call=" + call + " width=" + width + " height=" - + height); - VideoCallUi ui = getUi(); - if (ui == null) { - Log.e(this, "onCameraDimensionsChange ui is null"); - return; - } - - if (!call.equals(mPrimaryCall)) { - Log.e(this, "Call is not primary call"); - return; - } - - mPreviewSurfaceState = PreviewSurfaceState.CAPABILITIES_RECEIVED; - changePreviewDimensions(width, height); - - // Check if the preview surface is ready yet; if it is, set it on the {@code VideoCall}. - // If it not yet ready, it will be set when when creation completes. - if (ui.isPreviewVideoSurfaceCreated()) { - mPreviewSurfaceState = PreviewSurfaceState.SURFACE_SET; - mVideoCall.setPreviewSurface(ui.getPreviewVideoSurface()); - } - } - - /** - * Changes the dimensions of the preview surface. - * - * @param width The new width. - * @param height The new height. - */ - private void changePreviewDimensions(int width, int height) { - VideoCallUi ui = getUi(); - if (ui == null) { - return; - } - - // Resize the surface used to display the preview video - ui.setPreviewSurfaceSize(width, height); - - // Configure the preview surface to the correct aspect ratio. - float aspectRatio = 1.0f; - if (width > 0 && height > 0) { - aspectRatio = (float) width / (float) height; - } - - // Resize the textureview housing the preview video and rotate it appropriately based on - // the device orientation - setPreviewSize(mDeviceOrientation, aspectRatio); - } - - /** - * Called when call session event is raised. - * - * @param event The call session event. - */ - @Override - public void onCallSessionEvent(int event) { - StringBuilder sb = new StringBuilder(); - sb.append("onCallSessionEvent = "); - - switch (event) { - case Connection.VideoProvider.SESSION_EVENT_RX_PAUSE: - sb.append("rx_pause"); - break; - case Connection.VideoProvider.SESSION_EVENT_RX_RESUME: - sb.append("rx_resume"); - break; - case Connection.VideoProvider.SESSION_EVENT_CAMERA_FAILURE: - sb.append("camera_failure"); - break; - case Connection.VideoProvider.SESSION_EVENT_CAMERA_READY: - sb.append("camera_ready"); - break; - default: - sb.append("unknown event = "); - sb.append(event); - break; - } - Log.d(this, sb.toString()); - } - - /** - * Handles a change to the call data usage - * - * @param dataUsage call data usage value - */ - @Override - public void onCallDataUsageChange(long dataUsage) { - Log.d(this, "onCallDataUsageChange dataUsage=" + dataUsage); - } - - /** - * Handles changes to the device orientation. - * @param orientation The screen orientation of the device (one of: - * {@link InCallOrientationEventListener#SCREEN_ORIENTATION_0}, - * {@link InCallOrientationEventListener#SCREEN_ORIENTATION_90}, - * {@link InCallOrientationEventListener#SCREEN_ORIENTATION_180}, - * {@link InCallOrientationEventListener#SCREEN_ORIENTATION_270}). - */ - @Override - public void onDeviceOrientationChanged(int orientation) { - mDeviceOrientation = orientation; - - VideoCallUi ui = getUi(); - if (ui == null) { - Log.e(this, "onDeviceOrientationChanged: VideoCallUi is null"); - return; - } - - Point previewDimensions = ui.getPreviewSize(); - if (previewDimensions == null) { - return; - } - Log.d(this, "onDeviceOrientationChanged: orientation=" + orientation + " size: " - + previewDimensions); - changePreviewDimensions(previewDimensions.x, previewDimensions.y); - - ui.setPreviewRotation(mDeviceOrientation); - } - - /** - * Sets the preview surface size based on the current device orientation. - * See: {@link InCallOrientationEventListener#SCREEN_ORIENTATION_0}, - * {@link InCallOrientationEventListener#SCREEN_ORIENTATION_90}, - * {@link InCallOrientationEventListener#SCREEN_ORIENTATION_180}, - * {@link InCallOrientationEventListener#SCREEN_ORIENTATION_270}). - * - * @param orientation The device orientation - * @param aspectRatio The aspect ratio of the camera (width / height). - */ - private void setPreviewSize(int orientation, float aspectRatio) { - VideoCallUi ui = getUi(); - if (ui == null) { - return; - } - - int height; - int width; - - if (orientation == InCallOrientationEventListener.SCREEN_ORIENTATION_90 || - orientation == InCallOrientationEventListener.SCREEN_ORIENTATION_270) { - width = (int) (mMinimumVideoDimension * aspectRatio); - height = (int) mMinimumVideoDimension; - } else { - // Portrait or reverse portrait orientation. - width = (int) mMinimumVideoDimension; - height = (int) (mMinimumVideoDimension * aspectRatio); - } - ui.setPreviewSize(width, height); - } - - /** - * Sets the display video surface size based on peer width and height - * - * @param width peer width - * @param height peer height - */ - private void setDisplayVideoSize(int width, int height) { - Log.v(this, "setDisplayVideoSize: Received peer width=" + width + " height=" + height); - VideoCallUi ui = getUi(); - if (ui == null) { - return; - } - - // Get current display size - Point size = ui.getScreenSize(); - Log.v(this, "setDisplayVideoSize: windowmgr width=" + size.x - + " windowmgr height=" + size.y); - if (size.y * width > size.x * height) { - // current display height is too much. Correct it - size.y = (int) (size.x * height / width); - } else if (size.y * width < size.x * height) { - // current display width is too much. Correct it - size.x = (int) (size.y * width / height); - } - ui.setDisplayVideoSize(size.x, size.y); - } - - /** - * Exits fullscreen mode if the current call context has changed to a non-video call. - * - * @param call The call. - */ - protected void maybeExitFullscreen(Call call) { - if (call == null) { - return; - } - - if (!VideoUtils.isVideoCall(call) || call.getState() == Call.State.INCOMING) { - InCallPresenter.getInstance().setFullScreen(false); - } - } - - /** - * Schedules auto-entering of fullscreen mode. - * Will not enter full screen mode if any of the following conditions are met: - * 1. No call - * 2. Call is not active - * 3. Call is not video call - * 4. Already in fullscreen mode - * 5. The current video state is not bi-directional (if the remote party stops transmitting, - * the user's contact photo would dominate in fullscreen mode). - * - * @param call The current call. - */ - protected void maybeAutoEnterFullscreen(Call call) { - if (!mIsAutoFullscreenEnabled) { - return; - } - - if (call == null || ( - call != null && (call.getState() != Call.State.ACTIVE || - !VideoUtils.isVideoCall(call)) || - InCallPresenter.getInstance().isFullscreen()) || - !VideoUtils.isBidirectionalVideoCall(call)) { - // Ensure any previously scheduled attempt to enter fullscreen is cancelled. - cancelAutoFullScreen(); - return; - } - - if (mAutoFullScreenPending) { - Log.v(this, "maybeAutoEnterFullscreen : already pending."); - return; - } - Log.v(this, "maybeAutoEnterFullscreen : scheduled"); - mAutoFullScreenPending = true; - mHandler.postDelayed(mAutoFullscreenRunnable, mAutoFullscreenTimeoutMillis); - } - - /** - * Cancels pending auto fullscreen mode. - */ - public void cancelAutoFullScreen() { - if (!mAutoFullScreenPending) { - Log.v(this, "cancelAutoFullScreen : none pending."); - return; - } - Log.v(this, "cancelAutoFullScreen : cancelling pending"); - mAutoFullScreenPending = false; - } - - private static void updateCameraSelection(Call call) { - Log.d(TAG, "updateCameraSelection: call=" + call); - Log.d(TAG, "updateCameraSelection: call=" + toSimpleString(call)); - - final Call activeCall = CallList.getInstance().getActiveCall(); - int cameraDir = Call.VideoSettings.CAMERA_DIRECTION_UNKNOWN; - - // this function should never be called with null call object, however if it happens we - // should handle it gracefully. - if (call == null) { - cameraDir = Call.VideoSettings.CAMERA_DIRECTION_UNKNOWN; - com.android.incallui.Log.e(TAG, "updateCameraSelection: Call object is null." - + " Setting camera direction to default value (CAMERA_DIRECTION_UNKNOWN)"); - } - - // Clear camera direction if this is not a video call. - else if (VideoUtils.isAudioCall(call)) { - cameraDir = Call.VideoSettings.CAMERA_DIRECTION_UNKNOWN; - call.getVideoSettings().setCameraDir(cameraDir); - } - - // If this is a waiting video call, default to active call's camera, - // since we don't want to change the current camera for waiting call - // without user's permission. - else if (VideoUtils.isVideoCall(activeCall) && VideoUtils.isIncomingVideoCall(call)) { - cameraDir = activeCall.getVideoSettings().getCameraDir(); - } - - // Infer the camera direction from the video state and store it, - // if this is an outgoing video call. - else if (VideoUtils.isOutgoingVideoCall(call) && !isCameraDirectionSet(call) ) { - cameraDir = toCameraDirection(call.getVideoState()); - call.getVideoSettings().setCameraDir(cameraDir); - } - - // Use the stored camera dir if this is an outgoing video call for which camera direction - // is set. - else if (VideoUtils.isOutgoingVideoCall(call)) { - cameraDir = call.getVideoSettings().getCameraDir(); - } - - // Infer the camera direction from the video state and store it, - // if this is an active video call and camera direction is not set. - else if (VideoUtils.isActiveVideoCall(call) && !isCameraDirectionSet(call)) { - cameraDir = toCameraDirection(call.getVideoState()); - call.getVideoSettings().setCameraDir(cameraDir); - } - - // Use the stored camera dir if this is an active video call for which camera direction - // is set. - else if (VideoUtils.isActiveVideoCall(call)) { - cameraDir = call.getVideoSettings().getCameraDir(); - } - - // For all other cases infer the camera direction but don't store it in the call object. - else { - cameraDir = toCameraDirection(call.getVideoState()); - } - - com.android.incallui.Log.d(TAG, "updateCameraSelection: Setting camera direction to " + - cameraDir + " Call=" + call); - final InCallCameraManager cameraManager = InCallPresenter.getInstance(). - getInCallCameraManager(); - cameraManager.setUseFrontFacingCamera(cameraDir == - Call.VideoSettings.CAMERA_DIRECTION_FRONT_FACING); - } - - private static int toCameraDirection(int videoState) { - return VideoProfile.isTransmissionEnabled(videoState) && - !VideoProfile.isBidirectional(videoState) - ? Call.VideoSettings.CAMERA_DIRECTION_BACK_FACING - : Call.VideoSettings.CAMERA_DIRECTION_FRONT_FACING; - } - - private static boolean isCameraDirectionSet(Call call) { - return VideoUtils.isVideoCall(call) && call.getVideoSettings().getCameraDir() - != Call.VideoSettings.CAMERA_DIRECTION_UNKNOWN; - } - - private static String toSimpleString(Call call) { - return call == null ? null : call.toSimpleString(); - } - - /** - * Starts an asynchronous load of the user's profile photo. - */ - public void loadProfilePhotoAsync() { - final VideoCallUi ui = getUi(); - if (ui == null) { - return; - } - - final AsyncTask task = new AsyncTask() { - /** - * Performs asynchronous load of the user profile information. - * - * @param params The parameters of the task. - * - * @return {@code null}. - */ - @Override - protected Void doInBackground(Void... params) { - if (mProfileInfo == null) { - // Try and read the photo URI from the local profile. - mProfileInfo = new ContactInfoCache.ContactCacheEntry(); - final Cursor cursor = mContext.getContentResolver().query( - ContactsContract.Profile.CONTENT_URI, new String[]{ - ContactsContract.CommonDataKinds.Phone._ID, - ContactsContract.CommonDataKinds.Phone.PHOTO_URI, - ContactsContract.CommonDataKinds.Phone.LOOKUP_KEY, - ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME, - ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME_ALTERNATIVE - }, null, null, null); - if (cursor != null) { - try { - if (cursor.moveToFirst()) { - mProfileInfo.lookupKey = cursor.getString(cursor.getColumnIndex( - ContactsContract.CommonDataKinds.Phone.LOOKUP_KEY)); - String photoUri = cursor.getString(cursor.getColumnIndex( - ContactsContract.CommonDataKinds.Phone.PHOTO_URI)); - mProfileInfo.displayPhotoUri = photoUri == null ? null - : Uri.parse(photoUri); - mProfileInfo.namePrimary = cursor.getString(cursor.getColumnIndex( - ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME)); - mProfileInfo.nameAlternative = cursor.getString( - cursor.getColumnIndex(ContactsContract.CommonDataKinds - .Phone.DISPLAY_NAME_ALTERNATIVE)); - } - } finally { - cursor.close(); - } - } - } - return null; - } - - @Override - protected void onPostExecute(Void result) { - // If user profile information was found, issue an async request to load the user's - // profile photo. - if (mProfileInfo != null) { - if (mContactPhotoManager == null) { - mContactPhotoManager = ContactPhotoManager.getInstance(mContext); - } - ContactPhotoManager.DefaultImageRequest imageRequest = (mProfileInfo != null) - ? null : - new ContactPhotoManager.DefaultImageRequest(mProfileInfo.namePrimary, - mProfileInfo.lookupKey, false /* isCircularPhoto */); - - ImageView photoView = ui.getPreviewPhotoView(); - if (photoView == null) { - return; - } - mContactPhotoManager.loadDirectoryPhoto(photoView, - mProfileInfo.displayPhotoUri, - false /* darkTheme */, false /* isCircular */, imageRequest); - } - } - }; - - task.execute(); - } - - /** - * Defines the VideoCallUI interactions. - */ - public interface VideoCallUi extends Ui { - void showVideoViews(boolean showPreview, boolean showIncoming); - void hideVideoUi(); - boolean isDisplayVideoSurfaceCreated(); - boolean isPreviewVideoSurfaceCreated(); - Surface getDisplayVideoSurface(); - Surface getPreviewVideoSurface(); - int getCurrentRotation(); - void setPreviewSize(int width, int height); - void setPreviewSurfaceSize(int width, int height); - void setDisplayVideoSize(int width, int height); - Point getScreenSize(); - Point getPreviewSize(); - void cleanupSurfaces(); - ImageView getPreviewPhotoView(); - void adjustPreviewLocation(boolean shiftUp, int offset); - void setPreviewRotation(int orientation); - } -} diff --git a/InCallUI/src/com/android/incallui/VideoPauseController.java b/InCallUI/src/com/android/incallui/VideoPauseController.java deleted file mode 100644 index fb873500e..000000000 --- a/InCallUI/src/com/android/incallui/VideoPauseController.java +++ /dev/null @@ -1,420 +0,0 @@ -/* - * Copyright (C) 2015 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 com.android.incallui.Call.State; -import com.android.incallui.InCallPresenter.InCallState; -import com.android.incallui.InCallPresenter.InCallStateListener; -import com.android.incallui.InCallPresenter.IncomingCallListener; -import com.android.incallui.InCallVideoCallCallbackNotifier.SessionModificationListener; -import com.google.common.base.Preconditions; - -import android.telecom.VideoProfile; - -/** - * This class is responsible for generating video pause/resume requests when the InCall UI is sent - * to the background and subsequently brought back to the foreground. - */ -class VideoPauseController implements InCallStateListener, IncomingCallListener { - private static final String TAG = "VideoPauseController"; - - /** - * Keeps track of the current active/foreground call. - */ - private class CallContext { - public CallContext(Call call) { - Preconditions.checkNotNull(call); - update(call); - } - - public void update(Call call) { - mCall = Preconditions.checkNotNull(call); - mState = call.getState(); - mVideoState = call.getVideoState(); - } - - public int getState() { - return mState; - } - - public int getVideoState() { - return mVideoState; - } - - public String toString() { - return String.format("CallContext {CallId=%s, State=%s, VideoState=%d}", - mCall.getId(), mState, mVideoState); - } - - public Call getCall() { - return mCall; - } - - private int mState = State.INVALID; - private int mVideoState; - private Call mCall; - } - - private InCallPresenter mInCallPresenter; - private static VideoPauseController sVideoPauseController; - - /** - * The current call context, if applicable. - */ - private CallContext mPrimaryCallContext = null; - - /** - * Tracks whether the application is in the background. {@code True} if the application is in - * the background, {@code false} otherwise. - */ - private boolean mIsInBackground = false; - - /** - * Singleton accessor for the {@link VideoPauseController}. - * @return Singleton instance of the {@link VideoPauseController}. - */ - /*package*/ - static synchronized VideoPauseController getInstance() { - if (sVideoPauseController == null) { - sVideoPauseController = new VideoPauseController(); - } - return sVideoPauseController; - } - - /** - * Configures the {@link VideoPauseController} to listen to call events. Configured via the - * {@link com.android.incallui.InCallPresenter}. - * - * @param inCallPresenter The {@link com.android.incallui.InCallPresenter}. - */ - public void setUp(InCallPresenter inCallPresenter) { - log("setUp"); - mInCallPresenter = Preconditions.checkNotNull(inCallPresenter); - mInCallPresenter.addListener(this); - mInCallPresenter.addIncomingCallListener(this); - } - - /** - * Cleans up the {@link VideoPauseController} by removing all listeners and clearing its - * internal state. Called from {@link com.android.incallui.InCallPresenter}. - */ - public void tearDown() { - log("tearDown..."); - mInCallPresenter.removeListener(this); - mInCallPresenter.removeIncomingCallListener(this); - clear(); - } - - /** - * Clears the internal state for the {@link VideoPauseController}. - */ - private void clear() { - mInCallPresenter = null; - mPrimaryCallContext = null; - mIsInBackground = false; - } - - /** - * Handles changes in the {@link InCallState}. Triggers pause and resumption of video for the - * current foreground call. - * - * @param oldState The previous {@link InCallState}. - * @param newState The current {@link InCallState}. - * @param callList List of current call. - */ - @Override - public void onStateChange(InCallState oldState, InCallState newState, CallList callList) { - log("onStateChange, OldState=" + oldState + " NewState=" + newState); - - Call call = null; - if (newState == InCallState.INCOMING) { - call = callList.getIncomingCall(); - } else if (newState == InCallState.WAITING_FOR_ACCOUNT) { - call = callList.getWaitingForAccountCall(); - } else if (newState == InCallState.PENDING_OUTGOING) { - call = callList.getPendingOutgoingCall(); - } else if (newState == InCallState.OUTGOING) { - call = callList.getOutgoingCall(); - } else { - call = callList.getActiveCall(); - } - - boolean hasPrimaryCallChanged = !areSame(call, mPrimaryCallContext); - boolean canVideoPause = VideoUtils.canVideoPause(call); - log("onStateChange, hasPrimaryCallChanged=" + hasPrimaryCallChanged); - log("onStateChange, canVideoPause=" + canVideoPause); - log("onStateChange, IsInBackground=" + mIsInBackground); - - if (hasPrimaryCallChanged) { - onPrimaryCallChanged(call); - return; - } - - if (isDialing(mPrimaryCallContext) && canVideoPause && mIsInBackground) { - // Bring UI to foreground if outgoing request becomes active while UI is in - // background. - bringToForeground(); - } else if (!isVideoCall(mPrimaryCallContext) && canVideoPause && mIsInBackground) { - // Bring UI to foreground if VoLTE call becomes active while UI is in - // background. - bringToForeground(); - } - - updatePrimaryCallContext(call); - } - - /** - * Handles a change to the primary call. - *

- * Reject incoming or hangup dialing call: Where the previous call was an incoming call or a - * call in dialing state, resume the new primary call. - * Call swap: Where the new primary call is incoming, pause video on the previous primary call. - * - * @param call The new primary call. - */ - private void onPrimaryCallChanged(Call call) { - log("onPrimaryCallChanged: New call = " + call); - log("onPrimaryCallChanged: Old call = " + mPrimaryCallContext); - log("onPrimaryCallChanged, IsInBackground=" + mIsInBackground); - - Preconditions.checkState(!areSame(call, mPrimaryCallContext)); - final boolean canVideoPause = VideoUtils.canVideoPause(call); - - if ((isIncomingCall(mPrimaryCallContext) || isDialing(mPrimaryCallContext) || - (call != null && VideoProfile.isPaused(call.getVideoState()))) - && canVideoPause && !mIsInBackground) { - // Send resume request for the active call, if user rejects incoming call, ends dialing - // call, or the call was previously in a paused state and UI is in the foreground. - sendRequest(call, true); - } else if (isIncomingCall(call) && canVideoPause(mPrimaryCallContext)) { - // Send pause request if there is an active video call, and we just received a new - // incoming call. - sendRequest(mPrimaryCallContext.getCall(), false); - } - - updatePrimaryCallContext(call); - } - - /** - * Handles new incoming calls by triggering a change in the primary call. - * - * @param oldState the old {@link InCallState}. - * @param newState the new {@link InCallState}. - * @param call the incoming call. - */ - @Override - public void onIncomingCall(InCallState oldState, InCallState newState, Call call) { - log("onIncomingCall, OldState=" + oldState + " NewState=" + newState + " Call=" + call); - - if (areSame(call, mPrimaryCallContext)) { - return; - } - - onPrimaryCallChanged(call); - } - - /** - * Caches a reference to the primary call and stores its previous state. - * - * @param call The new primary call. - */ - private void updatePrimaryCallContext(Call call) { - if (call == null) { - mPrimaryCallContext = null; - } else if (mPrimaryCallContext != null) { - mPrimaryCallContext.update(call); - } else { - mPrimaryCallContext = new CallContext(call); - } - } - - /** - * Called when UI goes in/out of the foreground. - * @param showing true if UI is in the foreground, false otherwise. - */ - public void onUiShowing(boolean showing) { - // Only send pause/unpause requests if we are in the INCALL state. - if (mInCallPresenter == null) { - return; - } - final boolean isInCall = mInCallPresenter.getInCallState() == InCallState.INCALL; - if (showing) { - onResume(isInCall); - } else { - onPause(isInCall); - } - } - - /** - * Called when UI is brought to the foreground. Sends a session modification request to resume - * the outgoing video. - * @param isInCall true if phone state is INCALL, false otherwise - */ - private void onResume(boolean isInCall) { - log("onResume"); - - mIsInBackground = false; - if (canVideoPause(mPrimaryCallContext) && isInCall) { - sendRequest(mPrimaryCallContext.getCall(), true); - } else { - log("onResume. Ignoring..."); - } - } - - /** - * Called when UI is sent to the background. Sends a session modification request to pause the - * outgoing video. - * @param isInCall true if phone state is INCALL, false otherwise - */ - private void onPause(boolean isInCall) { - log("onPause"); - - mIsInBackground = true; - if (canVideoPause(mPrimaryCallContext) && isInCall) { - sendRequest(mPrimaryCallContext.getCall(), false); - } else { - log("onPause, Ignoring..."); - } - } - - private void bringToForeground() { - if (mInCallPresenter != null) { - log("Bringing UI to foreground"); - mInCallPresenter.bringToForeground(false); - } else { - loge("InCallPresenter is null. Cannot bring UI to foreground"); - } - } - - /** - * Sends Pause/Resume request. - * - * @param call Call to be paused/resumed. - * @param resume If true resume request will be sent, otherwise pause request. - */ - private void sendRequest(Call call, boolean resume) { - // Check if this call supports pause/un-pause. - if (!call.can(android.telecom.Call.Details.CAPABILITY_CAN_PAUSE_VIDEO)) { - return; - } - - if (resume) { - log("sending resume request, call=" + call); - call.getVideoCall() - .sendSessionModifyRequest(VideoUtils.makeVideoUnPauseProfile(call)); - } else { - log("sending pause request, call=" + call); - call.getVideoCall().sendSessionModifyRequest(VideoUtils.makeVideoPauseProfile(call)); - } - } - - /** - * Determines if a given call is the same one stored in a {@link CallContext}. - * - * @param call The call. - * @param callContext The call context. - * @return {@code true} if the {@link Call} is the same as the one referenced in the - * {@link CallContext}. - */ - private static boolean areSame(Call call, CallContext callContext) { - if (call == null && callContext == null) { - return true; - } else if (call == null || callContext == null) { - return false; - } - return call.equals(callContext.getCall()); - } - - /** - * Determines if a video call can be paused. Only a video call which is active can be paused. - * - * @param callContext The call context to check. - * @return {@code true} if the call is an active video call. - */ - private static boolean canVideoPause(CallContext callContext) { - return isVideoCall(callContext) && callContext.getState() == Call.State.ACTIVE; - } - - /** - * Determines if a call referenced by a {@link CallContext} is a video call. - * - * @param callContext The call context. - * @return {@code true} if the call is a video call, {@code false} otherwise. - */ - private static boolean isVideoCall(CallContext callContext) { - return callContext != null && VideoUtils.isVideoCall(callContext.getVideoState()); - } - - /** - * Determines if call is in incoming/waiting state. - * - * @param call The call context. - * @return {@code true} if the call is in incoming or waiting state, {@code false} otherwise. - */ - private static boolean isIncomingCall(CallContext call) { - return call != null && isIncomingCall(call.getCall()); - } - - /** - * Determines if a call is in incoming/waiting state. - * - * @param call The call. - * @return {@code true} if the call is in incoming or waiting state, {@code false} otherwise. - */ - private static boolean isIncomingCall(Call call) { - return call != null && (call.getState() == Call.State.CALL_WAITING - || call.getState() == Call.State.INCOMING); - } - - /** - * Determines if a call is dialing. - * - * @param call The call context. - * @return {@code true} if the call is dialing, {@code false} otherwise. - */ - private static boolean isDialing(CallContext call) { - return call != null && Call.State.isDialing(call.getState()); - } - - /** - * Determines if a call is holding. - * - * @param call The call context. - * @return {@code true} if the call is holding, {@code false} otherwise. - */ - private static boolean isHolding(CallContext call) { - return call != null && call.getState() == Call.State.ONHOLD; - } - - /** - * Logs a debug message. - * - * @param msg The message. - */ - private void log(String msg) { - Log.d(this, TAG + msg); - } - - /** - * Logs an error message. - * - * @param msg The message. - */ - private void loge(String msg) { - Log.e(this, TAG + msg); - } -} diff --git a/InCallUI/src/com/android/incallui/VideoUtils.java b/InCallUI/src/com/android/incallui/VideoUtils.java deleted file mode 100644 index a2eb8bcf2..000000000 --- a/InCallUI/src/com/android/incallui/VideoUtils.java +++ /dev/null @@ -1,109 +0,0 @@ -/* - * Copyright (C) 2015 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.telecom.VideoProfile; - -import com.android.contacts.common.compat.CompatUtils; - -import com.google.common.base.Preconditions; - -public class VideoUtils { - - public static boolean isVideoCall(Call call) { - return call != null && isVideoCall(call.getVideoState()); - } - - public static boolean isVideoCall(int videoState) { - if (!CompatUtils.isVideoCompatible()) { - return false; - } - - return VideoProfile.isTransmissionEnabled(videoState) - || VideoProfile.isReceptionEnabled(videoState); - } - - public static boolean isBidirectionalVideoCall(Call call) { - if (!CompatUtils.isVideoCompatible()) { - return false; - } - - return VideoProfile.isBidirectional(call.getVideoState()); - } - - public static boolean isTransmissionEnabled(Call call) { - if (!CompatUtils.isVideoCompatible()) { - return false; - } - - return VideoProfile.isTransmissionEnabled(call.getVideoState()); - } - - public static boolean isIncomingVideoCall(Call call) { - if (!VideoUtils.isVideoCall(call)) { - return false; - } - final int state = call.getState(); - return (state == Call.State.INCOMING) || (state == Call.State.CALL_WAITING); - } - - public static boolean isActiveVideoCall(Call call) { - return VideoUtils.isVideoCall(call) && call.getState() == Call.State.ACTIVE; - } - - public static boolean isOutgoingVideoCall(Call call) { - if (!VideoUtils.isVideoCall(call)) { - return false; - } - final int state = call.getState(); - return Call.State.isDialing(state) || state == Call.State.CONNECTING - || state == Call.State.SELECT_PHONE_ACCOUNT; - } - - public static boolean isAudioCall(Call call) { - if (!CompatUtils.isVideoCompatible()) { - return true; - } - - return call != null && VideoProfile.isAudioOnly(call.getVideoState()); - } - - // TODO (ims-vt) Check if special handling is needed for CONF calls. - public static boolean canVideoPause(Call call) { - return isVideoCall(call) && call.getState() == Call.State.ACTIVE; - } - - public static VideoProfile makeVideoPauseProfile(Call call) { - Preconditions.checkNotNull(call); - Preconditions.checkState(!VideoProfile.isAudioOnly(call.getVideoState())); - return new VideoProfile(getPausedVideoState(call.getVideoState())); - } - - public static VideoProfile makeVideoUnPauseProfile(Call call) { - Preconditions.checkNotNull(call); - return new VideoProfile(getUnPausedVideoState(call.getVideoState())); - } - - public static int getUnPausedVideoState(int videoState) { - return videoState & (~VideoProfile.STATE_PAUSED); - } - - public static int getPausedVideoState(int videoState) { - return videoState | VideoProfile.STATE_PAUSED; - } - -} diff --git a/InCallUI/src/com/android/incallui/async/PausableExecutor.java b/InCallUI/src/com/android/incallui/async/PausableExecutor.java deleted file mode 100644 index 1b8201a79..000000000 --- a/InCallUI/src/com/android/incallui/async/PausableExecutor.java +++ /dev/null @@ -1,61 +0,0 @@ -/* - * Copyright (C) 2016 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.async; - -import com.android.contacts.common.testing.NeededForTesting; - -import java.util.concurrent.Executor; - -/** - * Executor that can be used to easily synchronize testing and production code. Production code - * should call {@link #milestone()} at points in the code where the state of the system is worthy of - * testing. In a test scenario, this method will pause execution until the test acknowledges the - * milestone through the use of {@link #ackMilestoneForTesting()}. - */ -public interface PausableExecutor extends Executor { - - /** - * Method called from asynchronous production code to inform this executor that it has - * reached a point that puts the system into a state worth testing. TestableExecutors intended - * for use in a testing environment should cause the calling thread to block. In the production - * environment this should be a no-op. - */ - void milestone(); - - /** - * Method called from the test code to inform this executor that the state of the production - * system at the current milestone has been sufficiently tested. Every milestone must be - * acknowledged. - */ - @NeededForTesting - void ackMilestoneForTesting(); - - /** - * Method called from the test code to inform this executor that the tests are finished with all - * milestones. Future calls to {@link #milestone()} or {@link #awaitMilestoneForTesting()} - * should return immediately. - */ - @NeededForTesting - void ackAllMilestonesForTesting(); - - /** - * Method called from the test code to block until a milestone has been reached in the - * production code. - */ - @NeededForTesting - void awaitMilestoneForTesting() throws InterruptedException; -} diff --git a/InCallUI/src/com/android/incallui/async/PausableExecutorImpl.java b/InCallUI/src/com/android/incallui/async/PausableExecutorImpl.java deleted file mode 100644 index 15900e57b..000000000 --- a/InCallUI/src/com/android/incallui/async/PausableExecutorImpl.java +++ /dev/null @@ -1,42 +0,0 @@ -/* - * Copyright (C) 2016 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.async; - -import java.util.concurrent.Executors; - -/** - * {@link PausableExecutor} intended for use in production environments. - */ -public class PausableExecutorImpl implements PausableExecutor { - - @Override - public void milestone() {} - - @Override - public void ackMilestoneForTesting() {} - - @Override - public void ackAllMilestonesForTesting() {} - - @Override - public void awaitMilestoneForTesting() {} - - @Override - public void execute(Runnable command) { - Executors.newSingleThreadExecutor().execute(command); - } -} diff --git a/InCallUI/src/com/android/incallui/ringtone/DialerRingtoneManager.java b/InCallUI/src/com/android/incallui/ringtone/DialerRingtoneManager.java deleted file mode 100644 index 39844e5a2..000000000 --- a/InCallUI/src/com/android/incallui/ringtone/DialerRingtoneManager.java +++ /dev/null @@ -1,140 +0,0 @@ -/* - * Copyright (C) 2016 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.ringtone; - -import com.google.common.base.Preconditions; - -import android.content.ContentResolver; -import android.net.Uri; -import android.provider.Settings; -import android.support.annotation.Nullable; - -import com.android.contacts.common.compat.CompatUtils; -import com.android.contacts.common.testing.NeededForTesting; -import com.android.incallui.Call; -import com.android.incallui.Call.State; -import com.android.incallui.CallList; - -/** - * Class that determines when ringtones should be played and can play the call waiting tone when - * necessary. - */ -public class DialerRingtoneManager { - - /* - * Flag used to determine if the Dialer is responsible for playing ringtones for incoming calls. - * Once we're ready to enable Dialer Ringing, these flags should be removed. - */ - private static final boolean IS_DIALER_RINGING_ENABLED = false; - private Boolean mIsDialerRingingEnabledForTesting; - - private final InCallTonePlayer mInCallTonePlayer; - private final CallList mCallList; - - /** - * Creates the DialerRingtoneManager with the given {@link InCallTonePlayer}. - * - * @param inCallTonePlayer the tone player used to play in-call tones. - * @param callList the CallList used to check for {@link State#CALL_WAITING} - * @throws NullPointerException if inCallTonePlayer or callList are null - */ - public DialerRingtoneManager(InCallTonePlayer inCallTonePlayer, CallList callList) { - mInCallTonePlayer = Preconditions.checkNotNull(inCallTonePlayer); - mCallList = Preconditions.checkNotNull(callList); - } - - /** - * Determines if a ringtone should be played for the given call state (see {@link State}) and - * {@link Uri}. - * - * @param callState the call state for the call being checked. - * @param ringtoneUri the ringtone to potentially play. - * @return {@code true} if the ringtone should be played, {@code false} otherwise. - */ - public boolean shouldPlayRingtone(int callState, @Nullable Uri ringtoneUri) { - return isDialerRingingEnabled() - && translateCallStateForCallWaiting(callState) == State.INCOMING - && ringtoneUri != null; - } - - /** - * Determines if an incoming call should vibrate as well as ring. - * - * @param resolver {@link ContentResolver} used to look up the - * {@link Settings.System#VIBRATE_WHEN_RINGING} setting. - * @return {@code true} if the call should vibrate, {@code false} otherwise. - */ - public boolean shouldVibrate(ContentResolver resolver) { - return Settings.System.getInt(resolver, Settings.System.VIBRATE_WHEN_RINGING, 0) != 0; - } - - /** - * The incoming callState is never set as {@link State#CALL_WAITING} because - * {@link Call#translateState(int)} doesn't account for that case, check for it here - */ - private int translateCallStateForCallWaiting(int callState) { - if (callState != State.INCOMING) { - return callState; - } - return mCallList.getActiveCall() == null ? State.INCOMING : State.CALL_WAITING; - } - - private boolean isDialerRingingEnabled() { - if (mIsDialerRingingEnabledForTesting != null) { - return mIsDialerRingingEnabledForTesting; - } - return CompatUtils.isNCompatible() && IS_DIALER_RINGING_ENABLED; - } - - /** - * Determines if a call waiting tone should be played for the the given call state - * (see {@link State}). - * - * @param callState the call state for the call being checked. - * @return {@code true} if the call waiting tone should be played, {@code false} otherwise. - */ - public boolean shouldPlayCallWaitingTone(int callState) { - return isDialerRingingEnabled() - && translateCallStateForCallWaiting(callState) == State.CALL_WAITING - && !mInCallTonePlayer.isPlayingTone(); - } - - /** - * Plays the call waiting tone. - */ - public void playCallWaitingTone() { - if (!isDialerRingingEnabled()) { - return; - } - mInCallTonePlayer.play(InCallTonePlayer.TONE_CALL_WAITING); - } - - /** - * Stops playing the call waiting tone. - */ - public void stopCallWaitingTone() { - if (!isDialerRingingEnabled()) { - return; - } - mInCallTonePlayer.stop(); - } - - @NeededForTesting - void setDialerRingingEnabledForTesting(boolean status) { - mIsDialerRingingEnabledForTesting = status; - } -} diff --git a/InCallUI/src/com/android/incallui/ringtone/InCallTonePlayer.java b/InCallUI/src/com/android/incallui/ringtone/InCallTonePlayer.java deleted file mode 100644 index 3a8b03d91..000000000 --- a/InCallUI/src/com/android/incallui/ringtone/InCallTonePlayer.java +++ /dev/null @@ -1,168 +0,0 @@ -/* - * Copyright (C) 2016 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.ringtone; - -import com.google.common.base.MoreObjects; -import com.google.common.base.Preconditions; - -import android.media.AudioManager; -import android.media.ToneGenerator; -import android.support.annotation.Nullable; - -import com.android.incallui.Log; -import com.android.incallui.async.PausableExecutor; - -import java.util.concurrent.CountDownLatch; -import java.util.concurrent.TimeUnit; - -/** - * Class responsible for playing in-call related tones in a background thread. This class only - * allows one tone to be played at a time. - */ -public class InCallTonePlayer { - - public static final int TONE_CALL_WAITING = 4; - - public static final int VOLUME_RELATIVE_HIGH_PRIORITY = 80; - - private final ToneGeneratorFactory mToneGeneratorFactory; - private final PausableExecutor mExecutor; - private @Nullable CountDownLatch mNumPlayingTones; - - /** - * Creates a new InCallTonePlayer. - * - * @param toneGeneratorFactory the {@link ToneGeneratorFactory} used to create - * {@link ToneGenerator}s. - * @param executor the {@link PausableExecutor} used to play tones in a background thread. - * @throws NullPointerException if audioModeProvider, toneGeneratorFactory, or executor are - * {@code null}. - */ - public InCallTonePlayer(ToneGeneratorFactory toneGeneratorFactory, PausableExecutor executor) { - mToneGeneratorFactory = Preconditions.checkNotNull(toneGeneratorFactory); - mExecutor = Preconditions.checkNotNull(executor); - } - - /** - * @return {@code true} if a tone is currently playing, {@code false} otherwise. - */ - public boolean isPlayingTone() { - return mNumPlayingTones != null && mNumPlayingTones.getCount() > 0; - } - - /** - * Plays the given tone in a background thread. - * - * @param tone the tone to play. - * @throws IllegalStateException if a tone is already playing. - * @throws IllegalArgumentException if the tone is invalid. - */ - public void play(int tone) { - if (isPlayingTone()) { - throw new IllegalStateException("Tone already playing"); - } - final ToneGeneratorInfo info = getToneGeneratorInfo(tone); - mNumPlayingTones = new CountDownLatch(1); - mExecutor.execute(new Runnable() { - @Override - public void run() { - playOnBackgroundThread(info); - } - }); - } - - private ToneGeneratorInfo getToneGeneratorInfo(int tone) { - switch (tone) { - case TONE_CALL_WAITING: - /* - * Call waiting tones play until they're stopped either by the user accepting or - * declining the call so the tone length is set at what's effectively forever. The - * tone is played at a high priority volume and through STREAM_VOICE_CALL since it's - * call related and using that stream will route it through bluetooth devices - * appropriately. - */ - return new ToneGeneratorInfo(ToneGenerator.TONE_SUP_CALL_WAITING, - VOLUME_RELATIVE_HIGH_PRIORITY, - Integer.MAX_VALUE, - AudioManager.STREAM_VOICE_CALL); - default: - throw new IllegalArgumentException("Bad tone: " + tone); - } - } - - private void playOnBackgroundThread(ToneGeneratorInfo info) { - ToneGenerator toneGenerator = null; - try { - Log.v(this, "Starting tone " + info); - toneGenerator = mToneGeneratorFactory.newInCallToneGenerator(info.stream, info.volume); - toneGenerator.startTone(info.tone); - /* - * During tests, this will block until the tests call mExecutor.ackMilestone. This call - * allows for synchronization to the point where the tone has started playing. - */ - mExecutor.milestone(); - if (mNumPlayingTones != null) { - mNumPlayingTones.await(info.toneLengthMillis, TimeUnit.MILLISECONDS); - // Allows for synchronization to the point where the tone has completed playing. - mExecutor.milestone(); - } - } catch (InterruptedException e) { - Log.w(this, "Interrupted while playing in-call tone."); - } finally { - if (toneGenerator != null) { - toneGenerator.release(); - } - if (mNumPlayingTones != null) { - mNumPlayingTones.countDown(); - } - // Allows for synchronization to the point where this background thread has cleaned up. - mExecutor.milestone(); - } - } - - /** - * Stops playback of the current tone. - */ - public void stop() { - if (mNumPlayingTones != null) { - mNumPlayingTones.countDown(); - } - } - - private static class ToneGeneratorInfo { - public final int tone; - public final int volume; - public final int toneLengthMillis; - public final int stream; - - public ToneGeneratorInfo(int toneGeneratorType, int volume, int toneLengthMillis, - int stream) { - this.tone = toneGeneratorType; - this.volume = volume; - this.toneLengthMillis = toneLengthMillis; - this.stream = stream; - } - - @Override - public String toString() { - return MoreObjects.toStringHelper(this) - .add("tone", tone) - .add("volume", volume) - .add("toneLengthMillis", toneLengthMillis).toString(); - } - } -} diff --git a/InCallUI/src/com/android/incallui/ringtone/ToneGeneratorFactory.java b/InCallUI/src/com/android/incallui/ringtone/ToneGeneratorFactory.java deleted file mode 100644 index ac47c8a7d..000000000 --- a/InCallUI/src/com/android/incallui/ringtone/ToneGeneratorFactory.java +++ /dev/null @@ -1,36 +0,0 @@ -/* - * Copyright (C) 2016 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.ringtone; - -import android.media.ToneGenerator; - -/** - * Factory used to create {@link ToneGenerator}s. - */ -public class ToneGeneratorFactory { - - /** - * Creates a new {@link ToneGenerator} to use while in a call. - * - * @param stream the stream through which to play tones. - * @param volume the volume at which to play tones. - * @return a new ToneGenerator. - */ - public ToneGenerator newInCallToneGenerator(int stream, int volume) { - return new ToneGenerator(stream, volume); - } -} diff --git a/InCallUI/src/com/android/incallui/service/PhoneNumberService.java b/InCallUI/src/com/android/incallui/service/PhoneNumberService.java deleted file mode 100644 index 70da4ef3a..000000000 --- a/InCallUI/src/com/android/incallui/service/PhoneNumberService.java +++ /dev/null @@ -1,67 +0,0 @@ -/* - * Copyright (C) 2013 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License - */ - -package com.android.incallui.service; - -import android.graphics.Bitmap; - -/** - * Provides phone number lookup services. - */ -public interface PhoneNumberService { - - /** - * Get a phone number number asynchronously. - * - * @param phoneNumber The phone number to lookup. - * @param listener The listener to notify when the phone number lookup is complete. - * @param imageListener The listener to notify when the image lookup is complete. - */ - public void getPhoneNumberInfo(String phoneNumber, NumberLookupListener listener, - ImageLookupListener imageListener, boolean isIncoming); - - public interface NumberLookupListener { - - /** - * Callback when a phone number has been looked up. - * - * @param info The looked up information. Or (@literal null} if there are no results. - */ - public void onPhoneNumberInfoComplete(PhoneNumberInfo info); - } - - public interface ImageLookupListener { - - /** - * Callback when a image has been fetched. - * - * @param bitmap The fetched image. - */ - public void onImageFetchComplete(Bitmap bitmap); - } - - public interface PhoneNumberInfo { - public String getDisplayName(); - public String getNumber(); - public int getPhoneType(); - public String getPhoneLabel(); - public String getNormalizedNumber(); - public String getImageUrl(); - public String getLookupKey(); - public boolean isBusiness(); - public int getLookupSource(); - } -} diff --git a/InCallUI/src/com/android/incallui/spam/SpamCallListListener.java b/InCallUI/src/com/android/incallui/spam/SpamCallListListener.java deleted file mode 100644 index b97f4d099..000000000 --- a/InCallUI/src/com/android/incallui/spam/SpamCallListListener.java +++ /dev/null @@ -1,117 +0,0 @@ -/* - * Copyright (C) 2016 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.spam; - -import com.google.common.annotations.VisibleForTesting; - -import android.content.Context; -import android.telecom.DisconnectCause; -import android.text.TextUtils; - -import com.android.dialer.calllog.CallLogAsyncTaskUtil; -import com.android.incallui.Call; -import com.android.incallui.CallList; -import com.android.incallui.Log; - -public class SpamCallListListener implements CallList.Listener { - private static final String TAG = "SpamCallListListener"; - - private final Context mContext; - - public SpamCallListListener(Context context) { - mContext = context; - } - - @Override - public void onIncomingCall(final Call call) { - String number = call.getNumber(); - if (TextUtils.isEmpty(number)) { - return; - } - CallLogAsyncTaskUtil.getNumberInCallHistory(mContext, number, - new CallLogAsyncTaskUtil.OnGetNumberInCallHistoryListener() { - @Override - public void onComplete(boolean inCallHistory) { - call.setCallHistoryStatus(inCallHistory ? - Call.CALL_HISTORY_STATUS_PRESENT - : Call.CALL_HISTORY_STATUS_NOT_PRESENT); - } - }); - } - - @Override - public void onUpgradeToVideo(Call call) {} - - @Override - public void onCallListChange(CallList callList) {} - - @Override - public void onDisconnect(Call call) { - if (shouldShowAfterCallNotification(call)) { - showNotification(call.getNumber()); - } - } - - /** - * Posts the intent for displaying the after call spam notification to the user. - */ - @VisibleForTesting - /* package */ void showNotification(String number) { - //TODO(mhashmi): build and show notifications here - } - - /** - * Determines if the after call notification should be shown for the specified call. - */ - private boolean shouldShowAfterCallNotification(Call call) { - String number = call.getNumber(); - if (TextUtils.isEmpty(number)) { - return false; - } - - Call.LogState logState = call.getLogState(); - if (!logState.isIncoming) { - return false; - } - - if (logState.duration <= 0) { - return false; - } - - if (logState.contactLookupResult != Call.LogState.LOOKUP_NOT_FOUND - && logState.contactLookupResult != Call.LogState.LOOKUP_UNKNOWN) { - return false; - } - - int callHistoryStatus = call.getCallHistoryStatus(); - if (callHistoryStatus == Call.CALL_HISTORY_STATUS_PRESENT) { - return false; - } else if (callHistoryStatus == Call.CALL_HISTORY_STATUS_UNKNOWN) { - Log.i(TAG, "Call history status is unknown, returning false"); - return false; - } - - // Check if call disconnected because of either user hanging up - int disconnectCause = call.getDisconnectCause().getCode(); - if (disconnectCause != DisconnectCause.LOCAL && disconnectCause != DisconnectCause.REMOTE) { - return false; - } - - Log.i(TAG, "shouldShowAfterCallNotification, returning true"); - return true; - } -} \ No newline at end of file diff --git a/InCallUI/src/com/android/incallui/util/AccessibilityUtil.java b/InCallUI/src/com/android/incallui/util/AccessibilityUtil.java deleted file mode 100644 index 1fdd2bac6..000000000 --- a/InCallUI/src/com/android/incallui/util/AccessibilityUtil.java +++ /dev/null @@ -1,30 +0,0 @@ -/* - * Copyright (C) 2013 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License - */ - -package com.android.incallui.util; - -import android.content.Context; -import android.view.accessibility.AccessibilityManager; - -public class AccessibilityUtil { - public static boolean isTalkBackEnabled(Context context) { - AccessibilityManager accessibilityManager = (AccessibilityManager) context - .getSystemService(Context.ACCESSIBILITY_SERVICE); - return accessibilityManager != null - && accessibilityManager.isEnabled() - && accessibilityManager.isTouchExplorationEnabled(); - } -} diff --git a/InCallUI/src/com/android/incallui/util/TelecomCallUtil.java b/InCallUI/src/com/android/incallui/util/TelecomCallUtil.java deleted file mode 100644 index 53ecc29e9..000000000 --- a/InCallUI/src/com/android/incallui/util/TelecomCallUtil.java +++ /dev/null @@ -1,53 +0,0 @@ -/* - * Copyright (C) 2015 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.util; - -import android.net.Uri; -import android.telecom.Call; -import android.telephony.PhoneNumberUtils; - -/** - * Class to provide a standard interface for obtaining information from the underlying - * android.telecom.Call. Much of this should be obtained through the incall.Call, but - * on occasion we need to interact with the telecom.Call directly (eg. call blocking, - * before the incall.Call has been created). - */ -public class TelecomCallUtil { - - // Whether the call handle is an emergency number. - public static boolean isEmergencyCall(Call call) { - Uri handle = call.getDetails().getHandle(); - return PhoneNumberUtils.isEmergencyNumber( - handle == null ? "" : handle.getSchemeSpecificPart()); - } - - public static String getNumber(Call call) { - if (call == null) { - return null; - } - if (call.getDetails().getGatewayInfo() != null) { - return call.getDetails().getGatewayInfo() - .getOriginalAddress().getSchemeSpecificPart(); - } - Uri handle = getHandle(call); - return handle == null ? null : handle.getSchemeSpecificPart(); - } - - public static Uri getHandle(Call call) { - return call == null ? null : call.getDetails().getHandle(); - } -} diff --git a/InCallUI/src/com/android/incallui/widget/multiwaveview/Ease.java b/InCallUI/src/com/android/incallui/widget/multiwaveview/Ease.java deleted file mode 100644 index 5ef689771..000000000 --- a/InCallUI/src/com/android/incallui/widget/multiwaveview/Ease.java +++ /dev/null @@ -1,132 +0,0 @@ -/* - * Copyright (C) 2011 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.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 deleted file mode 100644 index efeb4b7e3..000000000 --- a/InCallUI/src/com/android/incallui/widget/multiwaveview/GlowPadView.java +++ /dev/null @@ -1,1473 +0,0 @@ -/* - * Copyright (C) 2012 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.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.Rect; -import android.graphics.drawable.Drawable; -import android.os.Bundle; -import android.os.Vibrator; -import android.support.v4.view.ViewCompat; -import android.support.v4.view.accessibility.AccessibilityEventCompat; -import android.support.v4.view.accessibility.AccessibilityNodeInfoCompat; -import android.support.v4.widget.ExploreByTouchHelper; -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.AccessibilityEvent; -import android.view.accessibility.AccessibilityManager; -import android.view.accessibility.AccessibilityNodeInfo; -import android.view.accessibility.AccessibilityNodeInfo.AccessibilityAction; -import android.view.accessibility.AccessibilityNodeProvider; - -import com.android.dialer.R; - -import java.util.ArrayList; -import java.util.List; - -/** - * This is a copy of com.android.internal.widget.multiwaveview.GlowPadView with minor changes - * to remove dependencies on private api's. - * - * Incoporated the scaling functionality. - * - * 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 mRingScaleFactor = 1f; - private boolean mAllowScaling; - - private float mOuterRadius = 0.0f; - private float mSnapMargin = 0.0f; - private boolean mDragging; - private int mNewTargetResources; - - private AccessibilityNodeProvider mAccessibilityNodeProvider; - private GlowpadExploreByTouchHelper mExploreByTouchHelper; - - 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); - mAllowScaling = a.getBoolean(R.styleable.GlowPadView_allowScaling, false); - TypedValue handle = a.peekValue(R.styleable.GlowPadView_handleDrawable); - setHandleDrawable(handle != null ? handle.resourceId : R.drawable.ic_incall_audio_handle); - 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); - } - - // 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); - - mExploreByTouchHelper = new GlowpadExploreByTouchHelper(this); - ViewCompat.setAccessibilityDelegate(this, mExploreByTouchHelper); - } - - 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); - } - - /** - * This gets the suggested width accounting for the ring's scale factor. - */ - protected int getScaledSuggestedMinimumWidth() { - return (int) (mRingScaleFactor * Math.max(mOuterRing.getWidth(), 2 * mOuterRadius) - + mMaxTargetWidth); - } - - /** - * This gets the suggested height accounting for the ring's scale factor. - */ - protected int getScaledSuggestedMinimumHeight() { - return (int) (mRingScaleFactor * 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); - - mRingScaleFactor = computeScaleFactor(minimumWidth, minimumHeight, - computedWidth, computedHeight); - - int scaledWidth = getScaledSuggestedMinimumWidth(); - int scaledHeight = getScaledSuggestedMinimumHeight(); - - computeInsets(computedWidth - scaledWidth, computedHeight - scaledHeight); - 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); - 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)); - } - - float ringScaleTarget = expanded ? - RING_SCALE_EXPANDED : RING_SCALE_COLLAPSED; - ringScaleTarget *= mRingScaleFactor; - 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)); - } - float ringScale = mRingScaleFactor * RING_SCALE_EXPANDED; - mTargetAnimations.add(Tweener.to(mOuterRing, duration, - "ease", Ease.Cubic.easeOut, - "alpha", 1.0f, - "scaleX", ringScale, - "scaleY", ringScale, - "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 handle drawable to the drawable specified by the resource ID. - * @param resourceId - */ - public void setHandleDrawable(int resourceId) { - if (mHandleDrawable != null) { - mHandleDrawable.setDrawable(getResources(), resourceId); - } else { - mHandleDrawable = new TargetDrawable(getResources(), resourceId, 1); - } - mHandleDrawable.setState(TargetDrawable.STATE_INACTIVE); - } - - /** - * 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) { - float dx = x - mOuterRing.getX(); - float dy = y - mOuterRing.getY(); - dx *= 1f / mRingScaleFactor; - dy *= 1f / mRingScaleFactor; - mPointCloud.glowManager.setX(mOuterRing.getX() + dx); - mPointCloud.glowManager.setY(mOuterRing.getY() + dy); - } - - 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.hypot(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 = mRingScaleFactor * 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; - } - } - - /** - * Given the desired width and height of the ring and the allocated width and height, compute - * how much we need to scale the ring. - */ - private float computeScaleFactor(int desiredWidth, int desiredHeight, - int actualWidth, int actualHeight) { - - // Return unity if scaling is not allowed. - if (!mAllowScaling) return 1f; - - final int layoutDirection = getLayoutDirection(); - final int absoluteGravity = Gravity.getAbsoluteGravity(mGravity, layoutDirection); - - float scaleX = 1f; - float scaleY = 1f; - - // We use the gravity as a cue for whether we want to scale on a particular axis. - // We only scale to fit horizontally if we're not pinned to the left or right. Likewise, - // we only scale to fit vertically if we're not pinned to the top or bottom. In these - // cases, we want the ring to hang off the side or top/bottom, respectively. - switch (absoluteGravity & Gravity.HORIZONTAL_GRAVITY_MASK) { - case Gravity.LEFT: - case Gravity.RIGHT: - break; - case Gravity.CENTER_HORIZONTAL: - default: - if (desiredWidth > actualWidth) { - scaleX = (1f * actualWidth - mMaxTargetWidth) / - (desiredWidth - mMaxTargetWidth); - } - break; - } - switch (absoluteGravity & Gravity.VERTICAL_GRAVITY_MASK) { - case Gravity.TOP: - case Gravity.BOTTOM: - break; - case Gravity.CENTER_VERTICAL: - default: - if (desiredHeight > actualHeight) { - scaleY = (1f * actualHeight - mMaxTargetHeight) / - (desiredHeight - mMaxTargetHeight); - } - break; - } - return Math.min(scaleX, scaleY); - } - - private float getRingWidth() { - return mRingScaleFactor * Math.max(mOuterRing.getWidth(), 2 * mOuterRadius); - } - - private float getRingHeight() { - return mRingScaleFactor * Math.max(mOuterRing.getHeight(), 2 * mOuterRadius); - } - - @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 = getRingWidth(); - final float placementHeight = getRingHeight(); - float newWaveCenterX = mHorizontalInset - + (mMaxTargetWidth + placementWidth) / 2; - float newWaveCenterY = mVerticalInset - + (mMaxTargetHeight + placementHeight) / 2; - - if (mInitialLayout) { - stopAndHideWaveAnimation(); - hideTargets(false, false); - mInitialLayout = false; - } - - mOuterRing.setPositionX(newWaveCenterX); - mOuterRing.setPositionY(newWaveCenterY); - - mPointCloud.setScale(mRingScaleFactor); - - 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(getRingWidth() / 2 * (float) Math.cos(angle)); - targetIcon.setY(getRingHeight() / 2 * (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; - } - - public class GlowpadExploreByTouchHelper extends ExploreByTouchHelper { - - private Rect mBounds = new Rect(); - - public GlowpadExploreByTouchHelper(View forView) { - super(forView); - } - - @Override - protected int getVirtualViewAt(float x, float y) { - if (mGrabbedState == OnTriggerListener.CENTER_HANDLE) { - for (int i = 0; i < mTargetDrawables.size(); i++) { - final TargetDrawable target = mTargetDrawables.get(i); - if (target.isEnabled() && target.getBounds().contains((int) x, (int) y)) { - return i; - } - } - return INVALID_ID; - } else { - return HOST_ID; - } - } - - @Override - protected void getVisibleVirtualViews(List virtualViewIds) { - if (mGrabbedState == OnTriggerListener.CENTER_HANDLE) { - // Add virtual views backwards so that accessibility services like switch - // access traverse them in the correct order - for (int i = mTargetDrawables.size() - 1; i >= 0; i--) { - if (mTargetDrawables.get(i).isEnabled()) { - virtualViewIds.add(i); - } - } - } - } - - @Override - protected void onPopulateEventForVirtualView(int virtualViewId, AccessibilityEvent event) { - if (virtualViewId >= 0 && virtualViewId < mTargetDescriptions.size()) { - event.setContentDescription(mTargetDescriptions.get(virtualViewId)); - } - } - - @Override - public void onInitializeAccessibilityEvent(View host, AccessibilityEvent event) { - if (host == GlowPadView.this && event.getEventType() - == AccessibilityEvent.TYPE_WINDOW_CONTENT_CHANGED) { - event.setContentChangeTypes(AccessibilityEvent.CONTENT_CHANGE_TYPE_SUBTREE); - } - super.onInitializeAccessibilityEvent(host, event); - } - - @Override - public void onPopulateNodeForHost(AccessibilityNodeInfoCompat node) { - if (mGrabbedState == OnTriggerListener.NO_HANDLE) { - node.setClickable(true); - node.addAction(AccessibilityNodeInfoCompat.ACTION_CLICK); - } - mBounds.set(0, 0, GlowPadView.this.getWidth(), GlowPadView.this.getHeight()); - node.setBoundsInParent(mBounds); - } - - @Override - public boolean performAccessibilityAction(View host, int action, Bundle args) { - if (mGrabbedState == OnTriggerListener.NO_HANDLE) { - // Simulate handle being grabbed to expose targets. - trySwitchToFirstTouchState(mWaveCenterX, mWaveCenterY); - invalidateRoot(); - return true; - } - return super.performAccessibilityAction(host, action, args); - } - - @Override - protected void onPopulateNodeForVirtualView(int virtualViewId, - AccessibilityNodeInfoCompat node) { - if (virtualViewId < mTargetDrawables.size()) { - final TargetDrawable target = mTargetDrawables.get(virtualViewId); - node.setBoundsInParent(target.getBounds()); - node.setClickable(true); - node.addAction(AccessibilityNodeInfoCompat.ACTION_CLICK); - node.setContentDescription(getTargetDescription(virtualViewId)); - } - } - - @Override - protected boolean onPerformActionForVirtualView(int virtualViewId, int action, - Bundle arguments) { - if (action == AccessibilityNodeInfo.ACTION_CLICK) { - if (virtualViewId >= 0 && virtualViewId < mTargetDrawables.size()) { - dispatchTriggerEvent(virtualViewId); - return true; - } - } - return false; - } - - } -} diff --git a/InCallUI/src/com/android/incallui/widget/multiwaveview/PointCloud.java b/InCallUI/src/com/android/incallui/widget/multiwaveview/PointCloud.java deleted file mode 100644 index 07a2cb964..000000000 --- a/InCallUI/src/com/android/incallui/widget/multiwaveview/PointCloud.java +++ /dev/null @@ -1,235 +0,0 @@ -/* - * Copyright (C) 2012 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.incallui.widget.multiwaveview; - -import android.graphics.Canvas; -import android.graphics.Color; -import android.graphics.Paint; -import android.graphics.drawable.Drawable; -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 * (float) Math.cos(eta); - float y = r * (float) Math.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 (float) Math.hypot(x, 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) { - double cos = Math.cos(Math.PI * 0.25d * glowDistance / glowManager.radius); - glowAlpha = glowManager.alpha * max(0.0f, (float) Math.pow(cos, 10.0d)); - } - - // 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) { - double cos = Math.cos(Math.PI * 0.25d * distanceToWaveRing / waveManager.width); - waveAlpha = waveManager.alpha * max(0.0f, (float) Math.pow(cos, 20.0d)); - } - - 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 deleted file mode 100644 index adc5324eb..000000000 --- a/InCallUI/src/com/android/incallui/widget/multiwaveview/TargetDrawable.java +++ /dev/null @@ -1,250 +0,0 @@ -/* - * Copyright (C) 2011 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.incallui.widget.multiwaveview; - -import android.content.res.Resources; -import android.graphics.Canvas; -import android.graphics.ColorFilter; -import android.graphics.Rect; -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; - private Rect mBounds; - - /** - * 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 Rect getBounds() { - if (mBounds == null) { - mBounds = new Rect(); - } - mBounds.set((int) (mTranslationX + mPositionX - getWidth() * 0.5), - (int) (mTranslationY + mPositionY - getHeight() * 0.5), - (int) (mTranslationX + mPositionX + getWidth() * 0.5), - (int) (mTranslationY + mPositionY + getHeight() * 0.5)); - return mBounds; - } - - 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 deleted file mode 100644 index 7222442fe..000000000 --- a/InCallUI/src/com/android/incallui/widget/multiwaveview/Tweener.java +++ /dev/null @@ -1,178 +0,0 @@ -/* - * Copyright (C) 2011 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.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); - } - } - } - } -} diff --git a/InCallUI/src/com/android/incalluibind/ObjectFactory.java b/InCallUI/src/com/android/incalluibind/ObjectFactory.java deleted file mode 100644 index 7e9423acf..000000000 --- a/InCallUI/src/com/android/incalluibind/ObjectFactory.java +++ /dev/null @@ -1,59 +0,0 @@ -/* - * Copyright (C) 2014 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.incalluibind; - -import android.content.Context; -import android.content.Intent; - -import com.android.incallui.CallCardPresenter.EmergencyCallListener; -import com.android.incallui.ContactUtils; -import com.android.incallui.DistanceHelper; -import com.android.incallui.service.PhoneNumberService; - -public class ObjectFactory { - - public static PhoneNumberService newPhoneNumberService(Context context) { - // no phone number service. - return null; - } - - public static EmergencyCallListener newEmergencyCallListener() { - return null; - } - - /** @return An {@link Intent} to be broadcast when the InCallUI is visible. */ - public static Intent getUiReadyBroadcastIntent(Context context) { - return null; - } - - /** - * @return An {@link Intent} to be broadcast when the call state button in the InCallUI is - * touched while in a call. - */ - public static Intent getCallStateButtonBroadcastIntent(Context context) { - return null; - } - - public static DistanceHelper newDistanceHelper(Context context, - DistanceHelper.Listener listener) { - return null; - } - - public static ContactUtils getContactUtilsInstance(Context context) { - return null; - } -} diff --git a/InCallUI/tests/src/com/android/incallui/CallCardPresenterTest.java b/InCallUI/tests/src/com/android/incallui/CallCardPresenterTest.java deleted file mode 100644 index 79545ce4b..000000000 --- a/InCallUI/tests/src/com/android/incallui/CallCardPresenterTest.java +++ /dev/null @@ -1,121 +0,0 @@ -/* - * Copyright (C) 2016 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.test.AndroidTestCase; -import android.test.suitebuilder.annotation.MediumTest; - -import com.android.contacts.common.preference.ContactsPreferences; -import com.android.incallui.ContactInfoCache.ContactCacheEntry; - -import org.mockito.Mock; -import org.mockito.Mockito; -import org.mockito.MockitoAnnotations; - -@MediumTest -public class CallCardPresenterTest extends AndroidTestCase { - - private static final String NAME_PRIMARY = "Full Name"; - private static final String NAME_ALTERNATIVE = "Name, Full"; - private static final String LOCATION = "US"; - private static final String NUMBER = "8006459001"; - - @Mock private ContactsPreferences mContactsPreferences; - private ContactCacheEntry mUnlockedContactInfo; - private ContactCacheEntry mLockedContactInfo; - - @Override - public void setUp() throws Exception { - super.setUp(); - MockitoAnnotations.initMocks(this); - - Mockito.when(mContactsPreferences.getDisplayOrder()) - .thenReturn(ContactsPreferences.DISPLAY_ORDER_PRIMARY); - - // Unlocked all contact info is available - mUnlockedContactInfo = new ContactCacheEntry(); - mUnlockedContactInfo.namePrimary = NAME_PRIMARY; - mUnlockedContactInfo.nameAlternative = NAME_ALTERNATIVE; - mUnlockedContactInfo.location = LOCATION; - mUnlockedContactInfo.number = NUMBER; - - // Locked only number and location are available - mLockedContactInfo = new ContactCacheEntry(); - mLockedContactInfo .location = LOCATION; - mLockedContactInfo .number = NUMBER; - } - - @Override - public void tearDown() throws Exception { - super.tearDown(); - ContactsPreferencesFactory.setTestInstance(null); - } - - public void testGetNameForCall_Unlocked() { - ContactsPreferencesFactory.setTestInstance(mContactsPreferences); - CallCardPresenter presenter = new CallCardPresenter(); - presenter.init(getContext(), null); - - assertEquals(NAME_PRIMARY, presenter.getNameForCall(mUnlockedContactInfo)); - } - - public void testGetNameForCall_Locked() { - ContactsPreferencesFactory.setTestInstance(null); - CallCardPresenter presenter = new CallCardPresenter(); - presenter.init(getContext(), null); - - assertEquals(NUMBER, presenter.getNameForCall(mLockedContactInfo)); - } - - public void testGetNameForCall_EmptyPreferredName() { - ContactCacheEntry contactInfo = new ContactCacheEntry(); - contactInfo.number = NUMBER; - - ContactsPreferencesFactory.setTestInstance(null); - CallCardPresenter presenter = new CallCardPresenter(); - presenter.init(getContext(), null); - - assertEquals(NUMBER, presenter.getNameForCall(contactInfo)); - } - - public void testGetNumberForCall_Unlocked() { - ContactsPreferencesFactory.setTestInstance(mContactsPreferences); - CallCardPresenter presenter = new CallCardPresenter(); - presenter.init(getContext(), null); - - assertEquals(NUMBER, presenter.getNumberForCall(mUnlockedContactInfo)); - } - - public void testGetNumberForCall_Locked() { - ContactsPreferencesFactory.setTestInstance(null); - CallCardPresenter presenter = new CallCardPresenter(); - presenter.init(getContext(), null); - - assertEquals(LOCATION, presenter.getNumberForCall(mLockedContactInfo)); - } - - public void testGetNumberForCall_EmptyPreferredName() { - ContactCacheEntry contactInfo = new ContactCacheEntry(); - contactInfo.location = LOCATION; - - ContactsPreferencesFactory.setTestInstance(null); - CallCardPresenter presenter = new CallCardPresenter(); - presenter.init(getContext(), null); - - assertEquals(LOCATION, presenter.getNumberForCall(contactInfo)); - } -} diff --git a/InCallUI/tests/src/com/android/incallui/CallTest.java b/InCallUI/tests/src/com/android/incallui/CallTest.java deleted file mode 100644 index 118ec38da..000000000 --- a/InCallUI/tests/src/com/android/incallui/CallTest.java +++ /dev/null @@ -1,125 +0,0 @@ -/* - * Copyright (C) 2016 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.os.Bundle; -import android.telecom.Connection; -import android.test.AndroidTestCase; -import android.test.suitebuilder.annotation.SmallTest; - -import java.util.ArrayList; -import java.util.Arrays; - -// @formatter:off -/** - * Run test with - * adb shell am instrument -e class com.android.incallui.CallTest -w com.google.android.dialer.tests/android.test.InstrumentationTestRunner - */ -// @formatter:on - -@SmallTest -public class CallTest extends AndroidTestCase { - - private TestCall mCall; - - private final static String CHILD_NUMBER = "123"; - private final static ArrayList LAST_FORWARDED_NUMBER_LIST = - new ArrayList(Arrays.asList("456", "789")); - private final static String LAST_FORWARDED_NUMBER = "789"; - private final static String CALL_SUBJECT = "foo"; - - @Override - public void setUp() throws Exception { - super.setUp(); - - mCall = new TestCall(); - } - - @Override - public void tearDown() throws Exception { - super.tearDown(); - } - - public void testUpdateFromCallExtras() { - mCall.updateFromCallExtras(getTestBundle()); - verifyTestBundleResult(); - } - - public void testUpdateFromCallExtras_corruptedBundle() { - mCall.setBundleCorrupted(true); - mCall.updateFromCallExtras(getTestBundle()); - - assertEquals(mCall.getChildNumber(), null); - assertEquals(mCall.getLastForwardedNumber(), null); - assertEquals(mCall.getCallSubject(), null); - } - - public void testUpdateFromCallExtras_corruptedBundleOverwrite() { - - mCall.updateFromCallExtras(getTestBundle()); - mCall.setBundleCorrupted(true); - Bundle bundle = new Bundle(); - bundle.putString(Connection.EXTRA_CHILD_ADDRESS, "321"); - bundle.putStringArrayList(Connection.EXTRA_LAST_FORWARDED_NUMBER, - new ArrayList(Arrays.asList("654", "987"))); - bundle.putString(Connection.EXTRA_CALL_SUBJECT, "bar"); - mCall.updateFromCallExtras(bundle); - //corrupted bundle should not overwrite existing values. - verifyTestBundleResult(); - } - - private Bundle getTestBundle() { - Bundle bundle = new Bundle(); - bundle.putString(Connection.EXTRA_CHILD_ADDRESS, CHILD_NUMBER); - bundle.putStringArrayList(Connection.EXTRA_LAST_FORWARDED_NUMBER, - LAST_FORWARDED_NUMBER_LIST); - bundle.putString(Connection.EXTRA_CALL_SUBJECT, CALL_SUBJECT); - return bundle; - } - - private void verifyTestBundleResult() { - assertEquals(CHILD_NUMBER, mCall.getChildNumber()); - assertEquals(LAST_FORWARDED_NUMBER, mCall.getLastForwardedNumber()); - assertEquals(CALL_SUBJECT, mCall.getCallSubject()); - } - - private class TestCall extends Call { - - private boolean mBundleCorrupted = false; - - public TestCall() { - super(Call.State.NEW); - } - - @Override - public void updateFromCallExtras(Bundle bundle) { - super.updateFromCallExtras(bundle); - } - - public void setBundleCorrupted(boolean value) { - this.mBundleCorrupted = value; - } - - @Override - protected boolean areCallExtrasCorrupted(Bundle callExtras) { - if (mBundleCorrupted) { - return true; - } - return super.areCallExtrasCorrupted(callExtras); - } - } -} diff --git a/InCallUI/tests/src/com/android/incallui/CallerInfoUtilsTest.java b/InCallUI/tests/src/com/android/incallui/CallerInfoUtilsTest.java deleted file mode 100644 index de5a0239e..000000000 --- a/InCallUI/tests/src/com/android/incallui/CallerInfoUtilsTest.java +++ /dev/null @@ -1,31 +0,0 @@ -/* - * Copyright (C) 2015 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.test.AndroidTestCase; -import android.test.suitebuilder.annotation.SmallTest; - -@SmallTest -public class CallerInfoUtilsTest extends AndroidTestCase { - public void testToLogSafeNumber_email() { - assertEquals("xxx@xxx.xxx", CallerInfoUtils.toLogSafePhoneNumber("foo@foo.com")); - } - - public void testToLogSafeNumber_phoneNumber() { - assertEquals("xxx-xxx-xxxx", CallerInfoUtils.toLogSafePhoneNumber("123-456-6789")); - } -} diff --git a/InCallUI/tests/src/com/android/incallui/ContactsPreferencesFactoryTest.java b/InCallUI/tests/src/com/android/incallui/ContactsPreferencesFactoryTest.java deleted file mode 100644 index bf915553b..000000000 --- a/InCallUI/tests/src/com/android/incallui/ContactsPreferencesFactoryTest.java +++ /dev/null @@ -1,51 +0,0 @@ -/* - * Copyright (C) 2016 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 com.android.dialer.compat.UserManagerCompat; -import android.test.AndroidTestCase; -import android.test.suitebuilder.annotation.SmallTest; - -import com.android.contacts.common.preference.ContactsPreferences; - -import org.mockito.Mockito; - -@SmallTest -public class ContactsPreferencesFactoryTest extends AndroidTestCase { - - public void testNewContactsPreferences_Unlocked() { - if (!UserManagerCompat.isUserUnlocked(getContext())) { - return; - } - assertNotNull(ContactsPreferencesFactory.newContactsPreferences(getContext())); - } - - public void testNewContactsPreferences_Locked() { - if (UserManagerCompat.isUserUnlocked(getContext())) { - return; - } - assertNull(ContactsPreferencesFactory.newContactsPreferences(getContext())); - } - - public void testNewContactsPreferences_TestInstance() { - ContactsPreferences testInstance = Mockito.mock(ContactsPreferences.class); - ContactsPreferencesFactory.setTestInstance(testInstance); - // Assert that it returns the same object always - assertSame(testInstance, ContactsPreferencesFactory.newContactsPreferences(getContext())); - assertSame(testInstance, ContactsPreferencesFactory.newContactsPreferences(getContext())); - } -} diff --git a/InCallUI/tests/src/com/android/incallui/ExternalCallListTest.java b/InCallUI/tests/src/com/android/incallui/ExternalCallListTest.java deleted file mode 100644 index 59434700c..000000000 --- a/InCallUI/tests/src/com/android/incallui/ExternalCallListTest.java +++ /dev/null @@ -1,144 +0,0 @@ -/* - * Copyright (C) 2016 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.content.ComponentName; -import android.content.Context; -import android.net.Uri; -import android.os.Bundle; -import android.telecom.*; -import android.telecom.Call; -import android.test.AndroidTestCase; - -import com.android.contacts.common.compat.CallSdkCompat; - -import java.lang.reflect.Constructor; -import java.util.concurrent.CountDownLatch; -import java.util.concurrent.TimeUnit; - -public class ExternalCallListTest extends AndroidTestCase { - - private static class Listener implements ExternalCallList.ExternalCallListener { - private CountDownLatch mCallAddedLatch = new CountDownLatch(1); - private CountDownLatch mCallRemovedLatch = new CountDownLatch(1); - private CountDownLatch mCallUpdatedLatch = new CountDownLatch(1); - - @Override - public void onExternalCallAdded(Call call) { - mCallAddedLatch.countDown(); - } - - @Override - public void onExternalCallRemoved(Call call) { - mCallRemovedLatch.countDown(); - } - - @Override - public void onExternalCallUpdated(Call call) { - mCallUpdatedLatch.countDown(); - } - - public boolean awaitCallAdded() { - try { - return mCallAddedLatch.await(WAIT_TIMEOUT_MILLIS, TimeUnit.MILLISECONDS); - } catch (InterruptedException e) { - return false; - } - } - - public boolean awaitCallRemoved() { - try { - return mCallRemovedLatch.await(WAIT_TIMEOUT_MILLIS, TimeUnit.MILLISECONDS); - } catch (InterruptedException e) { - return false; - } - } - - public boolean awaitCallUpdated() { - try { - return mCallUpdatedLatch.await(WAIT_TIMEOUT_MILLIS, TimeUnit.MILLISECONDS); - } catch (InterruptedException e) { - return false; - } - } - } - - private static final int WAIT_TIMEOUT_MILLIS = 5000; - - private ExternalCallList mExternalCallList = new ExternalCallList(); - private Listener mExternalCallListener = new Listener(); - - @Override - public void setUp() throws Exception { - super.setUp(); - mExternalCallList.addExternalCallListener(mExternalCallListener); - } - - public void testAddCallSuccess() { - TestTelecomCall call = getTestCall(CallSdkCompat.Details.PROPERTY_IS_EXTERNAL_CALL); - mExternalCallList.onCallAdded(call.getCall()); - assertTrue(mExternalCallListener.awaitCallAdded()); - } - - public void testAddCallFail() { - TestTelecomCall call = getTestCall(0 /* no properties */); - try { - mExternalCallList.onCallAdded(call.getCall()); - fail(); - } catch (IllegalArgumentException e) { - } - } - - public void testUpdateCall() { - TestTelecomCall call = getTestCall(CallSdkCompat.Details.PROPERTY_IS_EXTERNAL_CALL); - mExternalCallList.onCallAdded(call.getCall()); - assertTrue(mExternalCallListener.awaitCallAdded()); - - call.forceDetailsUpdate(); - assertTrue(mExternalCallListener.awaitCallUpdated()); - } - - public void testRemoveCall() { - TestTelecomCall call = getTestCall(CallSdkCompat.Details.PROPERTY_IS_EXTERNAL_CALL); - mExternalCallList.onCallAdded(call.getCall()); - assertTrue(mExternalCallListener.awaitCallAdded()); - - mExternalCallList.onCallRemoved(call.getCall()); - assertTrue(mExternalCallListener.awaitCallRemoved()); - } - - private TestTelecomCall getTestCall(int properties) { - TestTelecomCall testCall = TestTelecomCall.createInstance( - "1", - Uri.parse("tel:650-555-1212"), /* handle */ - TelecomManager.PRESENTATION_ALLOWED, /* handlePresentation */ - "Joe", /* callerDisplayName */ - TelecomManager.PRESENTATION_ALLOWED, /* callerDisplayNamePresentation */ - new PhoneAccountHandle(new ComponentName("test", "class"), - "handle"), /* accountHandle */ - CallSdkCompat.Details.CAPABILITY_CAN_PULL_CALL, /* capabilities */ - properties, /* properties */ - null, /* disconnectCause */ - 0, /* connectTimeMillis */ - null, /* GatewayInfo */ - VideoProfile.STATE_AUDIO_ONLY, /* videoState */ - null, /* statusHints */ - null, /* extras */ - null /* intentExtras */); - return testCall; - } -} diff --git a/InCallUI/tests/src/com/android/incallui/ExternalCallNotifierTest.java b/InCallUI/tests/src/com/android/incallui/ExternalCallNotifierTest.java deleted file mode 100644 index 64ddd2ea5..000000000 --- a/InCallUI/tests/src/com/android/incallui/ExternalCallNotifierTest.java +++ /dev/null @@ -1,214 +0,0 @@ -/* - * Copyright (C) 2016 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 static org.mockito.Matchers.anyInt; -import static org.mockito.Mockito.any; -import static org.mockito.Mockito.anyBoolean; -import static org.mockito.Mockito.doAnswer; -import static org.mockito.Mockito.eq; -import static org.mockito.Mockito.timeout; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.when; - -import com.android.contacts.common.preference.ContactsPreferences; - -import org.mockito.ArgumentCaptor; -import org.mockito.Mock; -import org.mockito.MockitoAnnotations; -import org.mockito.Spy; -import org.mockito.invocation.InvocationOnMock; -import org.mockito.stubbing.Answer; - -import android.app.Notification; -import android.app.NotificationManager; -import android.content.ComponentName; -import android.content.Context; -import android.content.res.Resources; -import android.net.Uri; -import android.telecom.*; -import android.telecom.Call; -import android.telephony.TelephonyManager; -import android.test.AndroidTestCase; -import android.test.mock.MockContext; - -import com.android.contacts.common.compat.CallSdkCompat; - -/** - * Unit tests for {@link ExternalCallNotifier}. - */ -public class ExternalCallNotifierTest extends AndroidTestCase { - private static final int TIMEOUT_MILLIS = 5000; - private static final String NAME_PRIMARY = "Full Name"; - private static final String NAME_ALTERNATIVE = "Name, Full"; - private static final String LOCATION = "US"; - private static final String NUMBER = "6505551212"; - - @Mock private ContactsPreferences mContactsPreferences; - @Mock private NotificationManager mNotificationManager; - @Mock private MockContext mMockContext; - @Mock private Resources mResources; - @Mock private StatusBarNotifier mStatusBarNotifier; - @Mock private ContactInfoCache mContactInfoCache; - @Mock private TelecomManager mTelecomManager; - @Mock private TelephonyManager mTelephonyManager; - @Mock private ProximitySensor mProximitySensor; - @Mock private CallList mCallList; - private InCallPresenter mInCallPresenter; - private ExternalCallNotifier mExternalCallNotifier; - private ContactInfoCache.ContactCacheEntry mContactInfo; - - @Override - public void setUp() throws Exception { - super.setUp(); - MockitoAnnotations.initMocks(this); - - when(mContactsPreferences.getDisplayOrder()) - .thenReturn(ContactsPreferences.DISPLAY_ORDER_PRIMARY); - - // Setup the mock context to return mocks for some of the needed services; the notification - // service is especially important as we want to be able to intercept calls into it and - // validate the notifcations. - when(mMockContext.getSystemService(eq(Context.NOTIFICATION_SERVICE))) - .thenReturn(mNotificationManager); - when(mMockContext.getSystemService(eq(Context.TELECOM_SERVICE))) - .thenReturn(mTelecomManager); - when(mMockContext.getSystemService(eq(Context.TELEPHONY_SERVICE))) - .thenReturn(mTelephonyManager); - - // These aspects of the context are used by the notification builder to build the actual - // notification; we will rely on the actual implementations of these. - when(mMockContext.getPackageManager()).thenReturn(mContext.getPackageManager()); - when(mMockContext.getResources()).thenReturn(mContext.getResources()); - when(mMockContext.getApplicationInfo()).thenReturn(mContext.getApplicationInfo()); - when(mMockContext.getContentResolver()).thenReturn(mContext.getContentResolver()); - when(mMockContext.getPackageName()).thenReturn(mContext.getPackageName()); - - ContactsPreferencesFactory.setTestInstance(null); - mExternalCallNotifier = new ExternalCallNotifier(mMockContext, mContactInfoCache); - - // We don't directly use the InCallPresenter in the test, or even in ExternalCallNotifier - // itself. However, ExternalCallNotifier needs to make instances of - // com.android.incallui.Call for the purpose of performing contact cache lookups. The - // Call class depends on the static InCallPresenter for a number of things, so we need to - // set it up here to prevent crashes. - mInCallPresenter = InCallPresenter.getInstance(); - mInCallPresenter.setUp(mMockContext, mCallList, new ExternalCallList(), - null, mStatusBarNotifier, mExternalCallNotifier, mContactInfoCache, - mProximitySensor); - - // Unlocked all contact info is available - mContactInfo = new ContactInfoCache.ContactCacheEntry(); - mContactInfo.namePrimary = NAME_PRIMARY; - mContactInfo.nameAlternative = NAME_ALTERNATIVE; - mContactInfo.location = LOCATION; - mContactInfo.number = NUMBER; - - // Given the mock ContactInfoCache cache, we need to mock out what happens when the - // ExternalCallNotifier calls into the contact info cache to do a lookup. We will always - // return mock info stored in mContactInfo. - doAnswer(new Answer() { - @Override - public Object answer(InvocationOnMock invocation) throws Throwable { - Object[] args = invocation.getArguments(); - com.android.incallui.Call call = (com.android.incallui.Call) args[0]; - ContactInfoCache.ContactInfoCacheCallback callback - = (ContactInfoCache.ContactInfoCacheCallback) args[2]; - callback.onContactInfoComplete(call.getId(), mContactInfo); - return null; - } - }).when(mContactInfoCache).findInfo(any(com.android.incallui.Call.class), anyBoolean(), - any(ContactInfoCache.ContactInfoCacheCallback.class)); - } - - @Override - public void tearDown() throws Exception { - super.tearDown(); - ContactsPreferencesFactory.setTestInstance(null); - mInCallPresenter.tearDown(); - } - - public void testPostNonPullable() { - TestTelecomCall call = getTestCall(false); - mExternalCallNotifier.onExternalCallAdded(call.getCall()); - Notification notification = verifyNotificationPosted(); - assertNull(notification.actions); - } - - public void testPostPullable() { - TestTelecomCall call = getTestCall(true); - mExternalCallNotifier.onExternalCallAdded(call.getCall()); - Notification notification = verifyNotificationPosted(); - assertEquals(1, notification.actions.length); - } - - public void testNotificationDismissed() { - TestTelecomCall call = getTestCall(false); - mExternalCallNotifier.onExternalCallAdded(call.getCall()); - verifyNotificationPosted(); - - mExternalCallNotifier.onExternalCallRemoved(call.getCall()); - verify(mNotificationManager, timeout(TIMEOUT_MILLIS)).cancel(eq("EXTERNAL_CALL"), eq(0)); - } - - public void testNotificationUpdated() { - TestTelecomCall call = getTestCall(false); - mExternalCallNotifier.onExternalCallAdded(call.getCall()); - verifyNotificationPosted(); - - call.setCapabilities(CallSdkCompat.Details.CAPABILITY_CAN_PULL_CALL); - mExternalCallNotifier.onExternalCallUpdated(call.getCall()); - - ArgumentCaptor notificationCaptor = - ArgumentCaptor.forClass(Notification.class); - verify(mNotificationManager, timeout(TIMEOUT_MILLIS).times(2)) - .notify(eq("EXTERNAL_CALL"), eq(0), notificationCaptor.capture()); - Notification notification1 = notificationCaptor.getAllValues().get(0); - assertNull(notification1.actions); - Notification notification2 = notificationCaptor.getAllValues().get(1); - assertEquals(1, notification2.actions.length); - } - - private Notification verifyNotificationPosted() { - ArgumentCaptor notificationCaptor = - ArgumentCaptor.forClass(Notification.class); - verify(mNotificationManager, timeout(TIMEOUT_MILLIS)) - .notify(eq("EXTERNAL_CALL"), eq(0), notificationCaptor.capture()); - return notificationCaptor.getValue(); - } - - private TestTelecomCall getTestCall(boolean canPull) { - TestTelecomCall testCall = TestTelecomCall.createInstance( - "1", - Uri.parse("tel:650-555-1212"), /* handle */ - TelecomManager.PRESENTATION_ALLOWED, /* handlePresentation */ - "Joe", /* callerDisplayName */ - TelecomManager.PRESENTATION_ALLOWED, /* callerDisplayNamePresentation */ - new PhoneAccountHandle(new ComponentName("test", "class"), - "handle"), /* accountHandle */ - canPull ? CallSdkCompat.Details.CAPABILITY_CAN_PULL_CALL : 0, /* capabilities */ - CallSdkCompat.Details.PROPERTY_IS_EXTERNAL_CALL, /* properties */ - null, /* disconnectCause */ - 0, /* connectTimeMillis */ - null, /* GatewayInfo */ - VideoProfile.STATE_AUDIO_ONLY, /* videoState */ - null, /* statusHints */ - null, /* extras */ - null /* intentExtras */); - return testCall; - } -} diff --git a/InCallUI/tests/src/com/android/incallui/InCallContactInteractionsTest.java b/InCallUI/tests/src/com/android/incallui/InCallContactInteractionsTest.java deleted file mode 100644 index 625cda448..000000000 --- a/InCallUI/tests/src/com/android/incallui/InCallContactInteractionsTest.java +++ /dev/null @@ -1,325 +0,0 @@ -/* - * Copyright (C) 2015 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.location.Address; -import android.test.AndroidTestCase; -import android.util.Pair; - -import com.android.incallui.InCallContactInteractions.BusinessContextInfo; - -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Calendar; -import java.util.List; -import java.util.Locale; - -/** - * Tests for InCallContactInteractions class methods for formatting info for display. - * - * NOTE: tests assume system settings are set to 12hr time format and US locale. This means that - * the output of InCallContactInteractions methods are compared against strings in 12hr time format - * and US locale address formatting unless otherwise specified. - */ -public class InCallContactInteractionsTest extends AndroidTestCase { - private InCallContactInteractions mInCallContactInteractions; - private static final float TEST_DISTANCE = (float) 1234.56; - - @Override - protected void setUp() { - mInCallContactInteractions = new InCallContactInteractions(mContext, true /* isBusiness */); - } - - public void testIsOpenNow_NowMatchesOpenTime() { - assertEquals(mContext.getString(R.string.open_now), - mInCallContactInteractions.constructHoursInfo( - getTestCalendarWithHour(8), - Arrays.asList( - Pair.create( - getTestCalendarWithHour(8), - getTestCalendarWithHour(20)))) - .heading); - } - - public void testIsOpenNow_ClosingAfterMidnight() { - assertEquals(mContext.getString(R.string.open_now), - mInCallContactInteractions.constructHoursInfo( - getTestCalendarWithHour(10), - Arrays.asList( - Pair.create( - getTestCalendarWithHour(8), - getTestCalendarWithHourAndDaysFromToday(1, 1)))) - .heading); - } - - public void testIsOpenNow_Open24Hours() { - assertEquals(mContext.getString(R.string.open_now), - mInCallContactInteractions.constructHoursInfo( - getTestCalendarWithHour(10), - Arrays.asList( - Pair.create( - getTestCalendarWithHour(8), - getTestCalendarWithHourAndDaysFromToday(8, 1)))) - .heading); - } - - public void testIsOpenNow_AfterMiddayBreak() { - assertEquals(mContext.getString(R.string.open_now), - mInCallContactInteractions.constructHoursInfo( - getTestCalendarWithHour(13), - Arrays.asList( - Pair.create( - getTestCalendarWithHour(8), - getTestCalendarWithHour(10)), - Pair.create( - getTestCalendarWithHour(12), - getTestCalendarWithHour(15)))) - .heading); - } - - public void testIsClosedNow_DuringMiddayBreak() { - assertEquals(mContext.getString(R.string.closed_now), - mInCallContactInteractions.constructHoursInfo( - getTestCalendarWithHour(11), - Arrays.asList( - Pair.create( - getTestCalendarWithHour(8), - getTestCalendarWithHour(10)), - Pair.create( - getTestCalendarWithHour(12), - getTestCalendarWithHour(15)))) - .heading); - } - - public void testIsClosedNow_BeforeOpen() { - assertEquals(mContext.getString(R.string.closed_now), - mInCallContactInteractions.constructHoursInfo( - getTestCalendarWithHour(6), - Arrays.asList( - Pair.create( - getTestCalendarWithHour(8), - getTestCalendarWithHour(20)))) - .heading); - } - - public void testIsClosedNow_NowMatchesClosedTime() { - assertEquals(mContext.getString(R.string.closed_now), - mInCallContactInteractions.constructHoursInfo( - getTestCalendarWithHour(20), - Arrays.asList( - Pair.create( - getTestCalendarWithHour(8), - getTestCalendarWithHour(20)))) - .heading); - } - - public void testIsClosedNow_AfterClosed() { - assertEquals(mContext.getString(R.string.closed_now), - mInCallContactInteractions.constructHoursInfo( - getTestCalendarWithHour(21), - Arrays.asList( - Pair.create( - getTestCalendarWithHour(8), - getTestCalendarWithHour(20)))) - .heading); - } - - public void testOpeningHours_SingleOpenRangeWhileOpen() { - assertEquals("8:00 AM - 8:00 PM", - mInCallContactInteractions.constructHoursInfo( - getTestCalendarWithHour(12), - Arrays.asList( - Pair.create( - getTestCalendarWithHour(8), - getTestCalendarWithHour(20)))) - .detail); - } - - public void testOpeningHours_TwoOpenRangesWhileOpen() { - assertEquals("8:00 AM - 10:00 AM, 12:00 PM - 3:00 PM", - mInCallContactInteractions.constructHoursInfo( - getTestCalendarWithHour(12), - Arrays.asList( - Pair.create( - getTestCalendarWithHour(8), - getTestCalendarWithHour(10)), - Pair.create( - getTestCalendarWithHour(12), - getTestCalendarWithHour(15)))) - .detail); - } - - public void testOpeningHours_AfterClosedNoTomorrow() { - assertEquals("Closed today at 8:00 PM", - mInCallContactInteractions.constructHoursInfo( - getTestCalendarWithHour(21), - Arrays.asList( - Pair.create( - getTestCalendarWithHour(8), - getTestCalendarWithHour(20)))) - .detail); - } - - public void testOpeningHours_NotOpenTodayOpenTomorrow() { - assertEquals("Opens tomorrow at 8:00 AM", - mInCallContactInteractions.constructHoursInfo( - getTestCalendarWithHour(21), - Arrays.asList( - Pair.create( - getTestCalendarWithHourAndDaysFromToday(8, 1), - getTestCalendarWithHourAndDaysFromToday(10, 1)))) - .detail); - } - - public void testMultipleOpenRanges_BeforeOpen() { - assertEquals("Opens today at 8:00 AM", - mInCallContactInteractions.constructHoursInfo( - getTestCalendarWithHour(7), - getMultipleOpeningHours()) - .detail); - } - - public void testMultipleOpenRanges_DuringFirstRange() { - assertEquals("Closes at 10:00 AM", - mInCallContactInteractions.constructHoursInfo( - getTestCalendarWithHour(9), - getMultipleOpeningHours()) - .detail); - } - - public void testMultipleOpenRanges_BeforeMiddleRange() { - assertEquals("Opens today at 12:00 PM", - mInCallContactInteractions.constructHoursInfo( - getTestCalendarWithHour(11), - getMultipleOpeningHours()) - .detail); - } - - public void testMultipleOpeningHours_DuringLastRange() { - assertEquals("Closes at 9:00 PM", - mInCallContactInteractions.constructHoursInfo( - getTestCalendarWithHour(19), - getMultipleOpeningHours()) - .detail); - } - - public void testMultipleOpeningHours_AfterClose() { - assertEquals("Opens tomorrow at 8:00 AM", - mInCallContactInteractions.constructHoursInfo( - getTestCalendarWithHour(22), - getMultipleOpeningHours()) - .detail); - } - - public void testNotOpenTodayOrTomorrow() { - assertEquals(null, - mInCallContactInteractions.constructHoursInfo( - getTestCalendarWithHour(21), - new ArrayList>())); - } - - public void testLocationInfo_ForUS() { - BusinessContextInfo info = - mInCallContactInteractions.constructLocationInfo( - Locale.US, - getAddressForTest(), - TEST_DISTANCE); - assertEquals("0.8 mi away", info.heading); - assertEquals("Test address, Test locality", info.detail); - } - - public void testLocationInfo_ForNotUS() { - BusinessContextInfo info = - mInCallContactInteractions.constructLocationInfo( - Locale.CANADA, - getAddressForTest(), - TEST_DISTANCE); - assertEquals("1.2 km away", info.heading); - assertEquals("Test address, Test locality", info.detail); - } - - public void testLocationInfo_NoLocality() { - Address address = getAddressForTest(); - address.setLocality(null); - BusinessContextInfo info = - mInCallContactInteractions.constructLocationInfo( - Locale.CANADA, - address, - TEST_DISTANCE); - assertEquals("1.2 km away", info.heading); - assertEquals("Test address", info.detail); - } - - public void testLocationInfo_NoAddress() { - BusinessContextInfo info = - mInCallContactInteractions.constructLocationInfo( - Locale.CANADA, - null, - TEST_DISTANCE); - assertEquals(null, info); - } - - public void testLocationInfo_NoDistance() { - BusinessContextInfo info = - mInCallContactInteractions.constructLocationInfo( - Locale.US, - getAddressForTest(), - DistanceHelper.DISTANCE_NOT_FOUND); - assertEquals(null, info.heading); - } - - private Address getAddressForTest() { - Address address = new Address(Locale.US); - address.setAddressLine(0, "Test address"); - address.setLocality("Test locality"); - return address; - } - - private Calendar getTestCalendarWithHour(int hour) { - Calendar calendar = Calendar.getInstance(); - calendar.set(Calendar.HOUR_OF_DAY, hour); - calendar.set(Calendar.MINUTE, 0); - calendar.set(Calendar.SECOND, 0); - calendar.set(Calendar.MILLISECOND, 0); - return calendar; - } - - private Calendar getTestCalendarWithHourAndDaysFromToday(int hour, int daysFromToday) { - Calendar calendar = getTestCalendarWithHour(hour); - calendar.add(Calendar.DATE, daysFromToday); - return calendar; - } - - private List> getMultipleOpeningHours() { - return Arrays.asList( - Pair.create( - getTestCalendarWithHour(8), - getTestCalendarWithHour(10)), - Pair.create( - getTestCalendarWithHour(12), - getTestCalendarWithHour(15)), - Pair.create( - getTestCalendarWithHour(17), - getTestCalendarWithHour(21)), - Pair.create( - getTestCalendarWithHourAndDaysFromToday(8, 1), - getTestCalendarWithHourAndDaysFromToday(10, 1)), - Pair.create( - getTestCalendarWithHourAndDaysFromToday(12, 1), - getTestCalendarWithHourAndDaysFromToday(8, 1))); - } -} diff --git a/InCallUI/tests/src/com/android/incallui/InCallPresenterTest.java b/InCallUI/tests/src/com/android/incallui/InCallPresenterTest.java deleted file mode 100644 index f0f08ab68..000000000 --- a/InCallUI/tests/src/com/android/incallui/InCallPresenterTest.java +++ /dev/null @@ -1,198 +0,0 @@ -/* - * Copyright (C) 2015 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 static org.mockito.Mockito.never; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.when; - -import android.content.Context; -import android.content.Intent; -import android.telecom.PhoneAccountHandle; -import android.telephony.TelephonyManager; -import android.test.InstrumentationTestCase; -import android.test.suitebuilder.annotation.MediumTest; - -import com.android.incallui.InCallPresenter.InCallState; - -import org.mockito.Mock; -import org.mockito.Mockito; -import org.mockito.MockitoAnnotations; - -@MediumTest -public class InCallPresenterTest extends InstrumentationTestCase { - private MockCallListWrapper mCallList; - @Mock private InCallActivity mInCallActivity; - @Mock private AudioModeProvider mAudioModeProvider; - @Mock private StatusBarNotifier mStatusBarNotifier; - @Mock private ExternalCallNotifier mExternalCallNotifier; - @Mock private ContactInfoCache mContactInfoCache; - @Mock private ProximitySensor mProximitySensor; - - InCallPresenter mInCallPresenter; - @Mock private Context mContext; - @Mock private TelephonyManager mTelephonyManager; - - @Override - protected void setUp() throws Exception { - super.setUp(); - System.setProperty("dexmaker.dexcache", - getInstrumentation().getTargetContext().getCacheDir().getPath()); - MockitoAnnotations.initMocks(this); - mCallList = new MockCallListWrapper(); - - when(mContext.getSystemService(Context.TELEPHONY_SERVICE)).thenReturn(mTelephonyManager); - - mInCallPresenter = InCallPresenter.getInstance(); - mInCallPresenter.setUp(mContext, mCallList.getCallList(), new ExternalCallList(), - mAudioModeProvider, mStatusBarNotifier, mExternalCallNotifier, mContactInfoCache, - mProximitySensor); - } - - @Override - protected void tearDown() throws Exception { - // The tear down method needs to run in the main thread since there is an explicit check - // inside TelecomAdapter.getInstance(). - getInstrumentation().runOnMainSync(new Runnable() { - @Override - public void run() { - mInCallPresenter.unsetActivity(mInCallActivity); - mInCallPresenter.tearDown(); - InCallPresenter.setInstance(null); - } - }); - } - - public void testOnActivitySet_finishesActivityWhenNoCalls() { - mInCallPresenter.setActivity(mInCallActivity); - - verify(mInCallActivity).finish(); - } - - public void testOnCallListChange_sendsNotificationWhenInCall() { - mCallList.setHasCall(Call.State.INCOMING, true); - - mInCallPresenter.onCallListChange(mCallList.getCallList()); - - verify(mStatusBarNotifier).updateNotification(InCallState.INCOMING, - mCallList.getCallList()); - verifyInCallActivityNotStarted(); - } - - /** - * This behavior is required to ensure that the screen is turned on again by the restarting - * activity. - */ - public void testOnCallListChange_handlesCallWaitingWhenScreenOffShouldRestartActivity() { - mCallList.setHasCall(Call.State.ACTIVE, true); - - mInCallPresenter.onCallListChange(mCallList.getCallList()); - mInCallPresenter.setActivity(mInCallActivity); - - // Pretend that there is a call waiting and the screen is off - when(mInCallActivity.isDestroyed()).thenReturn(false); - when(mInCallActivity.isFinishing()).thenReturn(false); - when(mProximitySensor.isScreenReallyOff()).thenReturn(true); - mCallList.setHasCall(Call.State.INCOMING, true); - - mInCallPresenter.onCallListChange(mCallList.getCallList()); - verify(mInCallActivity).finish(); - } - - /** - * Verifies that the PENDING_OUTGOING -> IN_CALL transition brings up InCallActivity so - * that it can display an error dialog. - */ - public void testOnCallListChange_pendingOutgoingToInCallTransitionShowsUiForErrorDialog() { - mCallList.setHasCall(Call.State.CONNECTING, true); - - mInCallPresenter.onCallListChange(mCallList.getCallList()); - - mCallList.setHasCall(Call.State.CONNECTING, false); - mCallList.setHasCall(Call.State.ACTIVE, true); - - mInCallPresenter.onCallListChange(mCallList.getCallList()); - - verify(mContext).startActivity(InCallPresenter.getInstance().getInCallIntent(false, false)); - verifyIncomingCallNotificationNotSent(); - } - - /** - * Verifies that if there is a call in the SELECT_PHONE_ACCOUNT state, InCallActivity is displayed - * to display the account picker. - */ - public void testOnCallListChange_noAccountProvidedForCallShowsUiForAccountPicker() { - mCallList.setHasCall(Call.State.SELECT_PHONE_ACCOUNT, true); - mInCallPresenter.onCallListChange(mCallList.getCallList()); - - verify(mContext).startActivity(InCallPresenter.getInstance().getInCallIntent(false, false)); - verifyIncomingCallNotificationNotSent(); - } - - /** - * Verifies that for an expected call state change (e.g. NO_CALLS -> PENDING_OUTGOING), - * InCallActivity is not displayed. - */ - public void testOnCallListChange_noCallsToPendingOutgoingDoesNotShowUi() { - mCallList.setHasCall(Call.State.CONNECTING, true); - mInCallPresenter.onCallListChange(mCallList.getCallList()); - - verifyInCallActivityNotStarted(); - verifyIncomingCallNotificationNotSent(); - } - - public void testOnCallListChange_LastCallDisconnectedNoCallsLeftFinishesUi() { - mCallList.setHasCall(Call.State.DISCONNECTED, true); - mInCallPresenter.onCallListChange(mCallList.getCallList()); - - mInCallPresenter.setActivity(mInCallActivity); - - verify(mInCallActivity, never()).finish(); - - // Last remaining disconnected call is removed from CallList, activity should shut down. - mCallList.setHasCall(Call.State.DISCONNECTED, false); - mInCallPresenter.onCallListChange(mCallList.getCallList()); - verify(mInCallActivity).finish(); - } - - - //TODO - public void testCircularReveal_startsCircularRevealForOutgoingCalls() { - - } - - public void testCircularReveal_waitTillCircularRevealSentBeforeShowingCallCard() { - } - - public void testHangupOngoingCall_disconnectsCallCorrectly() { - } - - public void testAnswerIncomingCall() { - } - - public void testDeclineIncomingCall() { - } - - private void verifyInCallActivityNotStarted() { - verify(mContext, never()).startActivity(Mockito.any(Intent.class)); - } - - private void verifyIncomingCallNotificationNotSent() { - verify(mStatusBarNotifier, never()).updateNotification(Mockito.any(InCallState.class), - Mockito.any(CallList.class)); - } -} diff --git a/InCallUI/tests/src/com/android/incallui/LatencyReportTest.java b/InCallUI/tests/src/com/android/incallui/LatencyReportTest.java deleted file mode 100644 index 9d8a5131b..000000000 --- a/InCallUI/tests/src/com/android/incallui/LatencyReportTest.java +++ /dev/null @@ -1,59 +0,0 @@ -/* - * Copyright (C) 2016 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 static com.android.incallui.LatencyReport.INVALID_TIME; - -import android.os.Bundle; -import android.telecom.Connection; -import android.test.AndroidTestCase; -import android.test.suitebuilder.annotation.SmallTest; - -import java.util.ArrayList; -import java.util.Arrays; - -public class LatencyReportTest extends AndroidTestCase { - public void testEmptyInit() { - LatencyReport report = new LatencyReport(); - assertEquals(INVALID_TIME, report.getCreatedTimeMillis()); - assertEquals(INVALID_TIME, report.getTelecomRoutingStartTimeMillis()); - assertEquals(INVALID_TIME, report.getTelecomRoutingEndTimeMillis()); - assertTrue(report.getCallAddedTimeMillis() > 0); - } - - public void testCallBlocking() { - LatencyReport report = new LatencyReport(); - assertEquals(INVALID_TIME, report.getCallBlockingTimeMillis()); - report.onCallBlockingDone(); - assertTrue(report.getCallBlockingTimeMillis() > 0); - } - - public void testNotificationShown() { - LatencyReport report = new LatencyReport(); - assertEquals(INVALID_TIME, report.getCallNotificationTimeMillis()); - report.onNotificationShown(); - assertTrue(report.getCallNotificationTimeMillis() > 0); - } - - public void testInCallUiShown() { - LatencyReport report = new LatencyReport(); - assertEquals(INVALID_TIME, report.getInCallUiShownTimeMillis()); - report.onInCallUiShown(false); - assertTrue(report.getInCallUiShownTimeMillis() > 0); - assertFalse(report.getDidDisplayHeadsUpNotification()); - } -} diff --git a/InCallUI/tests/src/com/android/incallui/MockCallListWrapper.java b/InCallUI/tests/src/com/android/incallui/MockCallListWrapper.java deleted file mode 100644 index 369c4303f..000000000 --- a/InCallUI/tests/src/com/android/incallui/MockCallListWrapper.java +++ /dev/null @@ -1,80 +0,0 @@ -/* - * Copyright (C) 2015 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 static org.mockito.Mockito.anyInt; -import static org.mockito.Mockito.spy; -import static org.mockito.Mockito.when; - -import android.telecom.PhoneAccountHandle; - -import org.mockito.Mockito; -import org.mockito.invocation.InvocationOnMock; -import org.mockito.stubbing.Answer; - -import java.util.HashSet; - -/** - * Provides an instance of a mock CallList, and provides utility methods to put the CallList into - * various states (e.g. incoming call, active call, call waiting). - */ -public class MockCallListWrapper { - private CallList mCallList; - private HashSet mCallSet = new HashSet<>(); - - public MockCallListWrapper() { - mCallList = Mockito.mock(CallList.class); - mCallList = spy(new CallList()); - when(mCallList.getFirstCallWithState(anyInt())).thenAnswer(new Answer() { - @Override - public Call answer(InvocationOnMock i) throws Throwable { - Object[] args = i.getArguments(); - final int state = (int) args[0]; - if (mCallSet.contains(state)) { - return getMockCall(state); - } else { - return null; - } - } - }); - } - - public CallList getCallList() { - return mCallList; - } - - public void setHasCall(int state, boolean hasCall) { - if (hasCall) { - mCallSet.add(state); - } else { - mCallSet.remove(state); - } - } - - private static Call getMockCall(int state) { - return getMockCall(state, state != Call.State.SELECT_PHONE_ACCOUNT); - } - - private static Call getMockCall(int state, boolean hasAccountHandle) { - final Call call = Mockito.mock(Call.class); - when(call.getState()).thenReturn(Integer.valueOf(state)); - if (hasAccountHandle) { - when(call.getAccountHandle()).thenReturn(new PhoneAccountHandle(null, null)); - } - return call; - } -} diff --git a/InCallUI/tests/src/com/android/incallui/ProximitySensorTest.java b/InCallUI/tests/src/com/android/incallui/ProximitySensorTest.java deleted file mode 100644 index 1c8f34721..000000000 --- a/InCallUI/tests/src/com/android/incallui/ProximitySensorTest.java +++ /dev/null @@ -1,66 +0,0 @@ -/* - * Copyright (C) 2015 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 static org.mockito.Mockito.anyBoolean; -import static org.mockito.Mockito.never; -import static org.mockito.Mockito.times; -import static org.mockito.Mockito.verify; - -import android.test.InstrumentationTestCase; -import android.test.suitebuilder.annotation.MediumTest; - -import com.android.incallui.InCallPresenter.InCallState; - -import org.mockito.Mock; -import org.mockito.Mockito; -import org.mockito.MockitoAnnotations; - -@MediumTest -public class ProximitySensorTest extends InstrumentationTestCase { - @Mock private AccelerometerListener mAccelerometerListener; - private MockCallListWrapper mCallList; - - @Override - protected void setUp() throws Exception { - super.setUp(); - System.setProperty("dexmaker.dexcache", - getInstrumentation().getTargetContext().getCacheDir().getPath()); - MockitoAnnotations.initMocks(this); - mCallList = new MockCallListWrapper(); - } - - public void testAccelerometerBehaviorOnDisplayChange() { - final ProximitySensor proximitySensor = - new ProximitySensor( - getInstrumentation().getContext(), - new AudioModeProvider(), - mAccelerometerListener); - verify(mAccelerometerListener, never()).enable(anyBoolean()); - proximitySensor.onStateChange(null, InCallState.OUTGOING, mCallList.getCallList()); - verify(mAccelerometerListener).enable(true); - verify(mAccelerometerListener, never()).enable(false); - - proximitySensor.onDisplayStateChanged(false); - verify(mAccelerometerListener).enable(true); - verify(mAccelerometerListener).enable(false); - - proximitySensor.onDisplayStateChanged(true); - verify(mAccelerometerListener, times(2)).enable(true); - verify(mAccelerometerListener).enable(false); - } -} diff --git a/InCallUI/tests/src/com/android/incallui/StatusBarNotifierTest.java b/InCallUI/tests/src/com/android/incallui/StatusBarNotifierTest.java deleted file mode 100644 index 4c55ddcc0..000000000 --- a/InCallUI/tests/src/com/android/incallui/StatusBarNotifierTest.java +++ /dev/null @@ -1,98 +0,0 @@ -/* - * Copyright (C) 2016 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.test.AndroidTestCase; -import android.test.suitebuilder.annotation.MediumTest; - -import com.android.contacts.common.preference.ContactsPreferences; -import com.android.incallui.ContactInfoCache.ContactCacheEntry; - -import org.mockito.Mock; -import org.mockito.Mockito; -import org.mockito.MockitoAnnotations; - -@MediumTest -public class StatusBarNotifierTest extends AndroidTestCase { - - private static final String NAME_PRIMARY = "Full Name"; - private static final String NAME_ALTERNATIVE = "Name, Full"; - private static final String LOCATION = "US"; - private static final String NUMBER = "8006459001"; - - @Mock private Call mCall; - @Mock private ContactsPreferences mContactsPreferences; - private ContactCacheEntry mUnlockedContactInfo; - private ContactCacheEntry mLockedContactInfo; - - @Override - public void setUp() throws Exception { - super.setUp(); - MockitoAnnotations.initMocks(this); - - Mockito.when(mContactsPreferences.getDisplayOrder()) - .thenReturn(ContactsPreferences.DISPLAY_ORDER_PRIMARY); - - // Unlocked all contact info is available - mUnlockedContactInfo = new ContactCacheEntry(); - mUnlockedContactInfo.namePrimary = NAME_PRIMARY; - mUnlockedContactInfo.nameAlternative = NAME_ALTERNATIVE; - mUnlockedContactInfo.location = LOCATION; - mUnlockedContactInfo.number = NUMBER; - - // Locked only number and location are available - mLockedContactInfo = new ContactCacheEntry(); - mLockedContactInfo .location = LOCATION; - mLockedContactInfo .number = NUMBER; - } - - @Override - public void tearDown() throws Exception { - super.tearDown(); - ContactsPreferencesFactory.setTestInstance(null); - } - - public void testGetContentTitle_ConferenceCall() { - ContactsPreferencesFactory.setTestInstance(null); - StatusBarNotifier statusBarNotifier = new StatusBarNotifier(mContext, null); - - Mockito.when(mCall.isConferenceCall()).thenReturn(true); - Mockito.when(mCall.hasProperty(Mockito.anyInt())).thenReturn(false); - - assertEquals(mContext.getResources().getString(R.string.card_title_conf_call), - statusBarNotifier.getContentTitle(null, mCall)); - } - - public void testGetContentTitle_Unlocked() { - ContactsPreferencesFactory.setTestInstance(mContactsPreferences); - StatusBarNotifier statusBarNotifier = new StatusBarNotifier(mContext, null); - assertEquals(NAME_PRIMARY, statusBarNotifier.getContentTitle(mUnlockedContactInfo, mCall)); - } - - public void testGetContentTitle_Locked() { - ContactsPreferencesFactory.setTestInstance(null); - StatusBarNotifier statusBarNotifier = new StatusBarNotifier(mContext, null); - assertEquals(NUMBER, statusBarNotifier.getContentTitle(mLockedContactInfo, mCall)); - } - - public void testGetContentTitle_EmptyPreferredName() { - ContactCacheEntry contactCacheEntry = new ContactCacheEntry(); - contactCacheEntry.number = NUMBER; - StatusBarNotifier statusBarNotifier = new StatusBarNotifier(mContext, null); - assertEquals(NUMBER, statusBarNotifier.getContentTitle(contactCacheEntry, mCall)); - } -} diff --git a/InCallUI/tests/src/com/android/incallui/TestTelecomCall.java b/InCallUI/tests/src/com/android/incallui/TestTelecomCall.java deleted file mode 100644 index 48ac6e18f..000000000 --- a/InCallUI/tests/src/com/android/incallui/TestTelecomCall.java +++ /dev/null @@ -1,161 +0,0 @@ -/* - * Copyright (C) 2016 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 com.google.common.base.Preconditions; - -import android.content.Context; -import android.net.Uri; -import android.os.Bundle; -import android.support.annotation.Nullable; -import android.telecom.DisconnectCause; -import android.telecom.GatewayInfo; -import android.telecom.PhoneAccountHandle; -import android.telecom.StatusHints; - -import java.lang.reflect.Constructor; -import java.lang.reflect.Field; -import java.lang.reflect.InvocationTargetException; -import java.lang.reflect.Method; - -/** - * Wrapper class which uses reflection to create instances of {@link android.telecom.Call} for use - * with unit testing. Since {@link android.telecom.Call} is final, it cannot be mocked using - * mockito, and since all setter methods are hidden, it is necessary to use reflection. In the - * future, it would be desirable to replace this if a different mocking solution is used. - */ -public class TestTelecomCall { - - private android.telecom.Call mCall; - - public static @Nullable TestTelecomCall createInstance(String callId, - Uri handle, - int handlePresentation, - String callerDisplayName, - int callerDisplayNamePresentation, - PhoneAccountHandle accountHandle, - int capabilities, - int properties, - DisconnectCause disconnectCause, - long connectTimeMillis, - GatewayInfo gatewayInfo, - int videoState, - StatusHints statusHints, - Bundle extras, - Bundle intentExtras) { - - try { - // Phone and InCall adapter are @hide, so we cannot refer to them directly. - Class phoneClass = Class.forName("android.telecom.Phone"); - Class incallAdapterClass = Class.forName("android.telecom.InCallAdapter"); - Class callClass = android.telecom.Call.class; - Constructor cons = callClass - .getDeclaredConstructor(phoneClass, String.class, incallAdapterClass); - cons.setAccessible(true); - - android.telecom.Call call = (android.telecom.Call) cons.newInstance(null, callId, null); - - // Create an instance of the call details. - Class callDetailsClass = android.telecom.Call.Details.class; - Constructor detailsCons = callDetailsClass.getDeclaredConstructor( - String.class, /* telecomCallId */ - Uri.class, /* handle */ - int.class, /* handlePresentation */ - String.class, /* callerDisplayName */ - int.class, /* callerDisplayNamePresentation */ - PhoneAccountHandle.class, /* accountHandle */ - int.class, /* capabilities */ - int.class, /* properties */ - DisconnectCause.class, /* disconnectCause */ - long.class, /* connectTimeMillis */ - GatewayInfo.class, /* gatewayInfo */ - int.class, /* videoState */ - StatusHints.class, /* statusHints */ - Bundle.class, /* extras */ - Bundle.class /* intentExtras */); - detailsCons.setAccessible(true); - - android.telecom.Call.Details details = (android.telecom.Call.Details) - detailsCons.newInstance(callId, handle, handlePresentation, callerDisplayName, - callerDisplayNamePresentation, accountHandle, capabilities, properties, - disconnectCause, connectTimeMillis, gatewayInfo, videoState, - statusHints, - extras, intentExtras); - - // Finally, set this as the details of the call. - Field detailsField = call.getClass().getDeclaredField("mDetails"); - detailsField.setAccessible(true); - detailsField.set(call, details); - - return new TestTelecomCall(call); - } catch (NoSuchMethodException nsm) { - return null; - } catch (ClassNotFoundException cnf) { - return null; - } catch (IllegalAccessException e) { - return null; - } catch (InstantiationException e) { - return null; - } catch (InvocationTargetException e) { - return null; - } catch (NoSuchFieldException e) { - return null; - } - } - - private TestTelecomCall(android.telecom.Call call) { - mCall = call; - } - - public android.telecom.Call getCall() { - return mCall; - } - - public void forceDetailsUpdate() { - Preconditions.checkNotNull(mCall); - - try { - Method method = mCall.getClass().getDeclaredMethod("fireDetailsChanged", - android.telecom.Call.Details.class); - method.setAccessible(true); - method.invoke(mCall, mCall.getDetails()); - } catch (NoSuchMethodException e) { - Log.e(this, "forceDetailsUpdate", e); - } catch (InvocationTargetException e) { - Log.e(this, "forceDetailsUpdate", e); - } catch (IllegalAccessException e) { - Log.e(this, "forceDetailsUpdate", e); - } - } - - public void setCapabilities(int capabilities) { - Preconditions.checkNotNull(mCall); - try { - Field field = mCall.getDetails().getClass().getDeclaredField("mCallCapabilities"); - field.setAccessible(true); - field.set(mCall.getDetails(), capabilities); - } catch (IllegalAccessException e) { - Log.e(this, "setProperties", e); - } catch (NoSuchFieldException e) { - Log.e(this, "setProperties", e); - } - } - - public void setCall(android.telecom.Call call) { - mCall = call; - } -} diff --git a/InCallUI/tests/src/com/android/incallui/async/SingleProdThreadExecutor.java b/InCallUI/tests/src/com/android/incallui/async/SingleProdThreadExecutor.java deleted file mode 100644 index 5717c9478..000000000 --- a/InCallUI/tests/src/com/android/incallui/async/SingleProdThreadExecutor.java +++ /dev/null @@ -1,69 +0,0 @@ -/* - * Copyright (C) 2016 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.async; - -import java.util.concurrent.Executors; - -import javax.annotation.concurrent.ThreadSafe; - -/** - * {@link PausableExecutor} for use in tests. It is intended to be used between one test thread - * and one prod thread. See {@link com.android.incallui.ringtone.InCallTonePlayerTest} for example - * usage. - */ -@ThreadSafe -public final class SingleProdThreadExecutor implements PausableExecutor { - - private int mMilestonesReached; - private int mMilestonesAcked; - private boolean mHasAckedAllMilestones; - - @Override - public synchronized void milestone() { - ++mMilestonesReached; - notify(); - while (!mHasAckedAllMilestones && mMilestonesReached > mMilestonesAcked) { - try { - wait(); - } catch (InterruptedException e) {} - } - } - - @Override - public synchronized void ackMilestoneForTesting() { - ++mMilestonesAcked; - notify(); - } - - @Override - public synchronized void ackAllMilestonesForTesting() { - mHasAckedAllMilestones = true; - notify(); - } - - @Override - public synchronized void awaitMilestoneForTesting() throws InterruptedException { - while (!mHasAckedAllMilestones && mMilestonesReached <= mMilestonesAcked) { - wait(); - } - } - - @Override - public synchronized void execute(Runnable command) { - Executors.newSingleThreadExecutor().execute(command); - } -} diff --git a/InCallUI/tests/src/com/android/incallui/ringtone/DialerRingtoneManagerTest.java b/InCallUI/tests/src/com/android/incallui/ringtone/DialerRingtoneManagerTest.java deleted file mode 100644 index 01db20272..000000000 --- a/InCallUI/tests/src/com/android/incallui/ringtone/DialerRingtoneManagerTest.java +++ /dev/null @@ -1,219 +0,0 @@ -/* - * Copyright (C) 2016 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.ringtone; - -import android.media.RingtoneManager; -import android.net.Uri; -import android.test.AndroidTestCase; -import android.test.suitebuilder.annotation.SmallTest; - -import com.android.contacts.common.compat.CompatUtils; -import com.android.incallui.Call; -import com.android.incallui.Call.State; -import com.android.incallui.CallList; - -import org.mockito.Mock; -import org.mockito.Mockito; -import org.mockito.MockitoAnnotations; - -@SmallTest -public class DialerRingtoneManagerTest extends AndroidTestCase { - - private static final Uri RINGTONE_URI = RingtoneManager - .getDefaultUri(RingtoneManager.TYPE_RINGTONE); - - @Mock private InCallTonePlayer mInCallTonePlayer; - @Mock private CallList mCallList; - @Mock private Call mCall; - private DialerRingtoneManager mRingtoneManagerEnabled; - private DialerRingtoneManager mRingtoneManagerDisabled; - - @Override - public void setUp() throws Exception { - super.setUp(); - MockitoAnnotations.initMocks(this); - mRingtoneManagerEnabled = new DialerRingtoneManager(mInCallTonePlayer, mCallList); - mRingtoneManagerEnabled.setDialerRingingEnabledForTesting(true); - mRingtoneManagerDisabled = new DialerRingtoneManager(mInCallTonePlayer, mCallList); - mRingtoneManagerDisabled.setDialerRingingEnabledForTesting(false); - } - - public void testNullInCallTonePlayer() { - try { - new DialerRingtoneManager(null, mCallList); - fail(); - } catch (NullPointerException e) {} - } - - public void testNullCallList() { - try { - new DialerRingtoneManager(mInCallTonePlayer, null); - fail(); - } catch (NullPointerException e) {} - } - - public void testShouldPlayRingtone_M() { - if (CompatUtils.isNCompatible()) { - return; - } - assertFalse(mRingtoneManagerEnabled.shouldPlayRingtone(0, RINGTONE_URI)); - } - - public void testShouldPlayRingtone_N_NullUri() { - if (!CompatUtils.isNCompatible()) { - return; - } - assertFalse(mRingtoneManagerEnabled.shouldPlayRingtone(State.INCOMING, null)); - } - - public void testShouldPlayRingtone_N_Disabled() { - if (!CompatUtils.isNCompatible()) { - return; - } - assertFalse(mRingtoneManagerDisabled.shouldPlayRingtone(State.INCOMING, RINGTONE_URI)); - } - - public void testShouldPlayRingtone_N_NotIncoming() { - if (!CompatUtils.isNCompatible()) { - return; - } - assertFalse(mRingtoneManagerEnabled.shouldPlayRingtone(State.ACTIVE, RINGTONE_URI)); - } - - // Specific case for call waiting since that needs its own sound - public void testShouldPlayRingtone_N_CallWaitingByState() { - if (!CompatUtils.isNCompatible()) { - return; - } - assertFalse(mRingtoneManagerEnabled.shouldPlayRingtone(State.CALL_WAITING, RINGTONE_URI)); - } - - public void testShouldPlayRingtone_N_CallWaitingByActiveCall() { - if (!CompatUtils.isNCompatible()) { - return; - } - Mockito.when(mCallList.getActiveCall()).thenReturn(mCall); - assertFalse(mRingtoneManagerEnabled.shouldPlayRingtone(State.INCOMING, RINGTONE_URI)); - } - - public void testShouldPlayRingtone_N() { - if (!CompatUtils.isNCompatible()) { - return; - } - assertTrue(mRingtoneManagerEnabled.shouldPlayRingtone(State.INCOMING, RINGTONE_URI)); - } - - public void testShouldPlayCallWaitingTone_M() { - if (CompatUtils.isNCompatible()) { - return; - } - assertFalse(mRingtoneManagerEnabled.shouldPlayCallWaitingTone(0)); - } - - public void testShouldPlayCallWaitingTone_N_Disabled() { - if (!CompatUtils.isNCompatible()) { - return; - } - assertFalse(mRingtoneManagerDisabled.shouldPlayCallWaitingTone(State.CALL_WAITING)); - } - - public void testShouldPlayCallWaitingTone_N_NotCallWaiting() { - if (!CompatUtils.isNCompatible()) { - return; - } - assertFalse(mRingtoneManagerEnabled.shouldPlayCallWaitingTone(State.ACTIVE)); - } - - // Specific case for incoming since it plays its own sound - public void testShouldPlayCallWaitingTone_N_Incoming() { - if (!CompatUtils.isNCompatible()) { - return; - } - assertFalse(mRingtoneManagerEnabled.shouldPlayCallWaitingTone(State.INCOMING)); - } - - public void testShouldPlayCallWaitingTone_N_AlreadyPlaying() { - if (!CompatUtils.isNCompatible()) { - return; - } - Mockito.when(mInCallTonePlayer.isPlayingTone()).thenReturn(true); - assertFalse(mRingtoneManagerEnabled.shouldPlayCallWaitingTone(State.CALL_WAITING)); - } - - public void testShouldPlayCallWaitingTone_N_ByState() { - if (!CompatUtils.isNCompatible()) { - return; - } - assertTrue(mRingtoneManagerEnabled.shouldPlayCallWaitingTone(State.CALL_WAITING)); - } - - public void testShouldPlayCallWaitingTone_N_ByActiveCall() { - if (!CompatUtils.isNCompatible()) { - return; - } - Mockito.when(mCallList.getActiveCall()).thenReturn(mCall); - assertTrue(mRingtoneManagerEnabled.shouldPlayCallWaitingTone(State.INCOMING)); - } - - public void testPlayCallWaitingTone_M() { - if (CompatUtils.isNCompatible()) { - return; - } - mRingtoneManagerEnabled.playCallWaitingTone(); - Mockito.verify(mInCallTonePlayer, Mockito.never()).play(Mockito.anyInt()); - } - - public void testPlayCallWaitingTone_N_NotEnabled() { - if (!CompatUtils.isNCompatible()) { - return; - } - mRingtoneManagerDisabled.playCallWaitingTone(); - Mockito.verify(mInCallTonePlayer, Mockito.never()).play(Mockito.anyInt()); - } - - public void testPlayCallWaitingTone_N() { - if (!CompatUtils.isNCompatible()) { - return; - } - mRingtoneManagerEnabled.playCallWaitingTone(); - Mockito.verify(mInCallTonePlayer).play(Mockito.anyInt()); - } - - public void testStopCallWaitingTone_M() { - if (CompatUtils.isNCompatible()) { - return; - } - mRingtoneManagerEnabled.stopCallWaitingTone(); - Mockito.verify(mInCallTonePlayer, Mockito.never()).stop(); - } - - public void testStopCallWaitingTone_N_NotEnabled() { - if (!CompatUtils.isNCompatible()) { - return; - } - mRingtoneManagerDisabled.stopCallWaitingTone(); - Mockito.verify(mInCallTonePlayer, Mockito.never()).stop(); - } - - public void testStopCallWaitingTone_N() { - if (!CompatUtils.isNCompatible()) { - return; - } - mRingtoneManagerEnabled.stopCallWaitingTone(); - Mockito.verify(mInCallTonePlayer).stop(); - } -} diff --git a/InCallUI/tests/src/com/android/incallui/ringtone/InCallTonePlayerTest.java b/InCallUI/tests/src/com/android/incallui/ringtone/InCallTonePlayerTest.java deleted file mode 100644 index bde5c50e4..000000000 --- a/InCallUI/tests/src/com/android/incallui/ringtone/InCallTonePlayerTest.java +++ /dev/null @@ -1,148 +0,0 @@ -/* - * Copyright (C) 2016 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.ringtone; - -import android.media.AudioManager; -import android.media.ToneGenerator; -import android.test.AndroidTestCase; -import android.test.suitebuilder.annotation.SmallTest; - -import com.android.incallui.async.PausableExecutor; -import com.android.incallui.async.SingleProdThreadExecutor; - -import org.mockito.Mock; -import org.mockito.Mockito; -import org.mockito.MockitoAnnotations; - -@SmallTest -public class InCallTonePlayerTest extends AndroidTestCase { - - @Mock private ToneGeneratorFactory mToneGeneratorFactory; - @Mock private ToneGenerator mToneGenerator; - private InCallTonePlayer mInCallTonePlayer; - - /* - * InCallTonePlayer milestones: - * 1) After tone starts playing - * 2) After tone finishes waiting (could have timed out) - * 3) After cleaning up state to allow new tone to play - */ - private PausableExecutor mExecutor; - - @Override - public void setUp() throws Exception { - super.setUp(); - MockitoAnnotations.initMocks(this); - Mockito.when(mToneGeneratorFactory.newInCallToneGenerator(Mockito.anyInt(), - Mockito.anyInt())).thenReturn(mToneGenerator); - mExecutor = new SingleProdThreadExecutor(); - mInCallTonePlayer = new InCallTonePlayer(mToneGeneratorFactory, mExecutor); - } - - @Override - public void tearDown() throws Exception { - super.tearDown(); - // Stop any playing so the InCallTonePlayer isn't stuck waiting for the tone to complete - mInCallTonePlayer.stop(); - // Ack all milestones to ensure that the prod thread doesn't block forever - mExecutor.ackAllMilestonesForTesting(); - } - - public void testIsPlayingTone_False() { - assertFalse(mInCallTonePlayer.isPlayingTone()); - } - - public void testIsPlayingTone_True() throws InterruptedException { - mInCallTonePlayer.play(InCallTonePlayer.TONE_CALL_WAITING); - mExecutor.awaitMilestoneForTesting(); - - assertTrue(mInCallTonePlayer.isPlayingTone()); - } - - public void testPlay_InvalidTone() { - try { - mInCallTonePlayer.play(Integer.MIN_VALUE); - fail(); - } catch (IllegalArgumentException e) {} - } - - public void testPlay_CurrentlyPlaying() throws InterruptedException { - mInCallTonePlayer.play(InCallTonePlayer.TONE_CALL_WAITING); - mExecutor.awaitMilestoneForTesting(); - try { - mInCallTonePlayer.play(InCallTonePlayer.TONE_CALL_WAITING); - fail(); - } catch (IllegalStateException e) {} - } - - public void testPlay_VoiceCallStream() throws InterruptedException { - mInCallTonePlayer.play(InCallTonePlayer.TONE_CALL_WAITING); - mExecutor.awaitMilestoneForTesting(); - Mockito.verify(mToneGeneratorFactory).newInCallToneGenerator(AudioManager.STREAM_VOICE_CALL, - InCallTonePlayer.VOLUME_RELATIVE_HIGH_PRIORITY); - } - - public void testPlay_Single() throws InterruptedException { - mInCallTonePlayer.play(InCallTonePlayer.TONE_CALL_WAITING); - mExecutor.awaitMilestoneForTesting(); - mExecutor.ackMilestoneForTesting(); - mInCallTonePlayer.stop(); - mExecutor.ackMilestoneForTesting(); - mExecutor.awaitMilestoneForTesting(); - mExecutor.ackMilestoneForTesting(); - - Mockito.verify(mToneGenerator).startTone(ToneGenerator.TONE_SUP_CALL_WAITING); - } - - public void testPlay_Consecutive() throws InterruptedException { - mInCallTonePlayer.play(InCallTonePlayer.TONE_CALL_WAITING); - mExecutor.awaitMilestoneForTesting(); - mExecutor.ackMilestoneForTesting(); - // Prevent waiting forever - mInCallTonePlayer.stop(); - mExecutor.ackMilestoneForTesting(); - mExecutor.awaitMilestoneForTesting(); - mExecutor.ackMilestoneForTesting(); - - mInCallTonePlayer.play(InCallTonePlayer.TONE_CALL_WAITING); - mExecutor.awaitMilestoneForTesting(); - mExecutor.ackMilestoneForTesting(); - mInCallTonePlayer.stop(); - mExecutor.ackMilestoneForTesting(); - mExecutor.awaitMilestoneForTesting(); - mExecutor.ackMilestoneForTesting(); - - Mockito.verify(mToneGenerator, Mockito.times(2)) - .startTone(ToneGenerator.TONE_SUP_CALL_WAITING); - } - - public void testStop_NotPlaying() { - // No crash - mInCallTonePlayer.stop(); - } - - public void testStop() throws InterruptedException { - mInCallTonePlayer.play(InCallTonePlayer.TONE_CALL_WAITING); - mExecutor.awaitMilestoneForTesting(); - - mInCallTonePlayer.stop(); - mExecutor.ackMilestoneForTesting(); - mExecutor.awaitMilestoneForTesting(); - - assertFalse(mInCallTonePlayer.isPlayingTone()); - } -} diff --git a/InCallUI/tests/src/com/android/incallui/spam/SpamCallListListenerTest.java b/InCallUI/tests/src/com/android/incallui/spam/SpamCallListListenerTest.java deleted file mode 100644 index fb0b460b6..000000000 --- a/InCallUI/tests/src/com/android/incallui/spam/SpamCallListListenerTest.java +++ /dev/null @@ -1,206 +0,0 @@ -/* - * Copyright (C) 2016 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.spam; - -import static org.mockito.Matchers.anyInt; -import static org.mockito.Mockito.doCallRealMethod; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.when; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.eq; -import static org.mockito.Mockito.any; - -import android.content.ContentValues; -import android.content.Context; -import android.provider.CallLog; -import android.telecom.DisconnectCause; -import android.test.InstrumentationTestCase; - -import com.android.contacts.common.test.mocks.ContactsMockContext; -import com.android.contacts.common.test.mocks.MockContentProvider; -import com.android.dialer.calllog.CallLogAsyncTaskUtil; -import com.android.dialer.util.AsyncTaskExecutors; -import com.android.dialer.util.FakeAsyncTaskExecutor; -import com.android.dialer.util.TelecomUtil; -import com.android.incallui.Call; -import com.android.incallui.Call.CallHistoryStatus; -import com.android.incallui.Call.LogState; - -public class SpamCallListListenerTest extends InstrumentationTestCase { - private static final String NUMBER = "+18005657862"; - private static final int DURATION = 100; - - private TestSpamCallListListener mListener; - private FakeAsyncTaskExecutor mFakeAsyncTaskExecutor; - private ContactsMockContext mContext; - - @Override - public void setUp() throws Exception { - super.setUp(); - mContext = new ContactsMockContext(getInstrumentation().getContext(), CallLog.AUTHORITY); - mListener = new TestSpamCallListListener(mContext); - mFakeAsyncTaskExecutor = new FakeAsyncTaskExecutor(getInstrumentation()); - AsyncTaskExecutors.setFactoryForTest(mFakeAsyncTaskExecutor.getFactory()); - } - - @Override - public void tearDown() throws Exception { - AsyncTaskExecutors.setFactoryForTest(null); - CallLogAsyncTaskUtil.resetForTest(); - super.tearDown(); - } - - public void testOutgoingCall() { - Call call = getMockCall(NUMBER, false, 0, Call.CALL_HISTORY_STATUS_NOT_PRESENT, - LogState.LOOKUP_UNKNOWN, DisconnectCause.REMOTE); - mListener.onDisconnect(call); - assertFalse(mListener.mShowNotificationCalled); - } - - public void testIncomingCall_UnknownNumber() { - Call call = getMockCall(null, true, DURATION, Call.CALL_HISTORY_STATUS_NOT_PRESENT, - LogState.LOOKUP_UNKNOWN, DisconnectCause.REMOTE); - mListener.onDisconnect(call); - assertFalse(mListener.mShowNotificationCalled); - } - - public void testIncomingCall_Rejected() { - Call call = getMockCall(NUMBER, true, 0, Call.CALL_HISTORY_STATUS_NOT_PRESENT, - LogState.LOOKUP_UNKNOWN, DisconnectCause.REJECTED); - mListener.onDisconnect(call); - assertFalse(mListener.mShowNotificationCalled); - } - public void testIncomingCall_HangUpLocal() { - Call call = getMockCall(NUMBER, true, DURATION, Call.CALL_HISTORY_STATUS_NOT_PRESENT, - LogState.LOOKUP_UNKNOWN, DisconnectCause.LOCAL); - mListener.onDisconnect(call); - assertTrue(mListener.mShowNotificationCalled); - } - - public void testIncomingCall_HangUpRemote() { - Call call = getMockCall(NUMBER, true, DURATION, Call.CALL_HISTORY_STATUS_NOT_PRESENT, - LogState.LOOKUP_UNKNOWN, DisconnectCause.REMOTE); - mListener.onDisconnect(call); - assertTrue(mListener.mShowNotificationCalled); - } - - public void testIncomingCall_ValidNumber_NotInCallHistory_InContacts() { - Call call = getMockCall(NUMBER, true, 0, Call.CALL_HISTORY_STATUS_NOT_PRESENT, - LogState.LOOKUP_LOCAL_CONTACT, DisconnectCause.REJECTED); - mListener.onDisconnect(call); - assertFalse(mListener.mShowNotificationCalled); - } - - public void testIncomingCall_ValidNumber_InCallHistory_InContacts() { - Call call = getMockCall(NUMBER, true, 0, Call.CALL_HISTORY_STATUS_PRESENT, - LogState.LOOKUP_LOCAL_CONTACT, DisconnectCause.REJECTED); - mListener.onDisconnect(call); - assertFalse(mListener.mShowNotificationCalled); - } - - public void testIncomingCall_ValidNumber_InCallHistory_NotInContacts() { - Call call = getMockCall(NUMBER, true, 0, Call.CALL_HISTORY_STATUS_PRESENT, - LogState.LOOKUP_UNKNOWN, DisconnectCause.REJECTED); - mListener.onDisconnect(call); - assertFalse(mListener.mShowNotificationCalled); - } - - public void testIncomingCall_ValidNumber_NotInCallHistory_NotInContacts() throws Throwable { - Call call = getMockCall(NUMBER, true, DURATION, Call.CALL_HISTORY_STATUS_NOT_PRESENT, - LogState.LOOKUP_UNKNOWN, DisconnectCause.LOCAL); - mListener.onDisconnect(call); - assertTrue(mListener.mShowNotificationCalled); - } - - public void testIncomingCall_CheckCallHistory_NumberExists() throws Throwable { - final Call call = getMockCall(NUMBER, true, DURATION, Call.CALL_HISTORY_STATUS_UNKNOWN, - LogState.LOOKUP_UNKNOWN, DisconnectCause.LOCAL); - expectCallLogQuery(NUMBER, true); - incomingCall(call); - verify(call).setCallHistoryStatus(eq(Call.CALL_HISTORY_STATUS_PRESENT)); - assertFalse(mListener.mShowNotificationCalled); - } - - public void testIncomingCall_CheckCallHistory_NumberNotExists() throws Throwable { - final Call call = getMockCall(NUMBER, true, DURATION, Call.CALL_HISTORY_STATUS_UNKNOWN, - LogState.LOOKUP_UNKNOWN, DisconnectCause.LOCAL); - expectCallLogQuery(NUMBER, false); - incomingCall(call); - verify(call).setCallHistoryStatus(eq(Call.CALL_HISTORY_STATUS_NOT_PRESENT)); - assertTrue(mListener.mShowNotificationCalled); - } - - private void incomingCall(final Call call) throws Throwable { - runTestOnUiThread(new Runnable() { - @Override - public void run() { - mListener.onIncomingCall(call); - } - }); - getInstrumentation().waitForIdleSync(); - mFakeAsyncTaskExecutor.runTask(CallLogAsyncTaskUtil.Tasks.GET_NUMBER_IN_CALL_HISTORY); - mListener.onDisconnect(call); - } - - private void expectCallLogQuery(String number, boolean inCallHistory) { - MockContentProvider.Query query = mContext.getContactsProvider() - .expectQuery(TelecomUtil.getCallLogUri(mContext)) - .withSelection(CallLog.Calls.NUMBER + " = ?", number) - .withProjection(CallLog.Calls._ID) - .withAnySortOrder(); - ContentValues values = new ContentValues(); - values.put(CallLog.Calls.NUMBER, number); - if (inCallHistory) { - query.returnRow(values); - } else { - query.returnEmptyCursor(); - } - } - - private static Call getMockCall(String number, - boolean isIncoming, - int duration, - @CallHistoryStatus int callHistoryStatus, - int contactLookupResult, - int disconnectCause) { - Call call = mock(Call.class); - LogState logState = new LogState(); - logState.isIncoming = isIncoming; - logState.duration = duration; - logState.contactLookupResult = contactLookupResult; - when(call.getDisconnectCause()).thenReturn(new DisconnectCause(disconnectCause)); - when(call.getLogState()).thenReturn(logState); - when(call.getNumber()).thenReturn(number); - doCallRealMethod().when(call).setCallHistoryStatus(anyInt()); - when(call.getCallHistoryStatus()).thenCallRealMethod(); - call.setCallHistoryStatus(callHistoryStatus); - return call; - } - - private static class TestSpamCallListListener extends SpamCallListListener { - private boolean mShowNotificationCalled; - - public TestSpamCallListListener(Context context) { - super(context); - } - - void showNotification(String number) { - mShowNotificationCalled = true; - } - } -} \ No newline at end of file -- cgit v1.2.3