From ea7890cd5e829ed3f0b5f726561c569690af2030 Mon Sep 17 00:00:00 2001 From: Eric Erfanian Date: Mon, 19 Jun 2017 12:40:59 -0700 Subject: Update AOSP Dialer source from internal google3 repository at cl/159428781. Test: make, treehugger This CL updates the AOSP Dialer source with all the changes that have gone into the private google3 repository. This includes all the changes from cl/158012278 (6/05/2017) to cl/159428781 (6/19/2017). This goal of these drops is to keep the AOSP source in sync with the internal google3 repository. Currently these sync are done by hand with very minor modifications to the internal source code. See the Android.mk file for list of modifications. Our current goal is to do frequent drops (daily if possible) and eventually switched to an automated process. Merged-In: Ie60a84b3936efd0ea3d95d7c86bf96d2b1663030 Change-Id: If1fa394df2609f0d38b4f794c83f4db3f1006484 --- Android.mk | 38 +- AndroidManifest.xml | 1 + .../drawable-hdpi/quantum_ic_close_white_24.png | Bin 221 -> 176 bytes .../drawable-hdpi/quantum_ic_grade_white_24.png | Bin 370 -> 352 bytes .../drawable-hdpi/quantum_ic_image_white_24.png | Bin 261 -> 246 bytes .../drawable-mdpi/quantum_ic_close_white_24.png | Bin 175 -> 139 bytes .../drawable-mdpi/quantum_ic_grade_white_24.png | Bin 271 -> 259 bytes .../drawable-mdpi/quantum_ic_image_white_24.png | Bin 185 -> 174 bytes .../drawable-xhdpi/quantum_ic_close_white_24.png | Bin 257 -> 204 bytes .../drawable-xhdpi/quantum_ic_grade_white_24.png | Bin 479 -> 455 bytes .../drawable-xhdpi/quantum_ic_image_white_24.png | Bin 304 -> 292 bytes .../drawable-xxhdpi/quantum_ic_close_white_24.png | Bin 347 -> 260 bytes .../drawable-xxhdpi/quantum_ic_grade_white_24.png | Bin 676 -> 657 bytes .../drawable-xxhdpi/quantum_ic_image_white_24.png | Bin 450 -> 409 bytes .../drawable-xxxhdpi/quantum_ic_close_white_24.png | Bin 436 -> 314 bytes .../drawable-xxxhdpi/quantum_ic_grade_white_24.png | Bin 887 -> 861 bytes .../drawable-xxxhdpi/quantum_ic_image_white_24.png | Bin 570 -> 519 bytes .../contacts/common/ContactPhotoManager.java | 3 + .../contacts/common/ContactPresenceIconUtil.java | 3 +- .../common/compat/TelephonyManagerCompat.java | 9 + .../compat/telecom/TelecomManagerCompat.java | 24 ++ .../common/extensions/PhoneDirectoryExtender.java | 10 + .../extensions/PhoneDirectoryExtenderAccessor.java | 6 + .../extensions/PhoneDirectoryExtenderStub.java | 13 + .../common/lettertiles/LetterTileDrawable.java | 14 +- .../common/list/ContactEntryListAdapter.java | 51 ++- .../common/list/ContactEntryListFragment.java | 19 +- .../contacts/common/list/ContactListItemView.java | 6 +- .../common/list/PhoneNumberListAdapter.java | 20 +- .../common/list/PhoneNumberPickerFragment.java | 4 +- .../contacts/common/model/account/AccountType.java | 3 +- .../contacts/common/res/values-af/strings.xml | 2 + .../contacts/common/res/values-am/strings.xml | 2 + .../contacts/common/res/values-ar/strings.xml | 2 + .../contacts/common/res/values-az/strings.xml | 2 + .../common/res/values-b+sr+Latn/strings.xml | 2 + .../contacts/common/res/values-be/strings.xml | 2 + .../contacts/common/res/values-bg/strings.xml | 2 + .../contacts/common/res/values-bn/strings.xml | 2 + .../contacts/common/res/values-bs/strings.xml | 2 + .../contacts/common/res/values-ca/strings.xml | 2 + .../contacts/common/res/values-cs/strings.xml | 2 + .../contacts/common/res/values-da/strings.xml | 2 + .../contacts/common/res/values-de/strings.xml | 2 + .../contacts/common/res/values-el/strings.xml | 2 + .../contacts/common/res/values-en-rAU/strings.xml | 2 + .../contacts/common/res/values-en-rGB/strings.xml | 2 + .../contacts/common/res/values-en-rIN/strings.xml | 2 + .../contacts/common/res/values-es-rUS/strings.xml | 2 + .../contacts/common/res/values-es/strings.xml | 2 + .../contacts/common/res/values-et/strings.xml | 2 + .../contacts/common/res/values-eu/strings.xml | 2 + .../contacts/common/res/values-fa/strings.xml | 2 + .../contacts/common/res/values-fi/strings.xml | 2 + .../contacts/common/res/values-fr-rCA/strings.xml | 2 + .../contacts/common/res/values-fr/strings.xml | 2 + .../contacts/common/res/values-gl/strings.xml | 2 + .../contacts/common/res/values-gu/strings.xml | 2 + .../contacts/common/res/values-hi/strings.xml | 2 + .../contacts/common/res/values-hr/strings.xml | 2 + .../contacts/common/res/values-hu/strings.xml | 2 + .../contacts/common/res/values-hy/strings.xml | 2 + .../contacts/common/res/values-in/strings.xml | 2 + .../contacts/common/res/values-is/strings.xml | 2 + .../contacts/common/res/values-it/strings.xml | 2 + .../contacts/common/res/values-iw/strings.xml | 2 + .../contacts/common/res/values-ja/strings.xml | 2 + .../contacts/common/res/values-ka/strings.xml | 2 + .../contacts/common/res/values-kk/strings.xml | 2 + .../contacts/common/res/values-km/strings.xml | 2 + .../contacts/common/res/values-kn/strings.xml | 2 + .../contacts/common/res/values-ko/strings.xml | 2 + .../contacts/common/res/values-ky/strings.xml | 2 + .../contacts/common/res/values-lo/strings.xml | 2 + .../contacts/common/res/values-lt/strings.xml | 2 + .../contacts/common/res/values-lv/strings.xml | 2 + .../contacts/common/res/values-mk/strings.xml | 2 + .../contacts/common/res/values-ml/strings.xml | 2 + .../contacts/common/res/values-mn/strings.xml | 2 + .../contacts/common/res/values-mr/strings.xml | 2 + .../contacts/common/res/values-ms/strings.xml | 2 + .../contacts/common/res/values-my/strings.xml | 2 + .../contacts/common/res/values-nb/strings.xml | 2 + .../contacts/common/res/values-ne/strings.xml | 2 + .../contacts/common/res/values-nl/strings.xml | 2 + .../contacts/common/res/values-no/strings.xml | 2 + .../contacts/common/res/values-pa/strings.xml | 2 + .../contacts/common/res/values-pl/strings.xml | 2 + .../contacts/common/res/values-pt-rBR/strings.xml | 2 + .../contacts/common/res/values-pt-rPT/strings.xml | 2 + .../contacts/common/res/values-pt/strings.xml | 2 + .../contacts/common/res/values-ro/strings.xml | 2 + .../contacts/common/res/values-ru/strings.xml | 2 + .../contacts/common/res/values-si/strings.xml | 2 + .../contacts/common/res/values-sk/strings.xml | 2 + .../contacts/common/res/values-sl/strings.xml | 2 + .../contacts/common/res/values-sq/strings.xml | 2 + .../contacts/common/res/values-sr/strings.xml | 2 + .../contacts/common/res/values-sv/strings.xml | 2 + .../contacts/common/res/values-sw/strings.xml | 2 + .../contacts/common/res/values-ta/strings.xml | 2 + .../contacts/common/res/values-te/strings.xml | 2 + .../contacts/common/res/values-th/strings.xml | 2 + .../contacts/common/res/values-tl/strings.xml | 2 + .../contacts/common/res/values-tr/strings.xml | 2 + .../contacts/common/res/values-uk/strings.xml | 2 + .../contacts/common/res/values-ur/strings.xml | 2 + .../contacts/common/res/values-uz/strings.xml | 2 + .../contacts/common/res/values-vi/strings.xml | 2 + .../contacts/common/res/values-zh-rCN/strings.xml | 2 + .../contacts/common/res/values-zh-rHK/strings.xml | 2 + .../contacts/common/res/values-zh-rTW/strings.xml | 2 + .../contacts/common/res/values-zu/strings.xml | 2 + .../android/contacts/common/res/values/dimens.xml | 2 +- .../android/contacts/common/res/values/strings.xml | 6 + java/com/android/dialer/app/Bindings.java | 28 -- java/com/android/dialer/app/DialtactsActivity.java | 94 +++-- .../dialer/app/bindings/DialerBindings.java | 25 -- .../dialer/app/bindings/DialerBindingsFactory.java | 26 -- .../dialer/app/bindings/DialerBindingsStub.java | 48 --- .../dialer/app/calllog/CallLogActivity.java | 34 +- .../android/dialer/app/calllog/CallLogAdapter.java | 160 ++++++-- .../dialer/app/calllog/CallLogAsyncTaskUtil.java | 6 +- .../dialer/app/calllog/CallLogFragment.java | 98 ++++- .../app/calllog/CallLogListItemViewHolder.java | 145 ++++++- .../calllog/CallLogNotificationsQueryHelper.java | 92 +++-- .../app/calllog/CallLogNotificationsService.java | 115 ++++-- .../dialer/app/calllog/CallLogReceiver.java | 4 +- .../dialer/app/calllog/ClearCallLogDialog.java | 2 +- .../app/calllog/DefaultVoicemailNotifier.java | 451 -------------------- .../app/calllog/DialerQuickContactBadge.java | 63 +++ .../android/dialer/app/calllog/IntentProvider.java | 5 +- .../app/calllog/LegacyVoicemailNotifier.java | 156 +++++++ .../dialer/app/calllog/MissedCallNotifier.java | 116 ++++-- .../dialer/app/calllog/PhoneAccountHandles.java | 62 --- .../app/calllog/VisualVoicemailNotifier.java | 291 +++++++++++++ .../app/calllog/VisualVoicemailUpdateTask.java | 168 ++++++++ .../dialer/app/calllog/VoicemailQueryHandler.java | 44 +- .../calllogcache/CallLogCacheLollipopMr1.java | 30 +- .../dialer/app/contactinfo/ContactInfoCache.java | 2 +- .../dialer/app/dialpad/DialpadFragment.java | 9 + .../app/legacybindings/DialerLegacyBindings.java | 1 + .../legacybindings/DialerLegacyBindingsStub.java | 2 + .../dialer/app/list/AllContactsFragment.java | 12 +- .../app/list/DialerPhoneNumberListAdapter.java | 13 +- .../dialer/app/list/DialtactsPagerAdapter.java | 4 +- .../com/android/dialer/app/list/ListsFragment.java | 65 +-- .../dialer/app/list/OldSpeedDialFragment.java | 11 +- .../dialer/app/list/PhoneFavoriteTileView.java | 2 + .../dialer/app/list/PhoneFavoritesTileAdapter.java | 6 +- .../dialer/app/list/RegularSearchFragment.java | 13 +- .../android/dialer/app/list/SearchFragment.java | 23 +- .../dialer/app/list/SmartDialSearchFragment.java | 18 +- .../app/manifests/activities/AndroidManifest.xml | 2 + .../dialer/app/res/layout/call_log_fragment.xml | 30 ++ .../dialer/app/res/layout/call_log_list_item.xml | 2 +- .../dialer/app/res/layout/lists_fragment.xml | 39 -- .../dialer/app/res/menu/dialtacts_options.xml | 3 + .../android/dialer/app/res/values-af/strings.xml | 11 +- .../android/dialer/app/res/values-am/strings.xml | 11 +- .../android/dialer/app/res/values-ar/strings.xml | 15 +- .../android/dialer/app/res/values-az/strings.xml | 11 +- .../dialer/app/res/values-b+sr+Latn/strings.xml | 12 +- .../android/dialer/app/res/values-be/strings.xml | 13 +- .../android/dialer/app/res/values-bg/strings.xml | 11 +- .../android/dialer/app/res/values-bn/strings.xml | 11 +- .../android/dialer/app/res/values-bs/strings.xml | 12 +- .../android/dialer/app/res/values-ca/strings.xml | 15 +- .../android/dialer/app/res/values-cs/strings.xml | 13 +- .../android/dialer/app/res/values-da/strings.xml | 13 +- .../android/dialer/app/res/values-de/strings.xml | 11 +- .../android/dialer/app/res/values-el/strings.xml | 11 +- .../dialer/app/res/values-en-rAU/strings.xml | 11 +- .../dialer/app/res/values-en-rGB/strings.xml | 11 +- .../dialer/app/res/values-en-rIN/strings.xml | 11 +- .../dialer/app/res/values-es-rUS/strings.xml | 11 +- .../android/dialer/app/res/values-es/strings.xml | 11 +- .../android/dialer/app/res/values-et/strings.xml | 11 +- .../android/dialer/app/res/values-eu/strings.xml | 11 +- .../android/dialer/app/res/values-fa/strings.xml | 11 +- .../android/dialer/app/res/values-fi/strings.xml | 11 +- .../dialer/app/res/values-fr-rCA/strings.xml | 11 +- .../android/dialer/app/res/values-fr/strings.xml | 11 +- .../android/dialer/app/res/values-gl/strings.xml | 11 +- .../android/dialer/app/res/values-gu/strings.xml | 11 +- .../android/dialer/app/res/values-hi/strings.xml | 11 +- .../android/dialer/app/res/values-hr/strings.xml | 12 +- .../android/dialer/app/res/values-hu/strings.xml | 11 +- .../android/dialer/app/res/values-hy/strings.xml | 13 +- .../android/dialer/app/res/values-in/strings.xml | 11 +- .../android/dialer/app/res/values-is/strings.xml | 11 +- .../android/dialer/app/res/values-it/strings.xml | 11 +- .../android/dialer/app/res/values-iw/strings.xml | 13 +- .../android/dialer/app/res/values-ja/strings.xml | 11 +- .../android/dialer/app/res/values-ka/strings.xml | 11 +- .../android/dialer/app/res/values-kk/strings.xml | 11 +- .../android/dialer/app/res/values-km/strings.xml | 11 +- .../android/dialer/app/res/values-kn/strings.xml | 11 +- .../android/dialer/app/res/values-ko/strings.xml | 11 +- .../android/dialer/app/res/values-ky/strings.xml | 11 +- .../android/dialer/app/res/values-lo/strings.xml | 11 +- .../android/dialer/app/res/values-lt/strings.xml | 13 +- .../android/dialer/app/res/values-lv/strings.xml | 12 +- .../android/dialer/app/res/values-mk/strings.xml | 11 +- .../android/dialer/app/res/values-ml/strings.xml | 11 +- .../android/dialer/app/res/values-mn/strings.xml | 11 +- .../android/dialer/app/res/values-mr/strings.xml | 11 +- .../android/dialer/app/res/values-ms/strings.xml | 11 +- .../android/dialer/app/res/values-my/strings.xml | 11 +- .../android/dialer/app/res/values-nb/strings.xml | 11 +- .../android/dialer/app/res/values-ne/strings.xml | 11 +- .../android/dialer/app/res/values-nl/strings.xml | 11 +- .../android/dialer/app/res/values-no/strings.xml | 11 +- .../android/dialer/app/res/values-pa/strings.xml | 11 +- .../android/dialer/app/res/values-pl/strings.xml | 13 +- .../dialer/app/res/values-pt-rBR/strings.xml | 11 +- .../dialer/app/res/values-pt-rPT/strings.xml | 11 +- .../android/dialer/app/res/values-pt/strings.xml | 11 +- .../android/dialer/app/res/values-ro/strings.xml | 12 +- .../android/dialer/app/res/values-ru/strings.xml | 13 +- .../android/dialer/app/res/values-si/strings.xml | 11 +- .../android/dialer/app/res/values-sk/strings.xml | 13 +- .../android/dialer/app/res/values-sl/strings.xml | 13 +- .../android/dialer/app/res/values-sq/strings.xml | 11 +- .../android/dialer/app/res/values-sr/strings.xml | 12 +- .../android/dialer/app/res/values-sv/strings.xml | 11 +- .../android/dialer/app/res/values-sw/strings.xml | 11 +- .../android/dialer/app/res/values-ta/strings.xml | 11 +- .../android/dialer/app/res/values-te/strings.xml | 11 +- .../android/dialer/app/res/values-th/strings.xml | 11 +- .../android/dialer/app/res/values-tl/strings.xml | 11 +- .../android/dialer/app/res/values-tr/strings.xml | 11 +- .../android/dialer/app/res/values-uk/strings.xml | 13 +- .../android/dialer/app/res/values-ur/strings.xml | 11 +- .../android/dialer/app/res/values-uz/strings.xml | 11 +- .../android/dialer/app/res/values-vi/strings.xml | 11 +- .../dialer/app/res/values-zh-rCN/strings.xml | 11 +- .../dialer/app/res/values-zh-rHK/strings.xml | 11 +- .../dialer/app/res/values-zh-rTW/strings.xml | 11 +- .../android/dialer/app/res/values-zu/strings.xml | 11 +- java/com/android/dialer/app/res/values/dimens.xml | 5 + java/com/android/dialer/app/res/values/strings.xml | 63 +-- java/com/android/dialer/app/res/values/styles.xml | 7 +- .../LegacyVoicemailNotificationReceiver.java | 22 +- .../app/voicemail/VoicemailPlaybackPresenter.java | 5 +- .../error/OmtpVoicemailMessageCreator.java | 6 + .../error/VoicemailStatusCorruptionHandler.java | 2 +- .../error/VoicemailTosMessageCreator.java | 301 ++++++++++++++ .../error/Vvm3VoicemailMessageCreator.java | 150 +------ .../error/res/layout/voicemail_tos_fragment.xml | 16 +- .../app/voicemail/error/res/values-af/strings.xml | 16 +- .../app/voicemail/error/res/values-am/strings.xml | 16 +- .../app/voicemail/error/res/values-ar/strings.xml | 16 +- .../app/voicemail/error/res/values-az/strings.xml | 16 +- .../error/res/values-b+sr+Latn/strings.xml | 16 +- .../app/voicemail/error/res/values-be/strings.xml | 16 +- .../app/voicemail/error/res/values-bg/strings.xml | 16 +- .../app/voicemail/error/res/values-bn/strings.xml | 16 +- .../app/voicemail/error/res/values-bs/strings.xml | 16 +- .../app/voicemail/error/res/values-ca/strings.xml | 16 +- .../app/voicemail/error/res/values-cs/strings.xml | 16 +- .../app/voicemail/error/res/values-da/strings.xml | 16 +- .../app/voicemail/error/res/values-de/strings.xml | 16 +- .../app/voicemail/error/res/values-el/strings.xml | 16 +- .../voicemail/error/res/values-en-rAU/strings.xml | 16 +- .../voicemail/error/res/values-en-rGB/strings.xml | 16 +- .../voicemail/error/res/values-en-rIN/strings.xml | 16 +- .../voicemail/error/res/values-es-rUS/strings.xml | 16 +- .../app/voicemail/error/res/values-es/strings.xml | 16 +- .../app/voicemail/error/res/values-et/strings.xml | 16 +- .../app/voicemail/error/res/values-eu/strings.xml | 16 +- .../app/voicemail/error/res/values-fa/strings.xml | 16 +- .../app/voicemail/error/res/values-fi/strings.xml | 16 +- .../voicemail/error/res/values-fr-rCA/strings.xml | 16 +- .../app/voicemail/error/res/values-fr/strings.xml | 16 +- .../app/voicemail/error/res/values-gl/strings.xml | 16 +- .../app/voicemail/error/res/values-gu/strings.xml | 16 +- .../app/voicemail/error/res/values-hi/strings.xml | 16 +- .../app/voicemail/error/res/values-hr/strings.xml | 16 +- .../app/voicemail/error/res/values-hu/strings.xml | 16 +- .../app/voicemail/error/res/values-hy/strings.xml | 16 +- .../app/voicemail/error/res/values-in/strings.xml | 16 +- .../app/voicemail/error/res/values-is/strings.xml | 16 +- .../app/voicemail/error/res/values-it/strings.xml | 16 +- .../app/voicemail/error/res/values-iw/strings.xml | 16 +- .../app/voicemail/error/res/values-ja/strings.xml | 16 +- .../app/voicemail/error/res/values-ka/strings.xml | 16 +- .../app/voicemail/error/res/values-kk/strings.xml | 16 +- .../app/voicemail/error/res/values-km/strings.xml | 16 +- .../app/voicemail/error/res/values-kn/strings.xml | 16 +- .../app/voicemail/error/res/values-ko/strings.xml | 16 +- .../app/voicemail/error/res/values-ky/strings.xml | 16 +- .../app/voicemail/error/res/values-lo/strings.xml | 16 +- .../app/voicemail/error/res/values-lt/strings.xml | 16 +- .../app/voicemail/error/res/values-lv/strings.xml | 16 +- .../app/voicemail/error/res/values-mk/strings.xml | 16 +- .../app/voicemail/error/res/values-ml/strings.xml | 16 +- .../app/voicemail/error/res/values-mn/strings.xml | 16 +- .../app/voicemail/error/res/values-mr/strings.xml | 16 +- .../app/voicemail/error/res/values-ms/strings.xml | 16 +- .../app/voicemail/error/res/values-my/strings.xml | 16 +- .../app/voicemail/error/res/values-nb/strings.xml | 16 +- .../app/voicemail/error/res/values-ne/strings.xml | 16 +- .../app/voicemail/error/res/values-nl/strings.xml | 16 +- .../app/voicemail/error/res/values-no/strings.xml | 16 +- .../app/voicemail/error/res/values-pa/strings.xml | 16 +- .../app/voicemail/error/res/values-pl/strings.xml | 16 +- .../voicemail/error/res/values-pt-rBR/strings.xml | 16 +- .../voicemail/error/res/values-pt-rPT/strings.xml | 16 +- .../app/voicemail/error/res/values-pt/strings.xml | 16 +- .../app/voicemail/error/res/values-ro/strings.xml | 16 +- .../app/voicemail/error/res/values-ru/strings.xml | 16 +- .../app/voicemail/error/res/values-si/strings.xml | 16 +- .../app/voicemail/error/res/values-sk/strings.xml | 16 +- .../app/voicemail/error/res/values-sl/strings.xml | 16 +- .../app/voicemail/error/res/values-sq/strings.xml | 16 +- .../app/voicemail/error/res/values-sr/strings.xml | 16 +- .../app/voicemail/error/res/values-sv/strings.xml | 16 +- .../app/voicemail/error/res/values-sw/strings.xml | 18 +- .../app/voicemail/error/res/values-ta/strings.xml | 16 +- .../app/voicemail/error/res/values-te/strings.xml | 16 +- .../app/voicemail/error/res/values-th/strings.xml | 16 +- .../app/voicemail/error/res/values-tl/strings.xml | 16 +- .../app/voicemail/error/res/values-tr/strings.xml | 16 +- .../app/voicemail/error/res/values-uk/strings.xml | 16 +- .../app/voicemail/error/res/values-ur/strings.xml | 16 +- .../app/voicemail/error/res/values-uz/strings.xml | 16 +- .../app/voicemail/error/res/values-vi/strings.xml | 16 +- .../voicemail/error/res/values-zh-rCN/strings.xml | 16 +- .../voicemail/error/res/values-zh-rHK/strings.xml | 16 +- .../voicemail/error/res/values-zh-rTW/strings.xml | 16 +- .../app/voicemail/error/res/values-zu/strings.xml | 16 +- .../app/voicemail/error/res/values/strings.xml | 37 +- .../dialer/app/widget/SearchEditTextLayout.java | 2 +- .../android/dialer/backup/DialerBackupAgent.java | 2 +- .../android/dialer/backup/DialerBackupUtils.java | 2 +- .../binary/aosp/AospDialerRootComponent.java | 2 + .../dialer/binary/aosp/testing/AndroidManifest.xml | 24 ++ .../dialer/binary/aosp/testing/TestActivity.java | 25 ++ .../basecomponent/BaseDialerRootComponent.java | 4 + .../dialer/binary/common/DialerApplication.java | 5 +- .../dialer/blocking/FilteredNumbersUtil.java | 11 +- .../dialer/callcomposer/CallComposerActivity.java | 64 ++- .../callcomposer/CameraComposerFragment.java | 30 +- .../dialer/callcomposer/camera/CameraManager.java | 113 +++-- .../callcomposer/camera/ImagePersistTask.java | 6 +- .../callcomposer/camera/exif/ExifInterface.java | 2 +- .../cameraui/res/layout/camera_view.xml | 19 +- .../cameraui/res/values-af/strings.xml | 29 +- .../cameraui/res/values-am/strings.xml | 29 +- .../cameraui/res/values-ar/strings.xml | 29 +- .../cameraui/res/values-az/strings.xml | 29 +- .../cameraui/res/values-b+sr+Latn/strings.xml | 29 +- .../cameraui/res/values-be/strings.xml | 29 +- .../cameraui/res/values-bg/strings.xml | 29 +- .../cameraui/res/values-bn/strings.xml | 29 +- .../cameraui/res/values-bs/strings.xml | 29 +- .../cameraui/res/values-ca/strings.xml | 29 +- .../cameraui/res/values-cs/strings.xml | 29 +- .../cameraui/res/values-da/strings.xml | 29 +- .../cameraui/res/values-de/strings.xml | 29 +- .../cameraui/res/values-el/strings.xml | 29 +- .../cameraui/res/values-en-rAU/strings.xml | 29 +- .../cameraui/res/values-en-rGB/strings.xml | 29 +- .../cameraui/res/values-en-rIN/strings.xml | 29 +- .../cameraui/res/values-es-rUS/strings.xml | 29 +- .../cameraui/res/values-es/strings.xml | 29 +- .../cameraui/res/values-et/strings.xml | 29 +- .../cameraui/res/values-eu/strings.xml | 29 +- .../cameraui/res/values-fa/strings.xml | 29 +- .../cameraui/res/values-fi/strings.xml | 29 +- .../cameraui/res/values-fr-rCA/strings.xml | 29 +- .../cameraui/res/values-fr/strings.xml | 29 +- .../cameraui/res/values-gl/strings.xml | 29 +- .../cameraui/res/values-gu/strings.xml | 29 +- .../cameraui/res/values-hi/strings.xml | 29 +- .../cameraui/res/values-hr/strings.xml | 29 +- .../cameraui/res/values-hu/strings.xml | 29 +- .../cameraui/res/values-hy/strings.xml | 29 +- .../cameraui/res/values-in/strings.xml | 29 +- .../cameraui/res/values-is/strings.xml | 29 +- .../cameraui/res/values-it/strings.xml | 29 +- .../cameraui/res/values-iw/strings.xml | 29 +- .../cameraui/res/values-ja/strings.xml | 29 +- .../cameraui/res/values-ka/strings.xml | 29 +- .../cameraui/res/values-kk/strings.xml | 29 +- .../cameraui/res/values-km/strings.xml | 29 +- .../cameraui/res/values-kn/strings.xml | 29 +- .../cameraui/res/values-ko/strings.xml | 29 +- .../cameraui/res/values-ky/strings.xml | 29 +- .../cameraui/res/values-lo/strings.xml | 29 +- .../cameraui/res/values-lt/strings.xml | 29 +- .../cameraui/res/values-lv/strings.xml | 29 +- .../cameraui/res/values-mk/strings.xml | 29 +- .../cameraui/res/values-ml/strings.xml | 29 +- .../cameraui/res/values-mn/strings.xml | 29 +- .../cameraui/res/values-mr/strings.xml | 29 +- .../cameraui/res/values-ms/strings.xml | 29 +- .../cameraui/res/values-my/strings.xml | 29 +- .../cameraui/res/values-nb/strings.xml | 29 +- .../cameraui/res/values-ne/strings.xml | 29 +- .../cameraui/res/values-nl/strings.xml | 29 +- .../cameraui/res/values-no/strings.xml | 29 +- .../cameraui/res/values-pa/strings.xml | 29 +- .../cameraui/res/values-pl/strings.xml | 29 +- .../cameraui/res/values-pt-rBR/strings.xml | 29 +- .../cameraui/res/values-pt-rPT/strings.xml | 29 +- .../cameraui/res/values-pt/strings.xml | 29 +- .../cameraui/res/values-ro/strings.xml | 29 +- .../cameraui/res/values-ru/strings.xml | 29 +- .../cameraui/res/values-si/strings.xml | 29 +- .../cameraui/res/values-sk/strings.xml | 29 +- .../cameraui/res/values-sl/strings.xml | 29 +- .../cameraui/res/values-sq/strings.xml | 29 +- .../cameraui/res/values-sr/strings.xml | 29 +- .../cameraui/res/values-sv/strings.xml | 29 +- .../cameraui/res/values-sw/strings.xml | 29 +- .../cameraui/res/values-ta/strings.xml | 29 +- .../cameraui/res/values-te/strings.xml | 29 +- .../cameraui/res/values-th/strings.xml | 29 +- .../cameraui/res/values-tl/strings.xml | 29 +- .../cameraui/res/values-tr/strings.xml | 29 +- .../cameraui/res/values-uk/strings.xml | 29 +- .../cameraui/res/values-ur/strings.xml | 29 +- .../cameraui/res/values-uz/strings.xml | 29 +- .../cameraui/res/values-vi/strings.xml | 29 +- .../cameraui/res/values-zh-rCN/strings.xml | 29 +- .../cameraui/res/values-zh-rHK/strings.xml | 29 +- .../cameraui/res/values-zh-rTW/strings.xml | 29 +- .../cameraui/res/values-zu/strings.xml | 29 +- .../callcomposer/cameraui/res/values/dimens.xml | 2 +- .../callcomposer/cameraui/res/values/strings.xml | 33 +- .../res/layout/call_composer_activity.xml | 29 +- .../dialer/callcomposer/res/values-af/strings.xml | 3 + .../dialer/callcomposer/res/values-am/strings.xml | 3 + .../dialer/callcomposer/res/values-ar/strings.xml | 3 + .../dialer/callcomposer/res/values-az/strings.xml | 3 + .../callcomposer/res/values-b+sr+Latn/strings.xml | 3 + .../dialer/callcomposer/res/values-be/strings.xml | 3 + .../dialer/callcomposer/res/values-bg/strings.xml | 3 + .../dialer/callcomposer/res/values-bn/strings.xml | 3 + .../dialer/callcomposer/res/values-bs/strings.xml | 3 + .../dialer/callcomposer/res/values-ca/strings.xml | 3 + .../dialer/callcomposer/res/values-cs/strings.xml | 3 + .../dialer/callcomposer/res/values-da/strings.xml | 3 + .../dialer/callcomposer/res/values-de/strings.xml | 3 + .../dialer/callcomposer/res/values-el/strings.xml | 3 + .../callcomposer/res/values-en-rAU/strings.xml | 3 + .../callcomposer/res/values-en-rGB/strings.xml | 3 + .../callcomposer/res/values-en-rIN/strings.xml | 3 + .../callcomposer/res/values-es-rUS/strings.xml | 3 + .../dialer/callcomposer/res/values-es/strings.xml | 3 + .../dialer/callcomposer/res/values-et/strings.xml | 3 + .../dialer/callcomposer/res/values-eu/strings.xml | 3 + .../dialer/callcomposer/res/values-fa/strings.xml | 3 + .../dialer/callcomposer/res/values-fi/strings.xml | 3 + .../callcomposer/res/values-fr-rCA/strings.xml | 3 + .../dialer/callcomposer/res/values-fr/strings.xml | 3 + .../dialer/callcomposer/res/values-gl/strings.xml | 3 + .../dialer/callcomposer/res/values-gu/strings.xml | 3 + .../dialer/callcomposer/res/values-hi/strings.xml | 3 + .../dialer/callcomposer/res/values-hr/strings.xml | 3 + .../dialer/callcomposer/res/values-hu/strings.xml | 3 + .../dialer/callcomposer/res/values-hy/strings.xml | 3 + .../dialer/callcomposer/res/values-in/strings.xml | 3 + .../dialer/callcomposer/res/values-is/strings.xml | 3 + .../dialer/callcomposer/res/values-it/strings.xml | 3 + .../dialer/callcomposer/res/values-iw/strings.xml | 3 + .../dialer/callcomposer/res/values-ja/strings.xml | 3 + .../dialer/callcomposer/res/values-ka/strings.xml | 3 + .../dialer/callcomposer/res/values-kk/strings.xml | 3 + .../dialer/callcomposer/res/values-km/strings.xml | 3 + .../dialer/callcomposer/res/values-kn/strings.xml | 3 + .../dialer/callcomposer/res/values-ko/strings.xml | 3 + .../dialer/callcomposer/res/values-ky/strings.xml | 3 + .../dialer/callcomposer/res/values-lo/strings.xml | 3 + .../dialer/callcomposer/res/values-lt/strings.xml | 3 + .../dialer/callcomposer/res/values-lv/strings.xml | 3 + .../dialer/callcomposer/res/values-mk/strings.xml | 3 + .../dialer/callcomposer/res/values-ml/strings.xml | 3 + .../dialer/callcomposer/res/values-mn/strings.xml | 3 + .../dialer/callcomposer/res/values-mr/strings.xml | 3 + .../dialer/callcomposer/res/values-ms/strings.xml | 3 + .../dialer/callcomposer/res/values-my/strings.xml | 3 + .../dialer/callcomposer/res/values-nb/strings.xml | 3 + .../dialer/callcomposer/res/values-ne/strings.xml | 3 + .../dialer/callcomposer/res/values-nl/strings.xml | 3 + .../dialer/callcomposer/res/values-no/strings.xml | 3 + .../dialer/callcomposer/res/values-pa/strings.xml | 3 + .../dialer/callcomposer/res/values-pl/strings.xml | 3 + .../callcomposer/res/values-pt-rBR/strings.xml | 3 + .../callcomposer/res/values-pt-rPT/strings.xml | 3 + .../dialer/callcomposer/res/values-pt/strings.xml | 3 + .../dialer/callcomposer/res/values-ro/strings.xml | 3 + .../dialer/callcomposer/res/values-ru/strings.xml | 3 + .../dialer/callcomposer/res/values-si/strings.xml | 3 + .../dialer/callcomposer/res/values-sk/strings.xml | 3 + .../dialer/callcomposer/res/values-sl/strings.xml | 3 + .../dialer/callcomposer/res/values-sq/strings.xml | 3 + .../dialer/callcomposer/res/values-sr/strings.xml | 3 + .../dialer/callcomposer/res/values-sv/strings.xml | 3 + .../dialer/callcomposer/res/values-sw/strings.xml | 3 + .../dialer/callcomposer/res/values-ta/strings.xml | 3 + .../dialer/callcomposer/res/values-te/strings.xml | 3 + .../dialer/callcomposer/res/values-th/strings.xml | 3 + .../dialer/callcomposer/res/values-tl/strings.xml | 3 + .../dialer/callcomposer/res/values-tr/strings.xml | 3 + .../dialer/callcomposer/res/values-uk/strings.xml | 3 + .../dialer/callcomposer/res/values-ur/strings.xml | 3 + .../dialer/callcomposer/res/values-uz/strings.xml | 3 + .../dialer/callcomposer/res/values-vi/strings.xml | 3 + .../callcomposer/res/values-zh-rCN/strings.xml | 3 + .../callcomposer/res/values-zh-rHK/strings.xml | 3 + .../callcomposer/res/values-zh-rTW/strings.xml | 3 + .../dialer/callcomposer/res/values-zu/strings.xml | 3 + .../dialer/callcomposer/res/values/strings.xml | 6 + .../dialer/calldetails/CallDetailsActivity.java | 48 ++- .../dialer/calldetails/CallDetailsAdapter.java | 7 +- .../calldetails/CallDetailsFooterViewHolder.java | 32 +- .../calldetails/CallDetailsHeaderViewHolder.java | 10 +- .../dialer/calldetails/ReportDialogFragment.java | 161 ++++++++ .../calldetails/res/layout/call_details_footer.xml | 9 + .../res/layout/caller_id_report_dialog.xml | 35 ++ .../calldetails/res/layout/contact_container.xml | 14 +- .../dialer/calldetails/res/values-af/strings.xml | 5 +- .../dialer/calldetails/res/values-am/strings.xml | 5 +- .../dialer/calldetails/res/values-ar/strings.xml | 5 +- .../dialer/calldetails/res/values-az/strings.xml | 5 +- .../calldetails/res/values-b+sr+Latn/strings.xml | 5 +- .../dialer/calldetails/res/values-be/strings.xml | 5 +- .../dialer/calldetails/res/values-bg/strings.xml | 5 +- .../dialer/calldetails/res/values-bn/strings.xml | 5 +- .../dialer/calldetails/res/values-bs/strings.xml | 5 +- .../dialer/calldetails/res/values-ca/strings.xml | 5 +- .../dialer/calldetails/res/values-cs/strings.xml | 5 +- .../dialer/calldetails/res/values-da/strings.xml | 5 +- .../dialer/calldetails/res/values-de/strings.xml | 5 +- .../dialer/calldetails/res/values-el/strings.xml | 5 +- .../calldetails/res/values-en-rAU/strings.xml | 5 +- .../calldetails/res/values-en-rGB/strings.xml | 5 +- .../calldetails/res/values-en-rIN/strings.xml | 5 +- .../calldetails/res/values-es-rUS/strings.xml | 5 +- .../dialer/calldetails/res/values-es/strings.xml | 5 +- .../dialer/calldetails/res/values-et/strings.xml | 5 +- .../dialer/calldetails/res/values-eu/strings.xml | 5 +- .../dialer/calldetails/res/values-fa/strings.xml | 5 +- .../dialer/calldetails/res/values-fi/strings.xml | 5 +- .../calldetails/res/values-fr-rCA/strings.xml | 5 +- .../dialer/calldetails/res/values-fr/strings.xml | 5 +- .../dialer/calldetails/res/values-gl/strings.xml | 5 +- .../dialer/calldetails/res/values-gu/strings.xml | 5 +- .../dialer/calldetails/res/values-hi/strings.xml | 5 +- .../dialer/calldetails/res/values-hr/strings.xml | 5 +- .../dialer/calldetails/res/values-hu/strings.xml | 5 +- .../dialer/calldetails/res/values-hy/strings.xml | 5 +- .../dialer/calldetails/res/values-in/strings.xml | 5 +- .../dialer/calldetails/res/values-is/strings.xml | 5 +- .../dialer/calldetails/res/values-it/strings.xml | 5 +- .../dialer/calldetails/res/values-iw/strings.xml | 5 +- .../dialer/calldetails/res/values-ja/strings.xml | 5 +- .../dialer/calldetails/res/values-ka/strings.xml | 5 +- .../dialer/calldetails/res/values-kk/strings.xml | 5 +- .../dialer/calldetails/res/values-km/strings.xml | 5 +- .../dialer/calldetails/res/values-kn/strings.xml | 5 +- .../dialer/calldetails/res/values-ko/strings.xml | 5 +- .../dialer/calldetails/res/values-ky/strings.xml | 5 +- .../dialer/calldetails/res/values-lo/strings.xml | 5 +- .../dialer/calldetails/res/values-lt/strings.xml | 5 +- .../dialer/calldetails/res/values-lv/strings.xml | 5 +- .../dialer/calldetails/res/values-mk/strings.xml | 5 +- .../dialer/calldetails/res/values-ml/strings.xml | 5 +- .../dialer/calldetails/res/values-mn/strings.xml | 5 +- .../dialer/calldetails/res/values-mr/strings.xml | 5 +- .../dialer/calldetails/res/values-ms/strings.xml | 5 +- .../dialer/calldetails/res/values-my/strings.xml | 5 +- .../dialer/calldetails/res/values-nb/strings.xml | 5 +- .../dialer/calldetails/res/values-ne/strings.xml | 5 +- .../dialer/calldetails/res/values-nl/strings.xml | 5 +- .../dialer/calldetails/res/values-no/strings.xml | 5 +- .../dialer/calldetails/res/values-pa/strings.xml | 5 +- .../dialer/calldetails/res/values-pl/strings.xml | 5 +- .../calldetails/res/values-pt-rBR/strings.xml | 5 +- .../calldetails/res/values-pt-rPT/strings.xml | 5 +- .../dialer/calldetails/res/values-pt/strings.xml | 5 +- .../dialer/calldetails/res/values-ro/strings.xml | 5 +- .../dialer/calldetails/res/values-ru/strings.xml | 5 +- .../dialer/calldetails/res/values-si/strings.xml | 5 +- .../dialer/calldetails/res/values-sk/strings.xml | 5 +- .../dialer/calldetails/res/values-sl/strings.xml | 5 +- .../dialer/calldetails/res/values-sq/strings.xml | 5 +- .../dialer/calldetails/res/values-sr/strings.xml | 5 +- .../dialer/calldetails/res/values-sv/strings.xml | 5 +- .../dialer/calldetails/res/values-sw/strings.xml | 5 +- .../dialer/calldetails/res/values-ta/strings.xml | 5 +- .../dialer/calldetails/res/values-te/strings.xml | 5 +- .../dialer/calldetails/res/values-th/strings.xml | 5 +- .../dialer/calldetails/res/values-tl/strings.xml | 5 +- .../dialer/calldetails/res/values-tr/strings.xml | 5 +- .../dialer/calldetails/res/values-uk/strings.xml | 5 +- .../dialer/calldetails/res/values-ur/strings.xml | 5 +- .../dialer/calldetails/res/values-uz/strings.xml | 5 +- .../dialer/calldetails/res/values-vi/strings.xml | 5 +- .../calldetails/res/values-zh-rCN/strings.xml | 5 +- .../calldetails/res/values-zh-rHK/strings.xml | 5 +- .../calldetails/res/values-zh-rTW/strings.xml | 5 +- .../dialer/calldetails/res/values-zu/strings.xml | 5 +- .../dialer/calldetails/res/values/strings.xml | 17 +- .../dialer/callintent/CallIntentBuilder.java | 16 +- .../dialer/callintent/call_specific_app_data.proto | 10 + .../callintent/speed_dial_contact_type.proto | 4 +- .../android/dialer/calllog/CallLogFramework.java | 2 +- .../calllog/RefreshAnnotatedCallLogWorker.java | 20 +- .../database/AnnotatedCallLogContentProvider.java | 25 +- .../database/AnnotatedCallLogDatabaseHelper.java | 33 +- .../android/dialer/calllog/database/Coalescer.java | 52 ++- .../contract/AnnotatedCallLogContract.java | 23 +- .../datasources/contacts/ContactsDataSource.java | 3 + .../systemcalllog/SystemCallLogDataSource.java | 54 ++- .../calllog/testing/FakeCallLogApplication.java | 22 +- .../dialer/calllog/ui/NewCallLogFragment.java | 12 +- java/com/android/dialer/common/Assert.java | 5 + java/com/android/dialer/common/ConfigProvider.java | 27 -- .../dialer/common/ConfigProviderBindings.java | 76 ---- .../dialer/common/ConfigProviderFactory.java | 26 -- .../concurrent/DefaultDialerExecutorFactory.java | 111 +++-- .../dialer/common/concurrent/DialerExecutor.java | 10 + .../common/concurrent/DialerUiTaskFragment.java | 94 ++--- .../dialer/common/concurrent/ThreadUtil.java | 5 + .../dialer/configprovider/AndroidManifest.xml | 23 ++ .../dialer/configprovider/ConfigProvider.java | 27 ++ .../configprovider/ConfigProviderBindings.java | 68 +++ .../configprovider/ConfigProviderComponent.java | 41 ++ .../configprovider/SharedPrefConfigProvider.java | 131 ++++++ .../SharedPrefConfigProviderModule.java | 30 ++ .../contactsfragment/AddContactViewHolder.java | 42 ++ .../dialer/contactsfragment/ContactsAdapter.java | 61 ++- .../contactsfragment/ContactsCursorLoader.java | 2 +- .../dialer/contactsfragment/ContactsFragment.java | 66 +-- .../dialer/contactsfragment/FastScroller.java | 3 +- .../res/layout/add_contact_row.xml | 50 +++ .../res/layout/fragment_contacts.xml | 3 +- .../dialer/dialercontact/dialer_contact.proto | 8 + .../enrichedcall/FuzzyPhoneNumberMatcher.java | 41 +- .../android/dialer/inject/ApplicationContext.java | 22 + java/com/android/dialer/inject/ContextModule.java | 7 +- .../android/dialer/lightbringer/Lightbringer.java | 18 +- .../dialer/lightbringer/stub/LightbringerStub.java | 55 ++- .../android/dialer/logging/LoggingBindings.java | 2 +- .../dialer/logging/LoggingBindingsStub.java | 2 +- .../dialer/logging/contact_lookup_result.proto | 39 +- .../android/dialer/logging/dialer_impression.proto | 37 +- java/com/android/dialer/logging/ui_action.proto | 43 ++ java/com/android/dialer/main/Main.java | 27 ++ java/com/android/dialer/main/MainComponent.java | 39 ++ .../android/dialer/main/impl/AndroidManifest.xml | 110 +++++ .../com/android/dialer/main/impl/MainActivity.java | 91 ++++ java/com/android/dialer/main/impl/MainImpl.java | 90 ++++ java/com/android/dialer/main/impl/MainModule.java | 30 ++ .../android/dialer/main/impl/MainPagerAdapter.java | 75 ++++ .../com/android/dialer/main/impl/StubFragment.java | 35 ++ .../res/drawable-xxxhdpi/nui_launcher_icon.png | Bin 0 -> 5554 bytes .../dialer/main/impl/res/layout/main_activity.xml | 68 +++ .../dialer/main/impl/res/layout/stub_fragment.xml | 27 ++ .../dialer/main/impl/res/menu/main_menu.xml | 47 +++ .../dialer/main/impl/res/values-af/strings.xml | 32 ++ .../dialer/main/impl/res/values-am/strings.xml | 36 ++ .../dialer/main/impl/res/values-ar/strings.xml | 32 ++ .../dialer/main/impl/res/values-az/strings.xml | 36 ++ .../main/impl/res/values-b+sr+Latn/strings.xml | 32 ++ .../dialer/main/impl/res/values-be/strings.xml | 36 ++ .../dialer/main/impl/res/values-bg/strings.xml | 32 ++ .../dialer/main/impl/res/values-bn/strings.xml | 32 ++ .../dialer/main/impl/res/values-bs/strings.xml | 32 ++ .../dialer/main/impl/res/values-ca/strings.xml | 36 ++ .../dialer/main/impl/res/values-cs/strings.xml | 36 ++ .../dialer/main/impl/res/values-da/strings.xml | 36 ++ .../dialer/main/impl/res/values-de/strings.xml | 32 ++ .../dialer/main/impl/res/values-el/strings.xml | 36 ++ .../dialer/main/impl/res/values-en-rAU/strings.xml | 32 ++ .../dialer/main/impl/res/values-en-rGB/strings.xml | 32 ++ .../dialer/main/impl/res/values-en-rIN/strings.xml | 32 ++ .../dialer/main/impl/res/values-es-rUS/strings.xml | 36 ++ .../dialer/main/impl/res/values-es/strings.xml | 32 ++ .../dialer/main/impl/res/values-et/strings.xml | 36 ++ .../dialer/main/impl/res/values-eu/strings.xml | 36 ++ .../dialer/main/impl/res/values-fa/strings.xml | 36 ++ .../dialer/main/impl/res/values-fi/strings.xml | 36 ++ .../dialer/main/impl/res/values-fr-rCA/strings.xml | 32 ++ .../dialer/main/impl/res/values-fr/strings.xml | 32 ++ .../dialer/main/impl/res/values-gl/strings.xml | 32 ++ .../dialer/main/impl/res/values-gu/strings.xml | 32 ++ .../dialer/main/impl/res/values-hi/strings.xml | 32 ++ .../dialer/main/impl/res/values-hr/strings.xml | 36 ++ .../dialer/main/impl/res/values-hu/strings.xml | 36 ++ .../dialer/main/impl/res/values-hy/strings.xml | 32 ++ .../dialer/main/impl/res/values-in/strings.xml | 36 ++ .../dialer/main/impl/res/values-is/strings.xml | 36 ++ .../dialer/main/impl/res/values-it/strings.xml | 36 ++ .../dialer/main/impl/res/values-iw/strings.xml | 32 ++ .../dialer/main/impl/res/values-ja/strings.xml | 36 ++ .../dialer/main/impl/res/values-ka/strings.xml | 36 ++ .../dialer/main/impl/res/values-kk/strings.xml | 36 ++ .../dialer/main/impl/res/values-km/strings.xml | 36 ++ .../dialer/main/impl/res/values-kn/strings.xml | 36 ++ .../dialer/main/impl/res/values-ko/strings.xml | 32 ++ .../dialer/main/impl/res/values-ky/strings.xml | 36 ++ .../dialer/main/impl/res/values-lo/strings.xml | 32 ++ .../dialer/main/impl/res/values-lt/strings.xml | 32 ++ .../dialer/main/impl/res/values-lv/strings.xml | 36 ++ .../dialer/main/impl/res/values-mk/strings.xml | 36 ++ .../dialer/main/impl/res/values-ml/strings.xml | 36 ++ .../dialer/main/impl/res/values-mn/strings.xml | 32 ++ .../dialer/main/impl/res/values-mr/strings.xml | 32 ++ .../dialer/main/impl/res/values-ms/strings.xml | 32 ++ .../dialer/main/impl/res/values-my/strings.xml | 32 ++ .../dialer/main/impl/res/values-nb/strings.xml | 36 ++ .../dialer/main/impl/res/values-ne/strings.xml | 32 ++ .../dialer/main/impl/res/values-nl/strings.xml | 36 ++ .../dialer/main/impl/res/values-no/strings.xml | 36 ++ .../dialer/main/impl/res/values-pa/strings.xml | 32 ++ .../dialer/main/impl/res/values-pl/strings.xml | 32 ++ .../dialer/main/impl/res/values-pt-rBR/strings.xml | 36 ++ .../dialer/main/impl/res/values-pt-rPT/strings.xml | 36 ++ .../dialer/main/impl/res/values-pt/strings.xml | 36 ++ .../dialer/main/impl/res/values-ro/strings.xml | 36 ++ .../dialer/main/impl/res/values-ru/strings.xml | 36 ++ .../dialer/main/impl/res/values-si/strings.xml | 36 ++ .../dialer/main/impl/res/values-sk/strings.xml | 36 ++ .../dialer/main/impl/res/values-sl/strings.xml | 36 ++ .../dialer/main/impl/res/values-sq/strings.xml | 36 ++ .../dialer/main/impl/res/values-sr/strings.xml | 32 ++ .../dialer/main/impl/res/values-sv/strings.xml | 32 ++ .../dialer/main/impl/res/values-sw/strings.xml | 36 ++ .../dialer/main/impl/res/values-ta/strings.xml | 32 ++ .../dialer/main/impl/res/values-te/strings.xml | 32 ++ .../dialer/main/impl/res/values-th/strings.xml | 32 ++ .../dialer/main/impl/res/values-tl/strings.xml | 36 ++ .../dialer/main/impl/res/values-tr/strings.xml | 36 ++ .../dialer/main/impl/res/values-uk/strings.xml | 32 ++ .../dialer/main/impl/res/values-ur/strings.xml | 32 ++ .../dialer/main/impl/res/values-uz/strings.xml | 36 ++ .../dialer/main/impl/res/values-vi/strings.xml | 36 ++ .../dialer/main/impl/res/values-zh-rCN/strings.xml | 32 ++ .../dialer/main/impl/res/values-zh-rHK/strings.xml | 32 ++ .../dialer/main/impl/res/values-zh-rTW/strings.xml | 36 ++ .../dialer/main/impl/res/values-zu/strings.xml | 36 ++ .../dialer/main/impl/res/values/strings.xml | 49 +++ .../android/dialer/main/impl/res/values/styles.xml | 28 ++ .../dialer/notification/AndroidManifest.xml | 16 +- .../notification/GroupedNotificationUtil.java | 66 --- .../dialer/notification/NotificationChannelId.java | 41 ++ .../notification/NotificationChannelManager.java | 456 ++++++--------------- .../notification/PackageUpdatedReceiver.java | 37 -- .../dialer/notification/VoicemailChannelUtils.java | 217 ++++++++++ .../dialer/notification/res/values-af/strings.xml | 1 - .../dialer/notification/res/values-am/strings.xml | 1 - .../dialer/notification/res/values-ar/strings.xml | 1 - .../dialer/notification/res/values-az/strings.xml | 1 - .../notification/res/values-b+sr+Latn/strings.xml | 1 - .../dialer/notification/res/values-be/strings.xml | 1 - .../dialer/notification/res/values-bg/strings.xml | 1 - .../dialer/notification/res/values-bn/strings.xml | 1 - .../dialer/notification/res/values-bs/strings.xml | 1 - .../dialer/notification/res/values-ca/strings.xml | 1 - .../dialer/notification/res/values-cs/strings.xml | 1 - .../dialer/notification/res/values-da/strings.xml | 1 - .../dialer/notification/res/values-de/strings.xml | 1 - .../dialer/notification/res/values-el/strings.xml | 1 - .../notification/res/values-en-rAU/strings.xml | 1 - .../notification/res/values-en-rGB/strings.xml | 1 - .../notification/res/values-en-rIN/strings.xml | 1 - .../notification/res/values-es-rUS/strings.xml | 1 - .../dialer/notification/res/values-es/strings.xml | 1 - .../dialer/notification/res/values-et/strings.xml | 1 - .../dialer/notification/res/values-eu/strings.xml | 1 - .../dialer/notification/res/values-fa/strings.xml | 1 - .../dialer/notification/res/values-fi/strings.xml | 1 - .../notification/res/values-fr-rCA/strings.xml | 1 - .../dialer/notification/res/values-fr/strings.xml | 1 - .../dialer/notification/res/values-gl/strings.xml | 1 - .../dialer/notification/res/values-gu/strings.xml | 1 - .../dialer/notification/res/values-hi/strings.xml | 1 - .../dialer/notification/res/values-hr/strings.xml | 1 - .../dialer/notification/res/values-hu/strings.xml | 1 - .../dialer/notification/res/values-hy/strings.xml | 1 - .../dialer/notification/res/values-in/strings.xml | 1 - .../dialer/notification/res/values-is/strings.xml | 1 - .../dialer/notification/res/values-it/strings.xml | 1 - .../dialer/notification/res/values-iw/strings.xml | 1 - .../dialer/notification/res/values-ja/strings.xml | 1 - .../dialer/notification/res/values-ka/strings.xml | 1 - .../dialer/notification/res/values-kk/strings.xml | 1 - .../dialer/notification/res/values-km/strings.xml | 1 - .../dialer/notification/res/values-kn/strings.xml | 1 - .../dialer/notification/res/values-ko/strings.xml | 1 - .../dialer/notification/res/values-ky/strings.xml | 1 - .../dialer/notification/res/values-lo/strings.xml | 1 - .../dialer/notification/res/values-lt/strings.xml | 1 - .../dialer/notification/res/values-lv/strings.xml | 1 - .../dialer/notification/res/values-mk/strings.xml | 1 - .../dialer/notification/res/values-ml/strings.xml | 1 - .../dialer/notification/res/values-mn/strings.xml | 1 - .../dialer/notification/res/values-mr/strings.xml | 1 - .../dialer/notification/res/values-ms/strings.xml | 1 - .../dialer/notification/res/values-my/strings.xml | 1 - .../dialer/notification/res/values-nb/strings.xml | 1 - .../dialer/notification/res/values-ne/strings.xml | 1 - .../dialer/notification/res/values-nl/strings.xml | 1 - .../dialer/notification/res/values-no/strings.xml | 1 - .../dialer/notification/res/values-pa/strings.xml | 1 - .../dialer/notification/res/values-pl/strings.xml | 1 - .../notification/res/values-pt-rBR/strings.xml | 1 - .../notification/res/values-pt-rPT/strings.xml | 1 - .../dialer/notification/res/values-pt/strings.xml | 1 - .../dialer/notification/res/values-ro/strings.xml | 1 - .../dialer/notification/res/values-ru/strings.xml | 1 - .../dialer/notification/res/values-si/strings.xml | 1 - .../dialer/notification/res/values-sk/strings.xml | 1 - .../dialer/notification/res/values-sl/strings.xml | 1 - .../dialer/notification/res/values-sq/strings.xml | 1 - .../dialer/notification/res/values-sr/strings.xml | 1 - .../dialer/notification/res/values-sv/strings.xml | 1 - .../dialer/notification/res/values-sw/strings.xml | 1 - .../dialer/notification/res/values-ta/strings.xml | 1 - .../dialer/notification/res/values-te/strings.xml | 1 - .../dialer/notification/res/values-th/strings.xml | 1 - .../dialer/notification/res/values-tl/strings.xml | 1 - .../dialer/notification/res/values-tr/strings.xml | 1 - .../dialer/notification/res/values-uk/strings.xml | 1 - .../dialer/notification/res/values-ur/strings.xml | 1 - .../dialer/notification/res/values-uz/strings.xml | 1 - .../dialer/notification/res/values-vi/strings.xml | 1 - .../notification/res/values-zh-rCN/strings.xml | 1 - .../notification/res/values-zh-rHK/strings.xml | 1 - .../notification/res/values-zh-rTW/strings.xml | 1 - .../dialer/notification/res/values-zu/strings.xml | 1 - .../android/dialer/notification/res/values/ids.xml | 27 -- .../dialer/notification/res/values/strings.xml | 1 - .../android/dialer/oem/CequintCallerIdManager.java | 2 +- java/com/android/dialer/oem/MotorolaUtils.java | 2 +- .../android/dialer/p13n/inference/P13nRanking.java | 2 +- .../performancereport/PerformanceReport.java | 155 +++++++ .../CachedNumberLookupService.java | 2 + .../dialer/phonenumbercache/ContactInfoHelper.java | 27 +- .../android/dialer/phonenumberproto/Converter.java | 120 ++++++ .../phonenumberproto/DialerPhoneNumberUtil.java | 108 +++++ .../phonenumberproto/dialer_phone_number.proto | 172 ++++++++ java/com/android/dialer/postcall/PostCall.java | 22 +- .../dialer/searchfragment/AndroidManifest.xml | 16 - .../dialer/searchfragment/NewSearchFragment.java | 83 ---- .../android/dialer/searchfragment/QueryUtil.java | 269 ------------ .../dialer/searchfragment/SearchAdapter.java | 84 ---- .../dialer/searchfragment/SearchContactCursor.java | 390 ------------------ .../searchfragment/SearchContactViewHolder.java | 203 --------- .../searchfragment/SearchContactsCursorLoader.java | 57 --- .../dialer/searchfragment/SearchCursorManager.java | 229 ----------- .../searchfragment/common/AndroidManifest.xml | 16 + .../dialer/searchfragment/common/Projections.java | 50 +++ .../searchfragment/common/QueryBoldingUtil.java | 154 +++++++ .../searchfragment/common/QueryFilteringUtil.java | 141 +++++++ .../common/res/layout/search_contact_row.xml | 69 ++++ .../searchfragment/common/res/values/dimens.xml | 23 ++ .../searchfragment/cp2/SearchContactCursor.java | 392 ++++++++++++++++++ .../cp2/SearchContactViewHolder.java | 204 +++++++++ .../cp2/SearchContactsCursorLoader.java | 42 ++ .../dialer/searchfragment/list/AndroidManifest.xml | 16 + .../searchfragment/list/HeaderViewHolder.java | 36 ++ .../searchfragment/list/NewSearchFragment.java | 125 ++++++ .../dialer/searchfragment/list/SearchAdapter.java | 108 +++++ .../searchfragment/list/SearchCursorManager.java | 273 ++++++++++++ .../list/res/layout/fragment_search.xml | 21 + .../list/res/layout/header_layout.xml | 22 + .../nearbyplaces/AndroidManifest.xml | 16 + .../nearbyplaces/NearbyPlaceViewHolder.java | 90 ++++ .../nearbyplaces/NearbyPlacesCursorLoader.java | 43 ++ .../nearbyplaces/res/values-af/strings.xml | 21 + .../nearbyplaces/res/values-am/strings.xml | 22 + .../nearbyplaces/res/values-ar/strings.xml | 21 + .../nearbyplaces/res/values-az/strings.xml | 22 + .../nearbyplaces/res/values-b+sr+Latn/strings.xml | 21 + .../nearbyplaces/res/values-be/strings.xml | 22 + .../nearbyplaces/res/values-bg/strings.xml | 21 + .../nearbyplaces/res/values-bn/strings.xml | 21 + .../nearbyplaces/res/values-bs/strings.xml | 21 + .../nearbyplaces/res/values-ca/strings.xml | 22 + .../nearbyplaces/res/values-cs/strings.xml | 22 + .../nearbyplaces/res/values-da/strings.xml | 22 + .../nearbyplaces/res/values-de/strings.xml | 21 + .../nearbyplaces/res/values-el/strings.xml | 22 + .../nearbyplaces/res/values-en-rAU/strings.xml | 21 + .../nearbyplaces/res/values-en-rGB/strings.xml | 21 + .../nearbyplaces/res/values-en-rIN/strings.xml | 21 + .../nearbyplaces/res/values-es-rUS/strings.xml | 22 + .../nearbyplaces/res/values-es/strings.xml | 21 + .../nearbyplaces/res/values-et/strings.xml | 22 + .../nearbyplaces/res/values-eu/strings.xml | 22 + .../nearbyplaces/res/values-fa/strings.xml | 22 + .../nearbyplaces/res/values-fi/strings.xml | 22 + .../nearbyplaces/res/values-fr-rCA/strings.xml | 21 + .../nearbyplaces/res/values-fr/strings.xml | 21 + .../nearbyplaces/res/values-gl/strings.xml | 21 + .../nearbyplaces/res/values-gu/strings.xml | 21 + .../nearbyplaces/res/values-hi/strings.xml | 21 + .../nearbyplaces/res/values-hr/strings.xml | 22 + .../nearbyplaces/res/values-hu/strings.xml | 22 + .../nearbyplaces/res/values-hy/strings.xml | 21 + .../nearbyplaces/res/values-in/strings.xml | 22 + .../nearbyplaces/res/values-is/strings.xml | 22 + .../nearbyplaces/res/values-it/strings.xml | 22 + .../nearbyplaces/res/values-iw/strings.xml | 21 + .../nearbyplaces/res/values-ja/strings.xml | 22 + .../nearbyplaces/res/values-ka/strings.xml | 22 + .../nearbyplaces/res/values-kk/strings.xml | 22 + .../nearbyplaces/res/values-km/strings.xml | 22 + .../nearbyplaces/res/values-kn/strings.xml | 22 + .../nearbyplaces/res/values-ko/strings.xml | 21 + .../nearbyplaces/res/values-ky/strings.xml | 22 + .../nearbyplaces/res/values-lo/strings.xml | 21 + .../nearbyplaces/res/values-lt/strings.xml | 21 + .../nearbyplaces/res/values-lv/strings.xml | 22 + .../nearbyplaces/res/values-mk/strings.xml | 22 + .../nearbyplaces/res/values-ml/strings.xml | 22 + .../nearbyplaces/res/values-mn/strings.xml | 21 + .../nearbyplaces/res/values-mr/strings.xml | 21 + .../nearbyplaces/res/values-ms/strings.xml | 21 + .../nearbyplaces/res/values-my/strings.xml | 21 + .../nearbyplaces/res/values-nb/strings.xml | 22 + .../nearbyplaces/res/values-ne/strings.xml | 21 + .../nearbyplaces/res/values-nl/strings.xml | 22 + .../nearbyplaces/res/values-no/strings.xml | 22 + .../nearbyplaces/res/values-pa/strings.xml | 21 + .../nearbyplaces/res/values-pl/strings.xml | 21 + .../nearbyplaces/res/values-pt-rBR/strings.xml | 22 + .../nearbyplaces/res/values-pt-rPT/strings.xml | 22 + .../nearbyplaces/res/values-pt/strings.xml | 22 + .../nearbyplaces/res/values-ro/strings.xml | 22 + .../nearbyplaces/res/values-ru/strings.xml | 22 + .../nearbyplaces/res/values-si/strings.xml | 22 + .../nearbyplaces/res/values-sk/strings.xml | 22 + .../nearbyplaces/res/values-sl/strings.xml | 22 + .../nearbyplaces/res/values-sq/strings.xml | 22 + .../nearbyplaces/res/values-sr/strings.xml | 21 + .../nearbyplaces/res/values-sv/strings.xml | 21 + .../nearbyplaces/res/values-sw/strings.xml | 22 + .../nearbyplaces/res/values-ta/strings.xml | 21 + .../nearbyplaces/res/values-te/strings.xml | 21 + .../nearbyplaces/res/values-th/strings.xml | 21 + .../nearbyplaces/res/values-tl/strings.xml | 22 + .../nearbyplaces/res/values-tr/strings.xml | 22 + .../nearbyplaces/res/values-uk/strings.xml | 21 + .../nearbyplaces/res/values-ur/strings.xml | 21 + .../nearbyplaces/res/values-uz/strings.xml | 22 + .../nearbyplaces/res/values-vi/strings.xml | 22 + .../nearbyplaces/res/values-zh-rCN/strings.xml | 21 + .../nearbyplaces/res/values-zh-rHK/strings.xml | 21 + .../nearbyplaces/res/values-zh-rTW/strings.xml | 22 + .../nearbyplaces/res/values-zu/strings.xml | 22 + .../nearbyplaces/res/values/strings.xml | 20 + .../searchfragment/res/layout/fragment_search.xml | 21 - .../res/layout/search_contact_row.xml | 75 ---- .../dialer/searchfragment/res/values/dimens.xml | 23 -- java/com/android/dialer/shortcuts/Shortcuts.java | 2 +- .../dialer/simulator/impl/SimulatorContacts.java | 2 +- java/com/android/dialer/telecom/TelecomUtil.java | 30 +- java/com/android/dialer/util/CallUtil.java | 2 +- java/com/android/dialer/util/PermissionsUtil.java | 68 ++- .../android/dialer/widget/LockableViewPager.java | 50 +++ .../widget/res/layout-land/empty_content_view.xml | 56 +++ .../dialer/widget/res/values-af/strings.xml | 18 +- .../dialer/widget/res/values-am/strings.xml | 19 +- .../dialer/widget/res/values-ar/strings.xml | 18 +- .../dialer/widget/res/values-az/strings.xml | 19 +- .../dialer/widget/res/values-b+sr+Latn/strings.xml | 18 +- .../dialer/widget/res/values-be/strings.xml | 19 +- .../dialer/widget/res/values-bg/strings.xml | 18 +- .../dialer/widget/res/values-bn/strings.xml | 18 +- .../dialer/widget/res/values-bs/strings.xml | 18 +- .../dialer/widget/res/values-ca/strings.xml | 19 +- .../dialer/widget/res/values-cs/strings.xml | 19 +- .../dialer/widget/res/values-da/strings.xml | 19 +- .../dialer/widget/res/values-de/strings.xml | 18 +- .../dialer/widget/res/values-el/strings.xml | 19 +- .../dialer/widget/res/values-en-rAU/strings.xml | 18 +- .../dialer/widget/res/values-en-rGB/strings.xml | 18 +- .../dialer/widget/res/values-en-rIN/strings.xml | 18 +- .../dialer/widget/res/values-es-rUS/strings.xml | 19 +- .../dialer/widget/res/values-es/strings.xml | 18 +- .../dialer/widget/res/values-et/strings.xml | 19 +- .../dialer/widget/res/values-eu/strings.xml | 19 +- .../dialer/widget/res/values-fa/strings.xml | 19 +- .../dialer/widget/res/values-fi/strings.xml | 19 +- .../dialer/widget/res/values-fr-rCA/strings.xml | 18 +- .../dialer/widget/res/values-fr/strings.xml | 18 +- .../dialer/widget/res/values-gl/strings.xml | 18 +- .../dialer/widget/res/values-gu/strings.xml | 18 +- .../dialer/widget/res/values-hi/strings.xml | 18 +- .../dialer/widget/res/values-hr/strings.xml | 19 +- .../dialer/widget/res/values-hu/strings.xml | 19 +- .../dialer/widget/res/values-hy/strings.xml | 18 +- .../dialer/widget/res/values-in/strings.xml | 19 +- .../dialer/widget/res/values-is/strings.xml | 19 +- .../dialer/widget/res/values-it/strings.xml | 19 +- .../dialer/widget/res/values-iw/strings.xml | 18 +- .../dialer/widget/res/values-ja/strings.xml | 19 +- .../dialer/widget/res/values-ka/strings.xml | 19 +- .../dialer/widget/res/values-kk/strings.xml | 19 +- .../dialer/widget/res/values-km/strings.xml | 19 +- .../dialer/widget/res/values-kn/strings.xml | 19 +- .../dialer/widget/res/values-ko/strings.xml | 18 +- .../dialer/widget/res/values-ky/strings.xml | 19 +- .../dialer/widget/res/values-lo/strings.xml | 18 +- .../dialer/widget/res/values-lt/strings.xml | 18 +- .../dialer/widget/res/values-lv/strings.xml | 19 +- .../dialer/widget/res/values-mk/strings.xml | 19 +- .../dialer/widget/res/values-ml/strings.xml | 19 +- .../dialer/widget/res/values-mn/strings.xml | 18 +- .../dialer/widget/res/values-mr/strings.xml | 18 +- .../dialer/widget/res/values-ms/strings.xml | 18 +- .../dialer/widget/res/values-my/strings.xml | 18 +- .../dialer/widget/res/values-nb/strings.xml | 19 +- .../dialer/widget/res/values-ne/strings.xml | 18 +- .../dialer/widget/res/values-nl/strings.xml | 19 +- .../dialer/widget/res/values-no/strings.xml | 19 +- .../dialer/widget/res/values-pa/strings.xml | 18 +- .../dialer/widget/res/values-pl/strings.xml | 18 +- .../dialer/widget/res/values-pt-rBR/strings.xml | 19 +- .../dialer/widget/res/values-pt-rPT/strings.xml | 19 +- .../dialer/widget/res/values-pt/strings.xml | 19 +- .../dialer/widget/res/values-ro/strings.xml | 19 +- .../dialer/widget/res/values-ru/strings.xml | 19 +- .../dialer/widget/res/values-si/strings.xml | 19 +- .../dialer/widget/res/values-sk/strings.xml | 19 +- .../dialer/widget/res/values-sl/strings.xml | 19 +- .../dialer/widget/res/values-sq/strings.xml | 19 +- .../dialer/widget/res/values-sr/strings.xml | 18 +- .../dialer/widget/res/values-sv/strings.xml | 18 +- .../dialer/widget/res/values-sw/strings.xml | 19 +- .../dialer/widget/res/values-ta/strings.xml | 18 +- .../dialer/widget/res/values-te/strings.xml | 18 +- .../dialer/widget/res/values-th/strings.xml | 18 +- .../dialer/widget/res/values-tl/strings.xml | 19 +- .../dialer/widget/res/values-tr/strings.xml | 19 +- .../dialer/widget/res/values-uk/strings.xml | 18 +- .../dialer/widget/res/values-ur/strings.xml | 18 +- .../dialer/widget/res/values-uz/strings.xml | 19 +- .../dialer/widget/res/values-vi/strings.xml | 19 +- .../dialer/widget/res/values-zh-rCN/strings.xml | 18 +- .../dialer/widget/res/values-zh-rHK/strings.xml | 18 +- .../dialer/widget/res/values-zh-rTW/strings.xml | 19 +- .../dialer/widget/res/values-zu/strings.xml | 19 +- .../android/dialer/widget/res/values/strings.xml | 17 +- java/com/android/dialershared/bubble/Bubble.java | 182 ++++++-- .../android/dialershared/bubble/BubbleInfo.java | 19 +- .../android/dialershared/bubble/MoveHandler.java | 22 +- .../dialershared/bubble/g3doc/INTEGRATION.md | 69 ++++ .../bubble/g3doc/images/bubble_collapsed.png | Bin 0 -> 60187 bytes .../bubble/g3doc/images/bubble_expanded.png | Bin 0 -> 79674 bytes .../bubble/g3doc/images/bubble_state.png | Bin 0 -> 83470 bytes .../bubble/g3doc/images/bubble_text.png | Bin 0 -> 65641 bytes .../dialershared/bubble/res/layout/bubble_base.xml | 25 +- .../dialershared/bubble/res/values/values.xml | 10 +- .../android/incallui/AnswerScreenPresenter.java | 39 +- .../incallui/AnswerScreenPresenterStub.java | 5 + java/com/android/incallui/CallButtonPresenter.java | 3 + java/com/android/incallui/CallCardPresenter.java | 13 +- java/com/android/incallui/ContactInfoCache.java | 3 +- .../com/android/incallui/ExternalCallNotifier.java | 43 +- java/com/android/incallui/InCallActivity.java | 20 +- java/com/android/incallui/InCallPresenter.java | 7 + java/com/android/incallui/InCallServiceImpl.java | 3 +- .../android/incallui/ReturnToCallController.java | 26 +- java/com/android/incallui/StatusBarNotifier.java | 63 ++- java/com/android/incallui/VideoCallPresenter.java | 2 +- .../incallui/answer/impl/AnswerFragment.java | 12 +- .../classifier/HumanInteractionClassifier.java | 2 +- .../answer/impl/hint/AnswerHintFactory.java | 2 +- .../answer/impl/hint/PawSecretCodeListener.java | 2 +- .../incallui/answer/protocol/AnswerScreen.java | 2 + .../answer/protocol/AnswerScreenDelegate.java | 3 + .../AnswerProximitySensor.java | 2 +- java/com/android/incallui/call/CallList.java | 5 +- java/com/android/incallui/call/DialerCall.java | 33 +- .../incallui/incall/impl/InCallFragment.java | 1 + .../incallui/incall/impl/LockableViewPager.java | 46 --- .../incall/impl/res/layout/frag_incall_voice.xml | 17 +- .../incallui/incall/protocol/PrimaryInfo.java | 5 +- .../android/incallui/res/anim/on_going_call.xml | 31 -- .../incallui/res/drawable/on_going_call.xml | 47 +++ .../com/android/incallui/res/values-af/strings.xml | 16 +- .../com/android/incallui/res/values-am/strings.xml | 16 +- .../com/android/incallui/res/values-ar/strings.xml | 16 +- .../com/android/incallui/res/values-az/strings.xml | 16 +- .../incallui/res/values-b+sr+Latn/strings.xml | 16 +- .../com/android/incallui/res/values-be/strings.xml | 16 +- .../com/android/incallui/res/values-bg/strings.xml | 16 +- .../com/android/incallui/res/values-bn/strings.xml | 16 +- .../com/android/incallui/res/values-bs/strings.xml | 16 +- .../com/android/incallui/res/values-ca/strings.xml | 18 +- .../com/android/incallui/res/values-cs/strings.xml | 16 +- .../com/android/incallui/res/values-da/strings.xml | 16 +- .../com/android/incallui/res/values-de/strings.xml | 16 +- .../com/android/incallui/res/values-el/strings.xml | 16 +- .../android/incallui/res/values-en-rAU/strings.xml | 18 +- .../android/incallui/res/values-en-rGB/strings.xml | 18 +- .../android/incallui/res/values-en-rIN/strings.xml | 18 +- .../android/incallui/res/values-es-rUS/strings.xml | 16 +- .../com/android/incallui/res/values-es/strings.xml | 16 +- .../com/android/incallui/res/values-et/strings.xml | 16 +- .../com/android/incallui/res/values-eu/strings.xml | 16 +- .../com/android/incallui/res/values-fa/strings.xml | 16 +- .../com/android/incallui/res/values-fi/strings.xml | 16 +- .../android/incallui/res/values-fr-rCA/strings.xml | 16 +- .../com/android/incallui/res/values-fr/strings.xml | 16 +- .../com/android/incallui/res/values-gl/strings.xml | 16 +- .../com/android/incallui/res/values-gu/strings.xml | 16 +- .../com/android/incallui/res/values-hi/strings.xml | 16 +- .../com/android/incallui/res/values-hr/strings.xml | 16 +- .../com/android/incallui/res/values-hu/strings.xml | 16 +- .../com/android/incallui/res/values-hy/strings.xml | 16 +- .../com/android/incallui/res/values-in/strings.xml | 16 +- .../com/android/incallui/res/values-is/strings.xml | 16 +- .../com/android/incallui/res/values-it/strings.xml | 16 +- .../com/android/incallui/res/values-iw/strings.xml | 16 +- .../com/android/incallui/res/values-ja/strings.xml | 16 +- .../com/android/incallui/res/values-ka/strings.xml | 16 +- .../com/android/incallui/res/values-kk/strings.xml | 16 +- .../com/android/incallui/res/values-km/strings.xml | 16 +- .../com/android/incallui/res/values-kn/strings.xml | 16 +- .../com/android/incallui/res/values-ko/strings.xml | 16 +- .../com/android/incallui/res/values-ky/strings.xml | 16 +- .../com/android/incallui/res/values-lo/strings.xml | 16 +- .../com/android/incallui/res/values-lt/strings.xml | 18 +- .../com/android/incallui/res/values-lv/strings.xml | 16 +- .../incallui/res/values-mcc262-mnc01/strings.xml | 32 -- .../com/android/incallui/res/values-mk/strings.xml | 16 +- .../com/android/incallui/res/values-ml/strings.xml | 16 +- .../com/android/incallui/res/values-mn/strings.xml | 16 +- .../com/android/incallui/res/values-mr/strings.xml | 16 +- .../com/android/incallui/res/values-ms/strings.xml | 18 +- .../com/android/incallui/res/values-my/strings.xml | 16 +- .../com/android/incallui/res/values-nb/strings.xml | 16 +- .../com/android/incallui/res/values-ne/strings.xml | 16 +- .../com/android/incallui/res/values-nl/strings.xml | 18 +- .../com/android/incallui/res/values-no/strings.xml | 16 +- .../com/android/incallui/res/values-pa/strings.xml | 16 +- .../com/android/incallui/res/values-pl/strings.xml | 16 +- .../android/incallui/res/values-pt-rBR/strings.xml | 16 +- .../android/incallui/res/values-pt-rPT/strings.xml | 16 +- .../com/android/incallui/res/values-pt/strings.xml | 16 +- .../com/android/incallui/res/values-ro/strings.xml | 16 +- .../com/android/incallui/res/values-ru/strings.xml | 16 +- .../com/android/incallui/res/values-si/strings.xml | 16 +- .../com/android/incallui/res/values-sk/strings.xml | 16 +- .../com/android/incallui/res/values-sl/strings.xml | 16 +- .../com/android/incallui/res/values-sq/strings.xml | 16 +- .../com/android/incallui/res/values-sr/strings.xml | 16 +- .../com/android/incallui/res/values-sv/strings.xml | 16 +- .../com/android/incallui/res/values-sw/strings.xml | 16 +- .../com/android/incallui/res/values-ta/strings.xml | 16 +- .../com/android/incallui/res/values-te/strings.xml | 16 +- .../com/android/incallui/res/values-th/strings.xml | 16 +- .../com/android/incallui/res/values-tl/strings.xml | 16 +- .../com/android/incallui/res/values-tr/strings.xml | 16 +- .../com/android/incallui/res/values-uk/strings.xml | 16 +- .../com/android/incallui/res/values-ur/strings.xml | 16 +- .../com/android/incallui/res/values-uz/strings.xml | 16 +- .../com/android/incallui/res/values-vi/strings.xml | 16 +- .../android/incallui/res/values-zh-rCN/strings.xml | 16 +- .../android/incallui/res/values-zh-rHK/strings.xml | 16 +- .../android/incallui/res/values-zh-rTW/strings.xml | 16 +- .../com/android/incallui/res/values-zu/strings.xml | 16 +- java/com/android/incallui/res/values/dimens.xml | 2 + java/com/android/incallui/res/values/strings.xml | 16 +- .../incallui/sessiondata/MultimediaFragment.java | 17 +- .../incallui/spam/SpamCallListListener.java | 53 +-- .../incallui/video/impl/VideoCallFragment.java | 9 +- java/com/android/incallui/videotech/VideoTech.java | 5 +- .../incallui/videotech/empty/EmptyVideoTech.java | 6 +- .../incallui/videotech/ims/ImsVideoTech.java | 6 +- .../videotech/lightbringer/LightbringerTech.java | 30 +- .../voicemail/impl/TelephonyVvmConfigManager.java | 2 +- .../voicemail/impl/VoicemailClientImpl.java | 2 +- .../android/voicemail/impl/VoicemailModule.java | 3 +- .../android/voicemail/impl/imap/ImapHelper.java | 19 +- java/com/android/voicemail/impl/mail/Message.java | 4 + .../voicemail/impl/mail/internet/MimeHeader.java | 1 + .../voicemail/impl/mail/internet/MimeMessage.java | 24 ++ .../impl/mail/store/imap/ImapConstants.java | 2 +- .../voicemail/impl/protocol/Vvm3Subscriber.java | 2 +- .../android/voicemail/impl/res/xml/vvm_config.xml | 69 ---- .../impl/settings/VoicemailSettingsFragment.java | 18 +- .../transcribe/TranscriptionConfigProvider.java | 2 +- 1192 files changed, 18916 insertions(+), 6380 deletions(-) delete mode 100644 java/com/android/dialer/app/bindings/DialerBindings.java delete mode 100644 java/com/android/dialer/app/bindings/DialerBindingsFactory.java delete mode 100644 java/com/android/dialer/app/bindings/DialerBindingsStub.java delete mode 100644 java/com/android/dialer/app/calllog/DefaultVoicemailNotifier.java create mode 100644 java/com/android/dialer/app/calllog/DialerQuickContactBadge.java create mode 100644 java/com/android/dialer/app/calllog/LegacyVoicemailNotifier.java delete mode 100644 java/com/android/dialer/app/calllog/PhoneAccountHandles.java create mode 100644 java/com/android/dialer/app/calllog/VisualVoicemailNotifier.java create mode 100644 java/com/android/dialer/app/calllog/VisualVoicemailUpdateTask.java create mode 100644 java/com/android/dialer/app/voicemail/error/VoicemailTosMessageCreator.java create mode 100644 java/com/android/dialer/binary/aosp/testing/AndroidManifest.xml create mode 100644 java/com/android/dialer/binary/aosp/testing/TestActivity.java create mode 100644 java/com/android/dialer/calldetails/ReportDialogFragment.java create mode 100644 java/com/android/dialer/calldetails/res/layout/caller_id_report_dialog.xml delete mode 100644 java/com/android/dialer/common/ConfigProvider.java delete mode 100644 java/com/android/dialer/common/ConfigProviderBindings.java delete mode 100644 java/com/android/dialer/common/ConfigProviderFactory.java create mode 100644 java/com/android/dialer/configprovider/AndroidManifest.xml create mode 100644 java/com/android/dialer/configprovider/ConfigProvider.java create mode 100644 java/com/android/dialer/configprovider/ConfigProviderBindings.java create mode 100644 java/com/android/dialer/configprovider/ConfigProviderComponent.java create mode 100644 java/com/android/dialer/configprovider/SharedPrefConfigProvider.java create mode 100644 java/com/android/dialer/configprovider/SharedPrefConfigProviderModule.java create mode 100644 java/com/android/dialer/contactsfragment/AddContactViewHolder.java create mode 100644 java/com/android/dialer/contactsfragment/res/layout/add_contact_row.xml create mode 100644 java/com/android/dialer/inject/ApplicationContext.java create mode 100644 java/com/android/dialer/logging/ui_action.proto create mode 100644 java/com/android/dialer/main/Main.java create mode 100644 java/com/android/dialer/main/MainComponent.java create mode 100644 java/com/android/dialer/main/impl/AndroidManifest.xml create mode 100644 java/com/android/dialer/main/impl/MainActivity.java create mode 100644 java/com/android/dialer/main/impl/MainImpl.java create mode 100644 java/com/android/dialer/main/impl/MainModule.java create mode 100644 java/com/android/dialer/main/impl/MainPagerAdapter.java create mode 100644 java/com/android/dialer/main/impl/StubFragment.java create mode 100644 java/com/android/dialer/main/impl/res/drawable-xxxhdpi/nui_launcher_icon.png create mode 100644 java/com/android/dialer/main/impl/res/layout/main_activity.xml create mode 100644 java/com/android/dialer/main/impl/res/layout/stub_fragment.xml create mode 100644 java/com/android/dialer/main/impl/res/menu/main_menu.xml create mode 100644 java/com/android/dialer/main/impl/res/values-af/strings.xml create mode 100644 java/com/android/dialer/main/impl/res/values-am/strings.xml create mode 100644 java/com/android/dialer/main/impl/res/values-ar/strings.xml create mode 100644 java/com/android/dialer/main/impl/res/values-az/strings.xml create mode 100644 java/com/android/dialer/main/impl/res/values-b+sr+Latn/strings.xml create mode 100644 java/com/android/dialer/main/impl/res/values-be/strings.xml create mode 100644 java/com/android/dialer/main/impl/res/values-bg/strings.xml create mode 100644 java/com/android/dialer/main/impl/res/values-bn/strings.xml create mode 100644 java/com/android/dialer/main/impl/res/values-bs/strings.xml create mode 100644 java/com/android/dialer/main/impl/res/values-ca/strings.xml create mode 100644 java/com/android/dialer/main/impl/res/values-cs/strings.xml create mode 100644 java/com/android/dialer/main/impl/res/values-da/strings.xml create mode 100644 java/com/android/dialer/main/impl/res/values-de/strings.xml create mode 100644 java/com/android/dialer/main/impl/res/values-el/strings.xml create mode 100644 java/com/android/dialer/main/impl/res/values-en-rAU/strings.xml create mode 100644 java/com/android/dialer/main/impl/res/values-en-rGB/strings.xml create mode 100644 java/com/android/dialer/main/impl/res/values-en-rIN/strings.xml create mode 100644 java/com/android/dialer/main/impl/res/values-es-rUS/strings.xml create mode 100644 java/com/android/dialer/main/impl/res/values-es/strings.xml create mode 100644 java/com/android/dialer/main/impl/res/values-et/strings.xml create mode 100644 java/com/android/dialer/main/impl/res/values-eu/strings.xml create mode 100644 java/com/android/dialer/main/impl/res/values-fa/strings.xml create mode 100644 java/com/android/dialer/main/impl/res/values-fi/strings.xml create mode 100644 java/com/android/dialer/main/impl/res/values-fr-rCA/strings.xml create mode 100644 java/com/android/dialer/main/impl/res/values-fr/strings.xml create mode 100644 java/com/android/dialer/main/impl/res/values-gl/strings.xml create mode 100644 java/com/android/dialer/main/impl/res/values-gu/strings.xml create mode 100644 java/com/android/dialer/main/impl/res/values-hi/strings.xml create mode 100644 java/com/android/dialer/main/impl/res/values-hr/strings.xml create mode 100644 java/com/android/dialer/main/impl/res/values-hu/strings.xml create mode 100644 java/com/android/dialer/main/impl/res/values-hy/strings.xml create mode 100644 java/com/android/dialer/main/impl/res/values-in/strings.xml create mode 100644 java/com/android/dialer/main/impl/res/values-is/strings.xml create mode 100644 java/com/android/dialer/main/impl/res/values-it/strings.xml create mode 100644 java/com/android/dialer/main/impl/res/values-iw/strings.xml create mode 100644 java/com/android/dialer/main/impl/res/values-ja/strings.xml create mode 100644 java/com/android/dialer/main/impl/res/values-ka/strings.xml create mode 100644 java/com/android/dialer/main/impl/res/values-kk/strings.xml create mode 100644 java/com/android/dialer/main/impl/res/values-km/strings.xml create mode 100644 java/com/android/dialer/main/impl/res/values-kn/strings.xml create mode 100644 java/com/android/dialer/main/impl/res/values-ko/strings.xml create mode 100644 java/com/android/dialer/main/impl/res/values-ky/strings.xml create mode 100644 java/com/android/dialer/main/impl/res/values-lo/strings.xml create mode 100644 java/com/android/dialer/main/impl/res/values-lt/strings.xml create mode 100644 java/com/android/dialer/main/impl/res/values-lv/strings.xml create mode 100644 java/com/android/dialer/main/impl/res/values-mk/strings.xml create mode 100644 java/com/android/dialer/main/impl/res/values-ml/strings.xml create mode 100644 java/com/android/dialer/main/impl/res/values-mn/strings.xml create mode 100644 java/com/android/dialer/main/impl/res/values-mr/strings.xml create mode 100644 java/com/android/dialer/main/impl/res/values-ms/strings.xml create mode 100644 java/com/android/dialer/main/impl/res/values-my/strings.xml create mode 100644 java/com/android/dialer/main/impl/res/values-nb/strings.xml create mode 100644 java/com/android/dialer/main/impl/res/values-ne/strings.xml create mode 100644 java/com/android/dialer/main/impl/res/values-nl/strings.xml create mode 100644 java/com/android/dialer/main/impl/res/values-no/strings.xml create mode 100644 java/com/android/dialer/main/impl/res/values-pa/strings.xml create mode 100644 java/com/android/dialer/main/impl/res/values-pl/strings.xml create mode 100644 java/com/android/dialer/main/impl/res/values-pt-rBR/strings.xml create mode 100644 java/com/android/dialer/main/impl/res/values-pt-rPT/strings.xml create mode 100644 java/com/android/dialer/main/impl/res/values-pt/strings.xml create mode 100644 java/com/android/dialer/main/impl/res/values-ro/strings.xml create mode 100644 java/com/android/dialer/main/impl/res/values-ru/strings.xml create mode 100644 java/com/android/dialer/main/impl/res/values-si/strings.xml create mode 100644 java/com/android/dialer/main/impl/res/values-sk/strings.xml create mode 100644 java/com/android/dialer/main/impl/res/values-sl/strings.xml create mode 100644 java/com/android/dialer/main/impl/res/values-sq/strings.xml create mode 100644 java/com/android/dialer/main/impl/res/values-sr/strings.xml create mode 100644 java/com/android/dialer/main/impl/res/values-sv/strings.xml create mode 100644 java/com/android/dialer/main/impl/res/values-sw/strings.xml create mode 100644 java/com/android/dialer/main/impl/res/values-ta/strings.xml create mode 100644 java/com/android/dialer/main/impl/res/values-te/strings.xml create mode 100644 java/com/android/dialer/main/impl/res/values-th/strings.xml create mode 100644 java/com/android/dialer/main/impl/res/values-tl/strings.xml create mode 100644 java/com/android/dialer/main/impl/res/values-tr/strings.xml create mode 100644 java/com/android/dialer/main/impl/res/values-uk/strings.xml create mode 100644 java/com/android/dialer/main/impl/res/values-ur/strings.xml create mode 100644 java/com/android/dialer/main/impl/res/values-uz/strings.xml create mode 100644 java/com/android/dialer/main/impl/res/values-vi/strings.xml create mode 100644 java/com/android/dialer/main/impl/res/values-zh-rCN/strings.xml create mode 100644 java/com/android/dialer/main/impl/res/values-zh-rHK/strings.xml create mode 100644 java/com/android/dialer/main/impl/res/values-zh-rTW/strings.xml create mode 100644 java/com/android/dialer/main/impl/res/values-zu/strings.xml create mode 100644 java/com/android/dialer/main/impl/res/values/strings.xml create mode 100644 java/com/android/dialer/main/impl/res/values/styles.xml delete mode 100644 java/com/android/dialer/notification/GroupedNotificationUtil.java create mode 100644 java/com/android/dialer/notification/NotificationChannelId.java delete mode 100644 java/com/android/dialer/notification/PackageUpdatedReceiver.java create mode 100644 java/com/android/dialer/notification/VoicemailChannelUtils.java delete mode 100644 java/com/android/dialer/notification/res/values/ids.xml create mode 100644 java/com/android/dialer/performancereport/PerformanceReport.java create mode 100644 java/com/android/dialer/phonenumberproto/Converter.java create mode 100644 java/com/android/dialer/phonenumberproto/DialerPhoneNumberUtil.java create mode 100644 java/com/android/dialer/phonenumberproto/dialer_phone_number.proto delete mode 100644 java/com/android/dialer/searchfragment/AndroidManifest.xml delete mode 100644 java/com/android/dialer/searchfragment/NewSearchFragment.java delete mode 100644 java/com/android/dialer/searchfragment/QueryUtil.java delete mode 100644 java/com/android/dialer/searchfragment/SearchAdapter.java delete mode 100644 java/com/android/dialer/searchfragment/SearchContactCursor.java delete mode 100644 java/com/android/dialer/searchfragment/SearchContactViewHolder.java delete mode 100644 java/com/android/dialer/searchfragment/SearchContactsCursorLoader.java delete mode 100644 java/com/android/dialer/searchfragment/SearchCursorManager.java create mode 100644 java/com/android/dialer/searchfragment/common/AndroidManifest.xml create mode 100644 java/com/android/dialer/searchfragment/common/Projections.java create mode 100644 java/com/android/dialer/searchfragment/common/QueryBoldingUtil.java create mode 100644 java/com/android/dialer/searchfragment/common/QueryFilteringUtil.java create mode 100644 java/com/android/dialer/searchfragment/common/res/layout/search_contact_row.xml create mode 100644 java/com/android/dialer/searchfragment/common/res/values/dimens.xml create mode 100644 java/com/android/dialer/searchfragment/cp2/SearchContactCursor.java create mode 100644 java/com/android/dialer/searchfragment/cp2/SearchContactViewHolder.java create mode 100644 java/com/android/dialer/searchfragment/cp2/SearchContactsCursorLoader.java create mode 100644 java/com/android/dialer/searchfragment/list/AndroidManifest.xml create mode 100644 java/com/android/dialer/searchfragment/list/HeaderViewHolder.java create mode 100644 java/com/android/dialer/searchfragment/list/NewSearchFragment.java create mode 100644 java/com/android/dialer/searchfragment/list/SearchAdapter.java create mode 100644 java/com/android/dialer/searchfragment/list/SearchCursorManager.java create mode 100644 java/com/android/dialer/searchfragment/list/res/layout/fragment_search.xml create mode 100644 java/com/android/dialer/searchfragment/list/res/layout/header_layout.xml create mode 100644 java/com/android/dialer/searchfragment/nearbyplaces/AndroidManifest.xml create mode 100644 java/com/android/dialer/searchfragment/nearbyplaces/NearbyPlaceViewHolder.java create mode 100644 java/com/android/dialer/searchfragment/nearbyplaces/NearbyPlacesCursorLoader.java create mode 100644 java/com/android/dialer/searchfragment/nearbyplaces/res/values-af/strings.xml create mode 100644 java/com/android/dialer/searchfragment/nearbyplaces/res/values-am/strings.xml create mode 100644 java/com/android/dialer/searchfragment/nearbyplaces/res/values-ar/strings.xml create mode 100644 java/com/android/dialer/searchfragment/nearbyplaces/res/values-az/strings.xml create mode 100644 java/com/android/dialer/searchfragment/nearbyplaces/res/values-b+sr+Latn/strings.xml create mode 100644 java/com/android/dialer/searchfragment/nearbyplaces/res/values-be/strings.xml create mode 100644 java/com/android/dialer/searchfragment/nearbyplaces/res/values-bg/strings.xml create mode 100644 java/com/android/dialer/searchfragment/nearbyplaces/res/values-bn/strings.xml create mode 100644 java/com/android/dialer/searchfragment/nearbyplaces/res/values-bs/strings.xml create mode 100644 java/com/android/dialer/searchfragment/nearbyplaces/res/values-ca/strings.xml create mode 100644 java/com/android/dialer/searchfragment/nearbyplaces/res/values-cs/strings.xml create mode 100644 java/com/android/dialer/searchfragment/nearbyplaces/res/values-da/strings.xml create mode 100644 java/com/android/dialer/searchfragment/nearbyplaces/res/values-de/strings.xml create mode 100644 java/com/android/dialer/searchfragment/nearbyplaces/res/values-el/strings.xml create mode 100644 java/com/android/dialer/searchfragment/nearbyplaces/res/values-en-rAU/strings.xml create mode 100644 java/com/android/dialer/searchfragment/nearbyplaces/res/values-en-rGB/strings.xml create mode 100644 java/com/android/dialer/searchfragment/nearbyplaces/res/values-en-rIN/strings.xml create mode 100644 java/com/android/dialer/searchfragment/nearbyplaces/res/values-es-rUS/strings.xml create mode 100644 java/com/android/dialer/searchfragment/nearbyplaces/res/values-es/strings.xml create mode 100644 java/com/android/dialer/searchfragment/nearbyplaces/res/values-et/strings.xml create mode 100644 java/com/android/dialer/searchfragment/nearbyplaces/res/values-eu/strings.xml create mode 100644 java/com/android/dialer/searchfragment/nearbyplaces/res/values-fa/strings.xml create mode 100644 java/com/android/dialer/searchfragment/nearbyplaces/res/values-fi/strings.xml create mode 100644 java/com/android/dialer/searchfragment/nearbyplaces/res/values-fr-rCA/strings.xml create mode 100644 java/com/android/dialer/searchfragment/nearbyplaces/res/values-fr/strings.xml create mode 100644 java/com/android/dialer/searchfragment/nearbyplaces/res/values-gl/strings.xml create mode 100644 java/com/android/dialer/searchfragment/nearbyplaces/res/values-gu/strings.xml create mode 100644 java/com/android/dialer/searchfragment/nearbyplaces/res/values-hi/strings.xml create mode 100644 java/com/android/dialer/searchfragment/nearbyplaces/res/values-hr/strings.xml create mode 100644 java/com/android/dialer/searchfragment/nearbyplaces/res/values-hu/strings.xml create mode 100644 java/com/android/dialer/searchfragment/nearbyplaces/res/values-hy/strings.xml create mode 100644 java/com/android/dialer/searchfragment/nearbyplaces/res/values-in/strings.xml create mode 100644 java/com/android/dialer/searchfragment/nearbyplaces/res/values-is/strings.xml create mode 100644 java/com/android/dialer/searchfragment/nearbyplaces/res/values-it/strings.xml create mode 100644 java/com/android/dialer/searchfragment/nearbyplaces/res/values-iw/strings.xml create mode 100644 java/com/android/dialer/searchfragment/nearbyplaces/res/values-ja/strings.xml create mode 100644 java/com/android/dialer/searchfragment/nearbyplaces/res/values-ka/strings.xml create mode 100644 java/com/android/dialer/searchfragment/nearbyplaces/res/values-kk/strings.xml create mode 100644 java/com/android/dialer/searchfragment/nearbyplaces/res/values-km/strings.xml create mode 100644 java/com/android/dialer/searchfragment/nearbyplaces/res/values-kn/strings.xml create mode 100644 java/com/android/dialer/searchfragment/nearbyplaces/res/values-ko/strings.xml create mode 100644 java/com/android/dialer/searchfragment/nearbyplaces/res/values-ky/strings.xml create mode 100644 java/com/android/dialer/searchfragment/nearbyplaces/res/values-lo/strings.xml create mode 100644 java/com/android/dialer/searchfragment/nearbyplaces/res/values-lt/strings.xml create mode 100644 java/com/android/dialer/searchfragment/nearbyplaces/res/values-lv/strings.xml create mode 100644 java/com/android/dialer/searchfragment/nearbyplaces/res/values-mk/strings.xml create mode 100644 java/com/android/dialer/searchfragment/nearbyplaces/res/values-ml/strings.xml create mode 100644 java/com/android/dialer/searchfragment/nearbyplaces/res/values-mn/strings.xml create mode 100644 java/com/android/dialer/searchfragment/nearbyplaces/res/values-mr/strings.xml create mode 100644 java/com/android/dialer/searchfragment/nearbyplaces/res/values-ms/strings.xml create mode 100644 java/com/android/dialer/searchfragment/nearbyplaces/res/values-my/strings.xml create mode 100644 java/com/android/dialer/searchfragment/nearbyplaces/res/values-nb/strings.xml create mode 100644 java/com/android/dialer/searchfragment/nearbyplaces/res/values-ne/strings.xml create mode 100644 java/com/android/dialer/searchfragment/nearbyplaces/res/values-nl/strings.xml create mode 100644 java/com/android/dialer/searchfragment/nearbyplaces/res/values-no/strings.xml create mode 100644 java/com/android/dialer/searchfragment/nearbyplaces/res/values-pa/strings.xml create mode 100644 java/com/android/dialer/searchfragment/nearbyplaces/res/values-pl/strings.xml create mode 100644 java/com/android/dialer/searchfragment/nearbyplaces/res/values-pt-rBR/strings.xml create mode 100644 java/com/android/dialer/searchfragment/nearbyplaces/res/values-pt-rPT/strings.xml create mode 100644 java/com/android/dialer/searchfragment/nearbyplaces/res/values-pt/strings.xml create mode 100644 java/com/android/dialer/searchfragment/nearbyplaces/res/values-ro/strings.xml create mode 100644 java/com/android/dialer/searchfragment/nearbyplaces/res/values-ru/strings.xml create mode 100644 java/com/android/dialer/searchfragment/nearbyplaces/res/values-si/strings.xml create mode 100644 java/com/android/dialer/searchfragment/nearbyplaces/res/values-sk/strings.xml create mode 100644 java/com/android/dialer/searchfragment/nearbyplaces/res/values-sl/strings.xml create mode 100644 java/com/android/dialer/searchfragment/nearbyplaces/res/values-sq/strings.xml create mode 100644 java/com/android/dialer/searchfragment/nearbyplaces/res/values-sr/strings.xml create mode 100644 java/com/android/dialer/searchfragment/nearbyplaces/res/values-sv/strings.xml create mode 100644 java/com/android/dialer/searchfragment/nearbyplaces/res/values-sw/strings.xml create mode 100644 java/com/android/dialer/searchfragment/nearbyplaces/res/values-ta/strings.xml create mode 100644 java/com/android/dialer/searchfragment/nearbyplaces/res/values-te/strings.xml create mode 100644 java/com/android/dialer/searchfragment/nearbyplaces/res/values-th/strings.xml create mode 100644 java/com/android/dialer/searchfragment/nearbyplaces/res/values-tl/strings.xml create mode 100644 java/com/android/dialer/searchfragment/nearbyplaces/res/values-tr/strings.xml create mode 100644 java/com/android/dialer/searchfragment/nearbyplaces/res/values-uk/strings.xml create mode 100644 java/com/android/dialer/searchfragment/nearbyplaces/res/values-ur/strings.xml create mode 100644 java/com/android/dialer/searchfragment/nearbyplaces/res/values-uz/strings.xml create mode 100644 java/com/android/dialer/searchfragment/nearbyplaces/res/values-vi/strings.xml create mode 100644 java/com/android/dialer/searchfragment/nearbyplaces/res/values-zh-rCN/strings.xml create mode 100644 java/com/android/dialer/searchfragment/nearbyplaces/res/values-zh-rHK/strings.xml create mode 100644 java/com/android/dialer/searchfragment/nearbyplaces/res/values-zh-rTW/strings.xml create mode 100644 java/com/android/dialer/searchfragment/nearbyplaces/res/values-zu/strings.xml create mode 100644 java/com/android/dialer/searchfragment/nearbyplaces/res/values/strings.xml delete mode 100644 java/com/android/dialer/searchfragment/res/layout/fragment_search.xml delete mode 100644 java/com/android/dialer/searchfragment/res/layout/search_contact_row.xml delete mode 100644 java/com/android/dialer/searchfragment/res/values/dimens.xml create mode 100644 java/com/android/dialer/widget/LockableViewPager.java create mode 100644 java/com/android/dialer/widget/res/layout-land/empty_content_view.xml create mode 100644 java/com/android/dialershared/bubble/g3doc/INTEGRATION.md create mode 100644 java/com/android/dialershared/bubble/g3doc/images/bubble_collapsed.png create mode 100644 java/com/android/dialershared/bubble/g3doc/images/bubble_expanded.png create mode 100644 java/com/android/dialershared/bubble/g3doc/images/bubble_state.png create mode 100644 java/com/android/dialershared/bubble/g3doc/images/bubble_text.png delete mode 100644 java/com/android/incallui/incall/impl/LockableViewPager.java delete mode 100644 java/com/android/incallui/res/anim/on_going_call.xml create mode 100644 java/com/android/incallui/res/drawable/on_going_call.xml delete mode 100644 java/com/android/incallui/res/values-mcc262-mnc01/strings.xml diff --git a/Android.mk b/Android.mk index c3b1094d4..48b12aacb 100644 --- a/Android.mk +++ b/Android.mk @@ -5,11 +5,12 @@ # the manifest files in java/com/android/incallui/calllocation/impl/ # and /java/com/android/incallui/maps/impl/ # * b/62417801 removed translation string variant: -# java/com/android/incallui/res/values-af-mcc262-mnc01/strings.xml +# $ find java/com/android/incallui/res/*mcc262*/strings.xml | xargs rm # * b/62343966 include manually generated GRPC service class: # $ protoc --plugin=protoc-gen-grpc-java=prebuilts/tools/common/m2/repository/io/grpc/protoc-gen-grpc-java/1.0.3/protoc-gen-grpc-java-1.0.3-linux-x86_64.exe \ # --grpc-java_out=lite:"packages/apps/Dialer/java/com/android/voicemail/impl/" \ -# --proto_path="packages/apps/Dialer/java/com/android/voicemail/impl/transcribe/grpc/" "packages/apps/Dialer/java/com/android/voicemail/impl/transcribe +# --proto_path="packages/apps/Dialer/java/com/android/voicemail/impl/transcribe/grpc/" "packages/apps/Dialer/java/com/android/voicemail/impl/transcribe/grpc/voicemail_transcription.proto" +# * b/62787062 / b/37077388 temporarily disable proguard with javac LOCAL_PATH:= $(call my-dir) include $(CLEAR_VARS) @@ -32,6 +33,7 @@ SRC_DIRS := \ # Exclude files incompatible with AOSP. EXCLUDE_FILES := \ + $(BASE_DIR)/dialer/calllog/testing/FakeCallLogApplication.java \ $(BASE_DIR)/incallui/calllocation/impl/AuthException.java \ $(BASE_DIR)/incallui/calllocation/impl/CallLocationImpl.java \ $(BASE_DIR)/incallui/calllocation/impl/CallLocationModule.java \ @@ -73,11 +75,14 @@ RES_DIRS := \ $(BASE_DIR)/dialer/contactsfragment/res \ $(BASE_DIR)/dialer/dialpadview/res \ $(BASE_DIR)/dialer/interactions/res \ + $(BASE_DIR)/dialer/main/impl/res \ $(BASE_DIR)/dialer/notification/res \ $(BASE_DIR)/dialer/oem/res \ $(BASE_DIR)/dialer/phonenumberutil/res \ $(BASE_DIR)/dialer/postcall/res \ - $(BASE_DIR)/dialer/searchfragment/res \ + $(BASE_DIR)/dialer/searchfragment/list/res \ + $(BASE_DIR)/dialer/searchfragment/nearbyplaces/res \ + $(BASE_DIR)/dialer/searchfragment/common/res \ $(BASE_DIR)/dialer/shortcuts/res \ $(BASE_DIR)/dialer/speeddial/res \ $(BASE_DIR)/dialer/theme/res \ @@ -128,11 +133,14 @@ DIALER_MANIFEST_FILES += \ $(BASE_DIR)/dialer/contactsfragment/AndroidManifest.xml \ $(BASE_DIR)/dialer/dialpadview/AndroidManifest.xml \ $(BASE_DIR)/dialer/interactions/AndroidManifest.xml \ + $(BASE_DIR)/dialer/main/impl/AndroidManifest.xml \ $(BASE_DIR)/dialer/notification/AndroidManifest.xml \ $(BASE_DIR)/dialer/oem/AndroidManifest.xml \ $(BASE_DIR)/dialer/phonenumberutil/AndroidManifest.xml \ $(BASE_DIR)/dialer/postcall/AndroidManifest.xml \ - $(BASE_DIR)/dialer/searchfragment/AndroidManifest.xml \ + $(BASE_DIR)/dialer/searchfragment/list/AndroidManifest.xml \ + $(BASE_DIR)/dialer/searchfragment/nearbyplaces/AndroidManifest.xml \ + $(BASE_DIR)/dialer/searchfragment/common/AndroidManifest.xml \ $(BASE_DIR)/dialer/shortcuts/AndroidManifest.xml \ $(BASE_DIR)/dialer/simulator/impl/AndroidManifest.xml \ $(BASE_DIR)/dialer/speeddial/AndroidManifest.xml \ @@ -199,11 +207,14 @@ LOCAL_AAPT_FLAGS := \ --extra-packages com.android.dialer.contactsfragment \ --extra-packages com.android.dialer.dialpadview \ --extra-packages com.android.dialer.interactions \ + --extra-packages com.android.dialer.main.impl \ --extra-packages com.android.dialer.notification \ --extra-packages com.android.dialer.oem \ --extra-packages com.android.dialer.phonenumberutil \ --extra-packages com.android.dialer.postcall \ - --extra-packages com.android.dialer.searchfragment \ + --extra-packages com.android.dialer.searchfragment.list \ + --extra-packages com.android.dialer.searchfragment.nearbyplaces \ + --extra-packages com.android.dialer.searchfragment.common \ --extra-packages com.android.dialer.shortcuts \ --extra-packages com.android.dialer.speeddial \ --extra-packages com.android.dialer.theme \ @@ -276,11 +287,6 @@ LOCAL_STATIC_ANDROID_LIBRARIES := \ LOCAL_JAVA_LIBRARIES := \ org.apache.http.legacy \ dialer-auto-value \ - dialer-grpc-all \ - dialer-grpc-core \ - dialer-grpc-okhttp \ - dialer-grpc-protobuf-lite \ - dialer-grpc-stub \ # Libraries needed by the compiler (JACK) to generate code. PROCESSOR_LIBRARIES_TARGET := \ @@ -300,6 +306,13 @@ LOCAL_ADDITIONAL_DEPENDENCIES += $(PROCESSOR_JARS) LOCAL_JACK_FLAGS += --processorpath $(call normalize-path-list,$(PROCESSOR_JARS)) LOCAL_JAVACFLAGS += -processorpath $(call normalize-path-list,$(PROCESSOR_JARS)) + +# Begin Bug: 37077388 +LOCAL_DX_FLAGS := --core-library --multi-dex +LOCAL_JACK_FLAGS := --multi-dex native + +LOCAL_PROGUARD_ENABLED := disabled +ifdef LOCAL_JACK_ENABLED # Proguard includes LOCAL_PROGUARD_FLAG_FILES := \ java/com/android/dialer/common/proguard.flags \ @@ -309,11 +322,11 @@ LOCAL_PROGUARD_FLAG_FILES := \ java/com/android/incallui/answer/impl/proguard.flags LOCAL_PROGUARD_ENABLED := custom -ifdef LOCAL_JACK_ENABLED -# Bug: 37077388 LOCAL_PROGUARD_ENABLED += optimization endif +# End Bug: 37077388 + LOCAL_SDK_VERSION := system_current LOCAL_MODULE_TAGS := optional LOCAL_PACKAGE_NAME := Dialer @@ -517,3 +530,4 @@ LOCAL_UNINSTALLABLE_MODULE := true include $(BUILD_PREBUILT) include $(CLEAR_VARS) + diff --git a/AndroidManifest.xml b/AndroidManifest.xml index 7966a55a4..8dc9f6bb9 100644 --- a/AndroidManifest.xml +++ b/AndroidManifest.xml @@ -55,6 +55,7 @@ + 14sp - 2dp + 0dp 16dp 2dp 0dp diff --git a/java/com/android/contacts/common/res/values/strings.xml b/java/com/android/contacts/common/res/values/strings.xml index 371d5b424..85866f736 100644 --- a/java/com/android/contacts/common/res/values/strings.xml +++ b/java/com/android/contacts/common/res/values/strings.xml @@ -143,6 +143,9 @@ Contacts + + Top Suggested + Other @@ -155,6 +158,9 @@ All contacts + + Suggestions + Me diff --git a/java/com/android/dialer/app/Bindings.java b/java/com/android/dialer/app/Bindings.java index 2beb40184..c8cf27eb2 100644 --- a/java/com/android/dialer/app/Bindings.java +++ b/java/com/android/dialer/app/Bindings.java @@ -17,9 +17,6 @@ package com.android.dialer.app; import android.content.Context; -import com.android.dialer.app.bindings.DialerBindings; -import com.android.dialer.app.bindings.DialerBindingsFactory; -import com.android.dialer.app.bindings.DialerBindingsStub; import com.android.dialer.app.legacybindings.DialerLegacyBindings; import com.android.dialer.app.legacybindings.DialerLegacyBindingsFactory; import com.android.dialer.app.legacybindings.DialerLegacyBindingsStub; @@ -28,28 +25,10 @@ import java.util.Objects; /** Accessor for the in call UI bindings. */ public class Bindings { - private static DialerBindings instance; private static DialerLegacyBindings legacyInstance; private Bindings() {} - public static DialerBindings get(Context context) { - Objects.requireNonNull(context); - if (instance != null) { - return instance; - } - - Context application = context.getApplicationContext(); - if (application instanceof DialerBindingsFactory) { - instance = ((DialerBindingsFactory) application).newDialerBindings(); - } - - if (instance == null) { - instance = new DialerBindingsStub(); - } - return instance; - } - public static DialerLegacyBindings getLegacy(Context context) { Objects.requireNonNull(context); if (legacyInstance != null) { @@ -67,11 +46,4 @@ public class Bindings { return legacyInstance; } - public static void setForTesting(DialerBindings testInstance) { - instance = testInstance; - } - - public static void setLegacyBindingForTesting(DialerLegacyBindings testLegacyInstance) { - legacyInstance = testLegacyInstance; - } } diff --git a/java/com/android/dialer/app/DialtactsActivity.java b/java/com/android/dialer/app/DialtactsActivity.java index b5e615075..527dbff18 100644 --- a/java/com/android/dialer/app/DialtactsActivity.java +++ b/java/com/android/dialer/app/DialtactsActivity.java @@ -71,10 +71,12 @@ import com.android.contacts.common.widget.FloatingActionButtonController; import com.android.dialer.animation.AnimUtils; import com.android.dialer.animation.AnimationListenerAdapter; import com.android.dialer.app.calllog.CallLogActivity; +import com.android.dialer.app.calllog.CallLogAdapter; import com.android.dialer.app.calllog.CallLogFragment; import com.android.dialer.app.calllog.CallLogNotificationsService; import com.android.dialer.app.dialpad.DialpadFragment; import com.android.dialer.app.list.DialtactsPagerAdapter; +import com.android.dialer.app.list.DialtactsPagerAdapter.TabIndex; import com.android.dialer.app.list.DragDropController; import com.android.dialer.app.list.ListsFragment; import com.android.dialer.app.list.OldSpeedDialFragment; @@ -91,8 +93,8 @@ import com.android.dialer.callcomposer.CallComposerActivity; import com.android.dialer.callintent.CallIntentBuilder; import com.android.dialer.callintent.CallSpecificAppData; import com.android.dialer.common.Assert; -import com.android.dialer.common.ConfigProviderBindings; import com.android.dialer.common.LogUtil; +import com.android.dialer.configprovider.ConfigProviderBindings; import com.android.dialer.database.Database; import com.android.dialer.database.DialerDatabaseHelper; import com.android.dialer.interactions.PhoneNumberInteraction; @@ -100,21 +102,24 @@ import com.android.dialer.interactions.PhoneNumberInteraction.InteractionErrorCo import com.android.dialer.logging.DialerImpression; import com.android.dialer.logging.Logger; import com.android.dialer.logging.ScreenEvent; +import com.android.dialer.logging.UiAction; +import com.android.dialer.main.Main; +import com.android.dialer.main.MainComponent; import com.android.dialer.p13n.inference.P13nRanking; import com.android.dialer.p13n.inference.protocol.P13nRanker; import com.android.dialer.p13n.inference.protocol.P13nRanker.P13nRefreshCompleteListener; import com.android.dialer.p13n.logging.P13nLogger; import com.android.dialer.p13n.logging.P13nLogging; +import com.android.dialer.performancereport.PerformanceReport; import com.android.dialer.postcall.PostCall; import com.android.dialer.proguard.UsedByReflection; -import com.android.dialer.searchfragment.NewSearchFragment; +import com.android.dialer.searchfragment.list.NewSearchFragment; import com.android.dialer.simulator.Simulator; import com.android.dialer.simulator.SimulatorComponent; import com.android.dialer.smartdial.SmartDialNameMatcher; import com.android.dialer.smartdial.SmartDialPrefix; import com.android.dialer.telecom.TelecomUtil; import com.android.dialer.util.DialerUtils; -import com.android.dialer.util.IntentUtil; import com.android.dialer.util.PermissionsUtil; import com.android.dialer.util.TouchPointManager; import com.android.dialer.util.TransactionSafeActivity; @@ -132,6 +137,7 @@ public class DialtactsActivity extends TransactionSafeActivity DialpadFragment.OnDialpadQueryChangedListener, OnListFragmentScrolledListener, CallLogFragment.HostInterface, + CallLogAdapter.OnActionModeStateChangedListener, DialpadFragment.HostInterface, OldSpeedDialFragment.HostInterface, SearchFragment.HostInterface, @@ -149,6 +155,7 @@ public class DialtactsActivity extends TransactionSafeActivity private static final String ACTION_SHOW_TAB = "ACTION_SHOW_TAB"; @VisibleForTesting public static final String EXTRA_SHOW_TAB = "EXTRA_SHOW_TAB"; public static final String EXTRA_CLEAR_NEW_VOICEMAILS = "EXTRA_CLEAR_NEW_VOICEMAILS"; + private static final String KEY_LAST_TAB = "last_tab"; private static final String TAG = "DialtactsActivity"; private static final String KEY_IN_REGULAR_SEARCH_UI = "in_regular_search_ui"; private static final String KEY_IN_DIALPAD_SEARCH_UI = "in_dialpad_search_ui"; @@ -232,6 +239,9 @@ public class DialtactsActivity extends TransactionSafeActivity private P13nLogger mP13nLogger; private P13nRanker mP13nRanker; + public boolean isMultiSelectModeEnabled; + + private boolean isLastTabEnabled; AnimationListenerAdapter mSlideInListener = new AnimationListenerAdapter() { @@ -263,6 +273,11 @@ public class DialtactsActivity extends TransactionSafeActivity // no need to do anything here. return; } + + if (count != 0) { + PerformanceReport.recordClick(UiAction.Type.TEXT_CHANGE_WITH_INPUT); + } + if (DEBUG) { LogUtil.v("DialtactsActivity.onTextChanged", "called with new query: " + newText); LogUtil.v("DialtactsActivity.onTextChanged", "previous query: " + mSearchQuery); @@ -299,6 +314,7 @@ public class DialtactsActivity extends TransactionSafeActivity @Override public void onClick(View v) { if (!isInSearchUi()) { + PerformanceReport.recordClick(UiAction.Type.OPEN_SEARCH); mActionBarController.onSearchBoxTapped(); enterSearchUi( false /* smartDialSearch */, mSearchView.getText().toString(), true /* animate */); @@ -316,9 +332,13 @@ public class DialtactsActivity extends TransactionSafeActivity if (keyCode == KeyEvent.KEYCODE_BACK && event.getAction() == KeyEvent.ACTION_DOWN) { if (TextUtils.isEmpty(mSearchView.getText().toString())) { // If the search term is empty, close the search UI. + PerformanceReport.recordClick(UiAction.Type.CLOSE_SEARCH_WITH_HIDE_BUTTON); maybeExitSearchUi(); } else { // If the search term is not empty, show the dialpad fab. + if (!mFloatingActionButtonController.isVisible()) { + PerformanceReport.recordClick(UiAction.Type.HIDE_KEYBOARD_IN_SEARCH); + } showFabInSearchUi(); } } @@ -365,6 +385,7 @@ public class DialtactsActivity extends TransactionSafeActivity super.onCreate(savedInstanceState); mFirstLaunch = true; + isLastTabEnabled = ConfigProviderBindings.get(this).getBoolean("last_tab_enabled", false); final Resources resources = getResources(); mActionBarHeight = resources.getDimensionPixelSize(R.dimen.action_bar_height_large); @@ -490,6 +511,13 @@ public class DialtactsActivity extends TransactionSafeActivity Trace.beginSection(TAG + " onResume"); super.onResume(); + // Some calls may not be recorded (eg. from quick contact), + // so we should restart recording after these calls. (Recorded call is stopped) + PostCall.restartPerformanceRecordingIfARecentCallExist(this); + if (!PerformanceReport.isRecording()) { + PerformanceReport.startRecording(); + } + mStateSaved = false; if (mFirstLaunch) { displayFragment(getIntent()); @@ -552,7 +580,8 @@ public class DialtactsActivity extends TransactionSafeActivity } if (getIntent().getBooleanExtra(EXTRA_CLEAR_NEW_VOICEMAILS, false)) { - CallLogNotificationsService.markNewVoicemailsAsOld(this, null); + LogUtil.i("DialtactsActivity.onResume", "clearing all new voicemails"); + CallLogNotificationsService.markAllNewVoicemailsAsOld(this); } } @@ -603,6 +632,10 @@ public class DialtactsActivity extends TransactionSafeActivity && !getSystemService(KeyguardManager.class).isKeyguardLocked()) { mListsFragment.markMissedCallsAsReadAndRemoveNotifications(); } + DialerUtils.getDefaultSharedPreferenceForDeviceProtectedStorageContext(this) + .edit() + .putInt(KEY_LAST_TAB, mListsFragment.getCurrentTabIndex()) + .apply(); } @Override @@ -676,13 +709,8 @@ public class DialtactsActivity extends TransactionSafeActivity public void onClick(View view) { int resId = view.getId(); if (resId == R.id.floating_action_button) { - if (mListsFragment.getCurrentTabIndex() == DialtactsPagerAdapter.TAB_INDEX_ALL_CONTACTS - && !mInRegularSearch - && !mInDialpadSearch) { - DialerUtils.startActivityWithErrorToast( - this, IntentUtil.getNewContactIntent(), R.string.add_contact_not_available); - Logger.get(this).logImpression(DialerImpression.Type.NEW_CONTACT_FAB); - } else if (!mIsDialpadShown) { + if (!mIsDialpadShown) { + PerformanceReport.recordClick(UiAction.Type.OPEN_DIALPAD); mInCallDialpadUp = false; showDialpadFragment(true); PostCall.closePrompt(); @@ -712,6 +740,7 @@ public class DialtactsActivity extends TransactionSafeActivity int resId = item.getItemId(); if (resId == R.id.menu_history) { + PerformanceReport.recordClick(UiAction.Type.OPEN_CALL_HISTORY); final Intent intent = new Intent(this, CallLogActivity.class); startActivity(intent); } else if (resId == R.id.menu_clear_frequents) { @@ -722,6 +751,9 @@ public class DialtactsActivity extends TransactionSafeActivity handleMenuSettings(); Logger.get(this).logScreenView(ScreenEvent.Type.SETTINGS, this); return true; + } else if (resId == R.id.menu_new_ui_launcher_shortcut) { + MainComponent.get(this).getMain().createNewUiLauncherShortcut(this); + return true; } return false; } @@ -1020,6 +1052,16 @@ public class DialtactsActivity extends TransactionSafeActivity if (showDialpadChooser && !mDialpadFragment.isVisible()) { mInCallDialpadUp = true; } + } else if (isLastTabEnabled) { + @TabIndex + int tabIndex = + DialerUtils.getDefaultSharedPreferenceForDeviceProtectedStorageContext(this) + .getInt(KEY_LAST_TAB, DialtactsPagerAdapter.TAB_INDEX_SPEED_DIAL); + // If voicemail tab is saved and its availability changes, we still move to the voicemail tab + // but it is quickly removed and shown the contacts tab. + if (mListsFragment != null) { + mListsFragment.showTab(tabIndex); + } } } @@ -1195,6 +1237,8 @@ public class DialtactsActivity extends TransactionSafeActivity @Override public void onBackPressed() { + PerformanceReport.recordClick(UiAction.Type.PRESS_ANDROID_BACK_BUTTON); + if (mStateSaved) { return; } @@ -1279,6 +1323,7 @@ public class DialtactsActivity extends TransactionSafeActivity if (mInDialpadSearch && mSmartDialSearchFragment != null && !mSmartDialSearchFragment.isShowingPermissionRequest()) { + PerformanceReport.recordClick(UiAction.Type.CLOSE_DIALPAD); hideDialpadFragment(true /* animate */, true /* clearDialpad */); return true; } @@ -1287,6 +1332,7 @@ public class DialtactsActivity extends TransactionSafeActivity @Override public void onListFragmentScrollStateChange(int scrollState) { + PerformanceReport.recordScrollStateChange(scrollState); if (scrollState == OnScrollListener.SCROLL_STATE_TOUCH_SCROLL) { hideDialpadFragment(true, false); DialerUtils.hideInputMethod(mParentLayout); @@ -1413,18 +1459,6 @@ public class DialtactsActivity extends TransactionSafeActivity int tabIndex = mListsFragment.getCurrentTabIndex(); mPreviouslySelectedTabIndex = tabIndex; mFloatingActionButtonController.setVisible(true); - if (tabIndex == DialtactsPagerAdapter.TAB_INDEX_ALL_CONTACTS - && !mInRegularSearch - && !mInDialpadSearch) { - mFloatingActionButtonController.changeIcon( - getResources().getDrawable(R.drawable.quantum_ic_person_add_white_24, null), - getResources().getString(R.string.search_shortcut_create_new_contact)); - } else { - mFloatingActionButtonController.changeIcon( - getResources().getDrawable(R.drawable.quantum_ic_dialpad_white_24, null), - getResources().getString(R.string.action_menu_dialpad_button)); - } - timeTabSelected = SystemClock.elapsedRealtime(); } @@ -1509,6 +1543,16 @@ public class DialtactsActivity extends TransactionSafeActivity Arrays.toString(grantResults))); } + @Override + public void onActionModeStateChanged(boolean isEnabled) { + isMultiSelectModeEnabled = isEnabled; + } + + @Override + public boolean isActionModeStateEnabled() { + return isMultiSelectModeEnabled; + } + /** Popup menu accessible from the search bar */ protected class OptionsPopupMenu extends PopupMenu { @@ -1538,6 +1582,10 @@ public class DialtactsActivity extends TransactionSafeActivity simulatorMenuItem.setVisible(false); } + Main dialtacts = MainComponent.get(context).getMain(); + menu.findItem(R.id.menu_new_ui_launcher_shortcut) + .setVisible(dialtacts.isNewUiEnabled(context)); + super.show(); } } diff --git a/java/com/android/dialer/app/bindings/DialerBindings.java b/java/com/android/dialer/app/bindings/DialerBindings.java deleted file mode 100644 index e1f517860..000000000 --- a/java/com/android/dialer/app/bindings/DialerBindings.java +++ /dev/null @@ -1,25 +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.dialer.app.bindings; - -import com.android.dialer.common.ConfigProvider; - -/** This interface allows the container application to customize the dialer. */ -public interface DialerBindings { - - ConfigProvider getConfigProvider(); -} diff --git a/java/com/android/dialer/app/bindings/DialerBindingsFactory.java b/java/com/android/dialer/app/bindings/DialerBindingsFactory.java deleted file mode 100644 index 9f209f99e..000000000 --- a/java/com/android/dialer/app/bindings/DialerBindingsFactory.java +++ /dev/null @@ -1,26 +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.dialer.app.bindings; - -/** - * This interface should be implementated by the Application subclass. It allows the dialer module - * to get references to the DialerBindings. - */ -public interface DialerBindingsFactory { - - DialerBindings newDialerBindings(); -} diff --git a/java/com/android/dialer/app/bindings/DialerBindingsStub.java b/java/com/android/dialer/app/bindings/DialerBindingsStub.java deleted file mode 100644 index f56743fa5..000000000 --- a/java/com/android/dialer/app/bindings/DialerBindingsStub.java +++ /dev/null @@ -1,48 +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.dialer.app.bindings; - -import com.android.dialer.common.ConfigProvider; - -/** Default implementation for dialer bindings. */ -public class DialerBindingsStub implements DialerBindings { - private ConfigProvider configProvider; - - @Override - public ConfigProvider getConfigProvider() { - if (configProvider == null) { - configProvider = - new ConfigProvider() { - @Override - public String getString(String key, String defaultValue) { - return defaultValue; - } - - @Override - public long getLong(String key, long defaultValue) { - return defaultValue; - } - - @Override - public boolean getBoolean(String key, boolean defaultValue) { - return defaultValue; - } - }; - } - return configProvider; - } -} diff --git a/java/com/android/dialer/app/calllog/CallLogActivity.java b/java/com/android/dialer/app/calllog/CallLogActivity.java index 443171d3f..6433af9a6 100644 --- a/java/com/android/dialer/app/calllog/CallLogActivity.java +++ b/java/com/android/dialer/app/calllog/CallLogActivity.java @@ -34,6 +34,9 @@ import com.android.dialer.app.R; import com.android.dialer.database.CallLogQueryHandler; import com.android.dialer.logging.Logger; import com.android.dialer.logging.ScreenEvent; +import com.android.dialer.logging.UiAction; +import com.android.dialer.performancereport.PerformanceReport; +import com.android.dialer.postcall.PostCall; import com.android.dialer.util.TransactionSafeActivity; import com.android.dialer.util.ViewUtil; @@ -48,7 +51,6 @@ public class CallLogActivity extends TransactionSafeActivity private ViewPagerTabs mViewPagerTabs; private ViewPagerAdapter mViewPagerAdapter; private CallLogFragment mAllCallsFragment; - private CallLogFragment mMissedCallsFragment; private String[] mTabTitles; private boolean mIsResumed; @@ -93,9 +95,16 @@ public class CallLogActivity extends TransactionSafeActivity @Override protected void onResume() { + // Some calls may not be recorded (eg. from quick contact), + // so we should restart recording after these calls. (Recorded call is stopped) + PostCall.restartPerformanceRecordingIfARecentCallExist(this); + if (!PerformanceReport.isRecording()) { + PerformanceReport.startRecording(); + } + mIsResumed = true; super.onResume(); - sendScreenViewForChildFragment(mViewPager.getCurrentItem()); + sendScreenViewForChildFragment(); } @Override @@ -129,6 +138,7 @@ public class CallLogActivity extends TransactionSafeActivity } if (item.getItemId() == android.R.id.home) { + PerformanceReport.recordClick(UiAction.Type.CLOSE_CALL_HISTORY_WITH_CANCEL_BUTTON); final Intent intent = new Intent(this, DialtactsActivity.class); intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); startActivity(intent); @@ -148,7 +158,7 @@ public class CallLogActivity extends TransactionSafeActivity @Override public void onPageSelected(int position) { if (mIsResumed) { - sendScreenViewForChildFragment(position); + sendScreenViewForChildFragment(); } mViewPagerTabs.onPageSelected(position); } @@ -158,7 +168,7 @@ public class CallLogActivity extends TransactionSafeActivity mViewPagerTabs.onPageScrollStateChanged(state); } - private void sendScreenViewForChildFragment(int position) { + private void sendScreenViewForChildFragment() { Logger.get(this).logScreenView(ScreenEvent.Type.CALL_LOG_FILTER, this); } @@ -169,6 +179,12 @@ public class CallLogActivity extends TransactionSafeActivity return position; } + @Override + public void onBackPressed() { + PerformanceReport.recordClick(UiAction.Type.PRESS_ANDROID_BACK_BUTTON); + super.onBackPressed(); + } + /** Adapter for the view pager. */ public class ViewPagerAdapter extends FragmentPagerAdapter { @@ -189,20 +205,16 @@ public class CallLogActivity extends TransactionSafeActivity CallLogQueryHandler.CALL_TYPE_ALL, true /* isCallLogActivity */); case TAB_INDEX_MISSED: return new CallLogFragment(Calls.MISSED_TYPE, true /* isCallLogActivity */); + default: + throw new IllegalStateException("No fragment at position " + position); } - throw new IllegalStateException("No fragment at position " + position); } @Override public Object instantiateItem(ViewGroup container, int position) { final CallLogFragment fragment = (CallLogFragment) super.instantiateItem(container, position); - switch (position) { - case TAB_INDEX_ALL: + if (position == TAB_INDEX_ALL) { mAllCallsFragment = fragment; - break; - case TAB_INDEX_MISSED: - mMissedCallsFragment = fragment; - break; } return fragment; } diff --git a/java/com/android/dialer/app/calllog/CallLogAdapter.java b/java/com/android/dialer/app/calllog/CallLogAdapter.java index 3357ee2f1..f1d051a8c 100644 --- a/java/com/android/dialer/app/calllog/CallLogAdapter.java +++ b/java/com/android/dialer/app/calllog/CallLogAdapter.java @@ -19,6 +19,7 @@ package com.android.dialer.app.calllog; import android.app.Activity; import android.content.ContentUris; import android.content.DialogInterface; +import android.content.DialogInterface.OnCancelListener; import android.content.res.Resources; import android.database.Cursor; import android.net.Uri; @@ -52,7 +53,6 @@ import android.view.ViewGroup; import com.android.contacts.common.ContactsUtils; import com.android.contacts.common.compat.PhoneNumberUtilsCompat; import com.android.contacts.common.preference.ContactsPreferences; -import com.android.dialer.app.Bindings; import com.android.dialer.app.DialtactsActivity; import com.android.dialer.app.R; import com.android.dialer.app.calllog.CallLogGroupBuilder.GroupCreator; @@ -66,10 +66,10 @@ import com.android.dialer.calldetails.CallDetailsEntries.CallDetailsEntry; import com.android.dialer.calllogutils.PhoneAccountUtils; import com.android.dialer.calllogutils.PhoneCallDetails; import com.android.dialer.common.Assert; -import com.android.dialer.common.ConfigProviderBindings; import com.android.dialer.common.LogUtil; import com.android.dialer.common.concurrent.AsyncTaskExecutor; import com.android.dialer.common.concurrent.AsyncTaskExecutors; +import com.android.dialer.configprovider.ConfigProviderBindings; import com.android.dialer.enrichedcall.EnrichedCallCapabilities; import com.android.dialer.enrichedcall.EnrichedCallComponent; import com.android.dialer.enrichedcall.EnrichedCallManager; @@ -80,6 +80,8 @@ import com.android.dialer.lightbringer.LightbringerListener; import com.android.dialer.logging.ContactSource; import com.android.dialer.logging.DialerImpression; import com.android.dialer.logging.Logger; +import com.android.dialer.logging.UiAction; +import com.android.dialer.performancereport.PerformanceReport; import com.android.dialer.phonenumbercache.CallLogQuery; import com.android.dialer.phonenumbercache.ContactInfo; import com.android.dialer.phonenumbercache.ContactInfoHelper; @@ -119,6 +121,7 @@ public class CallLogAdapter extends GroupingListAdapter protected final CallLogCache mCallLogCache; private final CallFetcher mCallFetcher; + private final OnActionModeStateChangedListener mActionModeStateChangedListener; private final MultiSelectRemoveView mMultiSelectRemoveView; @NonNull private final FilteredNumberAsyncQueryHandler mFilteredNumberAsyncQueryHandler; private final int mActivityType; @@ -159,6 +162,7 @@ public class CallLogAdapter extends GroupingListAdapter MenuInflater inflater = mode.getMenuInflater(); inflater.inflate(R.menu.actionbar_delete, menu); mMultiSelectRemoveView.showMultiSelectRemoveView(true); + mActionModeStateChangedListener.onActionModeStateChanged(true); return true; } @@ -173,6 +177,7 @@ public class CallLogAdapter extends GroupingListAdapter @Override public boolean onActionItemClicked(ActionMode mode, MenuItem item) { if (item.getItemId() == R.id.action_bar_delete_menu_item) { + Logger.get(mActivity).logImpression(DialerImpression.Type.MULTISELECT_TAP_DELETE_ICON); if (selectedItems.size() > 0) { showDeleteSelectedItemsDialog(); } @@ -195,52 +200,68 @@ public class CallLogAdapter extends GroupingListAdapter selectAllMode = false; deselectAllMode = false; mMultiSelectRemoveView.showMultiSelectRemoveView(false); + mActionModeStateChangedListener.onActionModeStateChanged(false); notifyDataSetChanged(); } }; - // Todo (uabdullah): Use plurals http://b/37751831 private void showDeleteSelectedItemsDialog() { - AlertDialog.Builder builder = new AlertDialog.Builder(mActivity); - Assert.checkArgument(selectedItems.size() > 0); - String voicemailString = - selectedItems.size() == 1 - ? mActivity.getResources().getString(R.string.voicemailMultiSelectVoicemail) - : mActivity.getResources().getString(R.string.voicemailMultiSelectVoicemails); - String deleteVoicemailTitle = - mActivity - .getResources() - .getString(R.string.voicemailMultiSelectDialogTitle, voicemailString); SparseArray voicemailsToDeleteOnConfirmation = selectedItems.clone(); - builder.setTitle(deleteVoicemailTitle); - - builder.setPositiveButton( - mActivity.getResources().getString(R.string.voicemailMultiSelectDeleteConfirm), - new DialogInterface.OnClickListener() { - @Override - public void onClick(DialogInterface dialog, int id) { - deleteSelectedItems(voicemailsToDeleteOnConfirmation); - mActionMode.finish(); - dialog.cancel(); - } - }); - - builder.setNegativeButton( - mActivity.getResources().getString(R.string.voicemailMultiSelectDeleteCancel), - new DialogInterface.OnClickListener() { - @Override - public void onClick(DialogInterface dialog, int id) { - dialog.cancel(); - } - }); - - AlertDialog dialog = builder.create(); - dialog.show(); + new AlertDialog.Builder(mActivity, R.style.AlertDialogCustom) + .setCancelable(true) + .setTitle( + mActivity + .getResources() + .getQuantityString( + R.plurals.delete_voicemails_confirmation_dialog_title, selectedItems.size())) + .setPositiveButton( + R.string.voicemailMultiSelectDeleteConfirm, + new DialogInterface.OnClickListener() { + @Override + public void onClick(final DialogInterface dialog, final int button) { + LogUtil.i( + "CallLogAdapter.showDeleteSelectedItemsDialog", + "onClick, these items to delete " + voicemailsToDeleteOnConfirmation); + deleteSelectedItems(voicemailsToDeleteOnConfirmation); + mActionMode.finish(); + dialog.cancel(); + Logger.get(mActivity) + .logImpression( + DialerImpression.Type.MULTISELECT_DELETE_ENTRY_VIA_CONFIRMATION_DIALOG); + } + }) + .setOnCancelListener( + new OnCancelListener() { + @Override + public void onCancel(DialogInterface dialogInterface) { + Logger.get(mActivity) + .logImpression( + DialerImpression.Type + .MULTISELECT_CANCEL_CONFIRMATION_DIALOG_VIA_CANCEL_TOUCH); + dialogInterface.cancel(); + } + }) + .setNegativeButton( + R.string.voicemailMultiSelectDeleteCancel, + new DialogInterface.OnClickListener() { + @Override + public void onClick(final DialogInterface dialog, final int button) { + Logger.get(mActivity) + .logImpression( + DialerImpression.Type + .MULTISELECT_CANCEL_CONFIRMATION_DIALOG_VIA_CANCEL_BUTTON); + dialog.cancel(); + } + }) + .show(); + Logger.get(mActivity) + .logImpression(DialerImpression.Type.MULTISELECT_DISPLAY_DELETE_CONFIRMATION_DIALOG); } private void deleteSelectedItems(SparseArray voicemailsToDelete) { for (int i = 0; i < voicemailsToDelete.size(); i++) { String voicemailUri = voicemailsToDelete.get(voicemailsToDelete.keyAt(i)); + LogUtil.i("CallLogAdapter.deleteSelectedItems", "deleting uri:" + voicemailUri); CallLogAsyncTaskUtil.deleteVoicemail(mActivity, Uri.parse(voicemailUri), null); } } @@ -254,8 +275,13 @@ public class CallLogAdapter extends GroupingListAdapter && mVoicemailPlaybackPresenter != null) { if (v.getId() == R.id.primary_action_view || v.getId() == R.id.quick_contact_photo) { if (mActionMode == null) { + Logger.get(mActivity) + .logImpression( + DialerImpression.Type.MULTISELECT_LONG_PRESS_ENTER_MULTI_SELECT_MODE); mActionMode = v.startActionMode(mActionModeCallback); } + Logger.get(mActivity) + .logImpression(DialerImpression.Type.MULTISELECT_LONG_PRESS_TAP_ENTRY); CallLogListItemViewHolder viewHolder = (CallLogListItemViewHolder) v.getTag(); viewHolder.quickContactView.setVisibility(View.GONE); viewHolder.checkBoxView.setVisibility(View.VISIBLE); @@ -272,6 +298,8 @@ public class CallLogAdapter extends GroupingListAdapter new View.OnClickListener() { @Override public void onClick(View v) { + PerformanceReport.recordClick(UiAction.Type.CLICK_CALL_LOG_ITEM); + CallLogListItemViewHolder viewHolder = (CallLogListItemViewHolder) v.getTag(); if (viewHolder == null) { return; @@ -282,8 +310,12 @@ public class CallLogAdapter extends GroupingListAdapter mMultiSelectRemoveView.setSelectAllModeToFalse(); int id = getVoicemailId(viewHolder.voicemailUri); if (selectedItems.get(id) != null) { + Logger.get(mActivity) + .logImpression(DialerImpression.Type.MULTISELECT_SINGLE_PRESS_UNSELECT_ENTRY); uncheckMarkCallLogEntry(viewHolder, id); } else { + Logger.get(mActivity) + .logImpression(DialerImpression.Type.MULTISELECT_SINGLE_PRESS_SELECT_ENTRY); checkMarkCallLogEntry(viewHolder); } return; @@ -343,6 +375,8 @@ public class CallLogAdapter extends GroupingListAdapter private void updateActionBar() { if (mActionMode == null && selectedItems.size() > 0) { + Logger.get(mActivity) + .logImpression(DialerImpression.Type.MULTISELECT_ROTATE_AND_SHOW_ACTION_MODE); mActivity.startActionMode(mActionModeCallback); } if (mActionMode != null) { @@ -413,6 +447,7 @@ public class CallLogAdapter extends GroupingListAdapter ViewGroup alertContainer, CallFetcher callFetcher, MultiSelectRemoveView multiSelectRemoveView, + OnActionModeStateChangedListener actionModeStateChangedListener, CallLogCache callLogCache, ContactInfoCache contactInfoCache, VoicemailPlaybackPresenter voicemailPlaybackPresenter, @@ -422,6 +457,7 @@ public class CallLogAdapter extends GroupingListAdapter mActivity = activity; mCallFetcher = callFetcher; + mActionModeStateChangedListener = actionModeStateChangedListener; mMultiSelectRemoveView = multiSelectRemoveView; mVoicemailPlaybackPresenter = voicemailPlaybackPresenter; if (mVoicemailPlaybackPresenter != null) { @@ -484,12 +520,23 @@ public class CallLogAdapter extends GroupingListAdapter outState.putLong(KEY_EXPANDED_ROW_ID, mCurrentlyExpandedRowId); ArrayList listOfSelectedItems = new ArrayList<>(); + if (selectedItems.size() > 0) { for (int i = 0; i < selectedItems.size(); i++) { - listOfSelectedItems.add(Integer.toString(selectedItems.keyAt(i))); + int id = selectedItems.keyAt(i); + String voicemailUri = selectedItems.valueAt(i); + LogUtil.i( + "CallLogAdapter.onSaveInstanceState", "index %d, id=%d, uri=%s ", i, id, voicemailUri); + listOfSelectedItems.add(voicemailUri); } } outState.putStringArrayList(KEY_ACTION_MODE, listOfSelectedItems); + + LogUtil.i( + "CallLogAdapter.onSaveInstanceState", + "saved: %d, selectedItemsSize:%d", + listOfSelectedItems.size(), + selectedItems.size()); } public void onRestoreInstanceState(Bundle savedInstanceState) { @@ -498,16 +545,31 @@ public class CallLogAdapter extends GroupingListAdapter savedInstanceState.getInt(KEY_EXPANDED_POSITION, RecyclerView.NO_POSITION); mCurrentlyExpandedRowId = savedInstanceState.getLong(KEY_EXPANDED_ROW_ID, NO_EXPANDED_LIST_ITEM); - // Restoring multi selected entries ArrayList listOfSelectedItems = savedInstanceState.getStringArrayList(KEY_ACTION_MODE); + LogUtil.i( + "CallLogAdapter.onRestoreInstanceState", + "restored selectedItemsList:%d", + listOfSelectedItems.size()); + if (!listOfSelectedItems.isEmpty()) { for (int i = 0; i < listOfSelectedItems.size(); i++) { - String voicemailId = listOfSelectedItems.get(i); - int id = Integer.parseInt(voicemailId); - selectedItems.put(id, voicemailId); + String voicemailUri = listOfSelectedItems.get(i); + int id = getVoicemailId(voicemailUri); + LogUtil.i( + "CallLogAdapter.onRestoreInstanceState", + "restoring selected index %d, id=%d, uri=%s ", + i, + id, + voicemailUri); + selectedItems.put(id, voicemailUri); } + + LogUtil.i( + "CallLogAdapter.onRestoreInstance", + "restored selectedItems %s", + selectedItems.toString()); updateActionBar(); } } @@ -597,6 +659,7 @@ public class CallLogAdapter extends GroupingListAdapter mBlockReportSpamListener, mExpandCollapseListener, mLongPressListener, + mActionModeStateChangedListener, mCallLogCache, mCallLogListItemHelper, mVoicemailPlaybackPresenter); @@ -622,7 +685,7 @@ public class CallLogAdapter extends GroupingListAdapter Trace.beginSection("onBindViewHolder: " + position); switch (getItemViewType(position)) { case VIEW_TYPE_ALERT: - //Do nothing + // Do nothing break; default: bindCallLogListViewHolder(viewHolder, position); @@ -931,8 +994,7 @@ public class CallLogAdapter extends GroupingListAdapter details.countryIso, details.cachedContactInfo, position - < Bindings.get(mActivity) - .getConfigProvider() + < ConfigProviderBindings.get(mActivity) .getLong("number_of_call_to_do_remote_lookup", 5L)); } CharSequence formattedNumber = @@ -1318,6 +1380,14 @@ public class CallLogAdapter extends GroupingListAdapter void fetchCalls(); } + /** Interface used to allow single tap multi select for contact photos. */ + public interface OnActionModeStateChangedListener { + + void onActionModeStateChanged(boolean isEnabled); + + boolean isActionModeStateEnabled(); + } + /** Interface used to hide the fragments. */ public interface MultiSelectRemoveView { diff --git a/java/com/android/dialer/app/calllog/CallLogAsyncTaskUtil.java b/java/com/android/dialer/app/calllog/CallLogAsyncTaskUtil.java index a5553d134..10866aae2 100644 --- a/java/com/android/dialer/app/calllog/CallLogAsyncTaskUtil.java +++ b/java/com/android/dialer/app/calllog/CallLogAsyncTaskUtil.java @@ -28,6 +28,7 @@ import android.provider.VoicemailContract.Voicemails; import android.support.annotation.NonNull; import android.support.annotation.Nullable; import android.text.TextUtils; +import com.android.dialer.common.LogUtil; import com.android.dialer.common.concurrent.AsyncTaskExecutor; import com.android.dialer.common.concurrent.AsyncTaskExecutors; import com.android.dialer.util.PermissionsUtil; @@ -45,6 +46,7 @@ public class CallLogAsyncTaskUtil { public static void markVoicemailAsRead( @NonNull final Context context, @NonNull final Uri voicemailUri) { + LogUtil.enterBlock("CallLogAsyncTaskUtil.markVoicemailAsRead, voicemailUri: " + voicemailUri); if (sAsyncTaskExecutor == null) { initTaskExecutor(); } @@ -66,9 +68,7 @@ public class CallLogAsyncTaskUtil { uploadVoicemailLocalChangesToServer(context); } - Intent intent = new Intent(context, CallLogNotificationsService.class); - intent.setAction(CallLogNotificationsService.ACTION_MARK_NEW_VOICEMAILS_AS_OLD); - context.startService(intent); + CallLogNotificationsService.markAllNewVoicemailsAsOld(context); return null; } }); diff --git a/java/com/android/dialer/app/calllog/CallLogFragment.java b/java/com/android/dialer/app/calllog/CallLogFragment.java index 1571c1aef..b03a4ad64 100644 --- a/java/com/android/dialer/app/calllog/CallLogFragment.java +++ b/java/com/android/dialer/app/calllog/CallLogFragment.java @@ -35,14 +35,20 @@ import android.provider.ContactsContract; import android.support.annotation.CallSuper; import android.support.annotation.Nullable; import android.support.v13.app.FragmentCompat; +import android.support.v13.app.FragmentCompat.OnRequestPermissionsResultCallback; import android.support.v7.app.AppCompatActivity; import android.support.v7.widget.LinearLayoutManager; import android.support.v7.widget.RecyclerView; import android.view.LayoutInflater; import android.view.View; +import android.view.View.OnClickListener; import android.view.ViewGroup; +import android.widget.ImageView; +import android.widget.TextView; import com.android.dialer.app.Bindings; import com.android.dialer.app.R; +import com.android.dialer.app.calllog.CallLogAdapter.CallFetcher; +import com.android.dialer.app.calllog.CallLogAdapter.MultiSelectRemoveView; import com.android.dialer.app.calllog.calllogcache.CallLogCache; import com.android.dialer.app.contactinfo.ContactInfoCache; import com.android.dialer.app.contactinfo.ContactInfoCache.OnContactInfoChangedListener; @@ -53,37 +59,44 @@ import com.android.dialer.blocking.FilteredNumberAsyncQueryHandler; import com.android.dialer.common.Assert; import com.android.dialer.common.LogUtil; import com.android.dialer.database.CallLogQueryHandler; +import com.android.dialer.database.CallLogQueryHandler.Listener; import com.android.dialer.location.GeoUtil; +import com.android.dialer.logging.DialerImpression; +import com.android.dialer.logging.Logger; import com.android.dialer.oem.CequintCallerIdManager; +import com.android.dialer.performancereport.PerformanceReport; import com.android.dialer.phonenumbercache.ContactInfoHelper; import com.android.dialer.util.PermissionsUtil; import com.android.dialer.widget.EmptyContentView; import com.android.dialer.widget.EmptyContentView.OnEmptyViewActionButtonClickedListener; +import java.util.Arrays; /** * Displays a list of call log entries. To filter for a particular kind of call (all, missed or * voicemails), specify it in the constructor. */ public class CallLogFragment extends Fragment - implements CallLogQueryHandler.Listener, - CallLogAdapter.CallFetcher, - CallLogAdapter.MultiSelectRemoveView, + implements Listener, + CallFetcher, + MultiSelectRemoveView, OnEmptyViewActionButtonClickedListener, - FragmentCompat.OnRequestPermissionsResultCallback, - CallLogModalAlertManager.Listener { + OnRequestPermissionsResultCallback, + CallLogModalAlertManager.Listener, + OnClickListener { private static final String KEY_FILTER_TYPE = "filter_type"; private static final String KEY_LOG_LIMIT = "log_limit"; private static final String KEY_DATE_LIMIT = "date_limit"; private static final String KEY_IS_CALL_LOG_ACTIVITY = "is_call_log_activity"; private static final String KEY_HAS_READ_CALL_LOG_PERMISSION = "has_read_call_log_permission"; private static final String KEY_REFRESH_DATA_REQUIRED = "refresh_data_required"; + private static final String KEY_SELECT_ALL_MODE = "select_all_mode_checked"; // No limit specified for the number of logs to show; use the CallLogQueryHandler's default. private static final int NO_LOG_LIMIT = -1; // No date-based filtering. private static final int NO_DATE_LIMIT = 0; - private static final int READ_CALL_LOG_PERMISSION_REQUEST_CODE = 1; + private static final int PHONE_PERMISSIONS_REQUEST_CODE = 1; private static final int EVENT_UPDATE_DISPLAY = 1; @@ -92,6 +105,9 @@ public class CallLogFragment extends Fragment // See issue 6363009 private final ContentObserver mCallLogObserver = new CustomContentObserver(); private final ContentObserver mContactsObserver = new CustomContentObserver(); + private View mMultiSelectUnSelectAllViewContent; + private TextView mSelectUnselectAllViewText; + private ImageView mSelectUnselectAllIcon; private RecyclerView mRecyclerView; private LinearLayoutManager mLayoutManager; private CallLogAdapter mAdapter; @@ -125,6 +141,7 @@ public class CallLogFragment extends Fragment * True if this instance of the CallLogFragment shown in the CallLogActivity. */ private boolean mIsCallLogActivity = false; + private boolean selectAllMode; private final Handler mDisplayUpdateHandler = new Handler() { @Override @@ -196,6 +213,7 @@ public class CallLogFragment extends Fragment mIsCallLogActivity = state.getBoolean(KEY_IS_CALL_LOG_ACTIVITY, mIsCallLogActivity); mHasReadCallLogPermission = state.getBoolean(KEY_HAS_READ_CALL_LOG_PERMISSION, false); mRefreshDataRequired = state.getBoolean(KEY_REFRESH_DATA_REQUIRED, mRefreshDataRequired); + selectAllMode = state.getBoolean(KEY_SELECT_ALL_MODE, false); } final Activity activity = getActivity(); @@ -292,12 +310,20 @@ public class CallLogFragment extends Fragment mRecyclerView.setHasFixedSize(true); mLayoutManager = new LinearLayoutManager(getActivity()); mRecyclerView.setLayoutManager(mLayoutManager); + PerformanceReport.logOnScrollStateChange(mRecyclerView); mEmptyListView = (EmptyContentView) view.findViewById(R.id.empty_list_view); mEmptyListView.setImage(R.drawable.empty_call_log); mEmptyListView.setActionClickedListener(this); mModalAlertView = (ViewGroup) view.findViewById(R.id.modal_message_container); mModalAlertManager = new CallLogModalAlertManager(LayoutInflater.from(getContext()), mModalAlertView, this); + mMultiSelectUnSelectAllViewContent = + view.findViewById(R.id.multi_select_select_all_view_content); + mSelectUnselectAllViewText = (TextView) view.findViewById(R.id.select_all_view_text); + mSelectUnselectAllIcon = (ImageView) view.findViewById(R.id.select_all_view_icon); + mMultiSelectUnSelectAllViewContent.setOnClickListener(null); + mSelectUnselectAllIcon.setOnClickListener(this); + mSelectUnselectAllViewText.setOnClickListener(this); } protected void setupData() { @@ -320,6 +346,9 @@ public class CallLogFragment extends Fragment mRecyclerView, this, this, + activityType == CallLogAdapter.ACTIVITY_TYPE_DIALTACTS + ? (CallLogAdapter.OnActionModeStateChangedListener) getActivity() + : null, CallLogCache.getCallLogCache(getActivity()), mContactInfoCache, getVoicemailPlaybackPresenter(), @@ -338,9 +367,18 @@ public class CallLogFragment extends Fragment public void onActivityCreated(Bundle savedInstanceState) { super.onActivityCreated(savedInstanceState); setupData(); + updateSelectAllState(savedInstanceState); mAdapter.onRestoreInstanceState(savedInstanceState); } + private void updateSelectAllState(Bundle savedInstanceState) { + if (savedInstanceState != null) { + if (savedInstanceState.getBoolean(KEY_SELECT_ALL_MODE, false)) { + updateSelectAllIcon(); + } + } + } + @Override public void onViewCreated(View view, Bundle savedInstanceState) { super.onViewCreated(view, savedInstanceState); @@ -420,7 +458,7 @@ public class CallLogFragment extends Fragment outState.putBoolean(KEY_IS_CALL_LOG_ACTIVITY, mIsCallLogActivity); outState.putBoolean(KEY_HAS_READ_CALL_LOG_PERMISSION, mHasReadCallLogPermission); outState.putBoolean(KEY_REFRESH_DATA_REQUIRED, mRefreshDataRequired); - + outState.putBoolean(KEY_SELECT_ALL_MODE, selectAllMode); mAdapter.onSaveInstanceState(outState); } @@ -518,7 +556,8 @@ public class CallLogFragment extends Fragment if (mKeyguardManager != null && !mKeyguardManager.inKeyguardRestrictedInputMode() && mCallTypeFilter == Calls.VOICEMAIL_TYPE) { - CallLogNotificationsService.markNewVoicemailsAsOld(getActivity(), null); + LogUtil.i("CallLogFragment.updateOnTransition", "clearing all new voicemails"); + CallLogNotificationsService.markAllNewVoicemailsAsOld(getActivity()); } } @@ -529,9 +568,14 @@ public class CallLogFragment extends Fragment return; } - if (!PermissionsUtil.hasPermission(activity, READ_CALL_LOG)) { - FragmentCompat.requestPermissions( - this, new String[] {READ_CALL_LOG}, READ_CALL_LOG_PERMISSION_REQUEST_CODE); + String[] deniedPermissions = + PermissionsUtil.getPermissionsCurrentlyDenied( + getContext(), PermissionsUtil.allPhoneGroupPermissionsUsedInDialer); + if (deniedPermissions.length > 0) { + LogUtil.i( + "CallLogFragment.onEmptyViewActionButtonClicked", + "Requesting permissions: " + Arrays.toString(deniedPermissions)); + FragmentCompat.requestPermissions(this, deniedPermissions, PHONE_PERMISSIONS_REQUEST_CODE); } else if (!mIsCallLogActivity) { // Show dialpad if we are not in the call log activity. ((HostInterface) activity).showDialpad(); @@ -541,7 +585,7 @@ public class CallLogFragment extends Fragment @Override public void onRequestPermissionsResult( int requestCode, String[] permissions, int[] grantResults) { - if (requestCode == READ_CALL_LOG_PERMISSION_REQUEST_CODE) { + if (requestCode == PHONE_PERMISSIONS_REQUEST_CODE) { if (grantResults.length >= 1 && PackageManager.PERMISSION_GRANTED == grantResults[0]) { // Force a refresh of the data since we were missing the permission before this. mRefreshDataRequired = true; @@ -606,12 +650,40 @@ public class CallLogFragment extends Fragment @Override public void showMultiSelectRemoveView(boolean show) { + mMultiSelectUnSelectAllViewContent.setVisibility(show ? View.VISIBLE : View.GONE); + mMultiSelectUnSelectAllViewContent.setAlpha(show ? 0 : 1); + mMultiSelectUnSelectAllViewContent.animate().alpha(show ? 1 : 0).start(); ((ListsFragment) getParentFragment()).showMultiSelectRemoveView(show); } @Override public void setSelectAllModeToFalse() { - ((ListsFragment) getParentFragment()).setSelectAllModeToFalse(); + selectAllMode = false; + mSelectUnselectAllIcon.setImageDrawable( + getContext().getDrawable(R.drawable.ic_empty_check_mark_white_24dp)); + } + + @Override + public void onClick(View v) { + selectAllMode = !selectAllMode; + if (selectAllMode) { + Logger.get(v.getContext()).logImpression(DialerImpression.Type.MULTISELECT_SELECT_ALL); + } else { + Logger.get(v.getContext()).logImpression(DialerImpression.Type.MULTISELECT_UNSELECT_ALL); + } + updateSelectAllIcon(); + } + + private void updateSelectAllIcon() { + if (selectAllMode) { + mSelectUnselectAllIcon.setImageDrawable( + getContext().getDrawable(R.drawable.ic_check_mark_blue_24dp)); + getAdapter().onAllSelected(); + } else { + mSelectUnselectAllIcon.setImageDrawable( + getContext().getDrawable(R.drawable.ic_empty_check_mark_white_24dp)); + getAdapter().onAllDeselected(); + } } public interface HostInterface { diff --git a/java/com/android/dialer/app/calllog/CallLogListItemViewHolder.java b/java/com/android/dialer/app/calllog/CallLogListItemViewHolder.java index a9a4d1d42..c59f0dd61 100644 --- a/java/com/android/dialer/app/calllog/CallLogListItemViewHolder.java +++ b/java/com/android/dialer/app/calllog/CallLogListItemViewHolder.java @@ -26,23 +26,25 @@ import android.os.AsyncTask; import android.provider.CallLog; import android.provider.CallLog.Calls; import android.provider.ContactsContract.CommonDataKinds.Phone; +import android.support.annotation.IntDef; import android.support.annotation.NonNull; import android.support.annotation.Nullable; import android.support.annotation.VisibleForTesting; import android.support.v7.widget.CardView; import android.support.v7.widget.RecyclerView; +import android.telecom.PhoneAccount; import android.telecom.PhoneAccountHandle; import android.telephony.PhoneNumberUtils; import android.text.BidiFormatter; import android.text.TextDirectionHeuristics; import android.text.TextUtils; import android.view.ContextMenu; +import android.view.LayoutInflater; import android.view.MenuItem; import android.view.View; import android.view.ViewStub; import android.widget.ImageButton; import android.widget.ImageView; -import android.widget.QuickContactBadge; import android.widget.TextView; import android.widget.Toast; import com.android.contacts.common.ClipboardUtils; @@ -54,6 +56,7 @@ import com.android.contacts.common.lettertiles.LetterTileDrawable.ContactType; import com.android.contacts.common.util.UriUtils; import com.android.dialer.app.DialtactsActivity; import com.android.dialer.app.R; +import com.android.dialer.app.calllog.CallLogAdapter.OnActionModeStateChangedListener; import com.android.dialer.app.calllog.calllogcache.CallLogCache; import com.android.dialer.app.voicemail.VoicemailPlaybackLayout; import com.android.dialer.app.voicemail.VoicemailPlaybackPresenter; @@ -61,11 +64,14 @@ import com.android.dialer.blocking.BlockedNumbersMigrator; import com.android.dialer.blocking.FilteredNumberCompat; import com.android.dialer.blocking.FilteredNumbersUtil; import com.android.dialer.callcomposer.CallComposerActivity; +import com.android.dialer.calldetails.CallDetailsActivity; import com.android.dialer.calldetails.CallDetailsEntries; -import com.android.dialer.common.ConfigProviderBindings; +import com.android.dialer.common.Assert; import com.android.dialer.common.LogUtil; import com.android.dialer.compat.CompatUtils; +import com.android.dialer.configprovider.ConfigProviderBindings; import com.android.dialer.dialercontact.DialerContact; +import com.android.dialer.dialercontact.SimDetails; import com.android.dialer.lightbringer.Lightbringer; import com.android.dialer.lightbringer.LightbringerComponent; import com.android.dialer.logging.ContactSource; @@ -73,12 +79,16 @@ import com.android.dialer.logging.DialerImpression; import com.android.dialer.logging.InteractionEvent; import com.android.dialer.logging.Logger; import com.android.dialer.logging.ScreenEvent; +import com.android.dialer.logging.UiAction; +import com.android.dialer.performancereport.PerformanceReport; import com.android.dialer.phonenumbercache.CachedNumberLookupService; import com.android.dialer.phonenumbercache.ContactInfo; import com.android.dialer.phonenumbercache.PhoneNumberCache; import com.android.dialer.phonenumberutil.PhoneNumberHelper; import com.android.dialer.util.CallUtil; import com.android.dialer.util.DialerUtils; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; /** * This is an object containing references to views contained by the call log list item. This @@ -94,7 +104,7 @@ public final class CallLogListItemViewHolder extends RecyclerView.ViewHolder /** The root view of the call log list item */ public final View rootView; /** The quick contact badge for the contact. */ - public final QuickContactBadge quickContactView; + public final DialerQuickContactBadge quickContactView; /** The primary action view of the entry. */ public final View primaryActionView; /** The details of the phone call. */ @@ -112,6 +122,7 @@ public final class CallLogListItemViewHolder extends RecyclerView.ViewHolder private final CachedNumberLookupService mCachedNumberLookupService; private final VoicemailPlaybackPresenter mVoicemailPlaybackPresenter; private final OnClickListener mBlockReportListener; + @HostUi private final int hostUi; /** Whether the data fields are populated by the worker thread, ready to be shown. */ public boolean isLoaded; /** The view containing call log item actions. Null until the ViewStub is inflated. */ @@ -205,6 +216,7 @@ public final class CallLogListItemViewHolder extends RecyclerView.ViewHolder public boolean lightbringerReady; private View.OnClickListener mExpandCollapseListener; + private final OnActionModeStateChangedListener onActionModeStateChangedListener; private final View.OnLongClickListener longPressListener; private boolean mVoicemailPrimaryActionButtonClicked; @@ -220,11 +232,12 @@ public final class CallLogListItemViewHolder extends RecyclerView.ViewHolder OnClickListener blockReportListener, View.OnClickListener expandCollapseListener, View.OnLongClickListener longClickListener, + CallLogAdapter.OnActionModeStateChangedListener actionModeStateChangedListener, CallLogCache callLogCache, CallLogListItemHelper callLogListItemHelper, VoicemailPlaybackPresenter voicemailPlaybackPresenter, View rootView, - QuickContactBadge quickContactView, + DialerQuickContactBadge dialerQuickContactView, View primaryActionView, PhoneCallDetailsViews phoneCallDetailsViews, CardView callLogEntryView, @@ -234,6 +247,7 @@ public final class CallLogListItemViewHolder extends RecyclerView.ViewHolder mContext = context; mExpandCollapseListener = expandCollapseListener; + onActionModeStateChangedListener = actionModeStateChangedListener; longPressListener = longClickListener; mCallLogCache = callLogCache; mCallLogListItemHelper = callLogListItemHelper; @@ -242,7 +256,7 @@ public final class CallLogListItemViewHolder extends RecyclerView.ViewHolder mCachedNumberLookupService = PhoneNumberCache.get(mContext).getCachedNumberLookupService(); this.rootView = rootView; - this.quickContactView = quickContactView; + this.quickContactView = dialerQuickContactView; this.primaryActionView = primaryActionView; this.phoneCallDetailsViews = phoneCallDetailsViews; this.callLogEntryView = callLogEntryView; @@ -256,14 +270,17 @@ public final class CallLogListItemViewHolder extends RecyclerView.ViewHolder phoneCallDetailsViews.callLocationAndDate.setElegantTextHeight(false); if (mContext instanceof CallLogActivity) { + hostUi = HostUi.CALL_HISTORY; Logger.get(mContext) .logQuickContactOnTouch( quickContactView, InteractionEvent.Type.OPEN_QUICK_CONTACT_FROM_CALL_HISTORY, true); } else if (mVoicemailPlaybackPresenter == null) { + hostUi = HostUi.CALL_LOG; Logger.get(mContext) .logQuickContactOnTouch( quickContactView, InteractionEvent.Type.OPEN_QUICK_CONTACT_FROM_CALL_LOG, true); } else { + hostUi = HostUi.VOICEMAIL; Logger.get(mContext) .logQuickContactOnTouch( quickContactView, InteractionEvent.Type.OPEN_QUICK_CONTACT_FROM_VOICEMAIL, false); @@ -282,6 +299,8 @@ public final class CallLogListItemViewHolder extends RecyclerView.ViewHolder CallLogAdapter.ENABLE_CALL_LOG_MULTI_SELECT_FLAG)) { primaryActionView.setOnLongClickListener(longPressListener); quickContactView.setOnLongClickListener(longPressListener); + quickContactView.setMulitSelectListeners( + mExpandCollapseListener, onActionModeStateChangedListener); } else { primaryActionView.setOnCreateContextMenuListener(this); } @@ -293,6 +312,7 @@ public final class CallLogListItemViewHolder extends RecyclerView.ViewHolder OnClickListener blockReportListener, View.OnClickListener expandCollapseListener, View.OnLongClickListener longClickListener, + CallLogAdapter.OnActionModeStateChangedListener actionModeStateChangeListener, CallLogCache callLogCache, CallLogListItemHelper callLogListItemHelper, VoicemailPlaybackPresenter voicemailPlaybackPresenter) { @@ -302,11 +322,12 @@ public final class CallLogListItemViewHolder extends RecyclerView.ViewHolder blockReportListener, expandCollapseListener, longClickListener, + actionModeStateChangeListener, callLogCache, callLogListItemHelper, voicemailPlaybackPresenter, view, - (QuickContactBadge) view.findViewById(R.id.quick_contact_photo), + (DialerQuickContactBadge) view.findViewById(R.id.quick_contact_photo), view.findViewById(R.id.primary_action_view), PhoneCallDetailsViews.fromView(view), (CardView) view.findViewById(R.id.call_log_row), @@ -315,6 +336,11 @@ public final class CallLogListItemViewHolder extends RecyclerView.ViewHolder } public static CallLogListItemViewHolder createForTest(Context context) { + return createForTest(context, null); + } + + static CallLogListItemViewHolder createForTest( + Context context, VoicemailPlaybackPresenter voicemailPlaybackPresenter) { Resources resources = context.getResources(); CallLogCache callLogCache = CallLogCache.getCallLogCache(context); PhoneCallDetailsHelper phoneCallDetailsHelper = @@ -326,11 +352,12 @@ public final class CallLogListItemViewHolder extends RecyclerView.ViewHolder null, null /* expandCollapseListener */, null, + null, callLogCache, new CallLogListItemHelper(phoneCallDetailsHelper, resources, callLogCache), - null /* voicemailPlaybackPresenter */, - new View(context), - new QuickContactBadge(context), + voicemailPlaybackPresenter, + LayoutInflater.from(context).inflate(R.layout.call_log_list_item, null), + new DialerQuickContactBadge(context), new View(context), PhoneCallDetailsViews.createForTest(context), new CardView(context), @@ -474,6 +501,17 @@ public final class CallLogListItemViewHolder extends RecyclerView.ViewHolder // Treat as normal list item; show call button, if possible. if (PhoneNumberHelper.canPlaceCallsTo(number, numberPresentation)) { boolean isVoicemailNumber = mCallLogCache.isVoicemailNumber(accountHandle, number); + + if (!isVoicemailNumber && showLightbringerPrimaryButton()) { + primaryActionButtonView.setTag(IntentProvider.getLightbringerIntentProvider(number)); + primaryActionButtonView.setContentDescription( + TextUtils.expandTemplate( + mContext.getString(R.string.description_video_call_action), validNameOrNumber)); + primaryActionButtonView.setImageResource(R.drawable.quantum_ic_videocam_vd_theme_24); + primaryActionButtonView.setVisibility(View.VISIBLE); + return; + } + if (isVoicemailNumber) { // Call to generic voicemail number, in case there are multiple accounts. primaryActionButtonView.setTag(IntentProvider.getReturnVoicemailCallIntentProvider()); @@ -531,8 +569,15 @@ public final class CallLogListItemViewHolder extends RecyclerView.ViewHolder return; } - if (!TextUtils.isEmpty(voicemailUri) && canPlaceCallToNumber) { + if (canPlaceCallToNumber) { + // Set up the call button but hide it by default (the primary action is to call so it is + // redundant). We then set it to be visible when appropriate below. This saves us having to + // remember to set it to GONE in multiple places. callButtonView.setTag(IntentProvider.getReturnCallIntentProvider(number)); + callButtonView.setVisibility(View.GONE); + } + + if (!TextUtils.isEmpty(voicemailUri) && canPlaceCallToNumber) { ((TextView) callButtonView.findViewById(R.id.call_action_text)) .setText( TextUtils.expandTemplate( @@ -547,13 +592,14 @@ public final class CallLogListItemViewHolder extends RecyclerView.ViewHolder callTypeOrLocationView.setVisibility(View.GONE); } callButtonView.setVisibility(View.VISIBLE); - } else { - callButtonView.setVisibility(View.GONE); } if (hasPlacedCarrierVideoCall() || canSupportCarrierVideoCall()) { videoCallButtonView.setTag(IntentProvider.getReturnVideoCallIntentProvider(number)); videoCallButtonView.setVisibility(View.VISIBLE); + } else if (showLightbringerPrimaryButton()) { + callButtonView.setVisibility(View.VISIBLE); + videoCallButtonView.setVisibility(View.GONE); } else if (lightbringerReady) { videoCallButtonView.setTag(IntentProvider.getLightbringerIntentProvider(number)); videoCallButtonView.setVisibility(View.VISIBLE); @@ -585,8 +631,12 @@ public final class CallLogListItemViewHolder extends RecyclerView.ViewHolder detailsButtonView.setVisibility(View.GONE); } else { detailsButtonView.setVisibility(View.VISIBLE); + boolean canReportCallerId = + mCachedNumberLookupService != null + && mCachedNumberLookupService.canReportAsInvalid(info.sourceType, info.objectId); detailsButtonView.setTag( - IntentProvider.getCallDetailIntentProvider(callDetailsEntries, buildContact())); + IntentProvider.getCallDetailIntentProvider( + callDetailsEntries, buildContact(), canReportCallerId)); } boolean isBlockedOrSpam = blockId != null || (isSpamFeatureEnabled && isSpam); @@ -634,6 +684,12 @@ public final class CallLogListItemViewHolder extends RecyclerView.ViewHolder return false; } + private boolean showLightbringerPrimaryButton() { + return accountHandle != null + && accountHandle.getComponentName().equals(getLightbringer().getPhoneAccountComponentName()) + && lightbringerReady; + } + private static boolean hasDialableChar(CharSequence number) { if (TextUtils.isEmpty(number)) { return false; @@ -653,9 +709,7 @@ public final class CallLogListItemViewHolder extends RecyclerView.ViewHolder if (accountHandle == null) { return false; } - if (accountHandle - .getComponentName() - .equals(getLightbringer().getPhoneAccountComponentName(mContext))) { + if (accountHandle.getComponentName().equals(getLightbringer().getPhoneAccountComponentName())) { return false; } return true; @@ -823,9 +877,14 @@ public final class CallLogListItemViewHolder extends RecyclerView.ViewHolder // We check to see if we are starting a Lightbringer intent. The reason is Lightbringer // intents need to be started using startActivityForResult instead of the usual startActivity String packageName = intent.getPackage(); - if (packageName != null && packageName.equals(getLightbringer().getPackageName(mContext))) { + if (getLightbringer().getPackageName().equals(packageName)) { startLightbringerActivity(intent); } else { + if (intent.getComponent() != null + && CallDetailsActivity.class.getName().equals(intent.getComponent().getClassName())) { + // We are going to open call detail + PerformanceReport.recordClick(UiAction.Type.OPEN_CALL_DETAIL); + } DialerUtils.startActivityWithErrorToast(mContext, intent); } } @@ -860,6 +919,19 @@ public final class CallLogListItemViewHolder extends RecyclerView.ViewHolder } /* phone number type (e.g. mobile) in second line of contact view */ contact.setNumberLabel(numberType); + + /* third line of contact view. */ + String accountLabel = mCallLogCache.getAccountLabel(accountHandle); + if (!TextUtils.isEmpty(accountLabel)) { + SimDetails.Builder simDetails = SimDetails.newBuilder().setNetwork(accountLabel); + int color = mCallLogCache.getAccountColor(accountHandle); + if (color == PhoneAccount.NO_HIGHLIGHT_COLOR) { + simDetails.setColor(R.color.secondary_text_color); + } else { + simDetails.setColor(color); + } + contact.setSimDetails(simDetails.build()); + } return contact.build(); } @@ -868,8 +940,38 @@ public final class CallLogListItemViewHolder extends RecyclerView.ViewHolder Logger.get(mContext).logImpression(DialerImpression.Type.CALL_LOG_SEND_MESSAGE); } else if (id == R.id.add_to_existing_contact_action) { Logger.get(mContext).logImpression(DialerImpression.Type.CALL_LOG_ADD_TO_CONTACT); + switch (hostUi) { + case HostUi.CALL_HISTORY: + Logger.get(mContext) + .logImpression(DialerImpression.Type.ADD_TO_A_CONTACT_FROM_CALL_HISTORY); + break; + case HostUi.CALL_LOG: + Logger.get(mContext).logImpression(DialerImpression.Type.ADD_TO_A_CONTACT_FROM_CALL_LOG); + break; + case HostUi.VOICEMAIL: + Logger.get(mContext).logImpression(DialerImpression.Type.ADD_TO_A_CONTACT_FROM_VOICEMAIL); + break; + default: + throw Assert.createIllegalStateFailException(); + } } else if (id == R.id.create_new_contact_action) { Logger.get(mContext).logImpression(DialerImpression.Type.CALL_LOG_CREATE_NEW_CONTACT); + switch (hostUi) { + case HostUi.CALL_HISTORY: + Logger.get(mContext) + .logImpression(DialerImpression.Type.CREATE_NEW_CONTACT_FROM_CALL_HISTORY); + break; + case HostUi.CALL_LOG: + Logger.get(mContext) + .logImpression(DialerImpression.Type.CREATE_NEW_CONTACT_FROM_CALL_LOG); + break; + case HostUi.VOICEMAIL: + Logger.get(mContext) + .logImpression(DialerImpression.Type.CREATE_NEW_CONTACT_FROM_VOICEMAIL); + break; + default: + throw Assert.createIllegalStateFailException(); + } } } @@ -1021,6 +1123,15 @@ public final class CallLogListItemViewHolder extends RecyclerView.ViewHolder Logger.get(mContext).logScreenView(ScreenEvent.Type.CALL_LOG_CONTEXT_MENU, (Activity) mContext); } + /** Specifies where the view holder belongs. */ + @IntDef({HostUi.CALL_LOG, HostUi.CALL_HISTORY, HostUi.VOICEMAIL}) + @Retention(RetentionPolicy.SOURCE) + private @interface HostUi { + int CALL_LOG = 0; + int CALL_HISTORY = 1; + int VOICEMAIL = 2; + } + public interface OnClickListener { void onBlockReportSpam( diff --git a/java/com/android/dialer/app/calllog/CallLogNotificationsQueryHelper.java b/java/com/android/dialer/app/calllog/CallLogNotificationsQueryHelper.java index e169b8de9..43e03e9fd 100644 --- a/java/com/android/dialer/app/calllog/CallLogNotificationsQueryHelper.java +++ b/java/com/android/dialer/app/calllog/CallLogNotificationsQueryHelper.java @@ -18,7 +18,6 @@ package com.android.dialer.app.calllog; import android.Manifest; import android.annotation.TargetApi; -import android.app.NotificationManager; import android.content.ContentResolver; import android.content.ContentUris; import android.content.ContentValues; @@ -27,6 +26,7 @@ import android.database.Cursor; import android.net.Uri; import android.os.Build.VERSION_CODES; import android.provider.CallLog.Calls; +import android.support.annotation.NonNull; import android.support.annotation.Nullable; import android.support.annotation.WorkerThread; import android.support.v4.os.UserManagerCompat; @@ -36,7 +36,6 @@ import com.android.dialer.app.R; import com.android.dialer.calllogutils.PhoneNumberDisplayUtil; import com.android.dialer.common.LogUtil; import com.android.dialer.location.GeoUtil; -import com.android.dialer.notification.GroupedNotificationUtil; import com.android.dialer.phonenumbercache.ContactInfo; import com.android.dialer.phonenumbercache.ContactInfoHelper; import com.android.dialer.util.PermissionsUtil; @@ -46,7 +45,6 @@ import java.util.List; /** Helper class operating on call log notifications. */ public class CallLogNotificationsQueryHelper { - private static final String TAG = "CallLogNotifHelper"; private final Context mContext; private final NewCallsQuery mNewCallsQuery; private final ContactInfoHelper mContactInfoHelper; @@ -74,44 +72,58 @@ public class CallLogNotificationsQueryHelper { countryIso); } + public static void markAllMissedCallsInCallLogAsRead(@NonNull Context context) { + markMissedCallsInCallLogAsRead(context, null); + } + + public static void markSingleMissedCallInCallLogAsRead( + @NonNull Context context, @Nullable Uri callUri) { + if (callUri == null) { + LogUtil.e( + "CallLogNotificationsQueryHelper.markSingleMissedCallInCallLogAsRead", + "call URI is null, unable to mark call as read"); + } else { + markMissedCallsInCallLogAsRead(context, callUri); + } + } + /** - * Removes the missed call notifications and marks calls as read. If a callUri is provided, only - * that call is marked as read. + * If callUri is null then calls with a matching callUri are marked as read, otherwise all calls + * are marked as read. */ @WorkerThread - public static void removeMissedCallNotifications(Context context, @Nullable Uri callUri) { - // Call log is only accessible when unlocked. If that's the case, clear the list of - // new missed calls from the call log. - if (UserManagerCompat.isUserUnlocked(context) && PermissionsUtil.hasPhonePermissions(context)) { - ContentValues values = new ContentValues(); - values.put(Calls.NEW, 0); - values.put(Calls.IS_READ, 1); - StringBuilder where = new StringBuilder(); - where.append(Calls.NEW); - where.append(" = 1 AND "); - where.append(Calls.TYPE); - where.append(" = ?"); - try { - context - .getContentResolver() - .update( - callUri == null ? Calls.CONTENT_URI : callUri, - values, - where.toString(), - new String[] {Integer.toString(Calls.MISSED_TYPE)}); - } catch (IllegalArgumentException e) { - LogUtil.e( - "CallLogNotificationsQueryHelper.removeMissedCallNotifications", - "contacts provider update command failed", - e); - } + private static void markMissedCallsInCallLogAsRead(Context context, @Nullable Uri callUri) { + if (!UserManagerCompat.isUserUnlocked(context)) { + LogUtil.e("CallLogNotificationsQueryHelper.markMissedCallsInCallLogAsRead", "locked"); + return; + } + if (!PermissionsUtil.hasPhonePermissions(context)) { + LogUtil.e("CallLogNotificationsQueryHelper.markMissedCallsInCallLogAsRead", "no permission"); + return; } - GroupedNotificationUtil.removeNotification( - context.getSystemService(NotificationManager.class), - callUri != null ? callUri.toString() : null, - R.id.notification_missed_call, - MissedCallNotifier.NOTIFICATION_TAG); + ContentValues values = new ContentValues(); + values.put(Calls.NEW, 0); + values.put(Calls.IS_READ, 1); + StringBuilder where = new StringBuilder(); + where.append(Calls.NEW); + where.append(" = 1 AND "); + where.append(Calls.TYPE); + where.append(" = ?"); + try { + context + .getContentResolver() + .update( + callUri == null ? Calls.CONTENT_URI : callUri, + values, + where.toString(), + new String[] {Integer.toString(Calls.MISSED_TYPE)}); + } catch (IllegalArgumentException e) { + LogUtil.e( + "CallLogNotificationsQueryHelper.markMissedCallsInCallLogAsRead", + "contacts provider update command failed", + e); + } } /** Create a new instance of {@link NewCallsQuery}. */ @@ -281,7 +293,9 @@ public class CallLogNotificationsQueryHelper { @TargetApi(VERSION_CODES.M) public List query(int type) { if (!PermissionsUtil.hasPermission(mContext, Manifest.permission.READ_CALL_LOG)) { - LogUtil.w(TAG, "No READ_CALL_LOG permission, returning null for calls lookup."); + LogUtil.w( + "CallLogNotificationsQueryHelper.DefaultNewCallsQuery.query", + "no READ_CALL_LOG permission, returning null for calls lookup."); return null; } final String selection = String.format("%s = 1 AND %s = ?", Calls.NEW, Calls.TYPE); @@ -302,7 +316,9 @@ public class CallLogNotificationsQueryHelper { } return newCalls; } catch (RuntimeException e) { - LogUtil.w(TAG, "Exception when querying Contacts Provider for calls lookup"); + LogUtil.w( + "CallLogNotificationsQueryHelper.DefaultNewCallsQuery.query", + "exception when querying Contacts Provider for calls lookup"); return null; } } diff --git a/java/com/android/dialer/app/calllog/CallLogNotificationsService.java b/java/com/android/dialer/app/calllog/CallLogNotificationsService.java index 7dfd2cb69..be1ebfb6d 100644 --- a/java/com/android/dialer/app/calllog/CallLogNotificationsService.java +++ b/java/com/android/dialer/app/calllog/CallLogNotificationsService.java @@ -17,12 +17,13 @@ package com.android.dialer.app.calllog; import android.app.IntentService; +import android.app.PendingIntent; import android.content.Context; import android.content.Intent; import android.net.Uri; -import android.os.Handler; -import android.os.Looper; +import android.support.annotation.NonNull; import android.support.annotation.Nullable; +import android.support.annotation.VisibleForTesting; import com.android.dialer.common.LogUtil; import com.android.dialer.telecom.TelecomUtil; import com.android.dialer.util.PermissionsUtil; @@ -43,16 +44,20 @@ import com.android.dialer.util.PermissionsUtil; */ public class CallLogNotificationsService extends IntentService { - /** Action to mark all the new voicemails as old. */ - public static final String ACTION_MARK_NEW_VOICEMAILS_AS_OLD = - "com.android.dialer.calllog.ACTION_MARK_NEW_VOICEMAILS_AS_OLD"; + private static final String ACTION_MARK_ALL_NEW_VOICEMAILS_AS_OLD = + "com.android.dialer.calllog.ACTION_MARK_ALL_NEW_VOICEMAILS_AS_OLD"; - /** Action to mark all the new missed calls as old. */ - public static final String ACTION_MARK_NEW_MISSED_CALLS_AS_OLD = - "com.android.dialer.calllog.ACTION_MARK_NEW_MISSED_CALLS_AS_OLD"; + private static final String ACTION_MARK_SINGLE_NEW_VOICEMAIL_AS_OLD = + "com.android.dialer.calllog.ACTION_MARK_SINGLE_NEW_VOICEMAIL_AS_OLD "; - /** Action to update missed call notifications with a post call note. */ - public static final String ACTION_INCOMING_POST_CALL = + @VisibleForTesting + static final String ACTION_CANCEL_ALL_MISSED_CALLS = + "com.android.dialer.calllog.ACTION_CANCEL_ALL_MISSED_CALLS"; + + private static final String ACTION_CANCEL_SINGLE_MISSED_CALL = + "com.android.dialer.calllog.ACTION_CANCEL_SINGLE_MISSED_CALL"; + + private static final String ACTION_INCOMING_POST_CALL = "com.android.dialer.calllog.INCOMING_POST_CALL"; /** Action to call back a missed call. */ @@ -64,7 +69,7 @@ public class CallLogNotificationsService extends IntentService { * *

It must be a {@link String} */ - public static final String EXTRA_POST_CALL_NOTE = "POST_CALL_NOTE"; + private static final String EXTRA_POST_CALL_NOTE = "POST_CALL_NOTE"; /** * Extra to be included with {@link #ACTION_INCOMING_POST_CALL} to represent the phone number the @@ -72,10 +77,9 @@ public class CallLogNotificationsService extends IntentService { * *

It must be a {@link String} */ - public static final String EXTRA_POST_CALL_NUMBER = "POST_CALL_NUMBER"; + private static final String EXTRA_POST_CALL_NUMBER = "POST_CALL_NUMBER"; public static final int UNKNOWN_MISSED_CALL_COUNT = -1; - private VoicemailQueryHandler mVoicemailQueryHandler; public CallLogNotificationsService() { super("CallLogNotificationsService"); @@ -89,52 +93,95 @@ public class CallLogNotificationsService extends IntentService { context.startService(serviceIntent); } - public static void markNewVoicemailsAsOld(Context context, @Nullable Uri voicemailUri) { + public static void markAllNewVoicemailsAsOld(Context context) { + LogUtil.enterBlock("CallLogNotificationsService.markAllNewVoicemailsAsOld"); Intent serviceIntent = new Intent(context, CallLogNotificationsService.class); - serviceIntent.setAction(CallLogNotificationsService.ACTION_MARK_NEW_VOICEMAILS_AS_OLD); + serviceIntent.setAction(CallLogNotificationsService.ACTION_MARK_ALL_NEW_VOICEMAILS_AS_OLD); + context.startService(serviceIntent); + } + + public static void markSingleNewVoicemailAsOld(Context context, @Nullable Uri voicemailUri) { + LogUtil.enterBlock("CallLogNotificationsService.markSingleNewVoicemailAsOld"); + Intent serviceIntent = new Intent(context, CallLogNotificationsService.class); + serviceIntent.setAction(CallLogNotificationsService.ACTION_MARK_SINGLE_NEW_VOICEMAIL_AS_OLD); serviceIntent.setData(voicemailUri); context.startService(serviceIntent); } - public static void markNewMissedCallsAsOld(Context context, @Nullable Uri callUri) { + public static PendingIntent createMarkAllNewVoicemailsAsOldIntent(@NonNull Context context) { + Intent intent = new Intent(context, CallLogNotificationsService.class); + intent.setAction(CallLogNotificationsService.ACTION_MARK_ALL_NEW_VOICEMAILS_AS_OLD); + return PendingIntent.getService(context, 0, intent, 0); + } + + public static PendingIntent createMarkSingleNewVoicemailAsOldIntent( + @NonNull Context context, @Nullable Uri voicemailUri) { + Intent intent = new Intent(context, CallLogNotificationsService.class); + intent.setAction(CallLogNotificationsService.ACTION_MARK_SINGLE_NEW_VOICEMAIL_AS_OLD); + intent.setData(voicemailUri); + return PendingIntent.getService(context, 0, intent, 0); + } + + public static void cancelAllMissedCalls(@NonNull Context context) { + LogUtil.enterBlock("CallLogNotificationsService.cancelAllMissedCalls"); Intent serviceIntent = new Intent(context, CallLogNotificationsService.class); - serviceIntent.setAction(ACTION_MARK_NEW_MISSED_CALLS_AS_OLD); - serviceIntent.setData(callUri); + serviceIntent.setAction(ACTION_CANCEL_ALL_MISSED_CALLS); context.startService(serviceIntent); } + public static PendingIntent createCancelAllMissedCallsPendingIntent(@NonNull Context context) { + Intent intent = new Intent(context, CallLogNotificationsService.class); + intent.setAction(ACTION_CANCEL_ALL_MISSED_CALLS); + return PendingIntent.getService(context, 0, intent, 0); + } + + public static PendingIntent createCancelSingleMissedCallPendingIntent( + @NonNull Context context, @Nullable Uri callUri) { + Intent intent = new Intent(context, CallLogNotificationsService.class); + intent.setAction(ACTION_CANCEL_SINGLE_MISSED_CALL); + intent.setData(callUri); + return PendingIntent.getService(context, 0, intent, 0); + } + @Override protected void onHandleIntent(Intent intent) { if (intent == null) { - LogUtil.d("CallLogNotificationsService.onHandleIntent", "could not handle null intent"); + LogUtil.e("CallLogNotificationsService.onHandleIntent", "could not handle null intent"); return; } - if (!PermissionsUtil.hasPermission(this, android.Manifest.permission.READ_CALL_LOG)) { + if (!PermissionsUtil.hasPermission(this, android.Manifest.permission.READ_CALL_LOG) + || !PermissionsUtil.hasPermission(this, android.Manifest.permission.WRITE_CALL_LOG)) { + LogUtil.e("CallLogNotificationsService.onHandleIntent", "no READ_CALL_LOG permission"); return; } String action = intent.getAction(); + LogUtil.i("CallLogNotificationsService.onHandleIntent", "action: " + action); switch (action) { - case ACTION_MARK_NEW_VOICEMAILS_AS_OLD: - // VoicemailQueryHandler cannot be created on the IntentService worker thread. The completed - // callback might happen when the thread is dead. - Handler handler = new Handler(Looper.getMainLooper()); - handler.post( - () -> { - if (mVoicemailQueryHandler == null) { - mVoicemailQueryHandler = new VoicemailQueryHandler(this, getContentResolver()); - } - mVoicemailQueryHandler.markNewVoicemailsAsOld(intent.getData()); - }); + case ACTION_MARK_ALL_NEW_VOICEMAILS_AS_OLD: + VoicemailQueryHandler.markAllNewVoicemailsAsRead(this); + VisualVoicemailNotifier.cancelAllVoicemailNotifications(this); + break; + case ACTION_MARK_SINGLE_NEW_VOICEMAIL_AS_OLD: + Uri voicemailUri = intent.getData(); + VoicemailQueryHandler.markSingleNewVoicemailAsRead(this, voicemailUri); + VisualVoicemailNotifier.cancelSingleVoicemailNotification(this, voicemailUri); break; case ACTION_INCOMING_POST_CALL: String note = intent.getStringExtra(EXTRA_POST_CALL_NOTE); String phoneNumber = intent.getStringExtra(EXTRA_POST_CALL_NUMBER); MissedCallNotifier.getIstance(this).insertPostCallNotification(phoneNumber, note); break; - case ACTION_MARK_NEW_MISSED_CALLS_AS_OLD: - CallLogNotificationsQueryHelper.removeMissedCallNotifications(this, intent.getData()); + case ACTION_CANCEL_ALL_MISSED_CALLS: + CallLogNotificationsQueryHelper.markAllMissedCallsInCallLogAsRead(this); + MissedCallNotifier.cancelAllMissedCallNotifications(this); + TelecomUtil.cancelMissedCallsNotification(this); + break; + case ACTION_CANCEL_SINGLE_MISSED_CALL: + Uri callUri = intent.getData(); + CallLogNotificationsQueryHelper.markSingleMissedCallInCallLogAsRead(this, callUri); + MissedCallNotifier.cancelSingleMissedCallNotification(this, callUri); TelecomUtil.cancelMissedCallsNotification(this); break; case ACTION_CALL_BACK_FROM_MISSED_CALL_NOTIFICATION: @@ -145,7 +192,7 @@ public class CallLogNotificationsService extends IntentService { intent.getData()); break; default: - LogUtil.d("CallLogNotificationsService.onHandleIntent", "could not handle: " + intent); + LogUtil.e("CallLogNotificationsService.onHandleIntent", "no handler for action: " + action); break; } } diff --git a/java/com/android/dialer/app/calllog/CallLogReceiver.java b/java/com/android/dialer/app/calllog/CallLogReceiver.java index 172d00100..ce3132d12 100644 --- a/java/com/android/dialer/app/calllog/CallLogReceiver.java +++ b/java/com/android/dialer/app/calllog/CallLogReceiver.java @@ -39,10 +39,10 @@ public class CallLogReceiver extends BroadcastReceiver { if (VoicemailContract.ACTION_NEW_VOICEMAIL.equals(intent.getAction())) { checkVoicemailStatus(context); PendingResult pendingResult = goAsync(); - DefaultVoicemailNotifier.updateVoicemailNotifications(context, pendingResult::finish); + VisualVoicemailUpdateTask.scheduleTask(context, pendingResult::finish); } else if (Intent.ACTION_BOOT_COMPLETED.equals(intent.getAction())) { PendingResult pendingResult = goAsync(); - DefaultVoicemailNotifier.updateVoicemailNotifications(context, pendingResult::finish); + VisualVoicemailUpdateTask.scheduleTask(context, pendingResult::finish); } else { LogUtil.w("CallLogReceiver.onReceive", "could not handle: " + intent); } diff --git a/java/com/android/dialer/app/calllog/ClearCallLogDialog.java b/java/com/android/dialer/app/calllog/ClearCallLogDialog.java index a01b89527..155a91618 100644 --- a/java/com/android/dialer/app/calllog/ClearCallLogDialog.java +++ b/java/com/android/dialer/app/calllog/ClearCallLogDialog.java @@ -54,7 +54,7 @@ public class ClearCallLogDialog extends DialogFragment { ProgressDialog.show( getActivity(), getString(R.string.clearCallLogProgress_title), "", true, false); progressDialog.setOwnerActivity(getActivity()); - CallLogNotificationsService.markNewMissedCallsAsOld(getContext(), null); + CallLogNotificationsService.cancelAllMissedCalls(getContext()); final AsyncTask task = new AsyncTask() { @Override diff --git a/java/com/android/dialer/app/calllog/DefaultVoicemailNotifier.java b/java/com/android/dialer/app/calllog/DefaultVoicemailNotifier.java deleted file mode 100644 index 1f45f7086..000000000 --- a/java/com/android/dialer/app/calllog/DefaultVoicemailNotifier.java +++ /dev/null @@ -1,451 +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.dialer.app.calllog; - -import android.annotation.TargetApi; -import android.app.Notification; -import android.app.NotificationManager; -import android.app.PendingIntent; -import android.content.Context; -import android.content.Intent; -import android.content.res.Resources; -import android.graphics.Bitmap; -import android.net.Uri; -import android.os.Build.VERSION; -import android.os.Build.VERSION_CODES; -import android.os.PersistableBundle; -import android.support.annotation.NonNull; -import android.support.annotation.Nullable; -import android.support.annotation.VisibleForTesting; -import android.support.annotation.WorkerThread; -import android.support.v4.os.BuildCompat; -import android.support.v4.util.Pair; -import android.telecom.PhoneAccount; -import android.telecom.PhoneAccountHandle; -import android.telecom.TelecomManager; -import android.telephony.CarrierConfigManager; -import android.telephony.PhoneNumberUtils; -import android.telephony.TelephonyManager; -import android.text.TextUtils; -import android.util.ArrayMap; -import com.android.contacts.common.compat.TelephonyManagerCompat; -import com.android.contacts.common.util.ContactDisplayUtils; -import com.android.dialer.app.DialtactsActivity; -import com.android.dialer.app.R; -import com.android.dialer.app.calllog.CallLogNotificationsQueryHelper.NewCall; -import com.android.dialer.app.contactinfo.ContactPhotoLoader; -import com.android.dialer.app.list.DialtactsPagerAdapter; -import com.android.dialer.blocking.FilteredNumberAsyncQueryHandler; -import com.android.dialer.blocking.FilteredNumbersUtil; -import com.android.dialer.calllogutils.PhoneAccountUtils; -import com.android.dialer.common.Assert; -import com.android.dialer.common.LogUtil; -import com.android.dialer.common.concurrent.DialerExecutor.Worker; -import com.android.dialer.common.concurrent.DialerExecutors; -import com.android.dialer.logging.DialerImpression; -import com.android.dialer.logging.Logger; -import com.android.dialer.notification.NotificationChannelManager; -import com.android.dialer.notification.NotificationChannelManager.Channel; -import com.android.dialer.phonenumbercache.ContactInfo; -import com.android.dialer.telecom.TelecomUtil; -import java.util.Iterator; -import java.util.List; -import java.util.Map; - -/** Shows a voicemail notification in the status bar. */ -public class DefaultVoicemailNotifier implements Worker { - - public static final String TAG = "VoicemailNotifier"; - - /** The tag used to identify notifications from this class. */ - static final String VISUAL_VOICEMAIL_NOTIFICATION_TAG = "DefaultVoicemailNotifier"; - /** The identifier of the notification of new voicemails. */ - private static final int VISUAL_VOICEMAIL_NOTIFICATION_ID = R.id.notification_visual_voicemail; - - private static final int LEGACY_VOICEMAIL_NOTIFICATION_ID = R.id.notification_legacy_voicemail; - private static final String LEGACY_VOICEMAIL_NOTIFICATION_TAG = "legacy_voicemail"; - - private final Context context; - private final CallLogNotificationsQueryHelper queryHelper; - private final FilteredNumberAsyncQueryHandler filteredNumberAsyncQueryHandler; - - @VisibleForTesting(otherwise = VisibleForTesting.PRIVATE) - DefaultVoicemailNotifier( - Context context, - CallLogNotificationsQueryHelper queryHelper, - FilteredNumberAsyncQueryHandler filteredNumberAsyncQueryHandler) { - this.context = context; - this.queryHelper = queryHelper; - this.filteredNumberAsyncQueryHandler = filteredNumberAsyncQueryHandler; - } - - public DefaultVoicemailNotifier(Context context) { - this( - context, - CallLogNotificationsQueryHelper.getInstance(context), - new FilteredNumberAsyncQueryHandler(context)); - } - - @Nullable - @Override - public Void doInBackground(@Nullable Void input) throws Throwable { - updateNotification(); - return null; - } - - /** - * Updates the notification and notifies of the call with the given URI. - * - *

Clears the notification if there are no new voicemails, and notifies if the given URI - * corresponds to a new voicemail. - * - *

It is not safe to call this method from the main thread. - */ - @VisibleForTesting - @WorkerThread - void updateNotification() { - Assert.isWorkerThread(); - // Lookup the list of new voicemails to include in the notification. - final List newCalls = queryHelper.getNewVoicemails(); - - if (newCalls == null) { - // Query failed, just return. - return; - } - - Resources resources = context.getResources(); - - // This represents a list of names to include in the notification. - String callers = null; - - // Maps each number into a name: if a number is in the map, it has already left a more - // recent voicemail. - final Map contactInfos = new ArrayMap<>(); - - // Iterate over the new voicemails to determine all the information above. - Iterator itr = newCalls.iterator(); - while (itr.hasNext()) { - NewCall newCall = itr.next(); - - // Skip notifying for numbers which are blocked. - if (!FilteredNumbersUtil.hasRecentEmergencyCall(context) - && filteredNumberAsyncQueryHandler.getBlockedIdSynchronous( - newCall.number, newCall.countryIso) - != null) { - itr.remove(); - - if (newCall.voicemailUri != null) { - // Delete the voicemail. - CallLogAsyncTaskUtil.deleteVoicemailSynchronous(context, newCall.voicemailUri); - } - continue; - } - - // Check if we already know the name associated with this number. - ContactInfo contactInfo = contactInfos.get(newCall.number); - if (contactInfo == null) { - contactInfo = - queryHelper.getContactInfo( - newCall.number, newCall.numberPresentation, newCall.countryIso); - contactInfos.put(newCall.number, contactInfo); - // This is a new caller. Add it to the back of the list of callers. - if (TextUtils.isEmpty(callers)) { - callers = contactInfo.name; - } else { - callers = - resources.getString( - R.string.notification_voicemail_callers_list, callers, contactInfo.name); - } - } - } - - if (newCalls.isEmpty()) { - // No voicemails to notify about - return; - } - - Notification.Builder groupSummary = - createNotificationBuilder() - .setContentTitle( - resources.getQuantityString( - R.plurals.notification_voicemail_title, newCalls.size(), newCalls.size())) - .setContentText(callers) - .setDeleteIntent(createMarkNewVoicemailsAsOldIntent(null)) - .setGroupSummary(true) - .setContentIntent(newVoicemailIntent(null)); - - if (BuildCompat.isAtLeastO()) { - groupSummary.setGroupAlertBehavior(Notification.GROUP_ALERT_CHILDREN); - } - - NotificationChannelManager.applyChannel( - groupSummary, - context, - Channel.VOICEMAIL, - PhoneAccountHandles.getAccount(context, newCalls.get(0))); - - LogUtil.i(TAG, "Creating visual voicemail notification"); - getNotificationManager() - .notify( - VISUAL_VOICEMAIL_NOTIFICATION_TAG, - VISUAL_VOICEMAIL_NOTIFICATION_ID, - groupSummary.build()); - - for (NewCall voicemail : newCalls) { - getNotificationManager() - .notify( - voicemail.callsUri.toString(), - VISUAL_VOICEMAIL_NOTIFICATION_ID, - createNotificationForVoicemail(voicemail, contactInfos)); - } - } - - /** - * Replicates how packages/services/Telephony/NotificationMgr.java handles legacy voicemail - * notification. The notification will not be stackable because no information is available for - * individual voicemails. - */ - @TargetApi(VERSION_CODES.O) - public void notifyLegacyVoicemail( - @NonNull PhoneAccountHandle phoneAccountHandle, - int count, - String voicemailNumber, - PendingIntent callVoicemailIntent, - PendingIntent voicemailSettingIntent, - boolean isRefresh) { - Assert.isNotNull(phoneAccountHandle); - Assert.checkArgument(BuildCompat.isAtLeastO()); - TelephonyManager telephonyManager = - context - .getSystemService(TelephonyManager.class) - .createForPhoneAccountHandle(phoneAccountHandle); - if (telephonyManager == null) { - LogUtil.e(TAG, "invalid PhoneAccountHandle, ignoring"); - return; - } - LogUtil.i(TAG, "Creating legacy voicemail notification"); - - PersistableBundle carrierConfig = telephonyManager.getCarrierConfig(); - - String notificationTitle = - context - .getResources() - .getQuantityString(R.plurals.notification_voicemail_title, count, count); - - TelecomManager telecomManager = context.getSystemService(TelecomManager.class); - PhoneAccount phoneAccount = telecomManager.getPhoneAccount(phoneAccountHandle); - - String notificationText; - PendingIntent pendingIntent; - - if (voicemailSettingIntent != null) { - // If the voicemail number if unknown, instead of calling voicemail, take the user - // to the voicemail settings. - notificationText = context.getString(R.string.notification_voicemail_no_vm_number); - pendingIntent = voicemailSettingIntent; - } else { - if (PhoneAccountUtils.getSubscriptionPhoneAccounts(context).size() > 1) { - notificationText = phoneAccount.getShortDescription().toString(); - } else { - notificationText = - String.format( - context.getString(R.string.notification_voicemail_text_format), - PhoneNumberUtils.formatNumber(voicemailNumber)); - } - pendingIntent = callVoicemailIntent; - } - Notification.Builder builder = new Notification.Builder(context); - builder - .setSmallIcon(android.R.drawable.stat_notify_voicemail) - .setColor(context.getColor(R.color.dialer_theme_color)) - .setWhen(System.currentTimeMillis()) - .setContentTitle(notificationTitle) - .setContentText(notificationText) - .setContentIntent(pendingIntent) - .setSound(telephonyManager.getVoicemailRingtoneUri(phoneAccountHandle)) - .setOngoing( - carrierConfig.getBoolean( - CarrierConfigManager.KEY_VOICEMAIL_NOTIFICATION_PERSISTENT_BOOL)) - .setOnlyAlertOnce(isRefresh); - - if (telephonyManager.isVoicemailVibrationEnabled(phoneAccountHandle)) { - builder.setDefaults(Notification.DEFAULT_VIBRATE); - } - - NotificationChannelManager.applyChannel( - builder, context, Channel.VOICEMAIL, phoneAccountHandle); - Notification notification = builder.build(); - getNotificationManager() - .notify(LEGACY_VOICEMAIL_NOTIFICATION_TAG, LEGACY_VOICEMAIL_NOTIFICATION_ID, notification); - } - - public void cancelLegacyNotification() { - LogUtil.i(TAG, "Clearing legacy voicemail notification"); - getNotificationManager() - .cancel(LEGACY_VOICEMAIL_NOTIFICATION_TAG, LEGACY_VOICEMAIL_NOTIFICATION_ID); - } - - /** - * Determines which ringtone Uri and Notification defaults to use when updating the notification - * for the given call. - */ - private Pair getNotificationInfo(@Nullable NewCall callToNotify) { - LogUtil.v(TAG, "getNotificationInfo"); - if (callToNotify == null) { - LogUtil.i(TAG, "callToNotify == null"); - return new Pair<>(null, 0); - } - PhoneAccountHandle accountHandle = PhoneAccountHandles.getAccount(context, callToNotify); - if (accountHandle == null) { - LogUtil.i(TAG, "No default phone account found, using default notification ringtone"); - return new Pair<>(null, Notification.DEFAULT_ALL); - } - return new Pair<>( - TelephonyManagerCompat.getVoicemailRingtoneUri(getTelephonyManager(), accountHandle), - getNotificationDefaults(accountHandle)); - } - - private int getNotificationDefaults(PhoneAccountHandle accountHandle) { - if (VERSION.SDK_INT >= VERSION_CODES.N) { - return TelephonyManagerCompat.isVoicemailVibrationEnabled( - getTelephonyManager(), accountHandle) - ? Notification.DEFAULT_VIBRATE - : 0; - } - return Notification.DEFAULT_ALL; - } - - /** Creates a pending intent that marks all new voicemails as old. */ - private PendingIntent createMarkNewVoicemailsAsOldIntent(@Nullable Uri voicemailUri) { - Intent intent = new Intent(context, CallLogNotificationsService.class); - intent.setAction(CallLogNotificationsService.ACTION_MARK_NEW_VOICEMAILS_AS_OLD); - intent.setData(voicemailUri); - return PendingIntent.getService(context, 0, intent, 0); - } - - private NotificationManager getNotificationManager() { - return (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE); - } - - private TelephonyManager getTelephonyManager() { - return (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE); - } - - private Notification createNotificationForVoicemail( - @NonNull NewCall voicemail, @NonNull Map contactInfos) { - Pair notificationInfo = getNotificationInfo(voicemail); - ContactInfo contactInfo = contactInfos.get(voicemail.number); - - Notification.Builder notificationBuilder = - createNotificationBuilder() - .setContentTitle( - context - .getResources() - .getQuantityString(R.plurals.notification_voicemail_title, 1, 1)) - .setContentText( - ContactDisplayUtils.getTtsSpannedPhoneNumber( - context.getResources(), - R.string.notification_new_voicemail_ticker, - contactInfo.name)) - .setWhen(voicemail.dateMs) - .setSound(notificationInfo.first) - .setDefaults(notificationInfo.second); - - if (voicemail.voicemailUri != null) { - notificationBuilder.setDeleteIntent( - createMarkNewVoicemailsAsOldIntent(voicemail.voicemailUri)); - } - - NotificationChannelManager.applyChannel( - notificationBuilder, - context, - Channel.VOICEMAIL, - PhoneAccountHandles.getAccount(context, voicemail)); - - ContactPhotoLoader loader = new ContactPhotoLoader(context, contactInfo); - Bitmap photoIcon = loader.loadPhotoIcon(); - if (photoIcon != null) { - notificationBuilder.setLargeIcon(photoIcon); - } - if (!TextUtils.isEmpty(voicemail.transcription)) { - Logger.get(context) - .logImpression(DialerImpression.Type.VVM_NOTIFICATION_CREATED_WITH_TRANSCRIPTION); - notificationBuilder.setStyle( - new Notification.BigTextStyle().bigText(voicemail.transcription)); - } - notificationBuilder.setContentIntent(newVoicemailIntent(voicemail)); - Logger.get(context).logImpression(DialerImpression.Type.VVM_NOTIFICATION_CREATED); - return notificationBuilder.build(); - } - - private Notification.Builder createNotificationBuilder() { - return new Notification.Builder(context) - .setSmallIcon(android.R.drawable.stat_notify_voicemail) - .setColor(context.getColor(R.color.dialer_theme_color)) - .setGroup(VISUAL_VOICEMAIL_NOTIFICATION_TAG) - .setOnlyAlertOnce(true) - .setAutoCancel(true); - } - - private PendingIntent newVoicemailIntent(@Nullable NewCall voicemail) { - Intent intent = - DialtactsActivity.getShowTabIntent(context, DialtactsPagerAdapter.TAB_INDEX_VOICEMAIL); - // TODO (b/35486204): scroll to this voicemail - if (voicemail != null) { - intent.setData(voicemail.voicemailUri); - } - intent.putExtra(DialtactsActivity.EXTRA_CLEAR_NEW_VOICEMAILS, true); - return PendingIntent.getActivity(context, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT); - } - - /** - * Updates the voicemail notifications displayed. - * - * @param runnable Called when the async update task completes no matter if it succeeds or fails. - * May be null. - */ - static void updateVoicemailNotifications(Context context, Runnable runnable) { - if (!TelecomUtil.isDefaultDialer(context)) { - LogUtil.i( - "DefaultVoicemailNotifier.updateVoicemailNotifications", - "not default dialer, not scheduling update to voicemail notifications"); - return; - } - - DialerExecutors.createNonUiTaskBuilder(new DefaultVoicemailNotifier(context)) - .onSuccess( - output -> { - LogUtil.i( - "DefaultVoicemailNotifier.updateVoicemailNotifications", - "update voicemail notifications successful"); - if (runnable != null) { - runnable.run(); - } - }) - .onFailure( - throwable -> { - LogUtil.i( - "DefaultVoicemailNotifier.updateVoicemailNotifications", - "update voicemail notifications failed"); - if (runnable != null) { - runnable.run(); - } - }) - .build() - .executeParallel(null); - } -} diff --git a/java/com/android/dialer/app/calllog/DialerQuickContactBadge.java b/java/com/android/dialer/app/calllog/DialerQuickContactBadge.java new file mode 100644 index 000000000..a3aac41fa --- /dev/null +++ b/java/com/android/dialer/app/calllog/DialerQuickContactBadge.java @@ -0,0 +1,63 @@ +/* + * Copyright (C) 2017 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.dialer.app.calllog; + +import android.content.Context; +import android.util.AttributeSet; +import android.view.View; +import android.widget.QuickContactBadge; +import com.android.dialer.app.calllog.CallLogAdapter.OnActionModeStateChangedListener; +import com.android.dialer.logging.DialerImpression; +import com.android.dialer.logging.Logger; + +/** Allows us to click the contact badge for non multi select mode. */ +class DialerQuickContactBadge extends QuickContactBadge { + + private View.OnClickListener mExtraOnClickListener; + private OnActionModeStateChangedListener onActionModeStateChangeListener; + + public DialerQuickContactBadge(Context context) { + super(context); + } + + public DialerQuickContactBadge(Context context, AttributeSet attrs) { + super(context, attrs); + } + + public DialerQuickContactBadge(Context context, AttributeSet attrs, int defStyle) { + super(context, attrs, defStyle); + } + + @Override + public void onClick(View v) { + if (mExtraOnClickListener != null + && onActionModeStateChangeListener.isActionModeStateEnabled()) { + Logger.get(v.getContext()) + .logImpression(DialerImpression.Type.MULTISELECT_SINGLE_PRESS_TAP_VIA_CONTACT_BADGE); + mExtraOnClickListener.onClick(v); + } else { + super.onClick(v); + } + } + + public void setMulitSelectListeners( + View.OnClickListener extraOnClickListener, + OnActionModeStateChangedListener actionModeStateChangeListener) { + mExtraOnClickListener = extraOnClickListener; + onActionModeStateChangeListener = actionModeStateChangeListener; + } +} diff --git a/java/com/android/dialer/app/calllog/IntentProvider.java b/java/com/android/dialer/app/calllog/IntentProvider.java index 9c3c18b60..e1ec9f509 100644 --- a/java/com/android/dialer/app/calllog/IntentProvider.java +++ b/java/com/android/dialer/app/calllog/IntentProvider.java @@ -117,11 +117,12 @@ public abstract class IntentProvider { * @return The call details intent provider. */ public static IntentProvider getCallDetailIntentProvider( - CallDetailsEntries callDetailsEntries, DialerContact contact) { + CallDetailsEntries callDetailsEntries, DialerContact contact, boolean canReportCallerId) { return new IntentProvider() { @Override public Intent getIntent(Context context) { - return CallDetailsActivity.newInstance(context, callDetailsEntries, contact); + return CallDetailsActivity.newInstance( + context, callDetailsEntries, contact, canReportCallerId); } }; } diff --git a/java/com/android/dialer/app/calllog/LegacyVoicemailNotifier.java b/java/com/android/dialer/app/calllog/LegacyVoicemailNotifier.java new file mode 100644 index 000000000..428c71677 --- /dev/null +++ b/java/com/android/dialer/app/calllog/LegacyVoicemailNotifier.java @@ -0,0 +1,156 @@ +/* + * Copyright (C) 2017 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.dialer.app.calllog; + +import android.annotation.TargetApi; +import android.app.Notification; +import android.app.NotificationManager; +import android.app.PendingIntent; +import android.content.Context; +import android.os.Build.VERSION_CODES; +import android.support.annotation.NonNull; +import android.support.v4.os.BuildCompat; +import android.telecom.PhoneAccount; +import android.telecom.PhoneAccountHandle; +import android.telecom.TelecomManager; +import android.telephony.CarrierConfigManager; +import android.telephony.PhoneNumberUtils; +import android.telephony.TelephonyManager; +import android.text.TextUtils; +import com.android.dialer.app.R; +import com.android.dialer.calllogutils.PhoneAccountUtils; +import com.android.dialer.common.Assert; +import com.android.dialer.common.LogUtil; +import com.android.dialer.notification.NotificationChannelManager; + +/** Shows a notification in the status bar for legacy vociemail. */ +@TargetApi(VERSION_CODES.O) +public final class LegacyVoicemailNotifier { + private static final String NOTIFICATION_TAG = "LegacyVoicemail"; + private static final int NOTIFICATION_ID = 1; + + /** + * Replicates how packages/services/Telephony/NotificationMgr.java handles legacy voicemail + * notification. The notification will not be stackable because no information is available for + * individual voicemails. + */ + public static void showNotification( + @NonNull Context context, + @NonNull PhoneAccountHandle handle, + int count, + String voicemailNumber, + PendingIntent callVoicemailIntent, + PendingIntent voicemailSettingsIntent, + boolean isRefresh) { + LogUtil.enterBlock("LegacyVoicemailNotifier.showNotification"); + Assert.isNotNull(handle); + Assert.checkArgument(BuildCompat.isAtLeastO()); + + TelephonyManager pinnedTelephonyManager = + context.getSystemService(TelephonyManager.class).createForPhoneAccountHandle(handle); + if (pinnedTelephonyManager == null) { + LogUtil.e("LegacyVoicemailNotifier.showNotification", "invalid PhoneAccountHandle"); + return; + } + + Notification notification = + createNotification( + context, + pinnedTelephonyManager, + handle, + count, + voicemailNumber, + callVoicemailIntent, + voicemailSettingsIntent, + isRefresh); + context + .getSystemService(NotificationManager.class) + .notify(NOTIFICATION_TAG, NOTIFICATION_ID, notification); + } + + @NonNull + private static Notification createNotification( + @NonNull Context context, + @NonNull TelephonyManager pinnedTelephonyManager, + @NonNull PhoneAccountHandle handle, + int count, + String voicemailNumber, + PendingIntent callVoicemailIntent, + PendingIntent voicemailSettingsIntent, + boolean isRefresh) { + String notificationTitle = + context + .getResources() + .getQuantityString(R.plurals.notification_voicemail_title, count, count); + boolean isOngoing = + pinnedTelephonyManager + .getCarrierConfig() + .getBoolean(CarrierConfigManager.KEY_VOICEMAIL_NOTIFICATION_PERSISTENT_BOOL); + + String contentText; + PendingIntent contentIntent; + if (!TextUtils.isEmpty(voicemailNumber) && callVoicemailIntent != null) { + contentText = getNotificationText(context, handle, voicemailNumber); + contentIntent = callVoicemailIntent; + } else { + contentText = context.getString(R.string.notification_voicemail_no_vm_number); + contentIntent = voicemailSettingsIntent; + } + + Notification.Builder builder = + new Notification.Builder(context) + .setSmallIcon(android.R.drawable.stat_notify_voicemail) + .setColor(context.getColor(R.color.dialer_theme_color)) + .setWhen(System.currentTimeMillis()) + .setContentTitle(notificationTitle) + .setContentText(contentText) + .setContentIntent(contentIntent) + .setSound(pinnedTelephonyManager.getVoicemailRingtoneUri(handle)) + .setOngoing(isOngoing) + .setOnlyAlertOnce(isRefresh) + .setChannelId(NotificationChannelManager.getVoicemailChannelId(context, handle)); + + if (pinnedTelephonyManager.isVoicemailVibrationEnabled(handle)) { + builder.setDefaults(Notification.DEFAULT_VIBRATE); + } + + return builder.build(); + } + + @NonNull + private static String getNotificationText( + @NonNull Context context, PhoneAccountHandle handle, String voicemailNumber) { + if (PhoneAccountUtils.getSubscriptionPhoneAccounts(context).size() > 1) { + TelecomManager telecomManager = context.getSystemService(TelecomManager.class); + PhoneAccount phoneAccount = telecomManager.getPhoneAccount(handle); + return phoneAccount.getShortDescription().toString(); + } else { + return String.format( + context.getString(R.string.notification_voicemail_text_format), + PhoneNumberUtils.formatNumber(voicemailNumber)); + } + } + + public static void cancelNotification(@NonNull Context context) { + LogUtil.enterBlock("LegacyVoicemailNotifier.cancelNotification"); + Assert.checkArgument(BuildCompat.isAtLeastO()); + NotificationManager notificationManager = context.getSystemService(NotificationManager.class); + notificationManager.cancel(NOTIFICATION_TAG, NOTIFICATION_ID); + } + + private LegacyVoicemailNotifier() {} +} diff --git a/java/com/android/dialer/app/calllog/MissedCallNotifier.java b/java/com/android/dialer/app/calllog/MissedCallNotifier.java index dd13298bc..e0e3fdf3f 100644 --- a/java/com/android/dialer/app/calllog/MissedCallNotifier.java +++ b/java/com/android/dialer/app/calllog/MissedCallNotifier.java @@ -30,11 +30,13 @@ import android.support.annotation.NonNull; import android.support.annotation.Nullable; import android.support.annotation.VisibleForTesting; import android.support.annotation.WorkerThread; +import android.support.v4.os.BuildCompat; import android.support.v4.os.UserManagerCompat; import android.support.v4.util.Pair; import android.text.BidiFormatter; import android.text.TextDirectionHeuristics; import android.text.TextUtils; +import android.util.ArraySet; import com.android.contacts.common.ContactsUtils; import com.android.contacts.common.compat.PhoneNumberUtilsCompat; import com.android.dialer.app.DialtactsActivity; @@ -46,23 +48,20 @@ import com.android.dialer.callintent.CallInitiationType; import com.android.dialer.callintent.CallIntentBuilder; import com.android.dialer.common.LogUtil; import com.android.dialer.common.concurrent.DialerExecutor.Worker; -import com.android.dialer.notification.NotificationChannelManager; -import com.android.dialer.notification.NotificationChannelManager.Channel; +import com.android.dialer.notification.NotificationChannelId; import com.android.dialer.phonenumbercache.ContactInfo; import com.android.dialer.phonenumberutil.PhoneNumberHelper; import com.android.dialer.util.DialerUtils; import com.android.dialer.util.IntentUtil; -import java.util.HashSet; import java.util.List; import java.util.Set; /** Creates a notification for calls that the user missed (neither answered nor rejected). */ public class MissedCallNotifier implements Worker, Void> { - /** The tag used to identify notifications from this class. */ - static final String NOTIFICATION_TAG = "MissedCallNotifier"; - /** The identifier of the notification of new missed calls. */ - private static final int NOTIFICATION_ID = R.id.notification_missed_call; + static final String NOTIFICATION_TAG_PREFIX = "MissedCall_"; + static final String NOTIFICATION_GROUP = "MissedCall"; + private static final int NOTIFICATION_ID = 1; private final Context context; private final CallLogNotificationsQueryHelper callLogNotificationsQueryHelper; @@ -104,7 +103,8 @@ public class MissedCallNotifier implements Worker, Void> { if ((newCalls != null && newCalls.isEmpty()) || count == 0) { // No calls to notify about: clear the notification. - CallLogNotificationsQueryHelper.removeMissedCallNotifications(context, null); + CallLogNotificationsQueryHelper.markAllMissedCallsInCallLogAsRead(context); + cancelAllMissedCallNotifications(context); return; } @@ -146,7 +146,7 @@ public class MissedCallNotifier implements Worker, Void> { null, System.currentTimeMillis()); - //TODO: look up caller ID that is not in contacts. + // TODO: look up caller ID that is not in contacts. ContactInfo contactInfo = callLogNotificationsQueryHelper.getContactInfo( call.number, call.numberPresentation, call.countryIso); @@ -181,36 +181,39 @@ public class MissedCallNotifier implements Worker, Void> { publicSummaryBuilder .setContentTitle(context.getText(titleResId)) .setContentIntent(createCallLogPendingIntent()) - .setDeleteIntent(createClearMissedCallsPendingIntent(null)); + .setDeleteIntent( + CallLogNotificationsService.createCancelAllMissedCallsPendingIntent(context)); // Create the notification summary suitable for display when sensitive information is showing. groupSummary .setContentTitle(context.getText(titleResId)) .setContentText(expandedText) .setContentIntent(createCallLogPendingIntent()) - .setDeleteIntent(createClearMissedCallsPendingIntent(null)) + .setDeleteIntent( + CallLogNotificationsService.createCancelAllMissedCallsPendingIntent(context)) .setGroupSummary(useCallList) .setOnlyAlertOnce(useCallList) .setPublicVersion(publicSummaryBuilder.build()); - - NotificationChannelManager.applyChannel(groupSummary, context, Channel.MISSED_CALL, null); + if (BuildCompat.isAtLeastO()) { + groupSummary.setChannelId(NotificationChannelId.MISSED_CALL); + } Notification notification = groupSummary.build(); configureLedOnNotification(notification); LogUtil.i("MissedCallNotifier.updateMissedCallNotification", "adding missed call notification"); - getNotificationMgr().notify(NOTIFICATION_TAG, NOTIFICATION_ID, notification); + getNotificationMgr().notify(getNotificationTagForGroupSummary(), NOTIFICATION_ID, notification); if (useCallList) { // Do not repost active notifications to prevent erasing post call notes. NotificationManager manager = getNotificationMgr(); - Set activeTags = new HashSet<>(); + Set activeTags = new ArraySet<>(); for (StatusBarNotification activeNotification : manager.getActiveNotifications()) { activeTags.add(activeNotification.getTag()); } for (NewCall call : newCalls) { - String callTag = call.callsUri.toString(); + String callTag = getNotificationTagForCall(call); if (!activeTags.contains(callTag)) { manager.notify(callTag, NOTIFICATION_ID, getNotificationForCall(call, null)); } @@ -218,6 +221,59 @@ public class MissedCallNotifier implements Worker, Void> { } } + public static void cancelAllMissedCallNotifications(@NonNull Context context) { + NotificationManager notificationManager = context.getSystemService(NotificationManager.class); + for (StatusBarNotification notification : notificationManager.getActiveNotifications()) { + String tag = notification.getTag(); + if (tag != null && tag.startsWith(NOTIFICATION_TAG_PREFIX)) { + notificationManager.cancel(tag, notification.getId()); + } + } + } + + public static void cancelSingleMissedCallNotification( + @NonNull Context context, @Nullable Uri callUri) { + if (callUri == null) { + LogUtil.e( + "MissedCallNotifier.cancelSingleMissedCallNotification", + "unable to cancel notification, uri is null"); + return; + } + NotificationManager notificationManager = context.getSystemService(NotificationManager.class); + String callTag = getNotificationTagForCallUri(callUri); + String summaryTag = getNotificationTagForGroupSummary(); + int notificationCount = 0; + + for (StatusBarNotification notification : notificationManager.getActiveNotifications()) { + String currentTag = notification.getTag(); + if (currentTag == null) { + continue; + } + if (currentTag.equals(callTag)) { + notificationManager.cancel(notification.getTag(), notification.getId()); + } else if (currentTag.startsWith(NOTIFICATION_TAG_PREFIX) && !currentTag.equals(summaryTag)) { + notificationCount++; + } + } + + if (notificationCount == 0) { + // There are no more missed call notifications. Remove the summary notification too. + notificationManager.cancel(summaryTag, NOTIFICATION_ID); + } + } + + private static String getNotificationTagForGroupSummary() { + return NOTIFICATION_TAG_PREFIX + "GroupSummary"; + } + + private static String getNotificationTagForCall(@NonNull NewCall call) { + return getNotificationTagForCallUri(call.callsUri); + } + + private static String getNotificationTagForCallUri(@NonNull Uri callUri) { + return NOTIFICATION_TAG_PREFIX + callUri; + } + public void insertPostCallNotification(@NonNull String number, @NonNull String note) { List newCalls = callLogNotificationsQueryHelper.getNewMissedCalls(); if (newCalls != null && !newCalls.isEmpty()) { @@ -226,7 +282,9 @@ public class MissedCallNotifier implements Worker, Void> { // Update the first notification that matches our post call note sender. getNotificationMgr() .notify( - call.callsUri.toString(), NOTIFICATION_ID, getNotificationForCall(call, note)); + getNotificationTagForCall(call), + NOTIFICATION_ID, + getNotificationForCall(call, note)); break; } } @@ -308,7 +366,7 @@ public class MissedCallNotifier implements Worker, Void> { private Notification.Builder createNotificationBuilder() { return new Notification.Builder(context) - .setGroup(NOTIFICATION_TAG) + .setGroup(NOTIFICATION_GROUP) .setSmallIcon(android.R.drawable.stat_notify_missed_call) .setColor(context.getResources().getColor(R.color.dialer_theme_color, null)) .setAutoCancel(true) @@ -321,10 +379,14 @@ public class MissedCallNotifier implements Worker, Void> { Builder builder = createNotificationBuilder() .setWhen(call.dateMs) - .setDeleteIntent(createClearMissedCallsPendingIntent(call.callsUri)) + .setDeleteIntent( + CallLogNotificationsService.createCancelSingleMissedCallPendingIntent( + context, call.callsUri)) .setContentIntent(createCallLogPendingIntent(call.callsUri)); + if (BuildCompat.isAtLeastO()) { + builder.setChannelId(NotificationChannelId.MISSED_CALL); + } - NotificationChannelManager.applyChannel(builder, context, Channel.MISSED_CALL, null); return builder; } @@ -332,7 +394,8 @@ public class MissedCallNotifier implements Worker, Void> { @WorkerThread public void callBackFromMissedCall(String number, Uri callUri) { closeSystemDialogs(context); - CallLogNotificationsQueryHelper.removeMissedCallNotifications(context, callUri); + CallLogNotificationsQueryHelper.markSingleMissedCallInCallLogAsRead(context, callUri); + cancelSingleMissedCallNotification(context, callUri); DialerUtils.startActivityWithErrorToast( context, new CallIntentBuilder(number, CallInitiationType.Type.MISSED_CALL_NOTIFICATION) @@ -343,7 +406,8 @@ public class MissedCallNotifier implements Worker, Void> { /** Trigger an intent to send an sms from a missed call number. */ public void sendSmsFromMissedCall(String number, Uri callUri) { closeSystemDialogs(context); - CallLogNotificationsQueryHelper.removeMissedCallNotifications(context, callUri); + CallLogNotificationsQueryHelper.markSingleMissedCallInCallLogAsRead(context, callUri); + cancelSingleMissedCallNotification(context, callUri); DialerUtils.startActivityWithErrorToast( context, IntentUtil.getSendSmsIntent(number).setFlags(Intent.FLAG_ACTIVITY_NEW_TASK)); } @@ -371,14 +435,6 @@ public class MissedCallNotifier implements Worker, Void> { return PendingIntent.getActivity(context, 0, contentIntent, PendingIntent.FLAG_UPDATE_CURRENT); } - /** Creates a pending intent that marks all new missed calls as old. */ - private PendingIntent createClearMissedCallsPendingIntent(@Nullable Uri callUri) { - Intent intent = new Intent(context, CallLogNotificationsService.class); - intent.setAction(CallLogNotificationsService.ACTION_MARK_NEW_MISSED_CALLS_AS_OLD); - intent.setData(callUri); - return PendingIntent.getService(context, 0, intent, 0); - } - private PendingIntent createCallBackPendingIntent(String number, @NonNull Uri callUri) { Intent intent = new Intent(context, CallLogNotificationsService.class); intent.setAction(CallLogNotificationsService.ACTION_CALL_BACK_FROM_MISSED_CALL_NOTIFICATION); diff --git a/java/com/android/dialer/app/calllog/PhoneAccountHandles.java b/java/com/android/dialer/app/calllog/PhoneAccountHandles.java deleted file mode 100644 index acffffb1d..000000000 --- a/java/com/android/dialer/app/calllog/PhoneAccountHandles.java +++ /dev/null @@ -1,62 +0,0 @@ -/* - * Copyright (C) 2017 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.dialer.app.calllog; - -import android.content.ComponentName; -import android.content.Context; -import android.support.annotation.NonNull; -import android.support.annotation.Nullable; -import android.telecom.PhoneAccount; -import android.telecom.PhoneAccountHandle; -import com.android.dialer.app.calllog.CallLogNotificationsQueryHelper.NewCall; -import com.android.dialer.common.LogUtil; -import com.android.dialer.telecom.TelecomUtil; -import java.util.List; - -/** Methods to help extract {@link PhoneAccount} information from database and Telecomm sources. */ -class PhoneAccountHandles { - - @Nullable - public static PhoneAccountHandle getAccount(@NonNull Context context, @Nullable NewCall call) { - PhoneAccountHandle handle; - if (call == null || call.accountComponentName == null || call.accountId == null) { - LogUtil.v( - "PhoneAccountUtils.getAccount", - "accountComponentName == null || callToNotify.accountId == null"); - handle = TelecomUtil.getDefaultOutgoingPhoneAccount(context, PhoneAccount.SCHEME_TEL); - if (handle == null) { - List callCapablePhoneAccounts = - TelecomUtil.getCallCapablePhoneAccounts(context); - if (!callCapablePhoneAccounts.isEmpty()) { - return callCapablePhoneAccounts.get(0); - } - return null; - } - } else { - handle = - new PhoneAccountHandle( - ComponentName.unflattenFromString(call.accountComponentName), call.accountId); - } - if (handle.getComponentName() != null) { - LogUtil.v( - "PhoneAccountUtils.getAccount", - "PhoneAccountHandle.ComponentInfo:" + handle.getComponentName()); - } else { - LogUtil.i("PhoneAccountUtils.getAccount", "PhoneAccountHandle.ComponentInfo: null"); - } - return handle; - } -} diff --git a/java/com/android/dialer/app/calllog/VisualVoicemailNotifier.java b/java/com/android/dialer/app/calllog/VisualVoicemailNotifier.java new file mode 100644 index 000000000..99fe466d8 --- /dev/null +++ b/java/com/android/dialer/app/calllog/VisualVoicemailNotifier.java @@ -0,0 +1,291 @@ +/* + * Copyright (C) 2017 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.dialer.app.calllog; + +import android.app.Notification; +import android.app.NotificationManager; +import android.app.PendingIntent; +import android.content.ComponentName; +import android.content.Context; +import android.content.Intent; +import android.graphics.Bitmap; +import android.net.Uri; +import android.os.Build.VERSION; +import android.os.Build.VERSION_CODES; +import android.service.notification.StatusBarNotification; +import android.support.annotation.NonNull; +import android.support.annotation.Nullable; +import android.support.v4.os.BuildCompat; +import android.telecom.PhoneAccount; +import android.telecom.PhoneAccountHandle; +import android.telephony.TelephonyManager; +import android.text.TextUtils; +import com.android.contacts.common.util.ContactDisplayUtils; +import com.android.dialer.app.DialtactsActivity; +import com.android.dialer.app.R; +import com.android.dialer.app.calllog.CallLogNotificationsQueryHelper.NewCall; +import com.android.dialer.app.contactinfo.ContactPhotoLoader; +import com.android.dialer.app.list.DialtactsPagerAdapter; +import com.android.dialer.common.LogUtil; +import com.android.dialer.logging.DialerImpression; +import com.android.dialer.logging.Logger; +import com.android.dialer.notification.NotificationChannelManager; +import com.android.dialer.phonenumbercache.ContactInfo; +import com.android.dialer.telecom.TelecomUtil; +import java.util.List; +import java.util.Map; + +/** Shows a notification in the status bar for visual voicemail. */ +final class VisualVoicemailNotifier { + private static final String NOTIFICATION_TAG_PREFIX = "VisualVoicemail_"; + private static final String NOTIFICATION_GROUP = "VisualVoicemail"; + private static final int NOTIFICATION_ID = 1; + + public static void showNotifications( + @NonNull Context context, + @NonNull List newCalls, + @NonNull Map contactInfos, + @Nullable String callers) { + LogUtil.enterBlock("VisualVoicemailNotifier.showNotifications"); + PendingIntent deleteIntent = + CallLogNotificationsService.createMarkAllNewVoicemailsAsOldIntent(context); + String contentTitle = + context + .getResources() + .getQuantityString( + R.plurals.notification_voicemail_title, newCalls.size(), newCalls.size()); + Notification.Builder groupSummary = + createNotificationBuilder(context) + .setContentTitle(contentTitle) + .setContentText(callers) + .setDeleteIntent(deleteIntent) + .setGroupSummary(true) + .setContentIntent(newVoicemailIntent(context, null)); + + if (BuildCompat.isAtLeastO()) { + groupSummary.setGroupAlertBehavior(Notification.GROUP_ALERT_CHILDREN); + PhoneAccountHandle handle = getAccountForCall(context, newCalls.get(0)); + groupSummary.setChannelId(NotificationChannelManager.getVoicemailChannelId(context, handle)); + } + + NotificationManager notificationManager = context.getSystemService(NotificationManager.class); + notificationManager.notify( + getNotificationTagForGroupSummary(), NOTIFICATION_ID, groupSummary.build()); + + for (NewCall voicemail : newCalls) { + notificationManager.notify( + getNotificationTagForVoicemail(voicemail), + NOTIFICATION_ID, + createNotificationForVoicemail(context, voicemail, contactInfos)); + } + } + + public static void cancelAllVoicemailNotifications(@NonNull Context context) { + LogUtil.enterBlock("VisualVoicemailNotifier.cancelAllVoicemailNotifications"); + NotificationManager notificationManager = context.getSystemService(NotificationManager.class); + for (StatusBarNotification notification : notificationManager.getActiveNotifications()) { + String tag = notification.getTag(); + if (tag != null && tag.startsWith(NOTIFICATION_TAG_PREFIX)) { + notificationManager.cancel(tag, notification.getId()); + } + } + } + + public static void cancelSingleVoicemailNotification( + @NonNull Context context, @Nullable Uri voicemailUri) { + LogUtil.enterBlock("VisualVoicemailNotifier.cancelSingleVoicemailNotification"); + if (voicemailUri == null) { + LogUtil.e("VisualVoicemailNotifier.cancelSingleVoicemailNotification", "uri is null"); + return; + } + NotificationManager notificationManager = context.getSystemService(NotificationManager.class); + String voicemailTag = getNotificationTagForUri(voicemailUri); + String summaryTag = getNotificationTagForGroupSummary(); + int notificationCount = 0; + + for (StatusBarNotification notification : notificationManager.getActiveNotifications()) { + String currentTag = notification.getTag(); + if (currentTag == null) { + continue; + } + if (currentTag.equals(voicemailTag)) { + notificationManager.cancel(notification.getTag(), notification.getId()); + } else if (currentTag.startsWith(NOTIFICATION_TAG_PREFIX) && !currentTag.equals(summaryTag)) { + notificationCount++; + } + } + + if (notificationCount == 0) { + // There are no more visual voicemail notifications. Remove the summary notification too. + notificationManager.cancel(summaryTag, NOTIFICATION_ID); + } + } + + private static String getNotificationTagForVoicemail(@NonNull NewCall voicemail) { + return getNotificationTagForUri(voicemail.voicemailUri); + } + + private static String getNotificationTagForUri(@NonNull Uri voicemailUri) { + return NOTIFICATION_TAG_PREFIX + voicemailUri; + } + + private static String getNotificationTagForGroupSummary() { + return NOTIFICATION_TAG_PREFIX + "GroupSummary"; + } + + private static Notification.Builder createNotificationBuilder(@NonNull Context context) { + return new Notification.Builder(context) + .setSmallIcon(android.R.drawable.stat_notify_voicemail) + .setColor(context.getColor(R.color.dialer_theme_color)) + .setGroup(NOTIFICATION_GROUP) + .setOnlyAlertOnce(true) + .setAutoCancel(true); + } + + private static Notification createNotificationForVoicemail( + @NonNull Context context, + @NonNull NewCall voicemail, + @NonNull Map contactInfos) { + PhoneAccountHandle handle = getAccountForCall(context, voicemail); + ContactInfo contactInfo = contactInfos.get(voicemail.number); + + Notification.Builder builder = + createNotificationBuilder(context) + .setContentTitle( + context + .getResources() + .getQuantityString(R.plurals.notification_voicemail_title, 1, 1)) + .setContentText( + ContactDisplayUtils.getTtsSpannedPhoneNumber( + context.getResources(), + R.string.notification_new_voicemail_ticker, + contactInfo.name)) + .setWhen(voicemail.dateMs) + .setSound(getVoicemailRingtoneUri(context, handle)) + .setDefaults(getNotificationDefaultFlags(context, handle)); + + if (voicemail.voicemailUri != null) { + builder.setDeleteIntent( + CallLogNotificationsService.createMarkSingleNewVoicemailAsOldIntent( + context, voicemail.voicemailUri)); + } + + if (BuildCompat.isAtLeastO()) { + builder.setChannelId(NotificationChannelManager.getVoicemailChannelId(context, handle)); + } + + ContactPhotoLoader loader = new ContactPhotoLoader(context, contactInfo); + Bitmap photoIcon = loader.loadPhotoIcon(); + if (photoIcon != null) { + builder.setLargeIcon(photoIcon); + } + if (!TextUtils.isEmpty(voicemail.transcription)) { + Logger.get(context) + .logImpression(DialerImpression.Type.VVM_NOTIFICATION_CREATED_WITH_TRANSCRIPTION); + builder.setStyle(new Notification.BigTextStyle().bigText(voicemail.transcription)); + } + builder.setContentIntent(newVoicemailIntent(context, voicemail)); + Logger.get(context).logImpression(DialerImpression.Type.VVM_NOTIFICATION_CREATED); + return builder.build(); + } + + @Nullable + private static Uri getVoicemailRingtoneUri( + @NonNull Context context, @Nullable PhoneAccountHandle handle) { + if (VERSION.SDK_INT < VERSION_CODES.N) { + return null; + } + if (handle == null) { + LogUtil.i("VisualVoicemailNotifier.getVoicemailRingtoneUri", "null handle, getting fallback"); + handle = getFallbackAccount(context); + if (handle == null) { + LogUtil.i( + "VisualVoicemailNotifier.getVoicemailRingtoneUri", + "no fallback handle, using null (default) ringtone"); + return null; + } + } + return context.getSystemService(TelephonyManager.class).getVoicemailRingtoneUri(handle); + } + + private static int getNotificationDefaultFlags( + @NonNull Context context, @Nullable PhoneAccountHandle handle) { + if (VERSION.SDK_INT < VERSION_CODES.N) { + return Notification.DEFAULT_ALL; + } + if (handle == null) { + LogUtil.i( + "VisualVoicemailNotifier.getNotificationDefaultFlags", "null handle, getting fallback"); + handle = getFallbackAccount(context); + if (handle == null) { + LogUtil.i( + "VisualVoicemailNotifier.getNotificationDefaultFlags", + "no fallback handle, using default vibration"); + return Notification.DEFAULT_ALL; + } + } + if (context.getSystemService(TelephonyManager.class).isVoicemailVibrationEnabled(handle)) { + return Notification.DEFAULT_VIBRATE; + } + return 0; + } + + private static PendingIntent newVoicemailIntent( + @NonNull Context context, @Nullable NewCall voicemail) { + Intent intent = + DialtactsActivity.getShowTabIntent(context, DialtactsPagerAdapter.TAB_INDEX_VOICEMAIL); + // TODO (b/35486204): scroll to this voicemail + if (voicemail != null) { + intent.setData(voicemail.voicemailUri); + } + intent.putExtra(DialtactsActivity.EXTRA_CLEAR_NEW_VOICEMAILS, true); + return PendingIntent.getActivity(context, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT); + } + + /** + * Gets a phone account for the given call entry. This could be null if SIM associated with the + * entry is no longer in the device or for other reasons (for example, modem reboot). + */ + @Nullable + public static PhoneAccountHandle getAccountForCall( + @NonNull Context context, @Nullable NewCall call) { + if (call == null || call.accountComponentName == null || call.accountId == null) { + return null; + } + return new PhoneAccountHandle( + ComponentName.unflattenFromString(call.accountComponentName), call.accountId); + } + + /** + * Gets any available phone account that can be used to get sound settings for voicemail. This is + * only called if the phone account for the voicemail entry can't be found. + */ + @Nullable + public static PhoneAccountHandle getFallbackAccount(@NonNull Context context) { + PhoneAccountHandle handle = + TelecomUtil.getDefaultOutgoingPhoneAccount(context, PhoneAccount.SCHEME_TEL); + if (handle == null) { + List handles = TelecomUtil.getCallCapablePhoneAccounts(context); + if (!handles.isEmpty()) { + handle = handles.get(0); + } + } + return handle; + } + + private VisualVoicemailNotifier() {} +} diff --git a/java/com/android/dialer/app/calllog/VisualVoicemailUpdateTask.java b/java/com/android/dialer/app/calllog/VisualVoicemailUpdateTask.java new file mode 100644 index 000000000..d6601be36 --- /dev/null +++ b/java/com/android/dialer/app/calllog/VisualVoicemailUpdateTask.java @@ -0,0 +1,168 @@ +/* + * 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.dialer.app.calllog; + +import android.content.Context; +import android.support.annotation.NonNull; +import android.support.annotation.Nullable; +import android.support.annotation.WorkerThread; +import android.text.TextUtils; +import android.util.ArrayMap; +import com.android.dialer.app.R; +import com.android.dialer.app.calllog.CallLogNotificationsQueryHelper.NewCall; +import com.android.dialer.blocking.FilteredNumberAsyncQueryHandler; +import com.android.dialer.blocking.FilteredNumbersUtil; +import com.android.dialer.common.Assert; +import com.android.dialer.common.LogUtil; +import com.android.dialer.common.concurrent.DialerExecutor.Worker; +import com.android.dialer.common.concurrent.DialerExecutors; +import com.android.dialer.phonenumbercache.ContactInfo; +import com.android.dialer.telecom.TelecomUtil; +import java.util.ArrayList; +import java.util.List; +import java.util.Map; + +/** Updates voicemail notifications in the background. */ +class VisualVoicemailUpdateTask implements Worker { + @Nullable + @Override + public Void doInBackground(@NonNull Input input) throws Throwable { + updateNotification(input.context, input.queryHelper, input.queryHandler); + return null; + } + + /** + * Updates the notification and notifies of the call with the given URI. + * + *

Clears the notification if there are no new voicemails, and notifies if the given URI + * corresponds to a new voicemail. + */ + @WorkerThread + private static void updateNotification( + Context context, + CallLogNotificationsQueryHelper queryHelper, + FilteredNumberAsyncQueryHandler queryHandler) { + Assert.isWorkerThread(); + + List newCalls = queryHelper.getNewVoicemails(); + if (newCalls == null) { + return; + } + newCalls = filterBlockedNumbers(context, queryHandler, newCalls); + if (newCalls.isEmpty()) { + return; + } + + // This represents a list of names to include in the notification. + String callers = null; + + // Maps each number into a name: if a number is in the map, it has already left a more + // recent voicemail. + Map contactInfos = new ArrayMap<>(); + for (NewCall newCall : newCalls) { + if (!contactInfos.containsKey(newCall.number)) { + ContactInfo contactInfo = + queryHelper.getContactInfo( + newCall.number, newCall.numberPresentation, newCall.countryIso); + contactInfos.put(newCall.number, contactInfo); + + // This is a new caller. Add it to the back of the list of callers. + if (TextUtils.isEmpty(callers)) { + callers = contactInfo.name; + } else { + callers = + context.getString( + R.string.notification_voicemail_callers_list, callers, contactInfo.name); + } + } + } + VisualVoicemailNotifier.showNotifications(context, newCalls, contactInfos, callers); + } + + @WorkerThread + private static List filterBlockedNumbers( + Context context, FilteredNumberAsyncQueryHandler queryHandler, List newCalls) { + Assert.isWorkerThread(); + if (FilteredNumbersUtil.hasRecentEmergencyCall(context)) { + LogUtil.i( + "VisualVoicemailUpdateTask.filterBlockedNumbers", + "not filtering due to recent emergency call"); + return newCalls; + } + + List result = new ArrayList<>(); + for (NewCall newCall : newCalls) { + if (queryHandler.getBlockedIdSynchronous(newCall.number, newCall.countryIso) != null) { + LogUtil.i( + "VisualVoicemailUpdateTask.filterBlockedNumbers", + "found voicemail from blocked number, deleting"); + if (newCall.voicemailUri != null) { + // Delete the voicemail. + CallLogAsyncTaskUtil.deleteVoicemailSynchronous(context, newCall.voicemailUri); + } + } else { + result.add(newCall); + } + } + return result; + } + + /** Updates the voicemail notifications displayed. */ + static void scheduleTask(@NonNull Context context, @NonNull Runnable callback) { + Assert.isNotNull(context); + Assert.isNotNull(callback); + if (!TelecomUtil.isDefaultDialer(context)) { + LogUtil.i("VisualVoicemailUpdateTask.scheduleTask", "not default dialer, not running"); + callback.run(); + return; + } + + Input input = + new Input( + context, + CallLogNotificationsQueryHelper.getInstance(context), + new FilteredNumberAsyncQueryHandler(context)); + DialerExecutors.createNonUiTaskBuilder(new VisualVoicemailUpdateTask()) + .onSuccess( + output -> { + LogUtil.i("VisualVoicemailUpdateTask.scheduleTask", "update successful"); + callback.run(); + }) + .onFailure( + throwable -> { + LogUtil.i("VisualVoicemailUpdateTask.scheduleTask", "update failed: " + throwable); + callback.run(); + }) + .build() + .executeParallel(input); + } + + static class Input { + @NonNull final Context context; + @NonNull final CallLogNotificationsQueryHelper queryHelper; + @NonNull final FilteredNumberAsyncQueryHandler queryHandler; + + Input( + Context context, + CallLogNotificationsQueryHelper queryHelper, + FilteredNumberAsyncQueryHandler queryHandler) { + this.context = context; + this.queryHelper = queryHelper; + this.queryHandler = queryHandler; + } + } +} diff --git a/java/com/android/dialer/app/calllog/VoicemailQueryHandler.java b/java/com/android/dialer/app/calllog/VoicemailQueryHandler.java index 777f4c79f..2fbebdd30 100644 --- a/java/com/android/dialer/app/calllog/VoicemailQueryHandler.java +++ b/java/com/android/dialer/app/calllog/VoicemailQueryHandler.java @@ -15,7 +15,6 @@ */ package com.android.dialer.app.calllog; -import android.app.NotificationManager; import android.content.AsyncQueryHandler; import android.content.ContentResolver; import android.content.ContentValues; @@ -23,30 +22,49 @@ import android.content.Context; import android.net.Uri; import android.provider.CallLog.Calls; import android.support.annotation.MainThread; +import android.support.annotation.NonNull; import android.support.annotation.Nullable; -import com.android.dialer.app.R; +import android.support.annotation.WorkerThread; import com.android.dialer.common.Assert; -import com.android.dialer.notification.GroupedNotificationUtil; +import com.android.dialer.common.LogUtil; +import com.android.dialer.common.concurrent.ThreadUtil; /** Handles asynchronous queries to the call log for voicemail. */ public class VoicemailQueryHandler extends AsyncQueryHandler { - private static final String TAG = "VoicemailQueryHandler"; - /** The token for the query to mark all new voicemails as old. */ private static final int UPDATE_MARK_VOICEMAILS_AS_OLD_TOKEN = 50; - private Context mContext; - @MainThread - public VoicemailQueryHandler(Context context, ContentResolver contentResolver) { + private VoicemailQueryHandler(ContentResolver contentResolver) { super(contentResolver); Assert.isMainThread(); - mContext = context; + } + + @WorkerThread + public static void markAllNewVoicemailsAsRead(final @NonNull Context context) { + ThreadUtil.postOnUiThread( + () -> { + new VoicemailQueryHandler(context.getContentResolver()).markNewVoicemailsAsOld(null); + }); + } + + @WorkerThread + public static void markSingleNewVoicemailAsRead( + final @NonNull Context context, final Uri voicemailUri) { + if (voicemailUri == null) { + LogUtil.e("VoicemailQueryHandler.markSingleNewVoicemailAsRead", "voicemail URI is null"); + return; + } + ThreadUtil.postOnUiThread( + () -> { + new VoicemailQueryHandler(context.getContentResolver()) + .markNewVoicemailsAsOld(voicemailUri); + }); } /** Updates all new voicemails to mark them as old. */ - public void markNewVoicemailsAsOld(@Nullable Uri voicemailUri) { + private void markNewVoicemailsAsOld(@Nullable Uri voicemailUri) { // Mark all "new" voicemails as not new anymore. StringBuilder where = new StringBuilder(); where.append(Calls.NEW); @@ -70,11 +88,5 @@ public class VoicemailQueryHandler extends AsyncQueryHandler { voicemailUri == null ? new String[] {Integer.toString(Calls.VOICEMAIL_TYPE)} : new String[] {Integer.toString(Calls.VOICEMAIL_TYPE), voicemailUri.toString()}); - - GroupedNotificationUtil.removeNotification( - mContext.getSystemService(NotificationManager.class), - voicemailUri != null ? voicemailUri.toString() : null, - R.id.notification_visual_voicemail, - DefaultVoicemailNotifier.VISUAL_VOICEMAIL_NOTIFICATION_TAG); } } diff --git a/java/com/android/dialer/app/calllog/calllogcache/CallLogCacheLollipopMr1.java b/java/com/android/dialer/app/calllog/calllogcache/CallLogCacheLollipopMr1.java index 039998780..f85680649 100644 --- a/java/com/android/dialer/app/calllog/calllogcache/CallLogCacheLollipopMr1.java +++ b/java/com/android/dialer/app/calllog/calllogcache/CallLogCacheLollipopMr1.java @@ -17,15 +17,11 @@ package com.android.dialer.app.calllog.calllogcache; import android.content.Context; -import android.support.annotation.VisibleForTesting; import android.telecom.PhoneAccountHandle; -import android.text.TextUtils; import android.util.ArrayMap; -import android.util.Pair; import com.android.dialer.calllogutils.PhoneAccountUtils; -import com.android.dialer.phonenumberutil.PhoneNumberHelper; +import com.android.dialer.telecom.TelecomUtil; import java.util.Map; -import java.util.concurrent.ConcurrentHashMap; /** * This is the CallLogCache for versions of dialer Lollipop Mr1 and above with support for multi-SIM @@ -36,15 +32,6 @@ import java.util.concurrent.ConcurrentHashMap; */ class CallLogCacheLollipopMr1 extends CallLogCache { - /* - * Maps from a phone-account/number pair to a boolean because multiple numbers could return true - * for the voicemail number if those numbers are not pre-normalized. Access must be synchronzied - * as it's used in the background thread in CallLogAdapter. {@see CallLogAdapter#loadData} - */ - @VisibleForTesting - final Map, Boolean> mVoicemailQueryCache = - new ConcurrentHashMap<>(); - private final Map mPhoneAccountLabelCache = new ArrayMap<>(); private final Map mPhoneAccountColorCache = new ArrayMap<>(); private final Map mPhoneAccountCallWithNoteCache = new ArrayMap<>(); @@ -55,7 +42,6 @@ class CallLogCacheLollipopMr1 extends CallLogCache { @Override public void reset() { - mVoicemailQueryCache.clear(); mPhoneAccountLabelCache.clear(); mPhoneAccountColorCache.clear(); mPhoneAccountCallWithNoteCache.clear(); @@ -65,19 +51,7 @@ class CallLogCacheLollipopMr1 extends CallLogCache { @Override public boolean isVoicemailNumber(PhoneAccountHandle accountHandle, CharSequence number) { - if (TextUtils.isEmpty(number)) { - return false; - } - - Pair key = new Pair<>(accountHandle, number); - Boolean value = mVoicemailQueryCache.get(key); - if (value != null) { - return value; - } - boolean isVoicemail = - PhoneNumberHelper.isVoicemailNumber(mContext, accountHandle, number.toString()); - mVoicemailQueryCache.put(key, isVoicemail); - return isVoicemail; + return TelecomUtil.isVoicemailNumber(mContext, accountHandle, number.toString()); } @Override diff --git a/java/com/android/dialer/app/contactinfo/ContactInfoCache.java b/java/com/android/dialer/app/contactinfo/ContactInfoCache.java index 32bbf06b5..82fc229af 100644 --- a/java/com/android/dialer/app/contactinfo/ContactInfoCache.java +++ b/java/com/android/dialer/app/contactinfo/ContactInfoCache.java @@ -162,7 +162,7 @@ public class ContactInfoCache { ContactInfo info; if (request.isLocalRequest()) { info = mContactInfoHelper.lookupNumber(request.number, request.countryIso); - if (!info.contactExists) { + if (info != null && !info.contactExists) { // TODO: Maybe skip look up if it's already available in cached number lookup // service. long start = SystemClock.elapsedRealtime(); diff --git a/java/com/android/dialer/app/dialpad/DialpadFragment.java b/java/com/android/dialer/app/dialpad/DialpadFragment.java index c0b26c91a..d33943773 100644 --- a/java/com/android/dialer/app/dialpad/DialpadFragment.java +++ b/java/com/android/dialer/app/dialpad/DialpadFragment.java @@ -85,7 +85,9 @@ import com.android.dialer.common.LogUtil; import com.android.dialer.dialpadview.DialpadKeyButton; import com.android.dialer.dialpadview.DialpadView; import com.android.dialer.location.GeoUtil; +import com.android.dialer.logging.UiAction; import com.android.dialer.oem.MotorolaUtils; +import com.android.dialer.performancereport.PerformanceReport; import com.android.dialer.proguard.UsedByReflection; import com.android.dialer.telecom.TelecomUtil; import com.android.dialer.util.CallUtil; @@ -1015,6 +1017,8 @@ public class DialpadFragment extends Fragment */ private void handleDialButtonPressed() { if (isDigitsEmpty()) { // No number entered. + // No real call made, so treat it as a click + PerformanceReport.recordClick(UiAction.Type.PRESS_CALL_BUTTON_WITHOUT_CALLING); handleDialButtonClickWithEmptyDigits(); } else { final String number = mDigits.getText().toString(); @@ -1025,6 +1029,7 @@ public class DialpadFragment extends Fragment if (number != null && !TextUtils.isEmpty(mProhibitedPhoneNumberRegexp) && number.matches(mProhibitedPhoneNumberRegexp)) { + PerformanceReport.recordClick(UiAction.Type.PRESS_CALL_BUTTON_WITHOUT_CALLING); LogUtil.i( "DialpadFragment.handleDialButtonPressed", "The phone number is prohibited explicitly by a rule."); @@ -1061,6 +1066,10 @@ public class DialpadFragment extends Fragment startActivity(newFlashIntent()); } else { if (!TextUtils.isEmpty(mLastNumberDialed)) { + // Dialpad will be filled with last called number, + // but we don't want to record it as user action + PerformanceReport.setIgnoreActionOnce(UiAction.Type.TEXT_CHANGE_WITH_INPUT); + // Recall the last number dialed. mDigits.setText(mLastNumberDialed); diff --git a/java/com/android/dialer/app/legacybindings/DialerLegacyBindings.java b/java/com/android/dialer/app/legacybindings/DialerLegacyBindings.java index c208fd57d..a483af9e9 100644 --- a/java/com/android/dialer/app/legacybindings/DialerLegacyBindings.java +++ b/java/com/android/dialer/app/legacybindings/DialerLegacyBindings.java @@ -41,6 +41,7 @@ public interface DialerLegacyBindings { ViewGroup alertContainer, CallLogAdapter.CallFetcher callFetcher, CallLogAdapter.MultiSelectRemoveView multiSelectRemoveView, + CallLogAdapter.OnActionModeStateChangedListener actionModeStateChangedListener, CallLogCache callLogCache, ContactInfoCache contactInfoCache, VoicemailPlaybackPresenter voicemailPlaybackPresenter, diff --git a/java/com/android/dialer/app/legacybindings/DialerLegacyBindingsStub.java b/java/com/android/dialer/app/legacybindings/DialerLegacyBindingsStub.java index 19fa1a70c..488fbad68 100644 --- a/java/com/android/dialer/app/legacybindings/DialerLegacyBindingsStub.java +++ b/java/com/android/dialer/app/legacybindings/DialerLegacyBindingsStub.java @@ -35,6 +35,7 @@ public class DialerLegacyBindingsStub implements DialerLegacyBindings { ViewGroup alertContainer, CallLogAdapter.CallFetcher callFetcher, CallLogAdapter.MultiSelectRemoveView multiSelectRemoveView, + CallLogAdapter.OnActionModeStateChangedListener actionModeStateChangedListener, CallLogCache callLogCache, ContactInfoCache contactInfoCache, VoicemailPlaybackPresenter voicemailPlaybackPresenter, @@ -45,6 +46,7 @@ public class DialerLegacyBindingsStub implements DialerLegacyBindings { alertContainer, callFetcher, multiSelectRemoveView, + actionModeStateChangedListener, callLogCache, contactInfoCache, voicemailPlaybackPresenter, diff --git a/java/com/android/dialer/app/list/AllContactsFragment.java b/java/com/android/dialer/app/list/AllContactsFragment.java index f5fdb9e2d..32a99e795 100644 --- a/java/com/android/dialer/app/list/AllContactsFragment.java +++ b/java/com/android/dialer/app/list/AllContactsFragment.java @@ -38,6 +38,7 @@ import com.android.contacts.common.list.ContactEntryListFragment; import com.android.contacts.common.list.ContactListFilter; import com.android.contacts.common.list.DefaultContactListAdapter; import com.android.dialer.app.R; +import com.android.dialer.common.LogUtil; import com.android.dialer.compat.CompatUtils; import com.android.dialer.logging.InteractionEvent; import com.android.dialer.logging.Logger; @@ -46,6 +47,7 @@ import com.android.dialer.util.IntentUtil; import com.android.dialer.util.PermissionsUtil; import com.android.dialer.widget.EmptyContentView; import com.android.dialer.widget.EmptyContentView.OnEmptyViewActionButtonClickedListener; +import java.util.Arrays; /** Fragments to show all contacts with phone numbers. */ public class AllContactsFragment extends ContactEntryListFragment @@ -173,9 +175,15 @@ public class AllContactsFragment extends ContactEntryListFragment 0) { + LogUtil.i( + "AllContactsFragment.onEmptyViewActionButtonClicked", + "Requesting permissions: " + Arrays.toString(deniedPermissions)); FragmentCompat.requestPermissions( - this, new String[] {READ_CONTACTS}, READ_CONTACTS_PERMISSION_REQUEST_CODE); + this, deniedPermissions, READ_CONTACTS_PERMISSION_REQUEST_CODE); } else { // Add new contact DialerUtils.startActivityWithErrorToast( diff --git a/java/com/android/dialer/app/list/DialerPhoneNumberListAdapter.java b/java/com/android/dialer/app/list/DialerPhoneNumberListAdapter.java index 04927cf7a..fc0bd3ccf 100644 --- a/java/com/android/dialer/app/list/DialerPhoneNumberListAdapter.java +++ b/java/com/android/dialer/app/list/DialerPhoneNumberListAdapter.java @@ -20,6 +20,7 @@ import android.content.Context; import android.content.res.Resources; import android.database.Cursor; import android.graphics.drawable.Drawable; +import android.support.v4.content.ContextCompat; import android.telephony.PhoneNumberUtils; import android.text.BidiFormatter; import android.text.TextDirectionHeuristics; @@ -177,33 +178,33 @@ public class DialerPhoneNumberListAdapter extends PhoneNumberListAdapter { resources, R.string.search_shortcut_call_number, mBidiFormatter.unicodeWrap(number, TextDirectionHeuristics.LTR)); - drawable = getContext().getResources().getDrawable(R.drawable.quantum_ic_call_vd_theme_24); + drawable = ContextCompat.getDrawable(getContext(), R.drawable.quantum_ic_call_vd_theme_24); break; case SHORTCUT_CREATE_NEW_CONTACT: text = resources.getString(R.string.search_shortcut_create_new_contact); drawable = - getContext().getResources().getDrawable(R.drawable.quantum_ic_person_add_vd_theme_24); + ContextCompat.getDrawable(getContext(), R.drawable.quantum_ic_person_add_vd_theme_24); drawable.setAutoMirrored(true); break; case SHORTCUT_ADD_TO_EXISTING_CONTACT: text = resources.getString(R.string.search_shortcut_add_to_contact); drawable = - getContext().getResources().getDrawable(R.drawable.quantum_ic_person_add_vd_theme_24); + ContextCompat.getDrawable(getContext(), R.drawable.quantum_ic_person_add_vd_theme_24); break; case SHORTCUT_SEND_SMS_MESSAGE: text = resources.getString(R.string.search_shortcut_send_sms_message); drawable = - getContext().getResources().getDrawable(R.drawable.quantum_ic_message_vd_theme_24); + ContextCompat.getDrawable(getContext(), R.drawable.quantum_ic_message_vd_theme_24); break; case SHORTCUT_MAKE_VIDEO_CALL: text = resources.getString(R.string.search_shortcut_make_video_call); drawable = - getContext().getResources().getDrawable(R.drawable.quantum_ic_videocam_vd_theme_24); + ContextCompat.getDrawable(getContext(), R.drawable.quantum_ic_videocam_vd_theme_24); break; case SHORTCUT_BLOCK_NUMBER: text = resources.getString(R.string.search_shortcut_block_number); drawable = - getContext().getResources().getDrawable(R.drawable.ic_not_interested_googblue_24dp); + ContextCompat.getDrawable(getContext(), R.drawable.ic_not_interested_googblue_24dp); break; default: throw new IllegalArgumentException("Invalid shortcut type"); diff --git a/java/com/android/dialer/app/list/DialtactsPagerAdapter.java b/java/com/android/dialer/app/list/DialtactsPagerAdapter.java index dba3d3a93..822aa789f 100644 --- a/java/com/android/dialer/app/list/DialtactsPagerAdapter.java +++ b/java/com/android/dialer/app/list/DialtactsPagerAdapter.java @@ -28,8 +28,8 @@ import com.android.dialer.calllog.CallLogComponent; import com.android.dialer.calllog.CallLogFramework; import com.android.dialer.calllog.ui.NewCallLogFragment; import com.android.dialer.common.Assert; -import com.android.dialer.common.ConfigProviderBindings; import com.android.dialer.common.LogUtil; +import com.android.dialer.configprovider.ConfigProviderBindings; import com.android.dialer.contactsfragment.ContactsFragment; import com.android.dialer.database.CallLogQueryHandler; import com.android.dialer.speeddial.SpeedDialFragment; @@ -78,7 +78,7 @@ public class DialtactsPagerAdapter extends FragmentPagerAdapter { CallLogFramework callLogFramework = CallLogComponent.get(context).callLogFramework(); useNewCallLogTab = callLogFramework.isNewCallLogEnabled(context); useNewContactsTab = - ConfigProviderBindings.get(context).getBoolean("enable_new_contacts_tab", false); + ConfigProviderBindings.get(context).getBoolean("enable_new_contacts_tab", true); this.tabTitles = tabTitles; hasActiveVoicemailProvider = hasVoicemailProvider; fragments.addAll(Collections.nCopies(TAB_COUNT_WITH_VOICEMAIL, null)); diff --git a/java/com/android/dialer/app/list/ListsFragment.java b/java/com/android/dialer/app/list/ListsFragment.java index 32501d556..3f03db1e8 100644 --- a/java/com/android/dialer/app/list/ListsFragment.java +++ b/java/com/android/dialer/app/list/ListsFragment.java @@ -34,15 +34,11 @@ import android.provider.VoicemailContract; import android.support.v4.view.ViewPager.OnPageChangeListener; import android.view.LayoutInflater; import android.view.View; -import android.view.View.OnClickListener; import android.view.ViewGroup; -import android.widget.ImageView; -import android.widget.TextView; import com.android.contacts.common.list.ViewPagerTabs; import com.android.dialer.app.R; import com.android.dialer.app.calllog.CallLogFragment; import com.android.dialer.app.calllog.CallLogNotificationsService; -import com.android.dialer.app.calllog.VisualVoicemailCallLogFragment; import com.android.dialer.app.voicemail.error.VoicemailStatusCorruptionHandler; import com.android.dialer.app.voicemail.error.VoicemailStatusCorruptionHandler.Source; import com.android.dialer.common.LogUtil; @@ -51,6 +47,8 @@ import com.android.dialer.database.CallLogQueryHandler.Listener; import com.android.dialer.logging.DialerImpression; import com.android.dialer.logging.Logger; import com.android.dialer.logging.ScreenEvent; +import com.android.dialer.logging.UiAction; +import com.android.dialer.performancereport.PerformanceReport; import com.android.dialer.speeddial.SpeedDialFragment; import com.android.dialer.util.PermissionsUtil; import com.android.dialer.voicemailstatus.VisualVoicemailEnabledChecker; @@ -64,22 +62,18 @@ import java.util.ArrayList; * Contacts list. This will also eventually contain the logic that allows sliding the ViewPager * containing the lists up above the search bar and pin it against the top of the screen. */ -public class ListsFragment extends Fragment - implements OnPageChangeListener, Listener, OnClickListener { +public class ListsFragment extends Fragment implements OnPageChangeListener, Listener { private static final String TAG = "ListsFragment"; + private DialerViewPager mViewPager; private ViewPagerTabs mViewPagerTabs; private DialtactsPagerAdapter mAdapter; private RemoveView mRemoveView; private View mRemoveViewContent; - private View mMultiSelectSelectAllViewContent; - private TextView mSelectUnselectAllViewText; - private ImageView mSelectUnselectAllIcon; private Fragment mCurrentPage; private SharedPreferences mPrefs; private boolean mHasFetchedVoicemailStatus; - private boolean selectAllMode; private boolean mShowVoicemailTabAfterVoicemailStatusIsFetched; private VoicemailStatusHelper mVoicemailStatusHelper; private final ArrayList mOnPageChangeListeners = new ArrayList<>(); @@ -89,6 +83,8 @@ public class ListsFragment extends Fragment private boolean mPaused; private CallLogQueryHandler mCallLogQueryHandler; + private UiAction.Type[] actionTypeList; + private final ContentObserver mVoicemailStatusObserver = new ContentObserver(new Handler()) { @Override @@ -159,6 +155,12 @@ public class ListsFragment extends Fragment Trace.endSection(); Trace.beginSection(TAG + " setup views"); + actionTypeList = new UiAction.Type[TAB_COUNT_WITH_VOICEMAIL]; + actionTypeList[TAB_INDEX_SPEED_DIAL] = UiAction.Type.CHANGE_TAB_TO_FAVORITE; + actionTypeList[TAB_INDEX_HISTORY] = UiAction.Type.CHANGE_TAB_TO_CALL_LOG; + actionTypeList[TAB_INDEX_ALL_CONTACTS] = UiAction.Type.CHANGE_TAB_TO_CONTACTS; + actionTypeList[TAB_INDEX_VOICEMAIL] = UiAction.Type.CHANGE_TAB_TO_VOICEMAIL; + String[] tabTitles = new String[TAB_COUNT_WITH_VOICEMAIL]; tabTitles[TAB_INDEX_SPEED_DIAL] = getResources().getString(R.string.tab_speed_dial); tabTitles[TAB_INDEX_HISTORY] = getResources().getString(R.string.tab_history); @@ -190,13 +192,6 @@ public class ListsFragment extends Fragment addOnPageChangeListener(mViewPagerTabs); mRemoveView = (RemoveView) parentView.findViewById(R.id.remove_view); mRemoveViewContent = parentView.findViewById(R.id.remove_view_content); - mMultiSelectSelectAllViewContent = - parentView.findViewById(R.id.multi_select_select_all_view_content); - mSelectUnselectAllViewText = (TextView) parentView.findViewById(R.id.select_all_view_text); - mSelectUnselectAllIcon = (ImageView) parentView.findViewById(R.id.select_all_view_icon); - mMultiSelectSelectAllViewContent.setOnClickListener(null); - mSelectUnselectAllIcon.setOnClickListener(this); - mSelectUnselectAllViewText.setOnClickListener(this); if (PermissionsUtil.hasReadVoicemailPermissions(getContext()) && PermissionsUtil.hasAddVoicemailPermissions(getContext())) { @@ -227,8 +222,8 @@ public class ListsFragment extends Fragment /** * Shows the tab with the specified index. If the voicemail tab index is specified, but the - * voicemail status hasn't been fetched, it will try to show the tab after the voicemail status - * has been fetched. + * voicemail status hasn't been fetched, it will show the speed dial tab and try to show the + * voicemail tab after the voicemail status has been fetched. */ public void showTab(int index) { if (index == TAB_INDEX_VOICEMAIL) { @@ -255,6 +250,8 @@ public class ListsFragment extends Fragment @Override public void onPageSelected(int position) { + PerformanceReport.recordClick(actionTypeList[position]); + LogUtil.i("ListsFragment.onPageSelected", "position: %d", position); mTabIndex = mAdapter.getRtlPosition(position); @@ -389,7 +386,7 @@ public class ListsFragment extends Fragment public void markMissedCallsAsReadAndRemoveNotifications() { if (mCallLogQueryHandler != null) { mCallLogQueryHandler.markMissedCallsAsRead(); - CallLogNotificationsService.markNewMissedCallsAsOld(getContext(), null); + CallLogNotificationsService.cancelAllMissedCalls(getContext()); } } @@ -400,9 +397,7 @@ public class ListsFragment extends Fragment } public void showMultiSelectRemoveView(boolean show) { - mMultiSelectSelectAllViewContent.setVisibility(show ? View.VISIBLE : View.GONE); - mMultiSelectSelectAllViewContent.setAlpha(show ? 0 : 1); - mMultiSelectSelectAllViewContent.animate().alpha(show ? 1 : 0).start(); + mViewPagerTabs.setVisibility(show ? View.GONE : View.VISIBLE); mViewPager.setEnableSwipingPages(!show); } @@ -445,28 +440,4 @@ public class ListsFragment extends Fragment } Logger.get(getActivity()).logScreenView(screenType, getActivity()); } - - @Override - public void onClick(View v) { - updateSelectAllIcon(); - selectAllMode = !selectAllMode; - } - - public void setSelectAllModeToFalse() { - selectAllMode = false; - mSelectUnselectAllIcon.setImageDrawable( - getContext().getDrawable(R.drawable.ic_empty_check_mark_white_24dp)); - } - - private void updateSelectAllIcon() { - if (selectAllMode) { - mSelectUnselectAllIcon.setImageDrawable( - getContext().getDrawable(R.drawable.ic_empty_check_mark_white_24dp)); - ((VisualVoicemailCallLogFragment) mCurrentPage).getAdapter().onAllDeselected(); - } else { - mSelectUnselectAllIcon.setImageDrawable( - getContext().getDrawable(R.drawable.ic_check_mark_blue_24dp)); - ((VisualVoicemailCallLogFragment) mCurrentPage).getAdapter().onAllSelected(); - } - } } diff --git a/java/com/android/dialer/app/list/OldSpeedDialFragment.java b/java/com/android/dialer/app/list/OldSpeedDialFragment.java index 1ddc0f4e1..05d017b28 100644 --- a/java/com/android/dialer/app/list/OldSpeedDialFragment.java +++ b/java/com/android/dialer/app/list/OldSpeedDialFragment.java @@ -56,6 +56,7 @@ import com.android.dialer.util.PermissionsUtil; import com.android.dialer.util.ViewUtil; import com.android.dialer.widget.EmptyContentView; import java.util.ArrayList; +import java.util.Arrays; /** This fragment displays the user's favorite/frequent contacts in a grid. */ public class OldSpeedDialFragment extends Fragment @@ -403,9 +404,15 @@ public class OldSpeedDialFragment extends Fragment return; } - if (!PermissionsUtil.hasPermission(activity, READ_CONTACTS)) { + String[] deniedPermissions = + PermissionsUtil.getPermissionsCurrentlyDenied( + getContext(), PermissionsUtil.allContactsGroupPermissionsUsedInDialer); + if (deniedPermissions.length > 0) { + LogUtil.i( + "OldSpeedDialFragment.onEmptyViewActionButtonClicked", + "Requesting permissions: " + Arrays.toString(deniedPermissions)); FragmentCompat.requestPermissions( - this, new String[] {READ_CONTACTS}, READ_CONTACTS_PERMISSION_REQUEST_CODE); + this, deniedPermissions, READ_CONTACTS_PERMISSION_REQUEST_CODE); } else { // Switch tabs ((HostInterface) activity).showAllContactsTab(); diff --git a/java/com/android/dialer/app/list/PhoneFavoriteTileView.java b/java/com/android/dialer/app/list/PhoneFavoriteTileView.java index 835b448bd..eb4f8e967 100644 --- a/java/com/android/dialer/app/list/PhoneFavoriteTileView.java +++ b/java/com/android/dialer/app/list/PhoneFavoriteTileView.java @@ -138,6 +138,8 @@ public abstract class PhoneFavoriteTileView extends ContactTileView { } if (TextUtils.isEmpty(mPhoneNumberString)) { + // Don't set performance report now, since user may spend some time on picking a number + // Copy "superclass" implementation Logger.get(getContext()) .logInteraction(InteractionEvent.Type.SPEED_DIAL_CLICK_CONTACT_WITH_AMBIGUOUS_NUMBER); diff --git a/java/com/android/dialer/app/list/PhoneFavoritesTileAdapter.java b/java/com/android/dialer/app/list/PhoneFavoritesTileAdapter.java index ce8598261..876fbf146 100644 --- a/java/com/android/dialer/app/list/PhoneFavoritesTileAdapter.java +++ b/java/com/android/dialer/app/list/PhoneFavoritesTileAdapter.java @@ -200,7 +200,7 @@ public class PhoneFavoritesTileAdapter extends BaseAdapter implements OnDragDrop int multipleNumbersContactsCount = 0; int contactsWithPhotoCount = 0; int contactsWithNameCount = 0; - int duoReachableContactsCount = 0; + int lightbringerReachableContactsCount = 0; // The cursor should not be closed since this is invoked from a CursorLoader. if (cursor.moveToFirst()) { @@ -308,7 +308,7 @@ public class PhoneFavoritesTileAdapter extends BaseAdapter implements OnDragDrop if (contact.phoneNumber == null) { multipleNumbersContactsCount++; } else if (lightbringer.isReachable(mContext, contact.phoneNumber)) { - duoReachableContactsCount++; + lightbringerReachableContactsCount++; } } @@ -320,7 +320,7 @@ public class PhoneFavoritesTileAdapter extends BaseAdapter implements OnDragDrop multipleNumbersContactsCount, contactsWithPhotoCount, contactsWithNameCount, - duoReachableContactsCount); + lightbringerReachableContactsCount); // Logs for manual testing LogUtil.v("PhoneFavoritesTileAdapter.saveCursorToCache", "counter: %d", counter); LogUtil.v( diff --git a/java/com/android/dialer/app/list/RegularSearchFragment.java b/java/com/android/dialer/app/list/RegularSearchFragment.java index 4f032032f..728948bfc 100644 --- a/java/com/android/dialer/app/list/RegularSearchFragment.java +++ b/java/com/android/dialer/app/list/RegularSearchFragment.java @@ -26,11 +26,13 @@ import com.android.contacts.common.list.ContactEntryListAdapter; import com.android.contacts.common.list.PinnedHeaderListView; import com.android.dialer.app.R; import com.android.dialer.callintent.CallInitiationType; +import com.android.dialer.common.LogUtil; import com.android.dialer.phonenumbercache.CachedNumberLookupService; import com.android.dialer.phonenumbercache.PhoneNumberCache; import com.android.dialer.util.PermissionsUtil; import com.android.dialer.widget.EmptyContentView; import com.android.dialer.widget.EmptyContentView.OnEmptyViewActionButtonClickedListener; +import java.util.Arrays; public class RegularSearchFragment extends SearchFragment implements OnEmptyViewActionButtonClickedListener, @@ -114,8 +116,15 @@ public class RegularSearchFragment extends SearchFragment } if (READ_CONTACTS.equals(mPermissionToRequest)) { - FragmentCompat.requestPermissions( - this, new String[] {mPermissionToRequest}, PERMISSION_REQUEST_CODE); + String[] deniedPermissions = + PermissionsUtil.getPermissionsCurrentlyDenied( + getContext(), PermissionsUtil.allContactsGroupPermissionsUsedInDialer); + if (deniedPermissions.length > 0) { + LogUtil.i( + "RegularSearchFragment.onEmptyViewActionButtonClicked", + "Requesting permissions: " + Arrays.toString(deniedPermissions)); + FragmentCompat.requestPermissions(this, deniedPermissions, PERMISSION_REQUEST_CODE); + } } } diff --git a/java/com/android/dialer/app/list/SearchFragment.java b/java/com/android/dialer/app/list/SearchFragment.java index 7f2d17650..00a2708a1 100644 --- a/java/com/android/dialer/app/list/SearchFragment.java +++ b/java/com/android/dialer/app/list/SearchFragment.java @@ -42,6 +42,8 @@ import com.android.dialer.app.dialpad.DialpadFragment.ErrorDialogFragment; import com.android.dialer.app.widget.DialpadSearchEmptyContentView; import com.android.dialer.callintent.CallSpecificAppData; import com.android.dialer.common.LogUtil; +import com.android.dialer.logging.DialerImpression; +import com.android.dialer.logging.Logger; import com.android.dialer.util.DialerUtils; import com.android.dialer.util.IntentUtil; import com.android.dialer.util.PermissionsUtil; @@ -96,9 +98,6 @@ public class SearchFragment extends PhoneNumberPickerFragment { public void onStart() { LogUtil.d("SearchFragment.onStart", ""); super.onStart(); - if (isSearchMode()) { - getAdapter().setHasHeader(0, false); - } mActivity = (HostInterface) getActivity(); @@ -170,16 +169,6 @@ public class SearchFragment extends PhoneNumberPickerFragment { return animator; } - @Override - protected void setSearchMode(boolean flag) { - super.setSearchMode(flag); - // This hides the "All contacts with phone numbers" header in the search fragment - final ContactEntryListAdapter adapter = getAdapter(); - if (adapter != null) { - adapter.setHasHeader(0, false); - } - } - public void setAddToContactNumber(String addToContactNumber) { mAddToContactNumber = addToContactNumber; } @@ -247,6 +236,10 @@ public class SearchFragment extends PhoneNumberPickerFragment { } break; case DialerPhoneNumberListAdapter.SHORTCUT_CREATE_NEW_CONTACT: + if (this instanceof SmartDialSearchFragment) { + Logger.get(getContext()) + .logImpression(DialerImpression.Type.CREATE_NEW_CONTACT_FROM_DIALPAD); + } number = TextUtils.isEmpty(mAddToContactNumber) ? adapter.getFormattedQueryString() @@ -255,6 +248,10 @@ public class SearchFragment extends PhoneNumberPickerFragment { DialerUtils.startActivityWithErrorToast(getActivity(), intent); break; case DialerPhoneNumberListAdapter.SHORTCUT_ADD_TO_EXISTING_CONTACT: + if (this instanceof SmartDialSearchFragment) { + Logger.get(getContext()) + .logImpression(DialerImpression.Type.ADD_TO_A_CONTACT_FROM_DIALPAD); + } number = TextUtils.isEmpty(mAddToContactNumber) ? adapter.getFormattedQueryString() diff --git a/java/com/android/dialer/app/list/SmartDialSearchFragment.java b/java/com/android/dialer/app/list/SmartDialSearchFragment.java index fc21c8bc3..2ebc06bc3 100644 --- a/java/com/android/dialer/app/list/SmartDialSearchFragment.java +++ b/java/com/android/dialer/app/list/SmartDialSearchFragment.java @@ -34,6 +34,7 @@ import com.android.dialer.common.LogUtil; import com.android.dialer.database.DialerDatabaseHelper; import com.android.dialer.util.PermissionsUtil; import com.android.dialer.widget.EmptyContentView; +import java.util.Arrays; /** Implements a fragment to load and display SmartDial search results. */ public class SmartDialSearchFragment extends SearchFragment @@ -79,6 +80,11 @@ public class SmartDialSearchFragment extends SearchFragment } } + @Override + public boolean getShowEmptyListForNullQuery() { + return true; + } + @Override protected void setupEmptyView() { if (mEmptyView != null && getActivity() != null) { @@ -123,8 +129,16 @@ public class SmartDialSearchFragment extends SearchFragment return; } - FragmentCompat.requestPermissions( - this, new String[] {CALL_PHONE}, CALL_PHONE_PERMISSION_REQUEST_CODE); + String[] deniedPermissions = + PermissionsUtil.getPermissionsCurrentlyDenied( + getContext(), PermissionsUtil.allPhoneGroupPermissionsUsedInDialer); + if (deniedPermissions.length > 0) { + LogUtil.i( + "SmartDialSearchFragment.onEmptyViewActionButtonClicked", + "Requesting permissions: " + Arrays.toString(deniedPermissions)); + FragmentCompat.requestPermissions( + this, deniedPermissions, CALL_PHONE_PERMISSION_REQUEST_CODE); + } } @Override diff --git a/java/com/android/dialer/app/manifests/activities/AndroidManifest.xml b/java/com/android/dialer/app/manifests/activities/AndroidManifest.xml index 7c6df9448..0729d7293 100644 --- a/java/com/android/dialer/app/manifests/activities/AndroidManifest.xml +++ b/java/com/android/dialer/app/manifests/activities/AndroidManifest.xml @@ -41,6 +41,7 @@ android:resizeableActivity="true" android:theme="@style/DialtactsActivityTheme" android:windowSoftInputMode="stateAlwaysHidden|adjustNothing"> + @@ -106,6 +107,7 @@ + + + + + + + - - - - - - - - - - - diff --git a/java/com/android/dialer/app/res/menu/dialtacts_options.xml b/java/com/android/dialer/app/res/menu/dialtacts_options.xml index 25a3e1811..b50e6ad5f 100644 --- a/java/com/android/dialer/app/res/menu/dialtacts_options.xml +++ b/java/com/android/dialer/app/res/menu/dialtacts_options.xml @@ -28,5 +28,8 @@ + diff --git a/java/com/android/dialer/app/res/values-af/strings.xml b/java/com/android/dialer/app/res/values-af/strings.xml index 4f4c65b8a..40e297386 100644 --- a/java/com/android/dialer/app/res/values-af/strings.xml +++ b/java/com/android/dialer/app/res/values-af/strings.xml @@ -80,6 +80,7 @@ "Voeg wagtyd by" "Instellings" "Nabootser" + "Skep nuwe UI-kortpad" "Alle kontakte" "Gebruik raak-nommerbord" "Keer terug na oproep wat besig is" @@ -104,12 +105,14 @@ "%s sek." "%s min. %s sek." "Kanselleer grootmaathandelingmodus" - "stemboodskap" - "stemboodskappe" - "Ja" - "Nee" + "Vee uit" + "Kanselleer" "Vee geselekteerde %1$s uit?" "%1$s gekies" + + ""Vee hierdie stemboodskappe uit? "" + ""Vee hierdie stemboodskap uit? "" + @string/call_log_header_today "%1$s om %2$s" "%1$02d:%2$02d" diff --git a/java/com/android/dialer/app/res/values-am/strings.xml b/java/com/android/dialer/app/res/values-am/strings.xml index 7f4a622d7..08b52a6ee 100644 --- a/java/com/android/dialer/app/res/values-am/strings.xml +++ b/java/com/android/dialer/app/res/values-am/strings.xml @@ -80,6 +80,7 @@ "መጠበቅ አክል" "ቅንብሮች" "ማስመሰያ" + "አዲስ የዩአይ አቋራጭ ፍጠር" "ሁሉም እውቅያዎች" "የድምፅ ቁልፍ ሰሌዳን ንካ" "በመካሄድ ላይ ወዳለው ጥሪ ተመለስ" @@ -104,12 +105,14 @@ "%s ሰከንድ" "%s ደቂቃ %s ሴከ" "የጅምላ እርምጃ ሁነታ ይቅር" - "የድምፅ መልዕክት" - "የድምፅ መልዕክቶች" - "አዎ" - "አይ" + "ሰርዝ" + "ይቅር" "የተመረጠው %1$s ይሰረዝ?" "%1$s ተመርጠዋል" + + ""እነዚህ የድምፅ መልዕክቶች ይሰረዙ? "" + ""እነዚህ የድምፅ መልዕክቶች ይሰረዙ? "" + @string/call_log_header_today "%1$s %2$s ላይ" "%1$02d:%2$02d" diff --git a/java/com/android/dialer/app/res/values-ar/strings.xml b/java/com/android/dialer/app/res/values-ar/strings.xml index 3687d0bcb..fe84a66ab 100644 --- a/java/com/android/dialer/app/res/values-ar/strings.xml +++ b/java/com/android/dialer/app/res/values-ar/strings.xml @@ -84,6 +84,7 @@ "إضافة انتظار" "الإعدادات" "المحاكي" + "إنشاء اختصار للواجهة الجديدة" "جميع جهات الاتصال" "استخدام لوحة مفاتيح نغمات باللمس" "عودة إلى المكالمة الجارية" @@ -108,12 +109,18 @@ "%s ثانية" "%s دقيقة %s ثانية" "إلغاء وضع الإجراءات المجمَّع" - "البريد الصوتي" - "رسائل البريد الصوتي" - "نعم" - "لا" + "حذف" + "إلغاء" "حذف رسائل %1$s المحددة؟" "تم تحديد %1$s" + + ""حذف رسائل البريد الصوتي هذه؟ "" + ""حذف رسالتي البريد الصوتي هاتين؟ "" + ""حذف رسائل البريد الصوتي هذه؟ "" + ""حذف رسائل البريد الصوتي هذه؟ "" + ""حذف رسائل البريد الصوتي هذه؟ "" + ""حذف رسالة البريد الصوتي هذه؟ "" + @string/call_log_header_today "%1$s في %2$s" "%1$02d:%2$02d" diff --git a/java/com/android/dialer/app/res/values-az/strings.xml b/java/com/android/dialer/app/res/values-az/strings.xml index b6681c9e2..f2b0cf35d 100644 --- a/java/com/android/dialer/app/res/values-az/strings.xml +++ b/java/com/android/dialer/app/res/values-az/strings.xml @@ -80,6 +80,7 @@ "Gözləmə əlavə edin" "Ayarlar" "Stimulyator" + "Yeni İİ Qısayolu yaradın" "Bütün kontaktlar" "Toxunma ton klaviaturasını istifadə edin" "Davam edən zəngə qayıdın" @@ -104,12 +105,14 @@ "%s san" "%s dəq %s san" "Qrup əməliyyatları rejimini ləğv edin" - "səsli e-məktub" - "səsli e-məktublar" - "Bəli" - "Xeyr" + "Silin" + "Ləğv edin" "Seçilmiş %1$s silinsin?" "%1$s seçilib" + + ""Bu səsli e-məktub silinsin? "" + ""Bu səsli e-məktub silinsin? "" + @string/call_log_header_today "%1$s tarixində %2$s" "%1$02d:%2$02d" diff --git a/java/com/android/dialer/app/res/values-b+sr+Latn/strings.xml b/java/com/android/dialer/app/res/values-b+sr+Latn/strings.xml index 40c0886c8..b011f7866 100644 --- a/java/com/android/dialer/app/res/values-b+sr+Latn/strings.xml +++ b/java/com/android/dialer/app/res/values-b+sr+Latn/strings.xml @@ -81,6 +81,7 @@ "Dodaj čekanje" "Podešavanja" "Simulator" + "Napravite prečicu za novi UI" "Svi kontakti" "Upotrebite brojčanik za tonsko biranje" "Vrati se na poziv koji je u toku" @@ -105,12 +106,15 @@ "%s sek" "%s min %s sek" "Otkažite režim grupnih radnji" - "govornu poruku" - "govorne poruke" - "Da" - "Ne" + "Izbriši" + "Otkaži" "Želite li da izbrišete izabranu(e) %1$s?" "Izabranih: %1$s" + + ""Želite li da izbrišete ove govorne poruke? "" + ""Želite li da izbrišete ove govorne poruke? "" + ""Želite li da izbrišete ove govorne poruke? "" + @string/call_log_header_today "%1$s u %2$s" "%1$02d:%2$02d" diff --git a/java/com/android/dialer/app/res/values-be/strings.xml b/java/com/android/dialer/app/res/values-be/strings.xml index f2ad3342b..f9b083747 100644 --- a/java/com/android/dialer/app/res/values-be/strings.xml +++ b/java/com/android/dialer/app/res/values-be/strings.xml @@ -82,6 +82,7 @@ "Дадаць чаканне" "Налады" "Сродак мадэліравання" + "Ярлык новага карыст. інтэрфейсу" "Усе кантакты" "Выкарыстанне тонавай клавіятуры" "Звярнуцца да бягучага выкліку" @@ -106,12 +107,16 @@ "%s с" "%s хв %s с" "Скасаваць рэжым пакетных дзеянняў" - "галасавая пошта" - "галасавая пошта" - "Так" - "Не" + "Выдаліць" + "Скасаваць" "Выдаліць вылучанае: %1$s?" "Выбрана: %1$s" + + ""Выдаліць гэтыя паведамленні галасавой пошты? "" + ""Выдаліць гэтыя паведамленні галасавой пошты? "" + ""Выдаліць гэтыя паведамленні галасавой пошты? "" + ""Выдаліць гэтыя паведамленні галасавой пошты? "" + @string/call_log_header_today "%1$s у %2$s" "%1$02d:%2$02d" diff --git a/java/com/android/dialer/app/res/values-bg/strings.xml b/java/com/android/dialer/app/res/values-bg/strings.xml index 8083f4828..8b1105cb3 100644 --- a/java/com/android/dialer/app/res/values-bg/strings.xml +++ b/java/com/android/dialer/app/res/values-bg/strings.xml @@ -80,6 +80,7 @@ "Добавяне на изчакване" "Настройки" "Симулатор" + "Пряк път към новия ПИ" "Всички контакти" "Използване на тонова клавиатура" "Назад към текущото обаждане" @@ -104,12 +105,14 @@ "%s сек" "%s мин %s сек" "Анулиране на режима на групови действия" - "гласово съобщение" - "гласови съобщения" - "Да" - "Не" + "Изтриване" + "Отказ" "Избрахте %1$s – да се изтрие ли избраното?" "Избрахте %1$s" + + ""Да се изтрият ли тези гласови съобщения? "" + ""Да се изтрие ли това гласово съобщение? "" + @string/call_log_header_today "%1$s в %2$s" "%1$02d:%2$02d" diff --git a/java/com/android/dialer/app/res/values-bn/strings.xml b/java/com/android/dialer/app/res/values-bn/strings.xml index 4d2d7cc1e..2ec362685 100644 --- a/java/com/android/dialer/app/res/values-bn/strings.xml +++ b/java/com/android/dialer/app/res/values-bn/strings.xml @@ -80,6 +80,7 @@ "অপেক্ষা যোগ করুন" "সেটিংস" "সিমুলেটার" + "নতুন UI শর্টকাট তৈরি করুন" "সকল পরিচিতি" "স্পর্শ স্বর কীপ্যাড ব্যবহার করুন" "প্রগতিতে থাকা কলে প্রত্যাবর্তন" @@ -104,12 +105,14 @@ "%s সেকেন্ড" "%s মিনিট %s সেকেন্ড" "ব্যাচ অ্যাকশন মোড বাতিল করুন" - "ভয়েসমেল" - "ভয়েসমেলগুলি" - "হ্যাঁ" - "না" + "মুছুন" + "বাতিল করুন" "নির্বাচিত %1$s মুছে ফেলতে চান?" "%1$sটি নির্বাচিত" + + ""এই ভয়েসমেলগুলি মুছবেন? "" + ""এই ভয়েসমেলগুলি মুছবেন? "" + @string/call_log_header_today "%1$s তারিখে %2$s\'টায়" "%1$02d:%2$02d" diff --git a/java/com/android/dialer/app/res/values-bs/strings.xml b/java/com/android/dialer/app/res/values-bs/strings.xml index d8347723d..087db1274 100644 --- a/java/com/android/dialer/app/res/values-bs/strings.xml +++ b/java/com/android/dialer/app/res/values-bs/strings.xml @@ -81,6 +81,7 @@ "Dodaj čekanje" "Postavke" "Simulator" + "Kreiraj prečicu za novi UI" "Svi kontakti" "Koristi tastaturu za tonsko biranje" "Povratak na poziv u toku" @@ -105,12 +106,15 @@ "%s sek." "%s min. %s sek." "Otkaži način rada za grupnu radnju" - "poruka govorne pošte" - "poruke govorne pošte" - "Da" - "Ne" + "Izbriši" + "Otkaži" "Izbrisati izabranu/e %1$s?" "Odabrano %1$s" + + ""Izbrisati ove govorne poruke? "" + ""Izbrisati ove govorne poruke? "" + ""Izbrisati ove govorne poruke? "" + @string/call_log_header_today "%1$s u %2$s" "%1$02d:%2$02d" diff --git a/java/com/android/dialer/app/res/values-ca/strings.xml b/java/com/android/dialer/app/res/values-ca/strings.xml index 7b12e0dbd..71385805a 100644 --- a/java/com/android/dialer/app/res/values-ca/strings.xml +++ b/java/com/android/dialer/app/res/values-ca/strings.xml @@ -80,6 +80,7 @@ "Afegeix espera" "Configuració" "Simulador" + "Crea drecera per a la nova IU" "Tots els contactes" "Utilitza el teclat de tons" "Torna a la trucada en curs" @@ -104,18 +105,20 @@ "%s s" "%s min %s s" "Cancel·la el mode d\'accions en lot" - "missatge de veu" - "missatges de veu" - "Sí" - "No" + "Suprimeix" + "Cancel·la" "Vols suprimir l\'element o elements seleccionats (%1$s)?" "%1$s seleccionades" + + ""Vols suprimir aquests missatges de veu? "" + ""Vols suprimir aquest missatge de veu? "" + @string/call_log_header_today "%1$s a les %2$s" "%1$02d:%2$02d" "%1$s%2$s" "No es pot trucar a aquest número." - "Per configurar els missatges de veu, vés a Menú > Configuració." + "Per configurar els missatges de veu, ves a Menú > Configuració." "Per trucar a la bústia de veu, primer has de desactivar el mode d\'avió." "S\'està carregant…" "IMEI" @@ -229,7 +232,7 @@ "Bloqueja el número" "No és una trucada brossa" "Desbloqueja el número" - "Contingut brossa" + "Trucada brossa" "%1$s no té connexió i no s\'hi pot contactar" "Informació" diff --git a/java/com/android/dialer/app/res/values-cs/strings.xml b/java/com/android/dialer/app/res/values-cs/strings.xml index bbcb35847..dbff467c0 100644 --- a/java/com/android/dialer/app/res/values-cs/strings.xml +++ b/java/com/android/dialer/app/res/values-cs/strings.xml @@ -82,6 +82,7 @@ "Přidat čekání" "Nastavení" "Simulátor" + "Vytv. zkratku na nové rozhraní" "Všechny kontakty" "Použít dotykovou tónovou klávesnici" "Návrat k probíhajícímu hovoru" @@ -106,12 +107,16 @@ "%s s" "%s min %s s" "Zrušit režim hromadných akcí" - "vybranou hlasovou zprávu" - "vybrané hlasové zprávy" - "Ano" - "Ne" + "Smazat" + "Zrušit" "Smazat %1$s?" "Vybráno: %1$s" + + ""Smazat tyto hlasové zprávy? "" + ""Smazat tyto hlasové zprávy? "" + ""Smazat tyto hlasové zprávy? "" + ""Smazat tuto hlasovou zprávu? "" + @string/call_log_header_today "%1$s%2$s" "%1$02d:%2$02d" diff --git a/java/com/android/dialer/app/res/values-da/strings.xml b/java/com/android/dialer/app/res/values-da/strings.xml index 31cf8e33d..72f5a2835 100644 --- a/java/com/android/dialer/app/res/values-da/strings.xml +++ b/java/com/android/dialer/app/res/values-da/strings.xml @@ -80,6 +80,7 @@ "Tilføj ventetid" "Indstillinger" "Simulator" + "Opret ny brugerfladegenvej" "Alle kontakter" "Brug numerisk tastatur" "Vend tilbage til igangværende opkald" @@ -88,7 +89,7 @@ "Massehandlingstilstanden startes" "Massehandlingstilstanden blev afsluttet" "Vælg %1$s" - "Fravælg %1$s" + "Fravalgt %1$s" "Afspil telefonsvarerbesked" "Vis kontaktpersonen %1$s" "Ring til %1$s" @@ -104,12 +105,14 @@ "%s sek." "%s min. %s sek." "Annuller massehandlingstilstand" - "talebesked" - "talebeskeder" - "Ja" - "Nej" + "Slet" + "Annuller" "Vil du slette de valgte %1$s?" "%1$s er valgt" + + ""Vil du slette denne talebesked? "" + ""Vil du slette disse talebeskeder? "" + @string/call_log_header_today "%1$s kl. %2$s" "%1$02d:%2$02d" diff --git a/java/com/android/dialer/app/res/values-de/strings.xml b/java/com/android/dialer/app/res/values-de/strings.xml index c1f644119..a7efd53a3 100644 --- a/java/com/android/dialer/app/res/values-de/strings.xml +++ b/java/com/android/dialer/app/res/values-de/strings.xml @@ -80,6 +80,7 @@ "Warten hinzufügen" "Einstellungen" "Simulator" + "Verknüpfung für neue Benutzeroberfläche erstellen" "Alle Kontakte" "Telefontastatur verwenden" "Zurück zum aktuellen Anruf" @@ -104,12 +105,14 @@ "%s s" "%s min %s s" "Modus für Batch-Aktionen abbrechen" - "Mailboxnachricht" - "Mailboxnachrichten" - "Ja" - "Nein" + "Löschen" + "Abbrechen" "Ausgewählte %1$s löschen?" "%1$s ausgewählt" + + ""Diese Mailboxnachrichten löschen? "" + ""Diese Mailboxnachricht löschen? "" + @string/call_log_header_today "%1$s um %2$s" "%1$02d:%2$02d" diff --git a/java/com/android/dialer/app/res/values-el/strings.xml b/java/com/android/dialer/app/res/values-el/strings.xml index c4ba02d0f..7080e5e50 100644 --- a/java/com/android/dialer/app/res/values-el/strings.xml +++ b/java/com/android/dialer/app/res/values-el/strings.xml @@ -80,6 +80,7 @@ "Προσθήκη αναμονής" "Ρυθμίσεις" "Προσομοιωτής" + "Δημ. νέας συντόμ. διεπαφής" "Όλες οι επαφές" "Χρησιμοποιήστε το πληκτρολόγιο αφής ηχητικών τόνων" "Επιστροφή στην κλήση που βρίσκεται σε εξέλιξη" @@ -104,12 +105,14 @@ "%s δευτερόλεπτα" "%s λεπτά %s δευτερόλεπτα" "Ακύρωση λειτουργίας μαζικών ενεργειών" - "φωνητικού μηνύματος αυτόματου τηλεφωνητή" - "φωνητικών μηνυμάτων αυτόματου τηλεφωνητή" - "Ναι" - "Όχι" + "Διαγραφή" + "Ακύρωση" "Διαγραφή επιλεγμ. %1$s;" "Έχουν επιλεγεί %1$s" + + ""Διαγραφή αυτών των μηνυμάτων αυτόματου τηλεφωνητή; "" + ""Διαγραφή αυτού του μηνύματος αυτόματου τηλεφωνητή; "" + @string/call_log_header_today "%1$s στις %2$s" "%1$02d:%2$02d" diff --git a/java/com/android/dialer/app/res/values-en-rAU/strings.xml b/java/com/android/dialer/app/res/values-en-rAU/strings.xml index cb7e912c7..999f7dab0 100644 --- a/java/com/android/dialer/app/res/values-en-rAU/strings.xml +++ b/java/com/android/dialer/app/res/values-en-rAU/strings.xml @@ -80,6 +80,7 @@ "Add wait" "Settings" "Simulator" + "Create new UI shortcut" "All contacts" "Use touch tone keypad" "Return to call in progress" @@ -104,12 +105,14 @@ "%s sec" "%s min %s sec" "Cancel batch actions mode" - "voicemail" - "voicemails" - "Yes" - "No" + "Delete" + "Cancel" "Delete selected %1$s?" "%1$s selected" + + ""Delete these voicemails? "" + ""Delete this voicemail? "" + @string/call_log_header_today "%1$s at %2$s" "%1$02d:%2$02d" diff --git a/java/com/android/dialer/app/res/values-en-rGB/strings.xml b/java/com/android/dialer/app/res/values-en-rGB/strings.xml index cb7e912c7..999f7dab0 100644 --- a/java/com/android/dialer/app/res/values-en-rGB/strings.xml +++ b/java/com/android/dialer/app/res/values-en-rGB/strings.xml @@ -80,6 +80,7 @@ "Add wait" "Settings" "Simulator" + "Create new UI shortcut" "All contacts" "Use touch tone keypad" "Return to call in progress" @@ -104,12 +105,14 @@ "%s sec" "%s min %s sec" "Cancel batch actions mode" - "voicemail" - "voicemails" - "Yes" - "No" + "Delete" + "Cancel" "Delete selected %1$s?" "%1$s selected" + + ""Delete these voicemails? "" + ""Delete this voicemail? "" + @string/call_log_header_today "%1$s at %2$s" "%1$02d:%2$02d" diff --git a/java/com/android/dialer/app/res/values-en-rIN/strings.xml b/java/com/android/dialer/app/res/values-en-rIN/strings.xml index cb7e912c7..999f7dab0 100644 --- a/java/com/android/dialer/app/res/values-en-rIN/strings.xml +++ b/java/com/android/dialer/app/res/values-en-rIN/strings.xml @@ -80,6 +80,7 @@ "Add wait" "Settings" "Simulator" + "Create new UI shortcut" "All contacts" "Use touch tone keypad" "Return to call in progress" @@ -104,12 +105,14 @@ "%s sec" "%s min %s sec" "Cancel batch actions mode" - "voicemail" - "voicemails" - "Yes" - "No" + "Delete" + "Cancel" "Delete selected %1$s?" "%1$s selected" + + ""Delete these voicemails? "" + ""Delete this voicemail? "" + @string/call_log_header_today "%1$s at %2$s" "%1$02d:%2$02d" diff --git a/java/com/android/dialer/app/res/values-es-rUS/strings.xml b/java/com/android/dialer/app/res/values-es-rUS/strings.xml index 79d607fc7..701d74ebc 100644 --- a/java/com/android/dialer/app/res/values-es-rUS/strings.xml +++ b/java/com/android/dialer/app/res/values-es-rUS/strings.xml @@ -80,6 +80,7 @@ "Agregar espera" "Configuración" "Simulador" + "Crear acceso a la nueva IU" "Todos los contactos" "Usar teclado numérico" "Regresar a la llamada en curso" @@ -104,12 +105,14 @@ "%s s" "%s min %s s" "Cancelar el modo de acción masiva" - "el mensaje de voz" - "los mensajes de voz" - "Sí" - "No" + "Borrar" + "Cancelar" "¿Deseas borrar %1$s que seleccionaste?" "%1$s seleccionada(s)" + + ""¿Deseas borrar estos mensajes de voz? "" + ""¿Deseas borrar este mensaje de voz? "" + @string/call_log_header_today "El %1$s a la hora %2$s" "%1$02d:%2$02d" diff --git a/java/com/android/dialer/app/res/values-es/strings.xml b/java/com/android/dialer/app/res/values-es/strings.xml index 170edc8ca..8cf47f554 100644 --- a/java/com/android/dialer/app/res/values-es/strings.xml +++ b/java/com/android/dialer/app/res/values-es/strings.xml @@ -80,6 +80,7 @@ "Añadir espera" "Ajustes" "Simulador" + "Crear acceso a la interfaz" "Todos los contactos" "Usar teclado táctil" "Volver a la llamada" @@ -104,12 +105,14 @@ "%s s" "%s min y %s s" "Cancelar el modo de acciones en lote" - "mensaje de voz" - "mensajes de voz" - "Sí" - "No" + "Eliminar" + "Cancelar" "¿Eliminar la selección de %1$s?" "Se han seleccionado %1$s" + + ""¿Eliminar estos mensajes de voz? "" + ""¿Eliminar este mensaje de voz? "" + @string/call_log_header_today "%1$s a las %2$s" "%1$02d:%2$02d" diff --git a/java/com/android/dialer/app/res/values-et/strings.xml b/java/com/android/dialer/app/res/values-et/strings.xml index e32b10403..da043bf3c 100644 --- a/java/com/android/dialer/app/res/values-et/strings.xml +++ b/java/com/android/dialer/app/res/values-et/strings.xml @@ -80,6 +80,7 @@ "Lisa ootamine" "Seaded" "Simulaator" + "Loo uue kasutajaliid. otsetee" "Kõik kontaktid" "Kasuta puutetooniga klahvistikku" "Tagasi käimasolevale kõnele" @@ -104,12 +105,14 @@ "%s s" "%s min %s s" "Mitme toimigu režiimi tühistamine" - "kõnepostisõnum" - "kõnepostisõnumid" - "Jah" - "Ei" + "Kustuta" + "Tühista" "Kas kustutada valitud kõnepostisõnumid %1$s?" "%1$s on valitud" + + ""Kas kustutada need kõnepostisõnumid? "" + ""Kas kustutada see kõnepostisõnum? "" + @string/call_log_header_today "%1$s kell %2$s" "%1$02d:%2$02d" diff --git a/java/com/android/dialer/app/res/values-eu/strings.xml b/java/com/android/dialer/app/res/values-eu/strings.xml index 57ef67d88..071c6f3f0 100644 --- a/java/com/android/dialer/app/res/values-eu/strings.xml +++ b/java/com/android/dialer/app/res/values-eu/strings.xml @@ -80,6 +80,7 @@ "Gehitu itxaronaldia" "Ezarpenak" "Simulagailua" + "Sortu interfazerako esteka" "Kontaktu guztiak" "Erabili ukipen-tonuak dituen teklatua" "Itzuli abian den deira" @@ -104,12 +105,14 @@ "%s s" "%s min %s s" "Utzi bertan behera ekintzak multzoka gauzatzeko modua" - "ahots-mezua" - "ahots-mezuak" - "Bai" - "Ez" + "Ezabatu" + "Utzi" "Hautatutako %1$s ezabatu?" "%1$s hautatu dira" + + ""Ahots-mezu hauek ezabatu nahi dituzu? "" + ""Ahots-mezu hau ezabatu nahi duzu? "" + @string/call_log_header_today "%1$s (%2$s)" "%1$02d:%2$02d" diff --git a/java/com/android/dialer/app/res/values-fa/strings.xml b/java/com/android/dialer/app/res/values-fa/strings.xml index eadb0dcb7..6c588747e 100644 --- a/java/com/android/dialer/app/res/values-fa/strings.xml +++ b/java/com/android/dialer/app/res/values-fa/strings.xml @@ -80,6 +80,7 @@ "افزودن انتظار" "تنظیمات" "شبیه‌ساز" + "ایجاد میان‌بر رابط کاربری جدید" "همه مخاطبین" "استفاده از صفحه‌کلید لمسی" "برگشت به تماس درحال انجام" @@ -104,12 +105,14 @@ "%s ثانیه" "%s دقیقه %s ثانیه" "لغو حالت اقدام‌ دسته‌ای" - "پست صوتی" - "پست‌های صوتی" - "بله" - "نه" + "حذف" + "لغو" "%1$s انتخاب‌شده حذف شود؟" "%1$s مورد انتخاب شد" + + ""این پست‌های صوتی حذف شوند؟ "" + ""این پست‌های صوتی حذف شوند؟ "" + @string/call_log_header_today "%1$s ساعت %2$s" "%1$02d:%2$02d" diff --git a/java/com/android/dialer/app/res/values-fi/strings.xml b/java/com/android/dialer/app/res/values-fi/strings.xml index 951095908..55865d44a 100644 --- a/java/com/android/dialer/app/res/values-fi/strings.xml +++ b/java/com/android/dialer/app/res/values-fi/strings.xml @@ -80,6 +80,7 @@ "Lisää tauko" "Asetukset" "Simulaattori" + "Luo uusi UI-pikakuvake" "Kaikki yhteystiedot" "Käytä näppäimistöä" "Palaa käynnissä olevaan puheluun" @@ -104,12 +105,14 @@ "%s s" "%s min %s s" "Peruuta joukkotoimintotila." - "vastaajaviesti" - "vastaajaviestit" - "Kyllä" - "Ei" + "Poista" + "Peruuta" "Poistetaanko %1$s?" "%1$s valittu" + + ""Poistetaanko nämä vastaajaviestit? "" + ""Poistetaanko tämä vastaajaviesti? "" + @string/call_log_header_today "%1$s klo %2$s" "%1$02d.%2$02d" diff --git a/java/com/android/dialer/app/res/values-fr-rCA/strings.xml b/java/com/android/dialer/app/res/values-fr-rCA/strings.xml index 6aa285c50..f10b121d5 100644 --- a/java/com/android/dialer/app/res/values-fr-rCA/strings.xml +++ b/java/com/android/dialer/app/res/values-fr-rCA/strings.xml @@ -80,6 +80,7 @@ "Ajouter Attendre" "Paramètres" "Simulateur" + "Créer un raccourci vers l\'IU" "Tous les contacts" "Utiliser le clavier DTMF" "Reprendre l\'appel en cours" @@ -104,12 +105,14 @@ "%s s" "%s min et %s sec" "Annuler le mode d\'action par lots" - "message vocal" - "messages vocaux" - "Oui" - "Non" + "Supprimer" + "Annuler" "Supprimer la sélection (%1$s)?" "%1$s sélection(s)" + + ""Supprimer ce message vocal? "" + ""Supprimer ces messages vocaux? "" + @string/call_log_header_today "%1$s à %2$s" "%1$02d:%2$02d" diff --git a/java/com/android/dialer/app/res/values-fr/strings.xml b/java/com/android/dialer/app/res/values-fr/strings.xml index f539d2e55..2ce930af5 100644 --- a/java/com/android/dialer/app/res/values-fr/strings.xml +++ b/java/com/android/dialer/app/res/values-fr/strings.xml @@ -80,6 +80,7 @@ "Ajouter une attente" "Paramètres" "Simulateur" + "Créer un raccourci vers la nouvelle interface" "Tous les contacts" "Utiliser le clavier DTMF" "Reprendre l\'appel en cours" @@ -104,12 +105,14 @@ "%s secondes" "%s min et %s s" "Annuler le mode d\'actions groupées" - "message vocal" - "messages vocaux" - "Oui" - "Non" + "Supprimer" + "Annuler" "Supprimer les messages vocaux sélectionnés (%1$s) ?" "%1$s sélectionnés" + + ""Supprimer ce message vocal ? "" + ""Supprimer ces message vocaux ? "" + @string/call_log_header_today "%1$s à %2$s" "%1$02d:%2$02d" diff --git a/java/com/android/dialer/app/res/values-gl/strings.xml b/java/com/android/dialer/app/res/values-gl/strings.xml index ca31c5e47..b9e540750 100644 --- a/java/com/android/dialer/app/res/values-gl/strings.xml +++ b/java/com/android/dialer/app/res/values-gl/strings.xml @@ -80,6 +80,7 @@ "Engadir espera" "Configuración" "Simulador" + "Crear atallo para a nova IU" "Todos os contactos" "Usar teclado de tons táctiles" "Volver á chamada en curso" @@ -104,12 +105,14 @@ "%s s" "%s min %s s" "Cancela o modo de accións en lote" - "correo de voz" - "correos de voz" - "Si" - "Non" + "Eliminar" + "Cancelar" "Queres eliminar a selección (%1$s)?" "Cantidade seleccionada: %1$s" + + ""Queres eliminar estes correos de voz? "" + ""Queres eliminar este correo de voz? "" + @string/call_log_header_today "%1$s ás %2$s" "%1$02d:%2$02d" diff --git a/java/com/android/dialer/app/res/values-gu/strings.xml b/java/com/android/dialer/app/res/values-gu/strings.xml index fbe4d0aaa..ca8749ad3 100644 --- a/java/com/android/dialer/app/res/values-gu/strings.xml +++ b/java/com/android/dialer/app/res/values-gu/strings.xml @@ -80,6 +80,7 @@ "પ્રતીક્ષા ઉમેરો" "સેટિંગ્સ" "સિમ્યુલેટર" + "નવું UI શૉર્ટકટ્સ બનાવો" "તમામ સંપર્કો" "ટચ ટોન કીપેડનો ઉપયોગ કરો" "કૉલ પર પાછા આવવું પ્રગતિ પર છે" @@ -104,12 +105,14 @@ "%s સેકંડ" "%s મિ %s સે" "બૅચ ક્રિયા મોડ રદ કરો" - "વૉઇસમેઇલ" - "વૉઇસમેઇલ" - "હા" - "નહીં" + "કાઢી નાખો" + "રદ કરો" "પસંદ કરેલ %1$sને કાઢી નાખીએ?" "%1$s પસંદ કરી" + + ""આ વૉઇસમેઇલ કાઢી નાખીએ? "" + ""આ વૉઇસમેઇલ કાઢી નાખીએ? "" + @string/call_log_header_today "%1$s નાં રોજ %2$s વાગ્યે" "%1$02d:%2$02d" diff --git a/java/com/android/dialer/app/res/values-hi/strings.xml b/java/com/android/dialer/app/res/values-hi/strings.xml index c998e4402..3bc931921 100644 --- a/java/com/android/dialer/app/res/values-hi/strings.xml +++ b/java/com/android/dialer/app/res/values-hi/strings.xml @@ -80,6 +80,7 @@ "प्रतीक्षा का समय बढ़ाएं" "सेटिंग" "सिम्युलेटर" + "नया UI शॉर्टकट बनाएं" "सभी संपर्क" "टच टोन कीपैड का उपयोग करें" "कॉल पर लौटना प्रगति पर है" @@ -104,12 +105,14 @@ "%s सेकंड" "%s मि. %s से." "बैच कार्रवाई मोड रद्द करें" - "वॉयसमेल" - "वॉयसमेल" - "हां" - "नहीं" + "हटाएं" + "रद्द करें" "क्या चुने गए %1$s हटाना चाहते हैं?" "%1$s चयनित" + + ""ये वॉइसमेल हटाएं? "" + ""ये वॉइसमेल हटाएं? "" + @string/call_log_header_today "%1$s को %2$s बजे" "%1$02d:%2$02d" diff --git a/java/com/android/dialer/app/res/values-hr/strings.xml b/java/com/android/dialer/app/res/values-hr/strings.xml index 5261cfb0d..0d2147008 100644 --- a/java/com/android/dialer/app/res/values-hr/strings.xml +++ b/java/com/android/dialer/app/res/values-hr/strings.xml @@ -81,6 +81,7 @@ "Dodaj čekanje" "Postavke" "Simulator" + "Izrada prečaca novog sučelja" "Svi kontakti" "Koristi dodirnu zvučnu tipkovnicu" "Natrag na poziv u tijeku" @@ -105,12 +106,15 @@ "%s s" "%s min %s s" "Otkaži način skupnih radnji" - "poruka govorne pošte" - "poruke govorne pošte" - "Da" - "Ne" + "Izbriši" + "Odustani" "Želite li izbrisati odabranu poruku/e govorne pošte %1$s?" "Odabrano: %1$s" + + ""Želite li izbrisati ove poruke govorne pošte? "" + ""Želite li izbrisati ove poruke govorne pošte? "" + ""Želite li izbrisati ove poruke govorne pošte? "" + @string/call_log_header_today "%1$s u %2$s" "%1$02d.%2$02d" diff --git a/java/com/android/dialer/app/res/values-hu/strings.xml b/java/com/android/dialer/app/res/values-hu/strings.xml index 452f0da47..9a373e6e8 100644 --- a/java/com/android/dialer/app/res/values-hu/strings.xml +++ b/java/com/android/dialer/app/res/values-hu/strings.xml @@ -80,6 +80,7 @@ "Várakozás hozzáadása" "Beállítások" "Szimulátor" + "Új felh. felület-parancsikon" "Összes névjegy" "Hangkódos telefonbillentyűzet használata" "Vissza a folyamatban lévő híváshoz" @@ -104,12 +105,14 @@ "%s másodperc" "%s perc %s másodperc" "Köteges művelet mód leállítva" - "hangpostaüzenetet" - "hangpostaüzeneteket" - "Igen" - "Nem" + "Törlés" + "Mégse" "Törli a kiválasztott %1$s?" "%1$s kiválasztva" + + ""Törli ezeket a hangpostaüzeneteket? "" + ""Törli ezt a hangpostaüzenetet? "" + @string/call_log_header_today "%1$s, %2$s" "%1$02d:%2$02d" diff --git a/java/com/android/dialer/app/res/values-hy/strings.xml b/java/com/android/dialer/app/res/values-hy/strings.xml index 97a84f2fe..2b2fbf61b 100644 --- a/java/com/android/dialer/app/res/values-hy/strings.xml +++ b/java/com/android/dialer/app/res/values-hy/strings.xml @@ -80,12 +80,13 @@ "Ավելացնել սպասում" "Կարգավորումներ" "Նմանակիչ" + "Ստեղծել միջերեսի նոր դյուրանցում" "Բոլոր կոնտակտները" "Օգտագործել հնչերանգներով ստեղնաշարը" "Վերադառնալ ընթացիկ զանգին" "Ավելացնել զանգ" "Մուտքային զանգեր" - "Մուտք զանգվածային գործողությունների ռեժին" + "Դուք մտել եք զանգվածային գործողության ռեժիմ" "Դուք դուրս եկաք զանգվածային գործողությունների ռեժիմից" "Ընտրվեց՝ %1$s" "Ապընտրվեց՝ %1$s" @@ -104,12 +105,14 @@ "%s վրկ" "%s րոպե %s վայրկյան" "Չեղարկել փաթեթային գործողությունների ռեժիմը" - "ձայնային հաղորդագրություն" - "ձայնային հաղորդագրություններ" - "Այո" - "Ոչ" + "Ջնջել" + "Չեղարկել" "Ջնջե՞լ նշված %1$sը" "Ընտրվել է՝ %1$s" + + ""Delete these voicemails? "" + ""Ջնջե՞լ այս ձայնային հաղորդագրությունները "" + @string/call_log_header_today "%1$s-ին, ժամը %2$s-ին" "%1$02d:%2$02d" diff --git a/java/com/android/dialer/app/res/values-in/strings.xml b/java/com/android/dialer/app/res/values-in/strings.xml index f309f927b..e72fd6337 100644 --- a/java/com/android/dialer/app/res/values-in/strings.xml +++ b/java/com/android/dialer/app/res/values-in/strings.xml @@ -80,6 +80,7 @@ "Tambahkan tunggu" "Setelan" "Simulator" + "Buat Pintasan UI Baru" "Semua kontak" "Gunakan keypad nada sentuh" "Kembali ke panggilan sedang berlangsung" @@ -104,12 +105,14 @@ "%s dtk" "%s mnt %s dtk" "Membatalkan mode tindakan kelompok" - "pesan suara" - "pesan suara" - "Ya" - "Tidak" + "Hapus" + "Batal" "Hapus %1$s yang dipilih?" "%1$s dipilih" + + ""Hapus pesan suara ini? "" + ""Hapus pesan suara ini? "" + @string/call_log_header_today "%1$s pukul %2$s" "%1$02d.%2$02d" diff --git a/java/com/android/dialer/app/res/values-is/strings.xml b/java/com/android/dialer/app/res/values-is/strings.xml index b291eae84..bd329be9d 100644 --- a/java/com/android/dialer/app/res/values-is/strings.xml +++ b/java/com/android/dialer/app/res/values-is/strings.xml @@ -80,6 +80,7 @@ "Bæta töf við" "Stillingar" "Hermir" + "Stofna flýtileið í nýtt viðmót" "Allir tengiliðir" "Nota snertitónatakkaborð" "Fara aftur í símtal í gangi" @@ -104,12 +105,14 @@ "%s sek." "%s mín. og %s sek." "Hætta við runuaðgerðastillingu" - "talhólfsskilaboð" - "talhólfsskilaboð" - "Já" - "Nei" + "Eyða" + "Hætta við" "Eyða völdum %1$s?" "%1$s valin" + + ""Eyða þessum talhólfsskilaboðum? "" + ""Eyða þessum talhólfsskilaboðum? "" + @string/call_log_header_today "%1$s kl. %2$s" "%1$02d:%2$02d" diff --git a/java/com/android/dialer/app/res/values-it/strings.xml b/java/com/android/dialer/app/res/values-it/strings.xml index 711ab26ee..356f5a603 100644 --- a/java/com/android/dialer/app/res/values-it/strings.xml +++ b/java/com/android/dialer/app/res/values-it/strings.xml @@ -80,6 +80,7 @@ "Aggiungi attesa" "Impostazioni" "Simulatore" + "Crea nuova scorciatoia UI" "Tutti i contatti" "Usa tastierino per selezione a toni" "Torna alla chiamata in corso" @@ -104,12 +105,14 @@ "%s secondi" "%s min %s s" "Annulla modalità di azione collettiva" - "messaggio vocale" - "messaggi vocali" - "Sì" - "No" + "Elimina" + "Annulla" "Eliminare i %1$s selezionati?" "%1$s selezionate" + + ""Eliminare questi messaggi vocali? "" + ""Eliminare questo messaggio vocale? "" + @string/call_log_header_today "%1$s alle ore %2$s" "%1$02d:%2$02d" diff --git a/java/com/android/dialer/app/res/values-iw/strings.xml b/java/com/android/dialer/app/res/values-iw/strings.xml index bd2a05aec..230555a14 100644 --- a/java/com/android/dialer/app/res/values-iw/strings.xml +++ b/java/com/android/dialer/app/res/values-iw/strings.xml @@ -82,6 +82,7 @@ "הוסף המתנה" "הגדרות" "סימולטור" + "יצירת קיצור דרך לממשק החדש" "כל אנשי הקשר" "השתמש במקלדת עם חיוג צלילים" "חזור לשיחה פעילה" @@ -106,12 +107,16 @@ "%s שניות" "%s דק\' %s שנ\'" "ביטול המצב של ביצוע פעולות בכמות גדולה" - "ההודעה הקולית" - "ההודעות הקוליות" - "כן" - "לא" + "מחיקה" + "ביטול" "האם למחוק את %1$s שבחרת?" "%1$s נבחרו" + + ""האם למחוק את ההודעות הקוליות האלה? "" + ""האם למחוק את ההודעות הקוליות האלה? "" + ""האם למחוק את ההודעות הקוליות האלה? "" + ""האם למחוק את ההודעה הקולית הזו? "" + @string/call_log_header_today "%1$s ב-%2$s" "%1$02d:%2$02d" diff --git a/java/com/android/dialer/app/res/values-ja/strings.xml b/java/com/android/dialer/app/res/values-ja/strings.xml index 9ba40fb8f..71fca83d5 100644 --- a/java/com/android/dialer/app/res/values-ja/strings.xml +++ b/java/com/android/dialer/app/res/values-ja/strings.xml @@ -80,6 +80,7 @@ "待機を追加" "設定" "シミュレーション" + "新しいUIのショートカットを作成" "すべての連絡先" "プッシュホン式キーパッドを使う" "通話に戻る" @@ -104,12 +105,14 @@ "%s秒" "%s%s秒" "一括操作モードをキャンセルします" - "ボイスメール" - "ボイスメール" - "はい" - "いいえ" + "削除" + "キャンセル" "選択した%1$sを削除しますか?" "%1$s 件選択済み" + + ""これらのボイスメールを削除しますか?"" + ""このボイスメールを削除しますか?"" + @string/call_log_header_today "%1$s%2$s" "%1$02d%2$02d 秒" diff --git a/java/com/android/dialer/app/res/values-ka/strings.xml b/java/com/android/dialer/app/res/values-ka/strings.xml index dbb48f4f5..fd9351f54 100644 --- a/java/com/android/dialer/app/res/values-ka/strings.xml +++ b/java/com/android/dialer/app/res/values-ka/strings.xml @@ -80,6 +80,7 @@ "ლოდინის დამატება" "პარამეტრები" "სიმულატორი" + "ახალი UI მალსახმობის შექმნა" "ყველა კონტაქტი" "ტონალური კლავიატურის გამოყენება" "მიმდინარე ზარზე დაბრუნება" @@ -104,12 +105,14 @@ "%s წმ" "%s მინ %s წამ" "ერთიანი ქმედების რეჟიმის გაუქმება" - "ხმოვანი ფოსტა" - "ხმოვანი ფოსტა" - "დიახ" - "არა" + "წაშლა" + "გაუქმება" "გსურთ, წაშალოთ არჩეული %1$s?" "არჩეულია %1$s" + + ""გსურთ ამ ხმოვანი შეტყობინებების წაშლა? "" + ""გსურთ ამ ხმოვანი შეტყობინების წაშლა? "" + @string/call_log_header_today "%1$s, %2$s" "%1$02d:%2$02d" diff --git a/java/com/android/dialer/app/res/values-kk/strings.xml b/java/com/android/dialer/app/res/values-kk/strings.xml index 8dfe531a1..f1763a21a 100644 --- a/java/com/android/dialer/app/res/values-kk/strings.xml +++ b/java/com/android/dialer/app/res/values-kk/strings.xml @@ -80,6 +80,7 @@ "Күтуді қосу" "Параметрлер" "Симулятор" + "Жаңа пайдаланушы интерфейсінің пернелер тіркесімін жасау" "Барлық контактілер" "Сенсорлы әуенді пернетақта" "Қосылып тұрған қоңырауға оралу" @@ -104,12 +105,14 @@ "%s сек." "%s мин %s сек" "Топтама әрекеттер режимін жабу" - "дауыстық хабар" - "дауыстық хабарлар" - "Иә" - "Жоқ" + "Жою" + "Жабу" "Таңдалған %1$s хабарларын жою қажет пе?" "%1$s таңдалды" + + ""Осы дауыстық хабарларды жою қажет пе? "" + ""Осы дауыстық хабарды жою қажет пе? "" + @string/call_log_header_today "%1$s, %2$s" "%1$02d:%2$02d" diff --git a/java/com/android/dialer/app/res/values-km/strings.xml b/java/com/android/dialer/app/res/values-km/strings.xml index ed0db05e2..54f1a126a 100644 --- a/java/com/android/dialer/app/res/values-km/strings.xml +++ b/java/com/android/dialer/app/res/values-km/strings.xml @@ -80,6 +80,7 @@ "បញ្ចូល​ការ​រង់ចាំ" "ការកំណត់" "កម្មវិធីធ្វើ​ដូច​មែនទែន" + "បង្កើត​ផ្លូវកាត់ UI ថ្មី" "ទំនាក់ទំនង​ទាំងអស់" "ប្រើ​សំឡេង​ប៉ះ​បន្ទះ​លេខ" "កំពុង​ត្រឡប់​ទៅកាន់​ការ​ហៅ" @@ -104,12 +105,14 @@ "%s វិនាទី" "%s នាទី %s វិនាទី" "បោះបង់​មុខងារ​សកម្មភាព​ជា​ក្រុម" - "សារ​ជា​សំឡេង" - "សារ​ជា​សំឡេង" - "បាទ/ចាស" - "ទេ" + "លុប" + "បោះបង់" "លុប %1$s ដែល​បាន​ជ្រើសរើស?" "បាន​ជ្រើសរើស %1$s" + + ""លុប​សារ​ជា​សំឡេង​ទាំងនេះ? "" + ""លុប​សារ​ជា​សំឡេង​នេះ? "" + @string/call_log_header_today "%1$s នៅម៉ោង %2$s" "%1$02d:%2$02d" diff --git a/java/com/android/dialer/app/res/values-kn/strings.xml b/java/com/android/dialer/app/res/values-kn/strings.xml index 932bc4035..d7f3aabbc 100644 --- a/java/com/android/dialer/app/res/values-kn/strings.xml +++ b/java/com/android/dialer/app/res/values-kn/strings.xml @@ -80,6 +80,7 @@ "ನಿರೀಕ್ಷೆಯನ್ನು ಸೇರಿಸಿ" "ಸೆಟ್ಟಿಂಗ್‌ಗಳು" "ಸಿಮ್ಯುಲೇಟರ್" + "ಹೊಸ UI ಶಾರ್ಟ್‌ಕಟ್ ರಚಿಸಿ" "ಎಲ್ಲಾ ಸಂಪರ್ಕಗಳು" "ಸ್ಪರ್ಶ ಟೋನ್ ಕೀಪ್ಯಾಡ್ ಬಳಸಿ" "ಪ್ರತ್ಯತ್ತರ ಕರೆಯು ಪ್ರಗತಿಯಲ್ಲಿದೆ" @@ -104,12 +105,14 @@ "%s ಸೆಕೆಂ" "%s ನಿಮಿ %s ಸೆಕೆಂ" "ಬ್ಯಾಚ್ ಕ್ರಿಯೆಗಳ ಮೋಡ್ ಅನ್ನು ರದ್ದುಮಾಡಿ" - "ಧ್ವನಿಮೇಲ್" - "ಧ್ವನಿಮೇಲ್‌ಗಳು" - "ಹೌದು" - "ಇಲ್ಲ" + "ಅಳಿಸಿ" + "ರದ್ದುಮಾಡಿ" "ಆಯ್ಕೆ ಮಾಡಲಾದ %1$s ಅನ್ನು ಅಳಿಸುವುದೇ?" "%1$s ಆಯ್ಕೆಮಾಡಲಾಗಿದೆ" + + ""ಈ ಧ್ವನಿಮೇಲ್‌ಗಳನ್ನು ಅಳಿಸುವುದೇ? "" + ""ಈ ಧ್ವನಿಮೇಲ್‌ಗಳನ್ನು ಅಳಿಸುವುದೇ? "" + @string/call_log_header_today "%1$s ರಂದು %2$s ಗಂಟೆಗೆ" "%1$02d:%2$02d" diff --git a/java/com/android/dialer/app/res/values-ko/strings.xml b/java/com/android/dialer/app/res/values-ko/strings.xml index de6b93c01..cb2e83c79 100644 --- a/java/com/android/dialer/app/res/values-ko/strings.xml +++ b/java/com/android/dialer/app/res/values-ko/strings.xml @@ -80,6 +80,7 @@ "대기 시간 추가" "설정" "시뮬레이터" + "새 UI 바로가기 만들기" "모든 연락처" "터치톤 키패드 사용" "진행 중인 통화로 돌아가기" @@ -104,12 +105,14 @@ "%s초" "%s%s초" "일괄 작업 모드 취소" - "음성사서함" - "음성사서함" - "예" - "아니요" + "삭제" + "취소" "선택한 %1$s을(를) 삭제하시겠습니까?" "%1$s개 선택됨" + + ""이 음성사서함을 삭제하시겠습니까? "" + ""이 음성사서함을 삭제하시겠습니까? "" + @string/call_log_header_today "%1$s %2$s" "%1$02d%2$02d초" diff --git a/java/com/android/dialer/app/res/values-ky/strings.xml b/java/com/android/dialer/app/res/values-ky/strings.xml index ac9a617ed..0a0b3e661 100644 --- a/java/com/android/dialer/app/res/values-ky/strings.xml +++ b/java/com/android/dialer/app/res/values-ky/strings.xml @@ -80,6 +80,7 @@ "Тыныгуу кошуу" "Жөндөөлөр" "Симулятор" + "Жаңы интерфейс үчүн кыска жол түзүү" "Бардык байланыштар" "Тоналдык терүү тактасын колдонуу" "Токтотулган чалууга кайтуу" @@ -104,12 +105,14 @@ "%s сек." "%s мүн. %s сек." "Жапырт аракет режимин жокко чыгаруу" - "үн почтасы" - "үн почталары" - "Ооба" - "Жок" + "Жок кылуу" + "Жокко чыгаруу" "Тандалган %1$s жок кылынсынбы?" "%1$s тандалды" + + ""Бул үн почталар жок кылынсынбы? "" + ""Бул үн почта жок кылынсынбы? "" + @string/call_log_header_today "%1$s саат %2$s" "%1$02d:%2$02d" diff --git a/java/com/android/dialer/app/res/values-lo/strings.xml b/java/com/android/dialer/app/res/values-lo/strings.xml index 2a829730f..267d1c6be 100644 --- a/java/com/android/dialer/app/res/values-lo/strings.xml +++ b/java/com/android/dialer/app/res/values-lo/strings.xml @@ -80,6 +80,7 @@ "ເພີ່ມການລໍຖ້າ" "ການ​ຕັ້ງ​ຄ່າ" "ຕົວຈຳລອງ" + "ສ້າງປຸ່ມລັດສ່ວນຕິດຕໍ່ຜູ້ໃຊ້ໃໝ່" "ລາຍຊື່ຜູ່ຕິດຕໍ່ທັງໝົດ" "ໃຊ້ປຸ່ມກົດສັນຍານສຽງ" "ກັບໄປການໂທທີ່ກຳລັງດຳເນີນຢູ່" @@ -104,12 +105,14 @@ "%s ວິນາທີ" "%s ນ​ທ %s ວິ" "ຍົກເລີກໂໝດຄຳສັ່ງເປັນຊຸດ" - "ຂໍ້ຄວາມສຽງ" - "ຂໍ້ຄວາມສຽງ" - "ແມ່ນແລ້ວ" - "ບໍ່" + "ລຶບ" + "ຍົກເລີກ" "ລຶບ %1$s ທີ່ເລືອກອອກໄປບໍ?" "ເລືອກ %1$s ລາຍການແລ້ວ" + + ""ລຶບຂໍ້ຄວາມສຽງເຫຼົ່ານີ້ບໍ? "" + ""ລຶບຂໍ້ຄວາມສຽງນີ້ບໍ? "" + @string/call_log_header_today "%1$s ເວລາ %2$s" "%1$02d:%2$02d" diff --git a/java/com/android/dialer/app/res/values-lt/strings.xml b/java/com/android/dialer/app/res/values-lt/strings.xml index 367c928f4..e26a90927 100644 --- a/java/com/android/dialer/app/res/values-lt/strings.xml +++ b/java/com/android/dialer/app/res/values-lt/strings.xml @@ -82,6 +82,7 @@ "Pridėti laukimą" "Nustatymai" "Simuliatorius" + "Sukurti naują NS spart. klav." "Visi kontaktai" "Naudoti jutiklinę klaviatūrą" "Grįžti prie vykdomo skambučio" @@ -106,12 +107,16 @@ "%s sek." "%s min. %s sek." "Atšaukti masinių veiksmų režimą" - "balso pašto praneš." - "balso pašto praneš." - "Taip" - "Ne" + "Ištrinti" + "Atšaukti" "Ištrinti pasir. %1$s?" "Pasirinkta: %1$s" + + ""Ištrinti šiuos balso pašto pranešimus? "" + ""Ištrinti šiuos balso pašto pranešimus? "" + ""Ištrinti šiuos balso pašto pranešimus? "" + ""Ištrinti šiuos balso pašto pranešimus? "" + @string/call_log_header_today "%1$s, %2$s" "%1$02d:%2$02d" diff --git a/java/com/android/dialer/app/res/values-lv/strings.xml b/java/com/android/dialer/app/res/values-lv/strings.xml index 2713b91b6..8df2813c4 100644 --- a/java/com/android/dialer/app/res/values-lv/strings.xml +++ b/java/com/android/dialer/app/res/values-lv/strings.xml @@ -81,6 +81,7 @@ "Pievienot gaidīšanu" "Iestatījumi" "Simulators" + "Jaunās liet. saskarnes saīsne" "Visas kontaktpersonas" "Izmantot skārientoņu tastatūru" "Atgriezties pie pašreizējā zvana" @@ -105,12 +106,15 @@ "%s s" "%s min %s s" "Iziet no grupas darbību režīma" - "balss pasta ziņojums" - "balss pasta ziņojumi" - "Jā" - "Nē" + "Dzēst" + "Atcelt" "Vai dzēst atlasi: %1$s?" "Atlasīti: %1$s" + + ""Vai dzēst šos balss pasta ziņojumus? "" + ""Vai dzēst šos balss pasta ziņojumus? "" + ""Vai dzēst šos balss pasta ziņojumus? "" + @string/call_log_header_today "%1$s plkst. %2$s" "%1$02d:%2$02d" diff --git a/java/com/android/dialer/app/res/values-mk/strings.xml b/java/com/android/dialer/app/res/values-mk/strings.xml index 09725a642..953a05569 100644 --- a/java/com/android/dialer/app/res/values-mk/strings.xml +++ b/java/com/android/dialer/app/res/values-mk/strings.xml @@ -80,6 +80,7 @@ "Додај почекај" "Поставки" "Симулатор" + "Создај крат. за нов интерфејс" "Сите контакти" "Користи тастатура со звуци на допир" "Врати се на повик во тек" @@ -104,12 +105,14 @@ "%s сек." "%s мин. %s сек." "Откажи го режимот на групни дејства" - "говорна пошта" - "говорни пораки" - "Да" - "Не" + "Избриши" + "Откажи" "Да се избришат избраните %1$s?" "Избрани се %1$s" + + ""Да се избришат говорните пораки? "" + ""Да се избришат говорните пораки? "" + @string/call_log_header_today "%1$s во %2$s" "%1$02d:%2$02d" diff --git a/java/com/android/dialer/app/res/values-ml/strings.xml b/java/com/android/dialer/app/res/values-ml/strings.xml index 7655dbe23..0eef40748 100644 --- a/java/com/android/dialer/app/res/values-ml/strings.xml +++ b/java/com/android/dialer/app/res/values-ml/strings.xml @@ -80,6 +80,7 @@ "കാത്തിരിക്കൽ ചേർക്കുക" "ക്രമീകരണം" "സിമുലേറ്റർ" + "പുതിയ UI കുറുക്കുവഴി സൃഷ്‌ടിക്കുക" "എല്ലാ കോൺടാക്റ്റുകളും" "ടച്ച് ടോൺ കീപാഡ് ഉപയോഗിക്കുക" "വിളിച്ചുകൊണ്ടിരിക്കുന്ന കോളിലേക്ക് മടങ്ങുക" @@ -104,12 +105,14 @@ "%s സെക്കൻഡ്" "%s മി. %s സെ." "\'ബാച്ച് പ്രവർത്തനങ്ങൾ\' മോഡ് റദ്ദാക്കുക" - "വോയ്‌സ്‌മെയിൽ" - "വോയ്‌സ്മെയിലുകൾ" - "അതെ" - "ഇല്ല" + "ഇല്ലാതാക്കുക" + "റദ്ദാക്കൂ" "തിരഞ്ഞെടുത്ത %1$s ഇല്ലാതാക്കണോ?" "%1$s എണ്ണം തിരഞ്ഞെടുത്തു" + + ""ഈ വോയ്‌സ്‌മെയിലുകൾ ഇല്ലാതാക്കണോ? "" + ""ഈ വോയ്‌സ്‌മെയിൽ ഇല്ലാതാക്കണോ? "" + @string/call_log_header_today "%1$s, %2$s-ന്" "%1$02d:%2$02d" diff --git a/java/com/android/dialer/app/res/values-mn/strings.xml b/java/com/android/dialer/app/res/values-mn/strings.xml index 29bd8af42..e0cd98710 100644 --- a/java/com/android/dialer/app/res/values-mn/strings.xml +++ b/java/com/android/dialer/app/res/values-mn/strings.xml @@ -80,6 +80,7 @@ "Хүлээлт нэмэх" "Тохиргоо" "Симулятор" + "Шинэ UI үүсгэх товчлол" "Бүх харилцагчид" "Хүрэлтээр дуугардаг гар ашиглах" "Үргэлжилж буй дуудлага руу буцах" @@ -104,12 +105,14 @@ "%s сек" "%s минут %s секунд" "Багц үйлдлийн горимыг цуцлах" - "дуут шуудан" - "дуут шуудан" - "Тийм" - "Үгүй" + "Устгах" + "Цуцлах" "Сонгосон %1$s-г устгах уу?" "%1$s сонгосон" + + ""Эдгээр дуут шууданг устгах уу? "" + ""Энэ дуут шууданг устгах уу? "" + @string/call_log_header_today "%1$s %2$s-д" "%1$02d:%2$02d" diff --git a/java/com/android/dialer/app/res/values-mr/strings.xml b/java/com/android/dialer/app/res/values-mr/strings.xml index ee21291e8..70e6d410c 100644 --- a/java/com/android/dialer/app/res/values-mr/strings.xml +++ b/java/com/android/dialer/app/res/values-mr/strings.xml @@ -80,6 +80,7 @@ "प्रतीक्षा करा जोडा" "सेटिंग्ज" "सिम्युलेटर" + "नवीन UI शॉर्टकट तयार करा" "सर्व संपर्क" "स्‍पर्श टोन कीपॅडचा वापर करा" "चालू असलेल्या कॉलवर परत जा" @@ -104,12 +105,14 @@ "%s सेकंद" "%s मिनिट %s सेकंद" "बॅच क्रिया मोड रद्द करा" - "व्हॉइसमेल" - "व्हॉइसमेल" - "होय" - "नाही" + "हटवा" + "रद्द करा" "निवडलेले %1$s हटवायचेे?" "%1$s निवडले" + + ""हा व्हॉइसमेल हटवायचा? "" + ""हे व्हॉइसमेल हटवायचे? "" + @string/call_log_header_today "%1$s रोजी %2$s वाजता" "%1$02d:%2$02d" diff --git a/java/com/android/dialer/app/res/values-ms/strings.xml b/java/com/android/dialer/app/res/values-ms/strings.xml index dbb021359..f58f08f02 100644 --- a/java/com/android/dialer/app/res/values-ms/strings.xml +++ b/java/com/android/dialer/app/res/values-ms/strings.xml @@ -80,6 +80,7 @@ "Tambah penungguan" "Tetapan" "Simulator" + "Buat Pintasan UI Baharu" "Semua kenalan" "Gunakan pad kekunci nada sentuh" "Kembali ke panggilan yang sedang berlangsung" @@ -104,12 +105,14 @@ "%s saat" "%s min %s saat" "Batalkan mod tindakan kelompok" - "mel suara" - "mel suara" - "Ya" - "Tidak" + "Padam" + "Batal" "Padam %1$s yang dipilih?" "%1$s dipilih" + + ""Padamkan mel suara ini? "" + ""Padamkan mel suara ini? "" + @string/call_log_header_today "%1$s pada %2$s" "%1$02d:%2$02d" diff --git a/java/com/android/dialer/app/res/values-my/strings.xml b/java/com/android/dialer/app/res/values-my/strings.xml index eecfeb234..60c3271a0 100644 --- a/java/com/android/dialer/app/res/values-my/strings.xml +++ b/java/com/android/dialer/app/res/values-my/strings.xml @@ -80,6 +80,7 @@ "စောင့်ဆိုင်းခြင်း ထည့်ပါ" "ဆက်တင်များ" "အသစ်ကဲ့သို့ တုပသည့်စနစ်" + "UI ဖြတ်လမ်းလင့်ခ်အသစ် လုပ်ရန်" "လိပ်စာများအားလုံး" "touch tone ကီးခလုတ် ကိုအသုံးပြုပါ" "ဖုန်းပြန်ခေါ်မှု ပြုလုပ်နေစဉ်" @@ -104,12 +105,14 @@ "%s စက္ကန့်" "%s မိနစ် %s စက္ကန့်" "တပြိုင်နက်တည်း စုပြုံလုပ်ဆောင်ချက်များမုဒ်ကိ ပယ်ဖျက်ရန်" - "အသံမေးလ်" - "အသံမေးလ်များ" - "Yes" - "No" + "ဖျက်ပါ" + "မလုပ်တော့" "ရွေးထားသော %1$s ကို ဖျက်လိုပါသလား။" "%1$s ကို ရွေးချယ်ထားသည်" + + ""ဤအသံမေးလ်များကို ဖျက်မလား။ "" + ""ဤအသံမေးလ်ကို ဖျက်မလား။ "" + @string/call_log_header_today "%1$s %2$s ၌" "%1$02d:%2$02d" diff --git a/java/com/android/dialer/app/res/values-nb/strings.xml b/java/com/android/dialer/app/res/values-nb/strings.xml index bda4915b5..344a26a51 100644 --- a/java/com/android/dialer/app/res/values-nb/strings.xml +++ b/java/com/android/dialer/app/res/values-nb/strings.xml @@ -80,6 +80,7 @@ "Legg til Vent" "Innstillinger" "Simulator" + "Nytt grensesnitt – lag snarvei" "Alle kontakter" "Bruk tonetastatur" "Gå tilbake til aktiv samtale" @@ -104,12 +105,14 @@ "%s sek" "%s min %s sek" "Avbryt massehandlinsmodus" - "talepost" - "talepost" - "Ja" - "Nei" + "Slett" + "Avbryt" "Slett markert %1$s?" "%1$s er valgt" + + ""Vil du slette disse talemeldingene? "" + ""Vil du slette denne talemeldingen? "" + @string/call_log_header_today "%1$s kl. %2$s" "%1$02d:%2$02d" diff --git a/java/com/android/dialer/app/res/values-ne/strings.xml b/java/com/android/dialer/app/res/values-ne/strings.xml index 8262a316c..5e70c40b6 100644 --- a/java/com/android/dialer/app/res/values-ne/strings.xml +++ b/java/com/android/dialer/app/res/values-ne/strings.xml @@ -80,6 +80,7 @@ "पर्खाइ थप्नुहोस्" "सेटिङ्हरू" "सिम्युलेटर" + "नयाँ UI सर्टकट सिर्जना गर्ने" "सबै सम्पर्कहरू" "स्पर्श टोन किप्याडको प्रयोग गर्नुहोस्" "हुदै गरेको कलमा फर्कनुहोस्" @@ -104,12 +105,14 @@ "%s सेकेन्ड" "%s मिनेट %s सकेन्ड" "ब्याच सम्बन्धी कारबाहीको मोडलाई रद्द गर्नुहोस्" - "भ्वाइस मेल" - "भ्वाइस मेलहरू" - "हो" - "होइन" + "मेट्नुहोस्" + "रद्द गर्नुहोस्" "चयन गरिएका %1$s लाई मेटाउने हो?" "%1$s चयन गरियो" + + ""यी भ्वाइस मेलहरू मेट्ने हो? "" + ""यो भ्वाइस मेल मेट्ने हो? "" + @string/call_log_header_today "%1$s मा %2$s" "%1$02d:%2$02d" diff --git a/java/com/android/dialer/app/res/values-nl/strings.xml b/java/com/android/dialer/app/res/values-nl/strings.xml index eed412d69..dbd29bc78 100644 --- a/java/com/android/dialer/app/res/values-nl/strings.xml +++ b/java/com/android/dialer/app/res/values-nl/strings.xml @@ -80,6 +80,7 @@ "Wachten toevoegen" "Instellingen" "Simulator" + "Snelkoppeling voor nieuwe UI" "Alle contacten" "Toetsen voor toonkiezen gebruiken" "Terug naar actief gesprek" @@ -104,12 +105,14 @@ "%s sec." "%s min. %s sec." "Modus voor batchacties annuleren" - "voicemail" - "voicemails" - "Ja" - "Nee" + "Verwijderen" + "Annuleren" "Geselecteerde %1$s verwijderen?" "%1$s geselecteerd" + + ""Deze voicemails verwijderen? "" + ""Deze voicemail verwijderen? "" + @string/call_log_header_today "%1$s om %2$s" "%1$02d:%2$02d" diff --git a/java/com/android/dialer/app/res/values-no/strings.xml b/java/com/android/dialer/app/res/values-no/strings.xml index bda4915b5..344a26a51 100644 --- a/java/com/android/dialer/app/res/values-no/strings.xml +++ b/java/com/android/dialer/app/res/values-no/strings.xml @@ -80,6 +80,7 @@ "Legg til Vent" "Innstillinger" "Simulator" + "Nytt grensesnitt – lag snarvei" "Alle kontakter" "Bruk tonetastatur" "Gå tilbake til aktiv samtale" @@ -104,12 +105,14 @@ "%s sek" "%s min %s sek" "Avbryt massehandlinsmodus" - "talepost" - "talepost" - "Ja" - "Nei" + "Slett" + "Avbryt" "Slett markert %1$s?" "%1$s er valgt" + + ""Vil du slette disse talemeldingene? "" + ""Vil du slette denne talemeldingen? "" + @string/call_log_header_today "%1$s kl. %2$s" "%1$02d:%2$02d" diff --git a/java/com/android/dialer/app/res/values-pa/strings.xml b/java/com/android/dialer/app/res/values-pa/strings.xml index 8e6540727..33afd5824 100644 --- a/java/com/android/dialer/app/res/values-pa/strings.xml +++ b/java/com/android/dialer/app/res/values-pa/strings.xml @@ -80,6 +80,7 @@ "ਉਡੀਕ ਜੋੜੋ" "ਸੈਟਿੰਗਾਂ" "ਸਿਮੁਲੇਟਰ" + "ਨਵਾਂ UI ਸ਼ਾਰਟਕੱਟ ਬਣਾਓ" "ਸਾਰੇ ਸੰਪਰਕ" "ਟਚ ਟੋਨ ਕੀਪੈਡ ਵਰਤੋ" "ਪ੍ਰਗਤੀ ਵਿੱਚ ਕਾਲ ਤੇ ਵਾਪਸ ਜਾਓ" @@ -104,12 +105,14 @@ "%s ਸਕਿੰਟ" "%s ਮਿੰਟ %s ਸਕਿੰਟ" "ਬੈਚ ਕਾਰਵਾਈਆਂ ਮੋਡ ਨੂੰ ਰੱਦ ਕਰੋ" - "ਵੌਇਸਮੇਲ" - "ਵੌਇਸਮੇਲਾਂ" - "ਹਾਂ" - "ਨਹੀਂ" + "ਮਿਟਾਓ" + "ਰੱਦ ਕਰੋ" "ਕੀ ਚੁਣੀ(ਆਂ) ਹੋਈ(ਆਂ) %1$s ਨੂੰ ਮਿਟਾਉਣਾ ਹੈ?" "%1$s ਨੂੰ ਚੁਣਿਆ ਗਿਆ" + + ""ਕੀ ਇਸ ਵੌਇਸਮੇਲ ਨੂੰ ਮਿਟਾਉਣਾ ਹੈ? "" + ""ਕੀ ਇਹਨਾਂ ਵੌਇਸਮੇਲਾਂ ਨੂੰ ਮਿਟਾਉਣਾ ਹੈ? "" + @string/call_log_header_today "%1$s ਨੂੰ %2$s ਵਜੇ" "%1$02d:%2$02d" diff --git a/java/com/android/dialer/app/res/values-pl/strings.xml b/java/com/android/dialer/app/res/values-pl/strings.xml index 8f57a82b4..7f6027c51 100644 --- a/java/com/android/dialer/app/res/values-pl/strings.xml +++ b/java/com/android/dialer/app/res/values-pl/strings.xml @@ -82,6 +82,7 @@ "Dodaj oczekiwanie" "Ustawienia" "Symulator" + "Utwórz skrót do nowego interfejsu" "Wszystkie kontakty" "Użyj klawiatury tonowej" "Wróć do aktywnego połączenia" @@ -106,12 +107,16 @@ "%s s" "%s min %s s" "Anuluj tryb działań zbiorczych" - "wiadomości głosowe" - "wiadomości głosowe" - "Tak" - "Nie" + "Usuń" + "Anuluj" "Usunąć wybrane %1$s?" "Wybrane: %1$s" + + ""Usunąć te wiadomości głosowe? "" + ""Usunąć te wiadomości głosowe? "" + ""Usunąć te wiadomości głosowe? "" + ""Usunąć tę wiadomość głosową? "" + @string/call_log_header_today "%1$s o %2$s" "%1$02d:%2$02d" diff --git a/java/com/android/dialer/app/res/values-pt-rBR/strings.xml b/java/com/android/dialer/app/res/values-pt-rBR/strings.xml index eb61923e9..768ce57d4 100644 --- a/java/com/android/dialer/app/res/values-pt-rBR/strings.xml +++ b/java/com/android/dialer/app/res/values-pt-rBR/strings.xml @@ -80,6 +80,7 @@ "Adicionar espera" "Configurações" "Simulador" + "Criar atalho para a nova IU" "Todos os contatos" "Usar teclado multifrequencial" "Retornar para a chamada em espera" @@ -104,12 +105,14 @@ "%s seg" "%s m %s s" "Cancelar modo de ações em lote" - "correio de voz" - "correios de voz" - "Sim" - "Não" + "Excluir" + "Cancelar" "Excluir a seleção de %1$s?" "Itens selecionados: %1$s" + + ""Excluir este correio de voz? "" + ""Excluir estes correios de voz? "" + @string/call_log_header_today "%1$s às %2$s" "%1$02d:%2$02d" diff --git a/java/com/android/dialer/app/res/values-pt-rPT/strings.xml b/java/com/android/dialer/app/res/values-pt-rPT/strings.xml index 493f846c4..3c636e1d6 100644 --- a/java/com/android/dialer/app/res/values-pt-rPT/strings.xml +++ b/java/com/android/dialer/app/res/values-pt-rPT/strings.xml @@ -80,6 +80,7 @@ "Adicionar espera" "Definições" "Simulador" + "Criar novo atalho de IU" "Todos os contactos" "Utilizar teclado numérico com tons de toque" "Voltar à chamada em curso" @@ -104,12 +105,14 @@ "%s seg" "%s min. %s seg." "Cancelar modo de ações em lote" - "mensagem de correio de voz" - "mensagens de correio de voz" - "Sim" - "Não" + "Eliminar" + "Cancelar" "Pretende eliminar a(s) %1$s selecionada(s)?" "%1$s selecionada(s)" + + ""Pretende eliminar esta(s) mensagem(ns) de correio de voz? "" + ""Pretende eliminar estas mensagens de correio de voz? "" + @string/call_log_header_today "%1$s às %2$s" "%1$02d:%2$02d" diff --git a/java/com/android/dialer/app/res/values-pt/strings.xml b/java/com/android/dialer/app/res/values-pt/strings.xml index eb61923e9..768ce57d4 100644 --- a/java/com/android/dialer/app/res/values-pt/strings.xml +++ b/java/com/android/dialer/app/res/values-pt/strings.xml @@ -80,6 +80,7 @@ "Adicionar espera" "Configurações" "Simulador" + "Criar atalho para a nova IU" "Todos os contatos" "Usar teclado multifrequencial" "Retornar para a chamada em espera" @@ -104,12 +105,14 @@ "%s seg" "%s m %s s" "Cancelar modo de ações em lote" - "correio de voz" - "correios de voz" - "Sim" - "Não" + "Excluir" + "Cancelar" "Excluir a seleção de %1$s?" "Itens selecionados: %1$s" + + ""Excluir este correio de voz? "" + ""Excluir estes correios de voz? "" + @string/call_log_header_today "%1$s às %2$s" "%1$02d:%2$02d" diff --git a/java/com/android/dialer/app/res/values-ro/strings.xml b/java/com/android/dialer/app/res/values-ro/strings.xml index 93d01888a..b85f84987 100644 --- a/java/com/android/dialer/app/res/values-ro/strings.xml +++ b/java/com/android/dialer/app/res/values-ro/strings.xml @@ -81,6 +81,7 @@ "Adăugați interval de așteptare" "Setări" "Simulator" + "Creați comandă rapidă IU nouă" "Toată agenda" "Tastatura tactilă cu sunet" "Reveniți la apelul în curs" @@ -105,12 +106,15 @@ "%s secunde" "%s min. %s sec." "Anulați modul de acțiuni în lot" - "mesagerie vocală" - "mesaje vocale" - "Da" - "Nu" + "Ștergeți" + "Anulați" "Ștergeți cele %1$s selectate?" "%1$s selectate" + + ""Ștergeți aceste mesaje vocale? "" + ""Ștergeți aceste mesaje vocale? "" + ""Ștergeți acest mesaj vocal? "" + @string/call_log_header_today "%1$s la %2$s" "%1$02d:%2$02d" diff --git a/java/com/android/dialer/app/res/values-ru/strings.xml b/java/com/android/dialer/app/res/values-ru/strings.xml index 54278c40b..91441cc56 100644 --- a/java/com/android/dialer/app/res/values-ru/strings.xml +++ b/java/com/android/dialer/app/res/values-ru/strings.xml @@ -82,6 +82,7 @@ "Добавить паузу" "Настройки" "Симулятор" + "Создать ярлык для нового интерфейса" "Все контакты" "Панель тонального набора" "Вернуться к текущему вызову" @@ -106,12 +107,16 @@ "%s сек." "%s мин. %s сек." "Отмена режима массового действия" - "голосовое сообщение" - "голосовые сообщения" - "Да" - "Нет" + "Удалить" + "Отмена" "Удалить %1$s?" "Выбрано: %1$s" + + ""Удалить эти голосовые сообщения? "" + ""Удалить эти голосовые сообщения? "" + ""Удалить эти голосовые сообщения? "" + ""Удалить эти голосовые сообщения? "" + @string/call_log_header_today "%1$s в %2$s" "%1$02d:%2$02d" diff --git a/java/com/android/dialer/app/res/values-si/strings.xml b/java/com/android/dialer/app/res/values-si/strings.xml index 63634577f..8a748d53c 100644 --- a/java/com/android/dialer/app/res/values-si/strings.xml +++ b/java/com/android/dialer/app/res/values-si/strings.xml @@ -80,6 +80,7 @@ "රැඳී සිටීම එක් කරන්න" "සැකසීම්" "සමාකෘතිය" + "නව UI කෙටිමග තනන්න" "සියලුම සම්බන්ධතා" "ස්පර්ශ නාද යතුරුපෑඩය භාවිතා කරන්න" "පවතින ඇමතුමට නැවත යන්න" @@ -104,12 +105,14 @@ "තත් %s" "මිනි %s තත් %s" "කාණ්ඩ ක්‍රියා ප්‍රකාරය අවලංගු කරන්න" - "හඬ තැපෑල" - "හඬ තැපැල්" - "ඔව්" - "නැත" + "මකන්න" + "අවලංගු කරන්න" "තෝරා ගත් %1$s මකන්නද?" "%1$s තෝරා ගන්නා ලදි" + + ""මෙම හඬ තැපැල් මකන්නද? "" + ""මෙම හඬ තැපැල් මකන්නද? "" + @string/call_log_header_today "%1$s දින %2$sට" "%1$02d:%2$02d" diff --git a/java/com/android/dialer/app/res/values-sk/strings.xml b/java/com/android/dialer/app/res/values-sk/strings.xml index f7bf4237c..e84febb17 100644 --- a/java/com/android/dialer/app/res/values-sk/strings.xml +++ b/java/com/android/dialer/app/res/values-sk/strings.xml @@ -82,6 +82,7 @@ "Pridať čakanie" "Nastavenia" "Simulátor" + "Vyt. skratku na nové rozhranie" "Všetky kontakty" "Použiť dotykovú tónovú klávesnicu" "Návrat k prebiehajúcemu hovoru" @@ -106,12 +107,16 @@ "%s s" "%s min. %s s" "Zrušiť režim hromadných akcií" - "hlasová správa" - "hlasové správy" - "Áno" - "Nie" + "Odstrániť" + "Zrušiť" "Chcete odstrániť vybraté položky (%1$s)?" "Vybraté: %1$s" + + ""Chcete odstrániť tieto hlasové správy? "" + ""Chcete odstrániť tieto hlasové správy? "" + ""Chcete odstrániť tieto hlasové správy? "" + ""Chcete odstrániť túto hlasovú správu? "" + @string/call_log_header_today "%1$s%2$s" "%1$02d:%2$02d" diff --git a/java/com/android/dialer/app/res/values-sl/strings.xml b/java/com/android/dialer/app/res/values-sl/strings.xml index d3c57dd92..495b6e802 100644 --- a/java/com/android/dialer/app/res/values-sl/strings.xml +++ b/java/com/android/dialer/app/res/values-sl/strings.xml @@ -82,6 +82,7 @@ "Dodaj premor" "Nastavitve" "Simulator" + "Ustvari bliž. za novi up. vm." "Vsi stiki" "Uporabi številčnico za tonsko klicanje" "Nazaj na klic, ki poteka" @@ -106,12 +107,16 @@ "%s s" "%s min %s s" "Prekliči način množičnega dejanja" - "sporočilo v odzivniku" - "sporočila v odzivniku" - "Da" - "Ne" + "Izbriši" + "Prekliči" "Želite izbrisati %1$s?" "Št. izbranih: %1$s" + + ""Želite izbrisati ta sporočila v odzivniku? "" + ""Želite izbrisati ta sporočila v odzivniku? "" + ""Želite izbrisati ta sporočila v odzivniku? "" + ""Želite izbrisati ta sporočila v odzivniku? "" + @string/call_log_header_today "%1$s ob %2$s" "%1$02d:%2$02d" diff --git a/java/com/android/dialer/app/res/values-sq/strings.xml b/java/com/android/dialer/app/res/values-sq/strings.xml index 84704459c..809fd8a22 100644 --- a/java/com/android/dialer/app/res/values-sq/strings.xml +++ b/java/com/android/dialer/app/res/values-sq/strings.xml @@ -80,6 +80,7 @@ "Shto një pritje" "Cilësimet" "Simuluesi" + "Krijo një shkurtore për ndërfaqen e re të përdoruesit" "Të gjitha kontaktet" "Përdor bllokun e tasteve" "Kthehu te telefonata" @@ -104,12 +105,14 @@ "%s sekonda" "%s min. e %s sek." "Anulo modalitetin e veprimeve në grup" - "posta zanore" - "postat zanore" - "Po" - "Jo" + "Fshi" + "Anulo" "Të fshihen %1$s të zgjedhura?" "%1$s të zgjedhura" + + ""Të fshihen këto posta zanore? "" + ""Të fshihet kjo postë zanore? "" + @string/call_log_header_today "%1$s%2$s" "%1$02d:%2$02d" diff --git a/java/com/android/dialer/app/res/values-sr/strings.xml b/java/com/android/dialer/app/res/values-sr/strings.xml index 6cf7a7c85..6f85c0ba8 100644 --- a/java/com/android/dialer/app/res/values-sr/strings.xml +++ b/java/com/android/dialer/app/res/values-sr/strings.xml @@ -81,6 +81,7 @@ "Додај чекање" "Подешавања" "Симулатор" + "Направите пречицу за нови UI" "Сви контакти" "Употребите бројчаник за тонско бирање" "Врати се на позив који је у току" @@ -105,12 +106,15 @@ "%s сек" "%s мин %s сек" "Откажите режим групних радњи" - "говорну поруку" - "говорне поруке" - "Да" - "Не" + "Избриши" + "Откажи" "Желите ли да избришете изабрану(е) %1$s?" "Изабраних: %1$s" + + ""Желите ли да избришете ове говорне поруке? "" + ""Желите ли да избришете ове говорне поруке? "" + ""Желите ли да избришете ове говорне поруке? "" + @string/call_log_header_today "%1$s у %2$s" "%1$02d:%2$02d" diff --git a/java/com/android/dialer/app/res/values-sv/strings.xml b/java/com/android/dialer/app/res/values-sv/strings.xml index 71ef3e55b..e8446cab1 100644 --- a/java/com/android/dialer/app/res/values-sv/strings.xml +++ b/java/com/android/dialer/app/res/values-sv/strings.xml @@ -80,6 +80,7 @@ "Lägg till väntetid" "Inställningar" "Simulator" + "Skapa genväg till anv.gränssn." "Alla kontakter" "Använd tonvalstelefon" "Återvänd till pågående samtal" @@ -104,12 +105,14 @@ "%s sekund" "%s min %s sek" "Avbryt läget för massåtgärd" - "röstbrevlåda" - "röstmeddelanden" - "Ja" - "Nej" + "Radera" + "Avbryt" "Vill du radera markerade %1$s?" "%1$s har markerats" + + ""Vill du ta bort dessa röstmeddelanden? "" + ""Vill du ta bort det här röstmeddelandet? "" + @string/call_log_header_today "%1$s kl. %2$s" "%1$02d:%2$02d" diff --git a/java/com/android/dialer/app/res/values-sw/strings.xml b/java/com/android/dialer/app/res/values-sw/strings.xml index 9cbdd3e8e..142aaf0de 100644 --- a/java/com/android/dialer/app/res/values-sw/strings.xml +++ b/java/com/android/dialer/app/res/values-sw/strings.xml @@ -80,6 +80,7 @@ "Ongeza kusubiri" "Mipangilio" "Kielelezo" + "Unda Mkato Mpya wa Kiolesura" "Anwani zote" "Tumia kibao cha kuchapa cha sauti na kugusa" "Rudi kwa simu inayoendelea" @@ -104,12 +105,14 @@ "Sekunde %s" "Dak %s sek %s" "Ghairi hali ya kutekeleza vitendo vingi" - "ujumbe wa sauti" - "ujumbe wa sauti" - "Ndiyo" - "Hapana" + "Futa" + "Ghairi" "Je, ungependa kufuta %1$s uliochagua?" "%1$s zimechaguliwa" + + ""Je, unataka kufuta kila ujumbe wa sauti ulioonyeshwa? "" + ""Je, unataka kufuta ujumbe huu wa sauti? "" + @string/call_log_header_today "%1$s saa %2$s" "%1$02d:%2$02d" diff --git a/java/com/android/dialer/app/res/values-ta/strings.xml b/java/com/android/dialer/app/res/values-ta/strings.xml index a91088c4f..e270a3cee 100644 --- a/java/com/android/dialer/app/res/values-ta/strings.xml +++ b/java/com/android/dialer/app/res/values-ta/strings.xml @@ -80,6 +80,7 @@ "காத்திருப்பைச் சேர்" "அமைப்பு" "சிமுலேட்டர்" + "புதிய UI குறுக்குவழியை உருவாக்கு" "எல்லா தொடர்புகளும்" "டச் டோன் விசைப்பலகையைப் பயன்படுத்தவும்" "செயலிலுள்ள அழைப்பிற்குத் திரும்பு" @@ -104,12 +105,14 @@ "%s வி" "%s நிமிடம் %s வினாடி" "தொகுப்புச் செயல்கள் பயன்முறையை ரத்துசெய்யும்" - "குரலஞ்சல்" - "குரலஞ்சல்கள்" - "ஆம்" - "வேண்டாம்" + "நீக்கு" + "ரத்துசெய்" "தேர்ந்தெடுத்த %1$sஐ நீக்கவா?" "%1$s தேர்ந்தெடுக்கப்பட்டன" + + ""இந்தக் குரலஞ்சல்களை நீக்கவா? "" + ""இந்தக் குரலஞ்சலை நீக்கவா? "" + @string/call_log_header_today "%1$s அன்று %2$s மணிக்கு" "%1$02d:%2$02d" diff --git a/java/com/android/dialer/app/res/values-te/strings.xml b/java/com/android/dialer/app/res/values-te/strings.xml index aecc1c4b9..8d2c66784 100644 --- a/java/com/android/dialer/app/res/values-te/strings.xml +++ b/java/com/android/dialer/app/res/values-te/strings.xml @@ -80,6 +80,7 @@ "నిరీక్షణ సమయాన్ని జోడించు" "సెట్టింగ్‌లు" "సిములేటర్" + "కొత్త UI సత్వరమార్గం సృష్టించు" "అన్ని పరిచయాలు" "టచ్ టోన్ కీప్యాడ్‌ను ఉపయోగించండి" "ప్రోగ్రెస్‌లో ఉన్న కాల్‌కు వెళ్లు" @@ -104,12 +105,14 @@ "%s సెక" "%s నిమి %s సెక" "సమూహ చర్యల మోడ్‌ను రద్దు చేస్తుంది" - "వాయిస్ మెయిల్" - "వాయిస్ మెయిల్‌లు" - "అవును" - "వద్దు" + "తొలగించు" + "రద్దు చేయి" "ఎంచుకున్న %1$sను తొలగించాలా?" "%1$s ఎంచుకోబడ్డాయి" + + ""ఈ వాయిస్ మెయిల్‌లను తొలగించాలా? "" + ""ఈ వాయిస్ మెయిల్‌ను తొలగించాలా? "" + @string/call_log_header_today "%1$s %2$sకి" "%1$02d:%2$02d" diff --git a/java/com/android/dialer/app/res/values-th/strings.xml b/java/com/android/dialer/app/res/values-th/strings.xml index 58507b49e..76a66e20e 100644 --- a/java/com/android/dialer/app/res/values-th/strings.xml +++ b/java/com/android/dialer/app/res/values-th/strings.xml @@ -80,6 +80,7 @@ "เพิ่มการรอ" "การตั้งค่า" "เครื่องมือจำลอง" + "สร้างทางลัด UI ใหม่" "รายชื่อติดต่อทั้งหมด" "ใช้ปุ่มกดสัญญาณเสียง" "กลับไปคุยสายต่อ" @@ -104,12 +105,14 @@ "%s วินาที" "%s นาที %s วินาที" "ยกเลิกโหมดการทำงานแบบกลุ่ม" - "ข้อความเสียง" - "ข้อความเสียง" - "ใช่" - "ไม่" + "ลบ" + "ยกเลิก" "ลบ%1$sที่เลือกหรือไม่" "เลือกไว้ %1$s รายการ" + + ""ลบข้อความเสียงเหล่านี้ไหม "" + ""ลบข้อความเสียงนี้ไหม "" + @string/call_log_header_today "วันที่ %1$s เวลา %2$s" "%1$02d:%2$02d" diff --git a/java/com/android/dialer/app/res/values-tl/strings.xml b/java/com/android/dialer/app/res/values-tl/strings.xml index 9a8157fea..51e7a6659 100644 --- a/java/com/android/dialer/app/res/values-tl/strings.xml +++ b/java/com/android/dialer/app/res/values-tl/strings.xml @@ -80,6 +80,7 @@ "Magdagdag ng paghihintay" "Mga Setting" "Simulator" + "Gawa ng Shortcut ng Bagong UI" "Lahat ng mga contact" "Gumamit ng touch tone na keypad" "Bumalik sa kasalukuyang tawag" @@ -104,12 +105,14 @@ "%s sec" "%s min %s sec" "Kanselahin ang batch actions mode" - "voicemail" - "mga voicemail" - "Oo" - "Hindi" + "I-delete" + "Kanselahin" "I-delete ang napiling %1$s?" "%1$s ang napili" + + ""I-delete ang mga voicemail na ito? "" + ""I-delete ang mga voicemail na ito? "" + @string/call_log_header_today "%1$s ng %2$s" "%1$02d:%2$02d" diff --git a/java/com/android/dialer/app/res/values-tr/strings.xml b/java/com/android/dialer/app/res/values-tr/strings.xml index 17bd6645c..1ff0128d4 100644 --- a/java/com/android/dialer/app/res/values-tr/strings.xml +++ b/java/com/android/dialer/app/res/values-tr/strings.xml @@ -80,6 +80,7 @@ "Bekleme ekle" "Ayarlar" "Simülatör" + "Kull. Arayüzü Kısayolu Oluştur" "Tüm kişiler" "Telefon tuş takımını kullan" "Çağrıya dön" @@ -104,12 +105,14 @@ "%s sn." "%s dk. %s sn." "Toplu işlemler modu iptal edilir" - "sesli mesaj" - "sesli mesajlar" - "Evet" - "Hayır" + "Sil" + "İptal" "Seçili %1$s silinsin mi?" "%1$s öğe seçildi" + + ""Bu sesli mesajlar silinsin mi? "" + ""Bu sesli mesaj silinsin mi? "" + @string/call_log_header_today "%1$s, %2$s" "%1$02d:%2$02d" diff --git a/java/com/android/dialer/app/res/values-uk/strings.xml b/java/com/android/dialer/app/res/values-uk/strings.xml index a020a1f1b..b92970daa 100644 --- a/java/com/android/dialer/app/res/values-uk/strings.xml +++ b/java/com/android/dialer/app/res/values-uk/strings.xml @@ -82,6 +82,7 @@ "Додати паузу" "Налаштування" "Симулятор" + "Створити ярлик для нової дії" "Усі контакти" "Використовувати тональний набір" "Повернутися до поточного виклику" @@ -106,12 +107,16 @@ "%s с" "%s хв %s с" "Скасувати режим масових дій" - "голосова пошта" - "голосова пошта" - "Так" - "Ні" + "Видалити" + "Скасувати" "Видалити вибране (%1$s)?" "Вибрано %1$s" + + ""Видалити ці повідомлення голосової пошти? "" + ""Видалити ці повідомлення голосової пошти? "" + ""Видалити ці повідомлення голосової пошти? "" + ""Видалити ці повідомлення голосової пошти? "" + @string/call_log_header_today "%1$s о %2$s" "%1$02d:%2$02d" diff --git a/java/com/android/dialer/app/res/values-ur/strings.xml b/java/com/android/dialer/app/res/values-ur/strings.xml index d696bd54c..cb2eb9e33 100644 --- a/java/com/android/dialer/app/res/values-ur/strings.xml +++ b/java/com/android/dialer/app/res/values-ur/strings.xml @@ -80,6 +80,7 @@ "انتظار شامل کریں" "ترتیبات" "Simulator" + "‏نیا UI شارٹ کٹ تخلیق کریں" "سبھی رابطے" "ٹچ ٹون کی پیڈ کا استعمال کریں" "جاری کال پر واپس لوٹیں" @@ -104,12 +105,14 @@ "%s سیکنڈ" "%s منٹ %s سیکنڈ" "بیچ کاروائی موڈ منسوخ کریں" - "صوتی میل" - "صوتی میلز" - "ہاں" - "نہیں" + "حذف کریں" + "منسوخ کریں" "منتخب کردہ %1$s حذف کریں؟" "%1$s منتخب کردہ" + + ""ان صوتی میلز کو حذف کریں؟ "" + ""اس صوتی میل کو حذف کریں؟ "" + @string/call_log_header_today "%1$s بوقت %2$s" "%1$02d:%2$02d" diff --git a/java/com/android/dialer/app/res/values-uz/strings.xml b/java/com/android/dialer/app/res/values-uz/strings.xml index aa645bf88..c7d08f3bf 100644 --- a/java/com/android/dialer/app/res/values-uz/strings.xml +++ b/java/com/android/dialer/app/res/values-uz/strings.xml @@ -80,6 +80,7 @@ "Kutishni qo‘shish" "Sozlamalar" "Simulyator" + "Yangi interfeys uchun yorliq" "Barcha kontaktlar" "Tovushli raqam tergich" "Amaldagi chaqiruvga qaytish" @@ -104,12 +105,14 @@ "%s soniya" "%s daq %s son" "Yoppasiga bajariladigan amallar rejimini bekor qilish" - "ovozli xabar" - "ovozli xabarlar" - "Ha" - "Yo‘q" + "O‘chirish" + "Bekor qilish" "Tanlangan %1$s o‘chirib tashlansinmi?" "Tanlandi: %1$s" + + ""Bu ovozli xabarlar o‘chirib tashlansinmi? "" + ""Bu ovozli xabar o‘chirib tashlansinmi? "" + @string/call_log_header_today "%1$s, %2$s" "%1$02d:%2$02d" diff --git a/java/com/android/dialer/app/res/values-vi/strings.xml b/java/com/android/dialer/app/res/values-vi/strings.xml index dda7c1523..c79e1ed20 100644 --- a/java/com/android/dialer/app/res/values-vi/strings.xml +++ b/java/com/android/dialer/app/res/values-vi/strings.xml @@ -80,6 +80,7 @@ "Thêm chờ" "Cài đặt" "Trình mô phỏng" + "Tạo phím tắt giao diện người dùng mới" "Tất cả liên hệ" "Sử dụng bàn phím số cảm ứng có âm" "Quay lại cuộc gọi đang thực hiện" @@ -104,12 +105,14 @@ "%s giây" "%s phút %s giây" "Hủy chế độ tác vụ hàng loạt" - "thư thoại" - "thư thoại" - "Có" - "Không" + "Xóa" + "Hủy" "Xóa %1$s đã chọn?" "Đã chọn %1$s" + + ""Xóa các thư thoại này? "" + ""Xóa thư thoại này? "" + @string/call_log_header_today "%1$s lúc %2$s" "%1$02d:%2$02d" diff --git a/java/com/android/dialer/app/res/values-zh-rCN/strings.xml b/java/com/android/dialer/app/res/values-zh-rCN/strings.xml index 672614e48..3262c1a02 100644 --- a/java/com/android/dialer/app/res/values-zh-rCN/strings.xml +++ b/java/com/android/dialer/app/res/values-zh-rCN/strings.xml @@ -80,6 +80,7 @@ "延长等待时间" "设置" "模拟器" + "创建可在新界面中使用的快捷键" "所有联系人" "使用按键式键盘" "返回正在进行的通话" @@ -104,12 +105,14 @@ "%s 秒" "%s 分钟 %s 秒" "取消批量操作模式" - "语音邮件" - "语音邮件" - "是" - "否" + "删除" + "取消" "要删除所选的%1$s吗?" "已选择 %1$s 封" + + ""要删除这些语音邮件吗?"" + ""要删除这封语音邮件吗?"" + @string/call_log_header_today "%1$s%2$s" "%1$02d:%2$02d" diff --git a/java/com/android/dialer/app/res/values-zh-rHK/strings.xml b/java/com/android/dialer/app/res/values-zh-rHK/strings.xml index f3dc44baf..71e62eddc 100644 --- a/java/com/android/dialer/app/res/values-zh-rHK/strings.xml +++ b/java/com/android/dialer/app/res/values-zh-rHK/strings.xml @@ -80,6 +80,7 @@ "新增插播功能" "設定" "模擬器" + "建立新使用者介面捷徑" "所有聯絡人" "使用觸控音頻按鍵" "返回進行中的通話" @@ -104,12 +105,14 @@ "%s 秒" "%s%s 秒" "取消批量操作模式" - "留言" - "留言" - "是" - "否" + "刪除" + "取消" "要刪除所選的%1$s嗎?" "已選取 %1$s 個" + + ""要刪除這些留言嗎?"" + ""要刪除此留言嗎?"" + @string/call_log_header_today "%1$s%2$s" "%1$02d:%2$02d" diff --git a/java/com/android/dialer/app/res/values-zh-rTW/strings.xml b/java/com/android/dialer/app/res/values-zh-rTW/strings.xml index 473955c5d..9178dcf67 100644 --- a/java/com/android/dialer/app/res/values-zh-rTW/strings.xml +++ b/java/com/android/dialer/app/res/values-zh-rTW/strings.xml @@ -80,6 +80,7 @@ "延長等待時間" "設定" "模擬工具" + "建立新版 UI 捷徑" "所有聯絡人" "使用觸控音按鍵" "返回進行中的通話" @@ -104,12 +105,14 @@ "%s 秒" "%s%s 秒" "取消批次操作模式" - "語音留言" - "語音留言" - "是" - "否" + "刪除" + "取消" "要刪除選取的%1$s嗎?" "已選取 %1$s 個" + + ""要刪除這些語音留言嗎?"" + ""要刪除這則語音留言嗎?"" + @string/call_log_header_today "%1$s%2$s" "%1$02d:%2$02d" diff --git a/java/com/android/dialer/app/res/values-zu/strings.xml b/java/com/android/dialer/app/res/values-zu/strings.xml index 93843aa2c..f52f597c8 100644 --- a/java/com/android/dialer/app/res/values-zu/strings.xml +++ b/java/com/android/dialer/app/res/values-zu/strings.xml @@ -80,6 +80,7 @@ "Yengeza ukulinda" "Izilungiselelo" "Isilingisi" + "Dala isinqamuleli esisha se-UI" "Bonke othintana nabo" "Sebenzisa ikhiphedi yethoni yokuthinta" "Buyela kukholi eqhubekayo" @@ -104,12 +105,14 @@ "%s isekhondi" "%s amaminithi %s amasekhondi" "Khansela imodi lezenzo zeqoqo" - "ivoyisimeyili" - "ama-meyli ezwi" - "Yebo" - "Cha" + "Susa" + "Khansela" "Susa okukhethiwe %1$s?" "Engu-%1$s ekhethiwe" + + ""Sula lawa mavoyisimeyili? "" + ""Sula lawa mavoyisimeyili? "" + @string/call_log_header_today "%1$s ngo-%2$s" "%1$02d:%2$02d" diff --git a/java/com/android/dialer/app/res/values/dimens.xml b/java/com/android/dialer/app/res/values/dimens.xml index 57c43ebbd..90a8bb879 100644 --- a/java/com/android/dialer/app/res/values/dimens.xml +++ b/java/com/android/dialer/app/res/values/dimens.xml @@ -24,6 +24,11 @@ --> 16dp + + 14sp + 16dp + 18dp + 8dp 32dp diff --git a/java/com/android/dialer/app/res/values/strings.xml b/java/com/android/dialer/app/res/values/strings.xml index 6110601d8..e02c6fb30 100644 --- a/java/com/android/dialer/app/res/values/strings.xml +++ b/java/com/android/dialer/app/res/values/strings.xml @@ -114,7 +114,7 @@ Voicemail - + %1$d Voicemails @@ -131,12 +131,12 @@ [CHAR LIMIT=10] --> - %1$s, + %1$s, %2$s - New voicemail from + New voicemail from %1$s @@ -165,7 +165,7 @@ Missed calls only - (%1$d) + (%1$d) %2$s @@ -258,6 +258,9 @@ and testing. [CHAR LIMIT=30]--> Simulator + + Create New UI Shortcut + All contacts @@ -395,14 +398,18 @@ [CHAR LIMIT=NONE] --> Cancel batch actions mode - voicemail - voicemails - Yes - No + Delete + Cancel Delete selected %1$s? %1$s selected + + + Delete this voicemail? + Delete these voicemails? + + @@ -516,7 +523,7 @@ Undo - Call + Call %s @@ -579,13 +586,13 @@ - + Call ^1 - + Missed call from ^1, ^2, ^3, ^4. - + Call ^1 @@ -629,7 +636,7 @@ action triggers a return video call to the named person/number. Note: AccessibilityServices uses this attribute to announce the purpose of the button. [CHAR LIMIT=NONE] --> - + Video call ^1. @@ -638,21 +645,21 @@ triggers playing back the voicemail. Note: AccessibilityServices uses this attribute to announce the purpose of the button. [CHAR LIMIT=NONE] --> - + Listen to voicemail from ^1 - + Play voicemail from ^1 - + Pause voicemail from ^1 @@ -660,7 +667,7 @@ - + Delete voicemail from ^1 @@ -674,14 +681,14 @@ - + Create contact for ^1 - + Add ^1 to existing contact @@ -689,7 +696,7 @@ displays the call details screen for an entry in the call log. This shows the calls to and from the specified number associated with the call log entry. [CHAR LIMIT=NONE] --> - + Call details for ^1 @@ -798,14 +805,14 @@ - + Call blocking temporarily off - + Call blocking has been disabled because you contacted emergency services from this phone within the last 48 hours. It will be automatically reenabled once the 48 hour period expires. @@ -818,7 +825,7 @@ - + You previously marked some callers to be automatically sent to voicemail via other apps. @@ -840,13 +847,13 @@ - + Calls from these numbers will be blocked and voicemails will be automatically deleted. - + Calls from these numbers will be blocked, but they may still be able to leave you voicemails. @@ -855,7 +862,7 @@ - %1$s + %1$s is already blocked. diff --git a/java/com/android/dialer/app/res/values/styles.xml b/java/com/android/dialer/app/res/values/styles.xml index 592f06d29..e0122e81c 100644 --- a/java/com/android/dialer/app/res/values/styles.xml +++ b/java/com/android/dialer/app/res/values/styles.xml @@ -16,6 +16,11 @@ --> + + + + + diff --git a/java/com/android/dialer/notification/AndroidManifest.xml b/java/com/android/dialer/notification/AndroidManifest.xml index 741f481ca..b89d8f816 100644 --- a/java/com/android/dialer/notification/AndroidManifest.xml +++ b/java/com/android/dialer/notification/AndroidManifest.xml @@ -1,3 +1,4 @@ + - - - - - - - - - - - - diff --git a/java/com/android/dialer/notification/GroupedNotificationUtil.java b/java/com/android/dialer/notification/GroupedNotificationUtil.java deleted file mode 100644 index 3925248d5..000000000 --- a/java/com/android/dialer/notification/GroupedNotificationUtil.java +++ /dev/null @@ -1,66 +0,0 @@ -/* - * Copyright (C) 2017 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.dialer.notification; - -import android.app.NotificationManager; -import android.service.notification.StatusBarNotification; -import android.support.annotation.NonNull; -import android.support.annotation.Nullable; -import java.util.Objects; - -/** Utilities for dealing with grouped notifications */ -public final class GroupedNotificationUtil { - - /** - * Remove notification(s) that were added as part of a group. Will ensure that if this is the last - * notification in the group the summary will be removed. - * - * @param tag String tag as included in {@link NotificationManager#notify(String, int, - * android.app.Notification)}. If null will remove all notifications under id - * @param id notification id as included with {@link NotificationManager#notify(String, int, - * android.app.Notification)}. - * @param summaryTag String tag of the summary notification - */ - public static void removeNotification( - @NonNull NotificationManager notificationManager, - @Nullable String tag, - int id, - @NonNull String summaryTag) { - if (tag == null) { - // Clear all grouped notifications - for (StatusBarNotification notification : notificationManager.getActiveNotifications()) { - if (notification.getId() == id) { - notificationManager.cancel(notification.getTag(), id); - } - } - } else { - notificationManager.cancel(tag, id); - - // See if other non-summary grouped notifications exist, and if not then clear the summary - boolean clearSummary = true; - for (StatusBarNotification notification : notificationManager.getActiveNotifications()) { - if (notification.getId() == id && !Objects.equals(summaryTag, notification.getTag())) { - clearSummary = false; - break; - } - } - if (clearSummary) { - notificationManager.cancel(summaryTag, id); - } - } - } -} diff --git a/java/com/android/dialer/notification/NotificationChannelId.java b/java/com/android/dialer/notification/NotificationChannelId.java new file mode 100644 index 000000000..4ab3d44f2 --- /dev/null +++ b/java/com/android/dialer/notification/NotificationChannelId.java @@ -0,0 +1,41 @@ +/* + * Copyright (C) 2017 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.dialer.notification; + +import android.support.annotation.StringDef; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; + +/** Centralized source of all notification channels used by Dialer. */ +@Retention(RetentionPolicy.SOURCE) +@StringDef({ + NotificationChannelId.INCOMING_CALL, + NotificationChannelId.ONGOING_CALL, + NotificationChannelId.MISSED_CALL, + NotificationChannelId.DEFAULT, +}) +public @interface NotificationChannelId { + // This value is white listed in the system. + // See /vendor/google/nexus_overlay/common/frameworks/base/core/res/res/values/config.xml + String INCOMING_CALL = "phone_incoming_call"; + + String ONGOING_CALL = "phone_ongoing_call"; + + String MISSED_CALL = "phone_missed_call"; + + String DEFAULT = "phone_default"; +} diff --git a/java/com/android/dialer/notification/NotificationChannelManager.java b/java/com/android/dialer/notification/NotificationChannelManager.java index 88679066d..790aac36f 100644 --- a/java/com/android/dialer/notification/NotificationChannelManager.java +++ b/java/com/android/dialer/notification/NotificationChannelManager.java @@ -17,366 +17,156 @@ package com.android.dialer.notification; import android.annotation.TargetApi; -import android.app.Notification; import android.app.NotificationChannel; -import android.app.NotificationChannelGroup; import android.app.NotificationManager; import android.content.Context; -import android.content.Intent; -import android.content.SharedPreferences; import android.media.AudioAttributes; -import android.net.Uri; import android.os.Build.VERSION_CODES; -import android.provider.Settings; import android.support.annotation.NonNull; import android.support.annotation.Nullable; -import android.support.annotation.RequiresApi; -import android.support.annotation.StringDef; import android.support.v4.os.BuildCompat; -import android.telecom.PhoneAccount; import android.telecom.PhoneAccountHandle; -import android.telecom.TelecomManager; -import android.telephony.TelephonyManager; -import com.android.contacts.common.compat.TelephonyManagerCompat; -import com.android.dialer.buildtype.BuildType; +import android.util.ArraySet; +import com.android.dialer.common.Assert; import com.android.dialer.common.LogUtil; -import com.android.dialer.common.concurrent.DialerExecutors; -import com.android.dialer.telecom.TelecomUtil; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.util.List; -import java.util.Objects; +import java.util.Set; -/** Contains info on how to create {@link NotificationChannel NotificationChannels} */ -public class NotificationChannelManager { - - private static final String PREFS_FILENAME = "NotificationChannelManager"; - private static final String PREF_NEED_FIRST_INIT = "needFirstInit"; - private static NotificationChannelManager instance; - - public static NotificationChannelManager getInstance() { - if (instance == null) { - instance = new NotificationChannelManager(); - } - return instance; - } +/** Creates all notification channels for Dialer. */ +@TargetApi(VERSION_CODES.O) +public final class NotificationChannelManager { /** - * Set the channel of notification appropriately. Will create the channel if it does not already - * exist. Safe to call pre-O (will no-op). + * Creates all the notification channels Dialer will need. This method is called at app startup + * and must be fast. Currently it takes between 3 to 7 milliseconds on a Pixel XL. + * + *

An alternative approach would be to lazily create channels when we actualy post a + * notification. The advatange to precreating channels is that: * - *

phoneAccount should only be null if channelName is {@link Channel#DEFAULT} or {@link - * Channel#MISSED_CALL} since these do not have account-specific settings. + *

    + *
  • channels will be available to user right away. For example, users can customize voicemail + * sounds when they first get their device without waiting for a voicemail to arrive first. + *
  • code that posts a notification can be simpler + *
  • channel management code is simpler and it's easier to ensure that the correct set of + * channels are visible. + *
      */ - @TargetApi(26) - public static void applyChannel( - @NonNull Notification.Builder notification, - @NonNull Context context, - @Channel String channelName, - @Nullable PhoneAccountHandle phoneAccount) { - checkNullity(channelName, phoneAccount); - - if (BuildCompat.isAtLeastO()) { - NotificationChannel channel = - NotificationChannelManager.getInstance().getChannel(context, channelName, phoneAccount); - notification.setChannelId(channel.getId()); - } - } - - private static void checkNullity( - @Channel String channelName, @Nullable PhoneAccountHandle phoneAccount) { - if (phoneAccount != null || channelAllowsNullPhoneAccountHandle(channelName)) { - return; - } - - // TODO (b/36568553): don't throw an exception once most cases have been identified - IllegalArgumentException exception = - new IllegalArgumentException( - "Phone account handle must not be null on channel " + channelName); - if (BuildType.get() == BuildType.RELEASE) { - LogUtil.e("NotificationChannelManager.applyChannel", null, exception); - } else { - throw exception; - } - } - - private static boolean channelAllowsNullPhoneAccountHandle(@Channel String channelName) { - switch (channelName) { - case Channel.DEFAULT: - case Channel.MISSED_CALL: - return true; - default: - return false; - } - } + public static void initChannels(@NonNull Context context) { + Assert.checkArgument(BuildCompat.isAtLeastO()); + Assert.isNotNull(context); - /** The base Channel IDs for {@link NotificationChannel} */ - @Retention(RetentionPolicy.SOURCE) - @StringDef({ - Channel.INCOMING_CALL, - Channel.ONGOING_CALL, - Channel.ONGOING_CALL_OLD, - Channel.MISSED_CALL, - Channel.VOICEMAIL, - Channel.EXTERNAL_CALL, - Channel.DEFAULT - }) - public @interface Channel { - @Deprecated String ONGOING_CALL_OLD = "ongoingCall"; - String INCOMING_CALL = "incomingCall"; - String ONGOING_CALL = "ongoingCall2"; - String MISSED_CALL = "missedCall"; - String VOICEMAIL = "voicemail"; - String EXTERNAL_CALL = "externalCall"; - String DEFAULT = "default"; - } - - @Channel - private static final String[] prepopulatedAccountChannels = - new String[] {Channel.INCOMING_CALL, Channel.ONGOING_CALL, Channel.VOICEMAIL}; - - @Channel - private static final String[] prepopulatedGlobalChannels = - new String[] {Channel.MISSED_CALL, Channel.DEFAULT}; - - private NotificationChannelManager() {} - - public void firstInitIfNeeded(@NonNull Context context) { - if (BuildCompat.isAtLeastO()) { - DialerExecutors.createNonUiTaskBuilder(this::firstInitIfNeededSync) - .build() - .executeSerial(context); - } - } - - private boolean firstInitIfNeededSync(@NonNull Context context) { - if (needsFirstInit(context)) { - initChannels(context); - return true; - } - return false; - } - - public boolean needsFirstInit(@NonNull Context context) { - return (BuildCompat.isAtLeastO() - && getSharedPreferences(context).getBoolean(PREF_NEED_FIRST_INIT, true)); - } - - @RequiresApi(VERSION_CODES.N) - private SharedPreferences getSharedPreferences(@NonNull Context context) { - // Use device protected storage since in some cases this will need to be accessed while device - // is locked - context = context.createDeviceProtectedStorageContext(); - return context.getSharedPreferences(PREFS_FILENAME, Context.MODE_PRIVATE); - } - - @RequiresApi(26) - public Intent getSettingsIntentForChannel( - @NonNull Context context, @Channel String channelName, PhoneAccountHandle accountHandle) { - checkNullity(channelName, accountHandle); - Intent intent = new Intent(Settings.ACTION_CHANNEL_NOTIFICATION_SETTINGS); - intent.putExtra( - Settings.EXTRA_CHANNEL_ID, getChannel(context, channelName, accountHandle).getId()); - intent.putExtra(Settings.EXTRA_APP_PACKAGE, context.getPackageName()); - return intent; - } + NotificationManager notificationManager = context.getSystemService(NotificationManager.class); + Set desiredChannelIds = getAllDesiredChannelIds(context); + Set existingChannelIds = getAllExistingChannelIds(context); - @TargetApi(26) - @SuppressWarnings("AndroidApiChecker") - public void initChannels(@NonNull Context context) { - if (!BuildCompat.isAtLeastO()) { + if (desiredChannelIds.equals(existingChannelIds)) { return; } - LogUtil.enterBlock("NotificationChannelManager.initChannels"); - List phoneAccounts = TelecomUtil.getCallCapablePhoneAccounts(context); - - // Remove notification channels for PhoneAccounts that don't exist anymore - NotificationManager notificationManager = context.getSystemService(NotificationManager.class); - List notificationChannelGroups = - notificationManager.getNotificationChannelGroups(); - notificationChannelGroups - .stream() - .filter(group -> !idExists(group.getId(), phoneAccounts)) - .forEach(group -> deleteGroup(notificationManager, group)); - - for (PhoneAccountHandle phoneAccountHandle : phoneAccounts) { - for (@Channel String channel : prepopulatedAccountChannels) { - getChannel(context, channel, phoneAccountHandle); + LogUtil.i( + "NotificationChannelManager.initChannels", + "doing an expensive initialization of all notification channels"); + LogUtil.i( + "NotificationChannelManager.initChannels", "desired channel IDs: " + desiredChannelIds); + LogUtil.i( + "NotificationChannelManager.initChannels", "existing channel IDs: " + existingChannelIds); + + // Delete any old channels that we don't use any more. This is safe because if we're recreate + // this later then any user settings will be restored. An example is SIM specific voicemail + // channel that gets deleted when the user removes the SIM and is then restored when the user + // re-inserts the SIM. + for (String existingChannelId : existingChannelIds) { + if (!desiredChannelIds.contains(existingChannelId)) { + notificationManager.deleteNotificationChannel(existingChannelId); } } - for (@Channel String channel : prepopulatedGlobalChannels) { - getChannel(context, channel, null); - } - getSharedPreferences(context).edit().putBoolean(PREF_NEED_FIRST_INIT, false).apply(); - } - - @TargetApi(26) - private void deleteGroup( - @NonNull NotificationManager notificationManager, @NonNull NotificationChannelGroup group) { - for (NotificationChannel channel : group.getChannels()) { - notificationManager.deleteNotificationChannel(channel.getId()); - } - notificationManager.deleteNotificationChannelGroup(group.getId()); - } - - private boolean idExists(String id, List phoneAccountHandles) { - for (PhoneAccountHandle handle : phoneAccountHandles) { - if (Objects.equals(handle.getId(), id)) { - return true; - } - } - return false; + // Just recreate all desired channels. We won't do this often so it's ok to do this now. + createIncomingCallChannel(context); + createOngoingCallChannel(context); + createMissedCallChannel(context); + createDefaultChannel(context); + VoicemailChannelUtils.createAllChannels(context); } @NonNull - @RequiresApi(26) - private NotificationChannel getChannel( - @NonNull Context context, - @Channel String channelName, - @Nullable PhoneAccountHandle phoneAccount) { - String channelId = channelNameToId(channelName, phoneAccount); - NotificationChannel channel = getNotificationManager(context).getNotificationChannel(channelId); - if (channel == null) { - channel = createChannel(context, channelName, phoneAccount); - } - return channel; + public static String getVoicemailChannelId( + @NonNull Context context, @Nullable PhoneAccountHandle handle) { + Assert.checkArgument(BuildCompat.isAtLeastO()); + Assert.isNotNull(context); + return VoicemailChannelUtils.getChannelId(context, handle); } - private static String channelNameToId( - @Channel String name, @Nullable PhoneAccountHandle phoneAccountHandle) { - if (phoneAccountHandle == null) { - return name; - } else { - return name + ":" + phoneAccountHandle.getId(); - } - } - - @RequiresApi(26) - private NotificationChannel createChannel( - Context context, - @Channel String channelName, - @Nullable PhoneAccountHandle phoneAccountHandle) { - String channelId = channelNameToId(channelName, phoneAccountHandle); - - if (phoneAccountHandle != null) { - PhoneAccount account = getTelecomManager(context).getPhoneAccount(phoneAccountHandle); - NotificationChannelGroup group = - new NotificationChannelGroup( - phoneAccountHandle.getId(), - (account == null) ? phoneAccountHandle.getId() : account.getLabel().toString()); - getNotificationManager(context) - .createNotificationChannelGroup(group); // No-op if already exists - } else if (!channelAllowsNullPhoneAccountHandle(channelName)) { - LogUtil.w( - "NotificationChannelManager.createChannel", - "Null PhoneAccountHandle with channel " + channelName); - } - - Uri silentRingtone = Uri.EMPTY; - - CharSequence name; - int importance; - boolean canShowBadge; - boolean lights; - boolean vibration; - Uri sound; - switch (channelName) { - case Channel.INCOMING_CALL: - name = context.getText(R.string.notification_channel_incoming_call); - importance = NotificationManager.IMPORTANCE_MAX; - canShowBadge = false; - lights = true; - vibration = false; - sound = silentRingtone; - break; - case Channel.MISSED_CALL: - name = context.getText(R.string.notification_channel_missed_call); - importance = NotificationManager.IMPORTANCE_DEFAULT; - canShowBadge = true; - lights = true; - vibration = true; - sound = silentRingtone; - break; - case Channel.ONGOING_CALL: - name = context.getText(R.string.notification_channel_ongoing_call); - importance = NotificationManager.IMPORTANCE_DEFAULT; - canShowBadge = false; - lights = false; - vibration = false; - sound = silentRingtone; - deleteOldOngoingCallChannelIfNeeded(context, phoneAccountHandle); - break; - case Channel.VOICEMAIL: - name = context.getText(R.string.notification_channel_voicemail); - importance = NotificationManager.IMPORTANCE_DEFAULT; - canShowBadge = true; - lights = true; - vibration = - TelephonyManagerCompat.isVoicemailVibrationEnabled( - getTelephonyManager(context), phoneAccountHandle); - sound = - TelephonyManagerCompat.getVoicemailRingtoneUri( - getTelephonyManager(context), phoneAccountHandle); - break; - case Channel.EXTERNAL_CALL: - name = context.getText(R.string.notification_channel_external_call); - importance = NotificationManager.IMPORTANCE_HIGH; - canShowBadge = false; - lights = true; - vibration = true; - sound = null; - break; - case Channel.DEFAULT: - name = context.getText(R.string.notification_channel_misc); - importance = NotificationManager.IMPORTANCE_DEFAULT; - canShowBadge = false; - lights = true; - vibration = true; - sound = null; - break; - default: - throw new IllegalArgumentException("Unknown channel: " + channelName); - } - - NotificationChannel channel = new NotificationChannel(channelId, name, importance); - channel.setShowBadge(canShowBadge); - if (sound != null) { - // silentRingtone acts as a sentinel value to indicate that setSound should still be called, - // but with a null value to indicate no sound. - channel.setSound( - sound.equals(silentRingtone) ? null : sound, - new AudioAttributes.Builder().setUsage(AudioAttributes.USAGE_NOTIFICATION).build()); - } - channel.enableLights(lights); - channel.enableVibration(vibration); - getNotificationManager(context).createNotificationChannel(channel); - return channel; - } - - @RequiresApi(26) - private void deleteOldOngoingCallChannelIfNeeded( - @NonNull Context context, PhoneAccountHandle phoneAccountHandle) { - String channelId = channelNameToId(Channel.ONGOING_CALL_OLD, phoneAccountHandle); - NotificationManager notificationManager = getNotificationManager(context); - NotificationChannel channel = notificationManager.getNotificationChannel(channelId); - if (channel != null) { - LogUtil.i( - "NotificationManager.deleteOldOngoingCallChannelIfNeeded", - "Old ongoing channel found. Deleting to create new channel"); - notificationManager.deleteNotificationChannel(channel.getId()); - } - } - - private static NotificationManager getNotificationManager(@NonNull Context context) { - return context.getSystemService(NotificationManager.class); - } - - private static TelephonyManager getTelephonyManager(@NonNull Context context) { - return context.getSystemService(TelephonyManager.class); + private static Set getAllExistingChannelIds(@NonNull Context context) { + Set result = new ArraySet<>(); + NotificationManager notificationManager = context.getSystemService(NotificationManager.class); + for (NotificationChannel channel : notificationManager.getNotificationChannels()) { + result.add(channel.getId()); + } + return result; + } + + private static Set getAllDesiredChannelIds(@NonNull Context context) { + Set result = new ArraySet<>(); + result.add(NotificationChannelId.INCOMING_CALL); + result.add(NotificationChannelId.ONGOING_CALL); + result.add(NotificationChannelId.MISSED_CALL); + result.add(NotificationChannelId.DEFAULT); + result.addAll(VoicemailChannelUtils.getAllChannelIds(context)); + return result; + } + + private static void createIncomingCallChannel(@NonNull Context context) { + NotificationChannel channel = + new NotificationChannel( + NotificationChannelId.INCOMING_CALL, + context.getText(R.string.notification_channel_incoming_call), + NotificationManager.IMPORTANCE_MAX); + channel.setShowBadge(false); + channel.enableLights(true); + channel.enableVibration(false); + channel.setSound( + null, new AudioAttributes.Builder().setUsage(AudioAttributes.USAGE_NOTIFICATION).build()); + context.getSystemService(NotificationManager.class).createNotificationChannel(channel); + } + + private static void createOngoingCallChannel(@NonNull Context context) { + NotificationChannel channel = + new NotificationChannel( + NotificationChannelId.ONGOING_CALL, + context.getText(R.string.notification_channel_ongoing_call), + NotificationManager.IMPORTANCE_DEFAULT); + channel.setShowBadge(false); + channel.enableLights(false); + channel.enableVibration(false); + channel.setSound( + null, new AudioAttributes.Builder().setUsage(AudioAttributes.USAGE_NOTIFICATION).build()); + context.getSystemService(NotificationManager.class).createNotificationChannel(channel); + } + + private static void createMissedCallChannel(@NonNull Context context) { + NotificationChannel channel = + new NotificationChannel( + NotificationChannelId.MISSED_CALL, + context.getText(R.string.notification_channel_missed_call), + NotificationManager.IMPORTANCE_DEFAULT); + channel.setShowBadge(true); + channel.enableLights(true); + channel.enableVibration(true); + channel.setSound( + null, new AudioAttributes.Builder().setUsage(AudioAttributes.USAGE_NOTIFICATION).build()); + context.getSystemService(NotificationManager.class).createNotificationChannel(channel); + } + + private static void createDefaultChannel(@NonNull Context context) { + NotificationChannel channel = + new NotificationChannel( + NotificationChannelId.DEFAULT, + context.getText(R.string.notification_channel_misc), + NotificationManager.IMPORTANCE_DEFAULT); + channel.setShowBadge(false); + channel.enableLights(true); + channel.enableVibration(true); + context.getSystemService(NotificationManager.class).createNotificationChannel(channel); } - private static TelecomManager getTelecomManager(@NonNull Context context) { - return context.getSystemService(TelecomManager.class); - } + private NotificationChannelManager() {} } diff --git a/java/com/android/dialer/notification/PackageUpdatedReceiver.java b/java/com/android/dialer/notification/PackageUpdatedReceiver.java deleted file mode 100644 index feed40263..000000000 --- a/java/com/android/dialer/notification/PackageUpdatedReceiver.java +++ /dev/null @@ -1,37 +0,0 @@ -/* - * Copyright (C) 2017 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.dialer.notification; - -import android.annotation.TargetApi; -import android.content.BroadcastReceiver; -import android.content.Context; -import android.content.Intent; -import android.support.v4.os.BuildCompat; - -/** Inits the notification channels when Dialer or OS is updated */ -public class PackageUpdatedReceiver extends BroadcastReceiver { - - @Override - @TargetApi(26) - public void onReceive(Context context, Intent intent) { - if (!BuildCompat.isAtLeastO()) { - return; - } - context = context.createDeviceProtectedStorageContext(); - NotificationChannelManager.getInstance().initChannels(context); - } -} diff --git a/java/com/android/dialer/notification/VoicemailChannelUtils.java b/java/com/android/dialer/notification/VoicemailChannelUtils.java new file mode 100644 index 000000000..dc74799ca --- /dev/null +++ b/java/com/android/dialer/notification/VoicemailChannelUtils.java @@ -0,0 +1,217 @@ +/* + * Copyright (C) 2017 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.dialer.notification; + +import android.annotation.TargetApi; +import android.app.NotificationChannel; +import android.app.NotificationManager; +import android.content.Context; +import android.media.AudioAttributes; +import android.os.Build.VERSION_CODES; +import android.provider.Settings; +import android.support.annotation.NonNull; +import android.support.annotation.Nullable; +import android.support.v4.os.BuildCompat; +import android.telecom.PhoneAccount; +import android.telecom.PhoneAccountHandle; +import android.telecom.TelecomManager; +import android.telephony.TelephonyManager; +import android.text.TextUtils; +import android.util.ArraySet; +import com.android.dialer.common.Assert; +import com.android.dialer.common.LogUtil; +import java.util.ArrayList; +import java.util.List; +import java.util.Set; + +/** Utilities for working with voicemail channels. */ +@TargetApi(VERSION_CODES.O) +/* package */ final class VoicemailChannelUtils { + private static final String GLOBAL_VOICEMAIL_CHANNEL_ID = "phone_voicemail"; + private static final String PER_ACCOUNT_VOICEMAIL_CHANNEL_ID_PREFIX = "phone_voicemail_account_"; + + static Set getAllChannelIds(@NonNull Context context) { + Assert.checkArgument(BuildCompat.isAtLeastO()); + Assert.isNotNull(context); + + Set result = new ArraySet<>(); + if (isSingleSimDevice(context)) { + result.add(GLOBAL_VOICEMAIL_CHANNEL_ID); + } else { + for (PhoneAccountHandle handle : getAllEligableAccounts(context)) { + result.add(getChannelIdForAccount(handle)); + } + } + return result; + } + + static void createAllChannels(@NonNull Context context) { + Assert.checkArgument(BuildCompat.isAtLeastO()); + Assert.isNotNull(context); + + if (isSingleSimDevice(context)) { + createGlobalVoicemailChannel(context); + } else { + for (PhoneAccountHandle handle : getAllEligableAccounts(context)) { + createVoicemailChannelForAccount(context, handle); + } + } + } + + @NonNull + static String getChannelId(@NonNull Context context, @Nullable PhoneAccountHandle handle) { + Assert.checkArgument(BuildCompat.isAtLeastO()); + Assert.isNotNull(context); + + // Most devices we deal with have a single SIM slot. No need to distinguish between phone + // accounts. + if (isSingleSimDevice(context)) { + return GLOBAL_VOICEMAIL_CHANNEL_ID; + } + + // We can get a null phone account at random points (modem reboot, etc...). Gracefully degrade + // by using the default channel. + if (handle == null) { + LogUtil.i( + "VoicemailChannelUtils.getChannelId", + "no phone account on a multi-SIM device, using default channel"); + return NotificationChannelId.DEFAULT; + } + + // Voicemail notifications should always be associated with a SIM based phone account. + if (!isChannelAllowedForAccount(context, handle)) { + LogUtil.i( + "VoicemailChannelUtils.getChannelId", + "phone account is not for a SIM, using default channel"); + return NotificationChannelId.DEFAULT; + } + + // Now we're in the multi-SIM case. + String channelId = getChannelIdForAccount(handle); + if (!doesChannelExist(context, channelId)) { + LogUtil.i( + "VoicemailChannelUtils.getChannelId", + "voicemail channel not found for phone account (possible SIM swap?), creating a new one"); + createVoicemailChannelForAccount(context, handle); + } + return channelId; + } + + private static boolean doesChannelExist(@NonNull Context context, @NonNull String channelId) { + return context.getSystemService(NotificationManager.class).getNotificationChannel(channelId) + != null; + } + + private static String getChannelIdForAccount(@NonNull PhoneAccountHandle handle) { + Assert.isNotNull(handle); + return PER_ACCOUNT_VOICEMAIL_CHANNEL_ID_PREFIX + ":" + handle.getId(); + } + + /** + * Creates a voicemail channel but doesn't associate it with a SIM. For devices with only one SIM + * slot this is ideal because there won't be duplication in the settings UI. + */ + private static void createGlobalVoicemailChannel(@NonNull Context context) { + NotificationChannel channel = newChannel(context, GLOBAL_VOICEMAIL_CHANNEL_ID, null); + + TelecomManager telecomManager = context.getSystemService(TelecomManager.class); + PhoneAccountHandle handle = + telecomManager.getDefaultOutgoingPhoneAccount(PhoneAccount.SCHEME_TEL); + if (handle == null) { + LogUtil.i( + "VoicemailChannelUtils.createGlobalVoicemailChannel", + "phone account is null, not migrating sound settings"); + } else if (!isChannelAllowedForAccount(context, handle)) { + LogUtil.i( + "VoicemailChannelUtils.createGlobalVoicemailChannel", + "phone account is not eligable, not migrating sound settings"); + } else { + migrateVoicemailSoundSettings(context, channel, handle); + } + context.getSystemService(NotificationManager.class).createNotificationChannel(channel); + } + + private static List getAllEligableAccounts(@NonNull Context context) { + List handles = new ArrayList<>(); + TelecomManager telecomManager = context.getSystemService(TelecomManager.class); + for (PhoneAccountHandle handle : telecomManager.getCallCapablePhoneAccounts()) { + if (isChannelAllowedForAccount(context, handle)) { + handles.add(handle); + } + } + return handles; + } + + private static void createVoicemailChannelForAccount( + @NonNull Context context, @NonNull PhoneAccountHandle handle) { + PhoneAccount phoneAccount = + context.getSystemService(TelecomManager.class).getPhoneAccount(handle); + NotificationChannel channel = + newChannel(context, getChannelIdForAccount(handle), phoneAccount.getLabel()); + migrateVoicemailSoundSettings(context, channel, handle); + context.getSystemService(NotificationManager.class).createNotificationChannel(channel); + } + + private static void migrateVoicemailSoundSettings( + @NonNull Context context, + @NonNull NotificationChannel channel, + @NonNull PhoneAccountHandle handle) { + TelephonyManager telephonyManager = context.getSystemService(TelephonyManager.class); + channel.enableVibration(telephonyManager.isVoicemailVibrationEnabled(handle)); + channel.setSound( + telephonyManager.getVoicemailRingtoneUri(handle), + new AudioAttributes.Builder().setUsage(AudioAttributes.USAGE_NOTIFICATION).build()); + } + + private static boolean isChannelAllowedForAccount( + @NonNull Context context, @NonNull PhoneAccountHandle handle) { + PhoneAccount phoneAccount = + context.getSystemService(TelecomManager.class).getPhoneAccount(handle); + if (phoneAccount == null) { + return false; + } + if (!phoneAccount.hasCapabilities(PhoneAccount.CAPABILITY_SIM_SUBSCRIPTION)) { + return false; + } + return true; + } + + private static NotificationChannel newChannel( + @NonNull Context context, @NonNull String channelId, @Nullable CharSequence nameSuffix) { + CharSequence name = context.getText(R.string.notification_channel_voicemail); + // TODO: Use a string resource template after v10. + if (!TextUtils.isEmpty(nameSuffix)) { + name = TextUtils.concat(name, ": ", nameSuffix); + } + + NotificationChannel channel = + new NotificationChannel(channelId, name, NotificationManager.IMPORTANCE_DEFAULT); + channel.setShowBadge(true); + channel.enableLights(true); + channel.enableVibration(true); + channel.setSound( + Settings.System.DEFAULT_NOTIFICATION_URI, + new AudioAttributes.Builder().setUsage(AudioAttributes.USAGE_NOTIFICATION).build()); + return channel; + } + + private static boolean isSingleSimDevice(@NonNull Context context) { + return context.getSystemService(TelephonyManager.class).getPhoneCount() <= 1; + } + + private VoicemailChannelUtils() {} +} diff --git a/java/com/android/dialer/notification/res/values-af/strings.xml b/java/com/android/dialer/notification/res/values-af/strings.xml index 08dd754dd..e48249b3c 100644 --- a/java/com/android/dialer/notification/res/values-af/strings.xml +++ b/java/com/android/dialer/notification/res/values-af/strings.xml @@ -21,6 +21,5 @@ "Deurlopende oproepe" "Gemiste oproepe" "Stemboodskappe" - "Ekterne oproepe" "Verstek" diff --git a/java/com/android/dialer/notification/res/values-am/strings.xml b/java/com/android/dialer/notification/res/values-am/strings.xml index 56d6c2ca1..0983e0591 100644 --- a/java/com/android/dialer/notification/res/values-am/strings.xml +++ b/java/com/android/dialer/notification/res/values-am/strings.xml @@ -21,6 +21,5 @@ "በመካሄድ ላይ ያሉ ጥሪዎች" "ያመለጡ ጥሪዎች" "የድምፅ መልዕክቶች" - "ውጫዊ ጥሪዎች" "ነባሪ" diff --git a/java/com/android/dialer/notification/res/values-ar/strings.xml b/java/com/android/dialer/notification/res/values-ar/strings.xml index 71857c274..ab6059ff1 100644 --- a/java/com/android/dialer/notification/res/values-ar/strings.xml +++ b/java/com/android/dialer/notification/res/values-ar/strings.xml @@ -21,6 +21,5 @@ "المكالمات الجارية" "المكالمات الفائتة" "رسائل البريد الصوتي" - "المكالمات الخارجية" "افتراضي" diff --git a/java/com/android/dialer/notification/res/values-az/strings.xml b/java/com/android/dialer/notification/res/values-az/strings.xml index f907e554e..425f30ad7 100644 --- a/java/com/android/dialer/notification/res/values-az/strings.xml +++ b/java/com/android/dialer/notification/res/values-az/strings.xml @@ -21,6 +21,5 @@ "Gedən zənglər" "Buraxılmış zənglər" "Səsli məktublar" - "External calls" "Defolt" diff --git a/java/com/android/dialer/notification/res/values-b+sr+Latn/strings.xml b/java/com/android/dialer/notification/res/values-b+sr+Latn/strings.xml index 4d5b5e78a..4598e7644 100644 --- a/java/com/android/dialer/notification/res/values-b+sr+Latn/strings.xml +++ b/java/com/android/dialer/notification/res/values-b+sr+Latn/strings.xml @@ -21,6 +21,5 @@ "Pozivi u toku" "Propušteni pozivi" "Govorne poruke" - "Spoljni pozivi" "Podrazumevano" diff --git a/java/com/android/dialer/notification/res/values-be/strings.xml b/java/com/android/dialer/notification/res/values-be/strings.xml index 70defe342..586a36c31 100644 --- a/java/com/android/dialer/notification/res/values-be/strings.xml +++ b/java/com/android/dialer/notification/res/values-be/strings.xml @@ -21,6 +21,5 @@ "Адбываючыяся выклікі" "Прапушчаныя выклікі" "Галасавая пошта" - "Знешнія выклікі" "Стандартны" diff --git a/java/com/android/dialer/notification/res/values-bg/strings.xml b/java/com/android/dialer/notification/res/values-bg/strings.xml index 1ec202e6c..9bc8f8f02 100644 --- a/java/com/android/dialer/notification/res/values-bg/strings.xml +++ b/java/com/android/dialer/notification/res/values-bg/strings.xml @@ -21,6 +21,5 @@ "Текущи обаждания" "Пропуснати обаждания" "Гласови съобщения" - "Външни обаждания" "По подразбиране" diff --git a/java/com/android/dialer/notification/res/values-bn/strings.xml b/java/com/android/dialer/notification/res/values-bn/strings.xml index 886f8317d..1d7781797 100644 --- a/java/com/android/dialer/notification/res/values-bn/strings.xml +++ b/java/com/android/dialer/notification/res/values-bn/strings.xml @@ -21,6 +21,5 @@ "সংযুক্ত কল" "মিস করা কল" "ভয়েসমেল" - "বাহ্যিক কল" "ডিফল্ট" diff --git a/java/com/android/dialer/notification/res/values-bs/strings.xml b/java/com/android/dialer/notification/res/values-bs/strings.xml index e408a6468..dedbb1c2d 100644 --- a/java/com/android/dialer/notification/res/values-bs/strings.xml +++ b/java/com/android/dialer/notification/res/values-bs/strings.xml @@ -21,6 +21,5 @@ "Tekući pozivi" "Propušteni pozivi" "Poruke govorne pošte" - "Vanjski pozivi" "Zadano" diff --git a/java/com/android/dialer/notification/res/values-ca/strings.xml b/java/com/android/dialer/notification/res/values-ca/strings.xml index ea81b627a..1c19d0f74 100644 --- a/java/com/android/dialer/notification/res/values-ca/strings.xml +++ b/java/com/android/dialer/notification/res/values-ca/strings.xml @@ -21,6 +21,5 @@ "Trucades en curs" "Trucades perdudes" "Missatges de veu" - "Trucades externes" "Predeterminat" diff --git a/java/com/android/dialer/notification/res/values-cs/strings.xml b/java/com/android/dialer/notification/res/values-cs/strings.xml index 9ea7b61ca..c428ca2f3 100644 --- a/java/com/android/dialer/notification/res/values-cs/strings.xml +++ b/java/com/android/dialer/notification/res/values-cs/strings.xml @@ -21,6 +21,5 @@ "Probíhající hovory" "Zmeškané hovory" "Hlasové zprávy" - "Externí hovory" "Výchozí" diff --git a/java/com/android/dialer/notification/res/values-da/strings.xml b/java/com/android/dialer/notification/res/values-da/strings.xml index e4fc4dded..7f0ce9f10 100644 --- a/java/com/android/dialer/notification/res/values-da/strings.xml +++ b/java/com/android/dialer/notification/res/values-da/strings.xml @@ -21,6 +21,5 @@ "Igangværende opkald" "Ubesvarede opkald" "Talebeskeder" - "Eksterne opkald" "Standard" diff --git a/java/com/android/dialer/notification/res/values-de/strings.xml b/java/com/android/dialer/notification/res/values-de/strings.xml index 7fce6bf47..86b752016 100644 --- a/java/com/android/dialer/notification/res/values-de/strings.xml +++ b/java/com/android/dialer/notification/res/values-de/strings.xml @@ -21,6 +21,5 @@ "Laufende Anrufe" "Entgangene Anrufe" "Mailboxnachrichten" - "Externe Anrufe" "Standard" diff --git a/java/com/android/dialer/notification/res/values-el/strings.xml b/java/com/android/dialer/notification/res/values-el/strings.xml index a25bb43e9..812dc2564 100644 --- a/java/com/android/dialer/notification/res/values-el/strings.xml +++ b/java/com/android/dialer/notification/res/values-el/strings.xml @@ -21,6 +21,5 @@ "Κλήσεις σε εξέλιξη" "Αναπάντητες κλήσεις" "Μηνύματα αυτόματου τηλεφωνητή" - "Εξωτερικές κλήσεις" "Προεπιλογή" diff --git a/java/com/android/dialer/notification/res/values-en-rAU/strings.xml b/java/com/android/dialer/notification/res/values-en-rAU/strings.xml index 7d4bd825b..43b722beb 100644 --- a/java/com/android/dialer/notification/res/values-en-rAU/strings.xml +++ b/java/com/android/dialer/notification/res/values-en-rAU/strings.xml @@ -21,6 +21,5 @@ "Ongoing calls" "Missed calls" "Voicemail" - "External calls" "Default" diff --git a/java/com/android/dialer/notification/res/values-en-rGB/strings.xml b/java/com/android/dialer/notification/res/values-en-rGB/strings.xml index 7d4bd825b..43b722beb 100644 --- a/java/com/android/dialer/notification/res/values-en-rGB/strings.xml +++ b/java/com/android/dialer/notification/res/values-en-rGB/strings.xml @@ -21,6 +21,5 @@ "Ongoing calls" "Missed calls" "Voicemail" - "External calls" "Default" diff --git a/java/com/android/dialer/notification/res/values-en-rIN/strings.xml b/java/com/android/dialer/notification/res/values-en-rIN/strings.xml index 7d4bd825b..43b722beb 100644 --- a/java/com/android/dialer/notification/res/values-en-rIN/strings.xml +++ b/java/com/android/dialer/notification/res/values-en-rIN/strings.xml @@ -21,6 +21,5 @@ "Ongoing calls" "Missed calls" "Voicemail" - "External calls" "Default" diff --git a/java/com/android/dialer/notification/res/values-es-rUS/strings.xml b/java/com/android/dialer/notification/res/values-es-rUS/strings.xml index fe8fe1354..c56edcfe6 100644 --- a/java/com/android/dialer/notification/res/values-es-rUS/strings.xml +++ b/java/com/android/dialer/notification/res/values-es-rUS/strings.xml @@ -21,6 +21,5 @@ "Llamadas en curso" "Llamadas perdidas" "Mensajes de voz" - "Llamadas externas" "Predeterminado" diff --git a/java/com/android/dialer/notification/res/values-es/strings.xml b/java/com/android/dialer/notification/res/values-es/strings.xml index fe8fe1354..c56edcfe6 100644 --- a/java/com/android/dialer/notification/res/values-es/strings.xml +++ b/java/com/android/dialer/notification/res/values-es/strings.xml @@ -21,6 +21,5 @@ "Llamadas en curso" "Llamadas perdidas" "Mensajes de voz" - "Llamadas externas" "Predeterminado" diff --git a/java/com/android/dialer/notification/res/values-et/strings.xml b/java/com/android/dialer/notification/res/values-et/strings.xml index 41623951f..9c60a3195 100644 --- a/java/com/android/dialer/notification/res/values-et/strings.xml +++ b/java/com/android/dialer/notification/res/values-et/strings.xml @@ -21,6 +21,5 @@ "Käimasolevad kõned" "Vastamata kõned" "Kõnepostisõnumid" - "Välised kõned" "Vaikeseade" diff --git a/java/com/android/dialer/notification/res/values-eu/strings.xml b/java/com/android/dialer/notification/res/values-eu/strings.xml index 326ac0ab6..d94ac0ab6 100644 --- a/java/com/android/dialer/notification/res/values-eu/strings.xml +++ b/java/com/android/dialer/notification/res/values-eu/strings.xml @@ -21,6 +21,5 @@ "Abian diren deiak" "Dei galduak" "Ahots-mezuak" - "Kanpoko deiak" "Lehenetsia" diff --git a/java/com/android/dialer/notification/res/values-fa/strings.xml b/java/com/android/dialer/notification/res/values-fa/strings.xml index f1a7efc3d..edbc98336 100644 --- a/java/com/android/dialer/notification/res/values-fa/strings.xml +++ b/java/com/android/dialer/notification/res/values-fa/strings.xml @@ -21,6 +21,5 @@ "تماس‌های درحال انجام" "تماس‌های بی‌پاسخ" "پست‌های صوتی" - "تماس‌های خارجی" "پیش‌فرض" diff --git a/java/com/android/dialer/notification/res/values-fi/strings.xml b/java/com/android/dialer/notification/res/values-fi/strings.xml index c88c2325a..87652f8a8 100644 --- a/java/com/android/dialer/notification/res/values-fi/strings.xml +++ b/java/com/android/dialer/notification/res/values-fi/strings.xml @@ -21,6 +21,5 @@ "Käynnissä olevat puhelut" "Vastaamattomat puhelut" "Vastaajaviestit" - "Ulkopuoliset puhelut" "Oletus" diff --git a/java/com/android/dialer/notification/res/values-fr-rCA/strings.xml b/java/com/android/dialer/notification/res/values-fr-rCA/strings.xml index a21d6b28b..5a2d7dcfe 100644 --- a/java/com/android/dialer/notification/res/values-fr-rCA/strings.xml +++ b/java/com/android/dialer/notification/res/values-fr-rCA/strings.xml @@ -21,6 +21,5 @@ "Appels en cours" "Appels manqués" "Messages vocaux" - "Appels externes" "Par défaut" diff --git a/java/com/android/dialer/notification/res/values-fr/strings.xml b/java/com/android/dialer/notification/res/values-fr/strings.xml index a21d6b28b..5a2d7dcfe 100644 --- a/java/com/android/dialer/notification/res/values-fr/strings.xml +++ b/java/com/android/dialer/notification/res/values-fr/strings.xml @@ -21,6 +21,5 @@ "Appels en cours" "Appels manqués" "Messages vocaux" - "Appels externes" "Par défaut" diff --git a/java/com/android/dialer/notification/res/values-gl/strings.xml b/java/com/android/dialer/notification/res/values-gl/strings.xml index 3b57a59b3..0e7fb612b 100644 --- a/java/com/android/dialer/notification/res/values-gl/strings.xml +++ b/java/com/android/dialer/notification/res/values-gl/strings.xml @@ -21,6 +21,5 @@ "Chamadas saíntes" "Chamadas perdidas" "Correos de voz" - "Chamadas externas" "Predeterminado" diff --git a/java/com/android/dialer/notification/res/values-gu/strings.xml b/java/com/android/dialer/notification/res/values-gu/strings.xml index f185e5971..a4a0a7ae1 100644 --- a/java/com/android/dialer/notification/res/values-gu/strings.xml +++ b/java/com/android/dialer/notification/res/values-gu/strings.xml @@ -21,6 +21,5 @@ "ચાલુ કૉલ" "છૂટેલા કૉલ" "વૉઇસમેઇલ" - "બાહ્ય કૉલ" "ડિફૉલ્ટ" diff --git a/java/com/android/dialer/notification/res/values-hi/strings.xml b/java/com/android/dialer/notification/res/values-hi/strings.xml index 89c8e5547..69ed9b0b2 100644 --- a/java/com/android/dialer/notification/res/values-hi/strings.xml +++ b/java/com/android/dialer/notification/res/values-hi/strings.xml @@ -21,6 +21,5 @@ "चल रहे कॉल" "छूटे कॉल" "वॉइसमेल" - "बाहरी कॉल" "डिफ़ॉल्ट" diff --git a/java/com/android/dialer/notification/res/values-hr/strings.xml b/java/com/android/dialer/notification/res/values-hr/strings.xml index 9f786d7d8..a5924c3ce 100644 --- a/java/com/android/dialer/notification/res/values-hr/strings.xml +++ b/java/com/android/dialer/notification/res/values-hr/strings.xml @@ -21,6 +21,5 @@ "Pozivi u tijeku" "Propušteni pozivi" "Poruke govorne pošte" - "Vanjski pozivi" "Zadano" diff --git a/java/com/android/dialer/notification/res/values-hu/strings.xml b/java/com/android/dialer/notification/res/values-hu/strings.xml index 09fa795d6..719252f0f 100644 --- a/java/com/android/dialer/notification/res/values-hu/strings.xml +++ b/java/com/android/dialer/notification/res/values-hu/strings.xml @@ -21,6 +21,5 @@ "Kimenő hívások" "Nem fogadott hívások" "Hangüzenetek" - "Külső hívások" "Alapértelmezett" diff --git a/java/com/android/dialer/notification/res/values-hy/strings.xml b/java/com/android/dialer/notification/res/values-hy/strings.xml index 693898a55..6bb2c34e3 100644 --- a/java/com/android/dialer/notification/res/values-hy/strings.xml +++ b/java/com/android/dialer/notification/res/values-hy/strings.xml @@ -21,6 +21,5 @@ "Ընթացիկ զանգեր" "Բաց թողնված զանգեր" "Ձայնային փոստ" - "Արտաքին զանգեր" "Կանխադրված" diff --git a/java/com/android/dialer/notification/res/values-in/strings.xml b/java/com/android/dialer/notification/res/values-in/strings.xml index 405b2927d..88ef3d524 100644 --- a/java/com/android/dialer/notification/res/values-in/strings.xml +++ b/java/com/android/dialer/notification/res/values-in/strings.xml @@ -21,6 +21,5 @@ "Panggilan keluar" "Panggilan tak terjawab" "Pesan suara" - "Panggilan eksternal" "Default" diff --git a/java/com/android/dialer/notification/res/values-is/strings.xml b/java/com/android/dialer/notification/res/values-is/strings.xml index be84917fc..166d97443 100644 --- a/java/com/android/dialer/notification/res/values-is/strings.xml +++ b/java/com/android/dialer/notification/res/values-is/strings.xml @@ -21,6 +21,5 @@ "Símtöl í gangi" "Ósvöruð símtöl" "Talhólfsskilaboð" - "Utanaðkomandi símtöl" "Sjálfgefið" diff --git a/java/com/android/dialer/notification/res/values-it/strings.xml b/java/com/android/dialer/notification/res/values-it/strings.xml index 1ac6e2d41..7b55da991 100644 --- a/java/com/android/dialer/notification/res/values-it/strings.xml +++ b/java/com/android/dialer/notification/res/values-it/strings.xml @@ -21,6 +21,5 @@ "Chiamate in uscita" "Chiamate perse" "Messaggi vocali" - "Chiamate esterne" "Predefinito" diff --git a/java/com/android/dialer/notification/res/values-iw/strings.xml b/java/com/android/dialer/notification/res/values-iw/strings.xml index ed07b8643..2b8b9df33 100644 --- a/java/com/android/dialer/notification/res/values-iw/strings.xml +++ b/java/com/android/dialer/notification/res/values-iw/strings.xml @@ -21,6 +21,5 @@ "שיחות יוצאות" "שיחות שלא נענו" "הודעות קוליות" - "שיחות חיצוניות" "ברירת מחדל" diff --git a/java/com/android/dialer/notification/res/values-ja/strings.xml b/java/com/android/dialer/notification/res/values-ja/strings.xml index 3265d7266..2ff8da7d0 100644 --- a/java/com/android/dialer/notification/res/values-ja/strings.xml +++ b/java/com/android/dialer/notification/res/values-ja/strings.xml @@ -21,6 +21,5 @@ "通話中" "不在着信" "ボイスメール" - "外部通話" "デフォルト" diff --git a/java/com/android/dialer/notification/res/values-ka/strings.xml b/java/com/android/dialer/notification/res/values-ka/strings.xml index 6d81465e2..73394efeb 100644 --- a/java/com/android/dialer/notification/res/values-ka/strings.xml +++ b/java/com/android/dialer/notification/res/values-ka/strings.xml @@ -21,6 +21,5 @@ "გამავალი ზარები" "გამოტოვებული ზარები" "ხმოვანი ფოსტა" - "გარე ზარები" "ნაგულისხმევი" diff --git a/java/com/android/dialer/notification/res/values-kk/strings.xml b/java/com/android/dialer/notification/res/values-kk/strings.xml index 35733fb04..8151c9ca9 100644 --- a/java/com/android/dialer/notification/res/values-kk/strings.xml +++ b/java/com/android/dialer/notification/res/values-kk/strings.xml @@ -21,6 +21,5 @@ "Қазіргі қоңыраулар" "Қабылданбаған қоңыраулар" "Дауыстық хабарлар" - "Сыртқы қоңыраулар" "Әдепкі" diff --git a/java/com/android/dialer/notification/res/values-km/strings.xml b/java/com/android/dialer/notification/res/values-km/strings.xml index 42bc11350..22131ff39 100644 --- a/java/com/android/dialer/notification/res/values-km/strings.xml +++ b/java/com/android/dialer/notification/res/values-km/strings.xml @@ -21,6 +21,5 @@ "ការ​ហៅ​បន្ត" "ការ​ហៅ​ដែល​មិន​បាន​ទទួល" "សារ​ជា​សំឡេង" - "ការ​ហៅខាង​ក្រៅ" "លំ​នាំ​ដើម" diff --git a/java/com/android/dialer/notification/res/values-kn/strings.xml b/java/com/android/dialer/notification/res/values-kn/strings.xml index 45f26e378..d6e55bdb1 100644 --- a/java/com/android/dialer/notification/res/values-kn/strings.xml +++ b/java/com/android/dialer/notification/res/values-kn/strings.xml @@ -21,6 +21,5 @@ "ಚಾಲ್ತಿಯಲ್ಲಿರುವ ಕರೆಗಳು" "ಮಿಸ್ಡ್‌ ಕರೆಗಳು" "ಧ್ವನಿಮೇಲ್‌ಗಳು" - "ಹೊರಗಿನ ಕರೆಗಳು" "ಡಿಫಾಲ್ಟ್" diff --git a/java/com/android/dialer/notification/res/values-ko/strings.xml b/java/com/android/dialer/notification/res/values-ko/strings.xml index d806cad06..5a667176d 100644 --- a/java/com/android/dialer/notification/res/values-ko/strings.xml +++ b/java/com/android/dialer/notification/res/values-ko/strings.xml @@ -21,6 +21,5 @@ "진행 중인 전화" "부재중 전화" "음성사서함" - "외부 전화" "기본" diff --git a/java/com/android/dialer/notification/res/values-ky/strings.xml b/java/com/android/dialer/notification/res/values-ky/strings.xml index eb6adf6e7..c5259315a 100644 --- a/java/com/android/dialer/notification/res/values-ky/strings.xml +++ b/java/com/android/dialer/notification/res/values-ky/strings.xml @@ -21,6 +21,5 @@ "Учурдагы чалуулар" "Кабыл алынбаган чалуулар" "Үнкаттар" - "Тышкы чалуулар" "Демейки" diff --git a/java/com/android/dialer/notification/res/values-lo/strings.xml b/java/com/android/dialer/notification/res/values-lo/strings.xml index f439807de..a52d9df14 100644 --- a/java/com/android/dialer/notification/res/values-lo/strings.xml +++ b/java/com/android/dialer/notification/res/values-lo/strings.xml @@ -21,6 +21,5 @@ "ສາຍໂທອອກ" "ສາຍບໍ່ໄດ້ຮັບ" "ຂໍ້ຄວາມສຽງ" - "ສາຍພາຍນອກ" "ຄ່າເລີ່ມຕົ້ນ" diff --git a/java/com/android/dialer/notification/res/values-lt/strings.xml b/java/com/android/dialer/notification/res/values-lt/strings.xml index f08697ad6..6f26d3e66 100644 --- a/java/com/android/dialer/notification/res/values-lt/strings.xml +++ b/java/com/android/dialer/notification/res/values-lt/strings.xml @@ -21,6 +21,5 @@ "Vykstantys skambučiai" "Praleisti skambučiai" "Balso pašto pranešimai" - "Išoriniai skambučiai" "Numatytasis" diff --git a/java/com/android/dialer/notification/res/values-lv/strings.xml b/java/com/android/dialer/notification/res/values-lv/strings.xml index d465b682d..1819d810a 100644 --- a/java/com/android/dialer/notification/res/values-lv/strings.xml +++ b/java/com/android/dialer/notification/res/values-lv/strings.xml @@ -21,6 +21,5 @@ "Aktīvie zvani" "Neatbildētie zvani" "Balss pasta ziņojumi" - "Ārējie zvani" "Noklusējums" diff --git a/java/com/android/dialer/notification/res/values-mk/strings.xml b/java/com/android/dialer/notification/res/values-mk/strings.xml index 838065ba9..56459c479 100644 --- a/java/com/android/dialer/notification/res/values-mk/strings.xml +++ b/java/com/android/dialer/notification/res/values-mk/strings.xml @@ -21,6 +21,5 @@ "Појдовни повици" "Пропуштени повици" "Говорни пораки" - "Надворешни повици" "Стандардно" diff --git a/java/com/android/dialer/notification/res/values-ml/strings.xml b/java/com/android/dialer/notification/res/values-ml/strings.xml index 448186a36..49a64e8f5 100644 --- a/java/com/android/dialer/notification/res/values-ml/strings.xml +++ b/java/com/android/dialer/notification/res/values-ml/strings.xml @@ -21,6 +21,5 @@ "നിലവിലുള്ള കോളുകൾ" "മിസ്‌ഡ് കോളുകൾ" "വോയ്‌സ്മെയിലുകൾ" - "എക്‌സ്റ്റേണൽ കോളുകൾ" "ഡിഫോൾട്ട്" diff --git a/java/com/android/dialer/notification/res/values-mn/strings.xml b/java/com/android/dialer/notification/res/values-mn/strings.xml index 3dca52e6b..28297b3c1 100644 --- a/java/com/android/dialer/notification/res/values-mn/strings.xml +++ b/java/com/android/dialer/notification/res/values-mn/strings.xml @@ -21,6 +21,5 @@ "Үргэлжилж буй дуудлага" "Аваагүй дуудлага" "Дуут шуудан" - "Гадаад дуудлага" "Өгөгдмөл" diff --git a/java/com/android/dialer/notification/res/values-mr/strings.xml b/java/com/android/dialer/notification/res/values-mr/strings.xml index 568537640..38fbd606a 100644 --- a/java/com/android/dialer/notification/res/values-mr/strings.xml +++ b/java/com/android/dialer/notification/res/values-mr/strings.xml @@ -21,6 +21,5 @@ "सुरू असलेले कॉल" "सुटलेले कॉल" "व्हॉइसमेल" - "बाह्य कॉल" "डीफॉल्ट" diff --git a/java/com/android/dialer/notification/res/values-ms/strings.xml b/java/com/android/dialer/notification/res/values-ms/strings.xml index a1961c4a4..ec7be04ef 100644 --- a/java/com/android/dialer/notification/res/values-ms/strings.xml +++ b/java/com/android/dialer/notification/res/values-ms/strings.xml @@ -21,6 +21,5 @@ "Panggilan sedang berlangsung" "Panggilan terlepas" "Mel suara" - "Panggilan luar" "Lalai" diff --git a/java/com/android/dialer/notification/res/values-my/strings.xml b/java/com/android/dialer/notification/res/values-my/strings.xml index 26398b459..44df84798 100644 --- a/java/com/android/dialer/notification/res/values-my/strings.xml +++ b/java/com/android/dialer/notification/res/values-my/strings.xml @@ -21,6 +21,5 @@ "လက်ရှိခေါ်ဆိုမှုများ" "လွဲသွားသော ခေါ်ဆိုမှုများ" "အသံစာပို့စနစ်များ" - "ပြင်ပခေါ်ဆိုမှုများ" "မူရင်း" diff --git a/java/com/android/dialer/notification/res/values-nb/strings.xml b/java/com/android/dialer/notification/res/values-nb/strings.xml index e4ccd48a0..8e63fd24b 100644 --- a/java/com/android/dialer/notification/res/values-nb/strings.xml +++ b/java/com/android/dialer/notification/res/values-nb/strings.xml @@ -21,6 +21,5 @@ "Pågående samtaler" "Tapte anrop" "Talepost" - "Eksterne anrop" "Standard" diff --git a/java/com/android/dialer/notification/res/values-ne/strings.xml b/java/com/android/dialer/notification/res/values-ne/strings.xml index 8ccd2997a..e653bb3f8 100644 --- a/java/com/android/dialer/notification/res/values-ne/strings.xml +++ b/java/com/android/dialer/notification/res/values-ne/strings.xml @@ -21,6 +21,5 @@ "जारी रहेका कलहरू" "छुटेका कलहरू" "भ्वाइस मेलहरू" - "बाह्य कलहरू" "पूर्वनिर्धारित मान" diff --git a/java/com/android/dialer/notification/res/values-nl/strings.xml b/java/com/android/dialer/notification/res/values-nl/strings.xml index e46dd19e3..094cc357f 100644 --- a/java/com/android/dialer/notification/res/values-nl/strings.xml +++ b/java/com/android/dialer/notification/res/values-nl/strings.xml @@ -21,6 +21,5 @@ "Actieve oproepen" "Gemiste oproepen" "Voicemails" - "Externe oproepen" "Standaard" diff --git a/java/com/android/dialer/notification/res/values-no/strings.xml b/java/com/android/dialer/notification/res/values-no/strings.xml index e4ccd48a0..8e63fd24b 100644 --- a/java/com/android/dialer/notification/res/values-no/strings.xml +++ b/java/com/android/dialer/notification/res/values-no/strings.xml @@ -21,6 +21,5 @@ "Pågående samtaler" "Tapte anrop" "Talepost" - "Eksterne anrop" "Standard" diff --git a/java/com/android/dialer/notification/res/values-pa/strings.xml b/java/com/android/dialer/notification/res/values-pa/strings.xml index 40709c1ac..c4ee97b22 100644 --- a/java/com/android/dialer/notification/res/values-pa/strings.xml +++ b/java/com/android/dialer/notification/res/values-pa/strings.xml @@ -21,6 +21,5 @@ "ਆਊਟਗੋਇੰਗ ਕਾਲਾਂ" "ਖੁੰਝੀਆਂ ਕਾਲਾਂ" "ਵੌਇਸਮੇਲਾਂ" - "ਬਾਹਰੀ ਕਾਲਾਂ" "ਪੂਰਵ-ਨਿਰਧਾਰਤ" diff --git a/java/com/android/dialer/notification/res/values-pl/strings.xml b/java/com/android/dialer/notification/res/values-pl/strings.xml index 73b795cff..4b3346001 100644 --- a/java/com/android/dialer/notification/res/values-pl/strings.xml +++ b/java/com/android/dialer/notification/res/values-pl/strings.xml @@ -21,6 +21,5 @@ "Połączenia trwające" "Połączenia nieodebrane" "Wiadomości głosowe" - "Połączenia zewnętrzne" "Domyślny" diff --git a/java/com/android/dialer/notification/res/values-pt-rBR/strings.xml b/java/com/android/dialer/notification/res/values-pt-rBR/strings.xml index f6e41cb11..4b988c3cc 100644 --- a/java/com/android/dialer/notification/res/values-pt-rBR/strings.xml +++ b/java/com/android/dialer/notification/res/values-pt-rBR/strings.xml @@ -21,6 +21,5 @@ "Chamadas em andamento" "Chamadas perdidas" "Correios de voz" - "Chamadas externas" "Padrão" diff --git a/java/com/android/dialer/notification/res/values-pt-rPT/strings.xml b/java/com/android/dialer/notification/res/values-pt-rPT/strings.xml index ec42a5bf5..45b31ebd0 100644 --- a/java/com/android/dialer/notification/res/values-pt-rPT/strings.xml +++ b/java/com/android/dialer/notification/res/values-pt-rPT/strings.xml @@ -21,6 +21,5 @@ "Chamadas efetuadas" "Chamadas não atendidas" "Mensagens de correio de voz" - "Chamadas externas" "Predefinição" diff --git a/java/com/android/dialer/notification/res/values-pt/strings.xml b/java/com/android/dialer/notification/res/values-pt/strings.xml index f6e41cb11..4b988c3cc 100644 --- a/java/com/android/dialer/notification/res/values-pt/strings.xml +++ b/java/com/android/dialer/notification/res/values-pt/strings.xml @@ -21,6 +21,5 @@ "Chamadas em andamento" "Chamadas perdidas" "Correios de voz" - "Chamadas externas" "Padrão" diff --git a/java/com/android/dialer/notification/res/values-ro/strings.xml b/java/com/android/dialer/notification/res/values-ro/strings.xml index 7deeabba3..040c58ad2 100644 --- a/java/com/android/dialer/notification/res/values-ro/strings.xml +++ b/java/com/android/dialer/notification/res/values-ro/strings.xml @@ -21,6 +21,5 @@ "Apeluri în desfășurare" "Apeluri nepreluate" "Mesaje vocale" - "Apeluri externe" "Prestabilit" diff --git a/java/com/android/dialer/notification/res/values-ru/strings.xml b/java/com/android/dialer/notification/res/values-ru/strings.xml index 3a1140455..a8117990a 100644 --- a/java/com/android/dialer/notification/res/values-ru/strings.xml +++ b/java/com/android/dialer/notification/res/values-ru/strings.xml @@ -21,6 +21,5 @@ "Текущие вызовы" "Пропущенные вызовы" "Голосовые сообщения" - "Внешние вызовы" "По умолчанию" diff --git a/java/com/android/dialer/notification/res/values-si/strings.xml b/java/com/android/dialer/notification/res/values-si/strings.xml index bf0a5a798..3ad0af729 100644 --- a/java/com/android/dialer/notification/res/values-si/strings.xml +++ b/java/com/android/dialer/notification/res/values-si/strings.xml @@ -21,6 +21,5 @@ "යන ඇමතුම්" "මඟ හැරුණු ඇමතුම්" "හඬ තැපැල්" - "බාහිර ඇමතුම්" "පෙරනිමි" diff --git a/java/com/android/dialer/notification/res/values-sk/strings.xml b/java/com/android/dialer/notification/res/values-sk/strings.xml index 4a67e60d2..30941bcd5 100644 --- a/java/com/android/dialer/notification/res/values-sk/strings.xml +++ b/java/com/android/dialer/notification/res/values-sk/strings.xml @@ -21,6 +21,5 @@ "Prebiehajúce hovory" "Zmeškané hovory" "Hlasové správy" - "Externé hovory" "Predvolené" diff --git a/java/com/android/dialer/notification/res/values-sl/strings.xml b/java/com/android/dialer/notification/res/values-sl/strings.xml index e54111d12..70474b87b 100644 --- a/java/com/android/dialer/notification/res/values-sl/strings.xml +++ b/java/com/android/dialer/notification/res/values-sl/strings.xml @@ -21,6 +21,5 @@ "Aktivni klici" "Neodgovorjeni klici" "Sporočila v odzivniku" - "Zunanji klici" "Privzeto" diff --git a/java/com/android/dialer/notification/res/values-sq/strings.xml b/java/com/android/dialer/notification/res/values-sq/strings.xml index 42d4daac3..03bc24775 100644 --- a/java/com/android/dialer/notification/res/values-sq/strings.xml +++ b/java/com/android/dialer/notification/res/values-sq/strings.xml @@ -21,6 +21,5 @@ "Telefonatat në vazhdim" "Telefonatat e humbura" "Postat zanore" - "Telefonatat e jashtme" "I parazgjedhur" diff --git a/java/com/android/dialer/notification/res/values-sr/strings.xml b/java/com/android/dialer/notification/res/values-sr/strings.xml index 10477170f..8326c0403 100644 --- a/java/com/android/dialer/notification/res/values-sr/strings.xml +++ b/java/com/android/dialer/notification/res/values-sr/strings.xml @@ -21,6 +21,5 @@ "Позиви у току" "Пропуштени позиви" "Говорне поруке" - "Спољни позиви" "Подразумевано" diff --git a/java/com/android/dialer/notification/res/values-sv/strings.xml b/java/com/android/dialer/notification/res/values-sv/strings.xml index 6c9ff83b7..e3170d48f 100644 --- a/java/com/android/dialer/notification/res/values-sv/strings.xml +++ b/java/com/android/dialer/notification/res/values-sv/strings.xml @@ -21,6 +21,5 @@ "Pågående samtal" "Missade samtal" "Röstmeddelanden" - "Externa samtal" "Standard" diff --git a/java/com/android/dialer/notification/res/values-sw/strings.xml b/java/com/android/dialer/notification/res/values-sw/strings.xml index a493f8897..d0a65b08c 100644 --- a/java/com/android/dialer/notification/res/values-sw/strings.xml +++ b/java/com/android/dialer/notification/res/values-sw/strings.xml @@ -21,6 +21,5 @@ "Simu zinazoendelea" "Simu ambazo hukujibu" "Ujumbe wa sauti" - "Simu za nje" "Chaguo-msingi" diff --git a/java/com/android/dialer/notification/res/values-ta/strings.xml b/java/com/android/dialer/notification/res/values-ta/strings.xml index d3000cf90..8a6ae89a8 100644 --- a/java/com/android/dialer/notification/res/values-ta/strings.xml +++ b/java/com/android/dialer/notification/res/values-ta/strings.xml @@ -21,6 +21,5 @@ "செயலில் உள்ள அழைப்புகள்" "தவறிய அழைப்புகள்" "குரலஞ்சல்கள்" - "வெளி அழைப்புகள்" "இயல்பு" diff --git a/java/com/android/dialer/notification/res/values-te/strings.xml b/java/com/android/dialer/notification/res/values-te/strings.xml index b14b21071..b1911d34d 100644 --- a/java/com/android/dialer/notification/res/values-te/strings.xml +++ b/java/com/android/dialer/notification/res/values-te/strings.xml @@ -21,6 +21,5 @@ "కొనసాగుతున్న కాల్‌లు" "సమాధానమివ్వని కాల్‌లు" "వాయిస్ మెయిల్‌లు" - "బాహ్య కాల్‌లు" "డిఫాల్ట్" diff --git a/java/com/android/dialer/notification/res/values-th/strings.xml b/java/com/android/dialer/notification/res/values-th/strings.xml index 45248bbbe..b2949e42f 100644 --- a/java/com/android/dialer/notification/res/values-th/strings.xml +++ b/java/com/android/dialer/notification/res/values-th/strings.xml @@ -21,6 +21,5 @@ "สายที่สนทนาอยู่" "สายที่ไม่ได้รับ" "ข้อความเสียง" - "สายนอก" "ค่าเริ่มต้น" diff --git a/java/com/android/dialer/notification/res/values-tl/strings.xml b/java/com/android/dialer/notification/res/values-tl/strings.xml index 3e88a055f..1219ad86f 100644 --- a/java/com/android/dialer/notification/res/values-tl/strings.xml +++ b/java/com/android/dialer/notification/res/values-tl/strings.xml @@ -21,6 +21,5 @@ "Mga kasalukuyang tawag" "Mga hindi nasagot na tawag" "Mga voicemail" - "Mga external na tawag" "Default" diff --git a/java/com/android/dialer/notification/res/values-tr/strings.xml b/java/com/android/dialer/notification/res/values-tr/strings.xml index d4e063bc2..71c91c806 100644 --- a/java/com/android/dialer/notification/res/values-tr/strings.xml +++ b/java/com/android/dialer/notification/res/values-tr/strings.xml @@ -21,6 +21,5 @@ "Devam eden çağrılar" "Cevapsız çağrılar" "Sesli mesajlar" - "Harici çağrılar" "Varsayılan" diff --git a/java/com/android/dialer/notification/res/values-uk/strings.xml b/java/com/android/dialer/notification/res/values-uk/strings.xml index a83a58460..a002f42e1 100644 --- a/java/com/android/dialer/notification/res/values-uk/strings.xml +++ b/java/com/android/dialer/notification/res/values-uk/strings.xml @@ -21,6 +21,5 @@ "Поточні виклики" "Пропущені виклики" "Голосова пошта" - "Зовнішні виклики" "За умовчанням" diff --git a/java/com/android/dialer/notification/res/values-ur/strings.xml b/java/com/android/dialer/notification/res/values-ur/strings.xml index ba6e0d1da..805fe08f8 100644 --- a/java/com/android/dialer/notification/res/values-ur/strings.xml +++ b/java/com/android/dialer/notification/res/values-ur/strings.xml @@ -21,6 +21,5 @@ "جاری کالیں" "چھوٹی ہوئی کالیں" "صوتی میلز" - "بیرونی کالیں" "ڈیفالٹ" diff --git a/java/com/android/dialer/notification/res/values-uz/strings.xml b/java/com/android/dialer/notification/res/values-uz/strings.xml index d45ff47d2..16075b031 100644 --- a/java/com/android/dialer/notification/res/values-uz/strings.xml +++ b/java/com/android/dialer/notification/res/values-uz/strings.xml @@ -21,6 +21,5 @@ "Davom etayotgan suhbatlar" "Javobsiz chaqiruvlar" "Ovozli xabarlar" - "Tashqi chaqiruvlar" "Standart" diff --git a/java/com/android/dialer/notification/res/values-vi/strings.xml b/java/com/android/dialer/notification/res/values-vi/strings.xml index 6df88721e..b6ab3d2d8 100644 --- a/java/com/android/dialer/notification/res/values-vi/strings.xml +++ b/java/com/android/dialer/notification/res/values-vi/strings.xml @@ -21,6 +21,5 @@ "Cuộc gọi đến" "Cuộc gọi nhỡ" "Thư thoại" - "Cuộc gọi bên ngoài" "Mặc định" diff --git a/java/com/android/dialer/notification/res/values-zh-rCN/strings.xml b/java/com/android/dialer/notification/res/values-zh-rCN/strings.xml index fa5f0a657..1ef46c2b9 100644 --- a/java/com/android/dialer/notification/res/values-zh-rCN/strings.xml +++ b/java/com/android/dialer/notification/res/values-zh-rCN/strings.xml @@ -21,6 +21,5 @@ "正在进行的通话" "未接电话" "语音邮件" - "外部来电" "默认" diff --git a/java/com/android/dialer/notification/res/values-zh-rHK/strings.xml b/java/com/android/dialer/notification/res/values-zh-rHK/strings.xml index 307a7f9bf..43a6fabf6 100644 --- a/java/com/android/dialer/notification/res/values-zh-rHK/strings.xml +++ b/java/com/android/dialer/notification/res/values-zh-rHK/strings.xml @@ -21,6 +21,5 @@ "進行中的通話" "未接來電" "留言信箱" - "外部通話" "預設" diff --git a/java/com/android/dialer/notification/res/values-zh-rTW/strings.xml b/java/com/android/dialer/notification/res/values-zh-rTW/strings.xml index 054a2d737..35236be1d 100644 --- a/java/com/android/dialer/notification/res/values-zh-rTW/strings.xml +++ b/java/com/android/dialer/notification/res/values-zh-rTW/strings.xml @@ -21,6 +21,5 @@ "進行中的通話" "未接來電" "語音留言" - "外部通話" "預設" diff --git a/java/com/android/dialer/notification/res/values-zu/strings.xml b/java/com/android/dialer/notification/res/values-zu/strings.xml index 744ffc816..f3d95531f 100644 --- a/java/com/android/dialer/notification/res/values-zu/strings.xml +++ b/java/com/android/dialer/notification/res/values-zu/strings.xml @@ -21,6 +21,5 @@ "Amakholi aqhubekayo" "Amakholi akuphuthile" "Amavoyisimeyili" - "Amakholi angaphandle" "Okuzenzakalelayo" diff --git a/java/com/android/dialer/notification/res/values/ids.xml b/java/com/android/dialer/notification/res/values/ids.xml deleted file mode 100644 index c965f319d..000000000 --- a/java/com/android/dialer/notification/res/values/ids.xml +++ /dev/null @@ -1,27 +0,0 @@ - - - - - - - - - - - - - diff --git a/java/com/android/dialer/notification/res/values/strings.xml b/java/com/android/dialer/notification/res/values/strings.xml index cb3119f67..a3c6935aa 100644 --- a/java/com/android/dialer/notification/res/values/strings.xml +++ b/java/com/android/dialer/notification/res/values/strings.xml @@ -20,7 +20,6 @@ Ongoing calls Missed calls Voicemails - External calls Default diff --git a/java/com/android/dialer/oem/CequintCallerIdManager.java b/java/com/android/dialer/oem/CequintCallerIdManager.java index 806d553eb..86097c41a 100644 --- a/java/com/android/dialer/oem/CequintCallerIdManager.java +++ b/java/com/android/dialer/oem/CequintCallerIdManager.java @@ -28,8 +28,8 @@ import android.support.annotation.WorkerThread; import android.telephony.PhoneNumberUtils; import android.text.TextUtils; import com.android.dialer.common.Assert; -import com.android.dialer.common.ConfigProviderBindings; import com.android.dialer.common.LogUtil; +import com.android.dialer.configprovider.ConfigProviderBindings; import java.util.concurrent.ConcurrentHashMap; /** diff --git a/java/com/android/dialer/oem/MotorolaUtils.java b/java/com/android/dialer/oem/MotorolaUtils.java index 2c91e60ab..ffab8ea23 100644 --- a/java/com/android/dialer/oem/MotorolaUtils.java +++ b/java/com/android/dialer/oem/MotorolaUtils.java @@ -18,9 +18,9 @@ package com.android.dialer.oem; import android.content.Context; import android.content.res.Resources; import android.telephony.TelephonyManager; -import com.android.dialer.common.ConfigProviderBindings; import com.android.dialer.common.LogUtil; import com.android.dialer.common.PackageUtils; +import com.android.dialer.configprovider.ConfigProviderBindings; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; diff --git a/java/com/android/dialer/p13n/inference/P13nRanking.java b/java/com/android/dialer/p13n/inference/P13nRanking.java index 0682e85db..79b4d7136 100644 --- a/java/com/android/dialer/p13n/inference/P13nRanking.java +++ b/java/com/android/dialer/p13n/inference/P13nRanking.java @@ -22,7 +22,7 @@ import android.support.annotation.MainThread; import android.support.annotation.NonNull; import android.support.annotation.Nullable; import com.android.dialer.common.Assert; -import com.android.dialer.common.ConfigProviderBindings; +import com.android.dialer.configprovider.ConfigProviderBindings; import com.android.dialer.p13n.inference.protocol.P13nRanker; import com.android.dialer.p13n.inference.protocol.P13nRankerFactory; import java.util.List; diff --git a/java/com/android/dialer/performancereport/PerformanceReport.java b/java/com/android/dialer/performancereport/PerformanceReport.java new file mode 100644 index 000000000..27fd7485b --- /dev/null +++ b/java/com/android/dialer/performancereport/PerformanceReport.java @@ -0,0 +1,155 @@ +/* + * Copyright (C) 2017 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.dialer.performancereport; + +import android.os.SystemClock; +import android.support.annotation.Nullable; +import android.support.v7.widget.RecyclerView; +import android.widget.AbsListView; +import com.android.dialer.common.LogUtil; +import com.android.dialer.logging.UiAction; +import java.util.ArrayList; +import java.util.List; +import java.util.concurrent.TimeUnit; + +/** Tracks UI performance for a call. */ +public final class PerformanceReport { + + private static final long INVALID_TIME = -1; + private static final long ACTIVE_DURATION = TimeUnit.MINUTES.toMillis(5); + + private static final List actions = new ArrayList<>(); + private static final List actionTimestamps = new ArrayList<>(); + + private static final RecyclerView.OnScrollListener recordOnScrollListener = + new RecyclerView.OnScrollListener() { + @Override + public void onScrollStateChanged(RecyclerView recyclerView, int newState) { + if (newState == RecyclerView.SCROLL_STATE_SETTLING) { + PerformanceReport.recordClick(UiAction.Type.SCROLL); + } + super.onScrollStateChanged(recyclerView, newState); + } + }; + + private static boolean recording = false; + private static long appLaunchTimeMillis = INVALID_TIME; + private static long firstClickTimeMillis = INVALID_TIME; + private static long lastActionTimeMillis = INVALID_TIME; + + @Nullable private static UiAction.Type ignoreActionOnce = null; + + private PerformanceReport() {} + + public static void startRecording() { + LogUtil.enterBlock("PerformanceReport.startRecording"); + + appLaunchTimeMillis = SystemClock.elapsedRealtime(); + lastActionTimeMillis = appLaunchTimeMillis; + if (!actions.isEmpty()) { + actions.clear(); + actionTimestamps.clear(); + } + recording = true; + } + + public static void stopRecording() { + LogUtil.enterBlock("PerformanceReport.stopRecording"); + recording = false; + } + + public static void recordClick(UiAction.Type action) { + if (!recording) { + return; + } + + if (action == ignoreActionOnce) { + LogUtil.i("PerformanceReport.recordClick", "%s is ignored", action.toString()); + ignoreActionOnce = null; + return; + } + ignoreActionOnce = null; + + LogUtil.v("PerformanceReport.recordClick", action.toString()); + + // Timeout + long currentTime = SystemClock.elapsedRealtime(); + if (currentTime - lastActionTimeMillis > ACTIVE_DURATION) { + startRecording(); + recordClick(action); + return; + } + + lastActionTimeMillis = currentTime; + if (actions.isEmpty()) { + firstClickTimeMillis = currentTime; + } + actions.add(action); + actionTimestamps.add(currentTime - appLaunchTimeMillis); + } + + public static void recordScrollStateChange(int scrollState) { + if (scrollState == AbsListView.OnScrollListener.SCROLL_STATE_TOUCH_SCROLL) { + recordClick(UiAction.Type.SCROLL); + } + } + + public static void logOnScrollStateChange(RecyclerView recyclerView) { + // Remove the listener in case it was added before + recyclerView.removeOnScrollListener(recordOnScrollListener); + recyclerView.addOnScrollListener(recordOnScrollListener); + } + + public static boolean isRecording() { + return recording; + } + + public static long getTimeSinceAppLaunch() { + if (appLaunchTimeMillis == INVALID_TIME) { + return INVALID_TIME; + } + return SystemClock.elapsedRealtime() - appLaunchTimeMillis; + } + + public static long getTimeSinceFirstClick() { + if (firstClickTimeMillis == INVALID_TIME) { + return INVALID_TIME; + } + return SystemClock.elapsedRealtime() - firstClickTimeMillis; + } + + public static List getActions() { + return actions; + } + + public static List getActionTimestamps() { + return actionTimestamps; + } + + @Nullable + public static UiAction.Type getIgnoreActionOnce() { + return ignoreActionOnce; + } + + public static void setIgnoreActionOnce(@Nullable UiAction.Type ignoreActionOnce) { + PerformanceReport.ignoreActionOnce = ignoreActionOnce; + LogUtil.i( + "PerformanceReport.setIgnoreActionOnce", + "next action will be ignored once if it is %s", + ignoreActionOnce.toString()); + } +} diff --git a/java/com/android/dialer/phonenumbercache/CachedNumberLookupService.java b/java/com/android/dialer/phonenumbercache/CachedNumberLookupService.java index 2aed9e75e..c398251e4 100644 --- a/java/com/android/dialer/phonenumbercache/CachedNumberLookupService.java +++ b/java/com/android/dialer/phonenumbercache/CachedNumberLookupService.java @@ -49,6 +49,8 @@ public interface CachedNumberLookupService { boolean canReportAsInvalid(ContactSource.Type sourceType, String objectId); + boolean reportAsInvalid(Context context, CachedContactInfo cachedContactInfo); + /** @return return {@link Uri} to the photo or return {@code null} when failing to add photo */ @Nullable Uri addPhoto(Context context, String number, InputStream in); diff --git a/java/com/android/dialer/phonenumbercache/ContactInfoHelper.java b/java/com/android/dialer/phonenumbercache/ContactInfoHelper.java index c9e940ef4..4fa3147eb 100644 --- a/java/com/android/dialer/phonenumbercache/ContactInfoHelper.java +++ b/java/com/android/dialer/phonenumbercache/ContactInfoHelper.java @@ -203,6 +203,7 @@ public class ContactInfoHelper { return info; } + @Nullable public ContactInfo lookupNumber(String number, String countryIso) { return lookupNumber(number, countryIso, -1); } @@ -223,12 +224,14 @@ public class ContactInfoHelper { @SuppressWarnings("ReferenceEquality") public ContactInfo lookupNumber(String number, String countryIso, long directoryId) { if (TextUtils.isEmpty(number)) { + LogUtil.d("ContactInfoHelper.lookupNumber", "number is empty"); return null; } ContactInfo info; if (PhoneNumberHelper.isUriNumber(number)) { + LogUtil.d("ContactInfoHelper.lookupNumber", "number is sip"); // The number is a SIP address.. info = lookupContactFromUri(getContactInfoLookupUri(number, directoryId)); if (info == null || info == ContactInfo.EMPTY) { @@ -246,6 +249,7 @@ public class ContactInfoHelper { final ContactInfo updatedInfo; if (info == null) { // The lookup failed. + LogUtil.d("ContactInfoHelper.lookupNumber", "lookup failed"); updatedInfo = null; } else { // If we did not find a matching contact, generate an empty contact info for the number. @@ -325,9 +329,11 @@ public class ContactInfoHelper { */ ContactInfo lookupContactFromUri(Uri uri) { if (uri == null) { + LogUtil.d("ContactInfoHelper.lookupContactFromUri", "uri is null"); return null; } if (!PermissionsUtil.hasContactsReadPermissions(mContext)) { + LogUtil.d("ContactInfoHelper.lookupContactFromUri", "no contact permission, return empty"); return ContactInfo.EMPTY; } @@ -336,10 +342,12 @@ public class ContactInfoHelper { String[] projection = PhoneQuery.getPhoneLookupProjection(uri); phoneLookupCursor = mContext.getContentResolver().query(uri, projection, null, null, null); } catch (NullPointerException e) { + LogUtil.e("ContactInfoHelper.lookupContactFromUri", "phone lookup", e); // Trap NPE from pre-N CP2 return null; } if (phoneLookupCursor == null) { + LogUtil.d("ContactInfoHelper.lookupContactFromUri", "phoneLookupCursor is null"); return null; } @@ -408,19 +416,32 @@ public class ContactInfoHelper { private ContactInfo queryContactInfoForPhoneNumber( String number, String countryIso, long directoryId) { if (TextUtils.isEmpty(number)) { + LogUtil.d("ContactInfoHelper.queryContactInfoForPhoneNumber", "number is empty"); return null; } ContactInfo info = lookupContactFromUri(getContactInfoLookupUri(number, directoryId)); + if (info == null) { + LogUtil.d("ContactInfoHelper.queryContactInfoForPhoneNumber", "info looked up is null"); + } if (info != null && info != ContactInfo.EMPTY) { info.formattedNumber = formatPhoneNumber(number, null, countryIso); + if (directoryId == -1) { + // Contact found in the default directory + info.sourceType = ContactSource.Type.SOURCE_TYPE_DIRECTORY; + } else { + // Contact found in the extended directory specified by directoryId + info.sourceType = ContactSource.Type.SOURCE_TYPE_EXTENDED; + } } else if (mCachedNumberLookupService != null) { CachedContactInfo cacheInfo = mCachedNumberLookupService.lookupCachedContactFromNumber(mContext, number); if (cacheInfo != null) { - info = cacheInfo.getContactInfo().isBadData ? null : cacheInfo.getContactInfo(); - } else { - info = null; + if (!cacheInfo.getContactInfo().isBadData) { + info = cacheInfo.getContactInfo(); + } else { + LogUtil.i("ContactInfoHelper.queryContactInfoForPhoneNumber", "info is bad data"); + } } } return info; diff --git a/java/com/android/dialer/phonenumberproto/Converter.java b/java/com/android/dialer/phonenumberproto/Converter.java new file mode 100644 index 000000000..453b98844 --- /dev/null +++ b/java/com/android/dialer/phonenumberproto/Converter.java @@ -0,0 +1,120 @@ +/* + * Copyright (C) 2017 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.dialer.phonenumberproto; + +import com.android.dialer.DialerInternalPhoneNumber; +import com.google.i18n.phonenumbers.Phonenumber.PhoneNumber; + +/** + * Methods for converting from {@link PhoneNumber} POJOs to {@link DialerInternalPhoneNumber} protos + * and back. + */ +class Converter { + + static DialerInternalPhoneNumber pojoToProto(PhoneNumber pojo) { + DialerInternalPhoneNumber.Builder proto = DialerInternalPhoneNumber.newBuilder(); + if (pojo.hasCountryCode()) { + proto.setCountryCode(pojo.getCountryCode()); + } + if (pojo.hasCountryCodeSource()) { + switch (pojo.getCountryCodeSource()) { + case FROM_NUMBER_WITH_PLUS_SIGN: + proto.setCountryCodeSource( + DialerInternalPhoneNumber.CountryCodeSource.FROM_NUMBER_WITH_PLUS_SIGN); + break; + case FROM_NUMBER_WITH_IDD: + proto.setCountryCodeSource( + DialerInternalPhoneNumber.CountryCodeSource.FROM_NUMBER_WITH_IDD); + break; + case FROM_NUMBER_WITHOUT_PLUS_SIGN: + proto.setCountryCodeSource( + DialerInternalPhoneNumber.CountryCodeSource.FROM_NUMBER_WITHOUT_PLUS_SIGN); + break; + case FROM_DEFAULT_COUNTRY: + proto.setCountryCodeSource( + DialerInternalPhoneNumber.CountryCodeSource.FROM_DEFAULT_COUNTRY); + break; + default: + throw new IllegalArgumentException( + "unsupported country code source: " + pojo.getCountryCodeSource()); + } + } + if (pojo.hasExtension()) { + proto.setExtension(pojo.getExtension()); + } + if (pojo.hasItalianLeadingZero()) { + proto.setItalianLeadingZero(pojo.isItalianLeadingZero()); + } + if (pojo.hasNationalNumber()) { + proto.setNationalNumber(pojo.getNationalNumber()); + } + if (pojo.hasNumberOfLeadingZeros()) { + proto.setNumberOfLeadingZeros(pojo.getNumberOfLeadingZeros()); + } + if (pojo.hasPreferredDomesticCarrierCode()) { + proto.setPreferredDomesticCarrierCode(pojo.getPreferredDomesticCarrierCode()); + } + if (pojo.hasRawInput()) { + proto.setRawInput(pojo.getRawInput()); + } + return proto.build(); + } + + static PhoneNumber protoToPojo(DialerInternalPhoneNumber proto) { + PhoneNumber pojo = new PhoneNumber(); + if (proto.hasCountryCode()) { + pojo.setCountryCode(proto.getCountryCode()); + } + if (proto.hasCountryCodeSource()) { + switch (proto.getCountryCodeSource()) { + case FROM_NUMBER_WITH_PLUS_SIGN: + pojo.setCountryCodeSource(PhoneNumber.CountryCodeSource.FROM_NUMBER_WITH_PLUS_SIGN); + break; + case FROM_NUMBER_WITH_IDD: + pojo.setCountryCodeSource(PhoneNumber.CountryCodeSource.FROM_NUMBER_WITH_IDD); + break; + case FROM_NUMBER_WITHOUT_PLUS_SIGN: + pojo.setCountryCodeSource(PhoneNumber.CountryCodeSource.FROM_NUMBER_WITHOUT_PLUS_SIGN); + break; + case FROM_DEFAULT_COUNTRY: + pojo.setCountryCodeSource(PhoneNumber.CountryCodeSource.FROM_DEFAULT_COUNTRY); + break; + default: + throw new IllegalArgumentException( + "unsupported country code source: " + proto.getCountryCodeSource()); + } + } + if (proto.hasExtension()) { + pojo.setExtension(proto.getExtension()); + } + if (proto.hasItalianLeadingZero()) { + pojo.setItalianLeadingZero(proto.getItalianLeadingZero()); + } + if (proto.hasNationalNumber()) { + pojo.setNationalNumber(proto.getNationalNumber()); + } + if (proto.hasNumberOfLeadingZeros()) { + pojo.setNumberOfLeadingZeros(proto.getNumberOfLeadingZeros()); + } + if (proto.hasPreferredDomesticCarrierCode()) { + pojo.setPreferredDomesticCarrierCode(proto.getPreferredDomesticCarrierCode()); + } + if (proto.hasRawInput()) { + pojo.setRawInput(proto.getRawInput()); + } + return pojo; + } +} diff --git a/java/com/android/dialer/phonenumberproto/DialerPhoneNumberUtil.java b/java/com/android/dialer/phonenumberproto/DialerPhoneNumberUtil.java new file mode 100644 index 000000000..cc509f41b --- /dev/null +++ b/java/com/android/dialer/phonenumberproto/DialerPhoneNumberUtil.java @@ -0,0 +1,108 @@ +/* + * Copyright (C) 2017 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.dialer.phonenumberproto; + +import android.support.annotation.NonNull; +import android.support.annotation.Nullable; +import android.support.annotation.WorkerThread; +import com.android.dialer.DialerInternalPhoneNumber; +import com.android.dialer.DialerPhoneNumber; +import com.android.dialer.DialerPhoneNumber.RawInput; +import com.android.dialer.common.Assert; +import com.android.dialer.common.LogUtil; +import com.google.i18n.phonenumbers.NumberParseException; +import com.google.i18n.phonenumbers.PhoneNumberUtil; +import com.google.i18n.phonenumbers.PhoneNumberUtil.MatchType; + +/** + * Wrapper for selected methods in {@link PhoneNumberUtil} which uses the {@link DialerPhoneNumber} + * lite proto instead of the {@link com.google.i18n.phonenumbers.Phonenumber.PhoneNumber} POJO. + * + *

      All methods should be called on a worker thread. + */ +public class DialerPhoneNumberUtil { + private final PhoneNumberUtil phoneNumberUtil; + + @WorkerThread + public DialerPhoneNumberUtil(@NonNull PhoneNumberUtil phoneNumberUtil) { + Assert.isWorkerThread(); + this.phoneNumberUtil = Assert.isNotNull(phoneNumberUtil); + } + + /** + * Parses the provided raw phone number into a {@link DialerPhoneNumber}. + * + * @see PhoneNumberUtil#parse(String, String) + */ + @WorkerThread + public DialerPhoneNumber parse(@Nullable String numberToParse, @Nullable String defaultRegion) { + Assert.isWorkerThread(); + + DialerPhoneNumber.Builder dialerPhoneNumber = DialerPhoneNumber.newBuilder(); + RawInput.Builder rawInput = RawInput.newBuilder(); + // Numbers can be null or empty for incoming "unknown" calls. + if (numberToParse != null) { + rawInput.setNumber(numberToParse); + } + if (defaultRegion != null) { + rawInput.setCountryIso(defaultRegion); + } + dialerPhoneNumber.setRawInput(rawInput.build()); + + try { + dialerPhoneNumber.setDialerInternalPhoneNumber( + Converter.pojoToProto(phoneNumberUtil.parse(numberToParse, defaultRegion))); + } catch (NumberParseException e) { + LogUtil.w("DialerPhoneNumberUtil.parse", "couldn't parse phone number", e); + } + return dialerPhoneNumber.build(); + } + + /** + * Returns true if the two numbers were parseable by libphonenumber and are an {@link + * MatchType#EXACT_MATCH} or if they have the same raw input. + */ + @WorkerThread + public boolean isExactMatch( + @NonNull DialerPhoneNumber firstNumberIn, @NonNull DialerPhoneNumber secondNumberIn) { + Assert.isWorkerThread(); + if (!Assert.isNotNull(firstNumberIn).hasDialerInternalPhoneNumber() + || !Assert.isNotNull(secondNumberIn).hasDialerInternalPhoneNumber()) { + return firstNumberIn.getRawInput().equals(secondNumberIn.getRawInput()); + } + return isNumberMatch( + firstNumberIn.getDialerInternalPhoneNumber(), + secondNumberIn.getDialerInternalPhoneNumber()) + == MatchType.EXACT_MATCH; + } + + /** + * Compares the provided phone numbers. + * + * @see PhoneNumberUtil#isNumberMatch(com.google.i18n.phonenumbers.Phonenumber.PhoneNumber, + * com.google.i18n.phonenumbers.Phonenumber.PhoneNumber) + */ + @WorkerThread + private MatchType isNumberMatch( + @NonNull DialerInternalPhoneNumber firstNumberIn, + @NonNull DialerInternalPhoneNumber secondNumberIn) { + Assert.isWorkerThread(); + return phoneNumberUtil.isNumberMatch( + Converter.protoToPojo(Assert.isNotNull(firstNumberIn)), + Converter.protoToPojo(Assert.isNotNull(secondNumberIn))); + } +} diff --git a/java/com/android/dialer/phonenumberproto/dialer_phone_number.proto b/java/com/android/dialer/phonenumberproto/dialer_phone_number.proto new file mode 100644 index 000000000..a0f362631 --- /dev/null +++ b/java/com/android/dialer/phonenumberproto/dialer_phone_number.proto @@ -0,0 +1,172 @@ +// Copyright (C) 2017 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 + +syntax = "proto2"; + +option java_package = "com.android.dialer"; +option java_multiple_files = true; +option optimize_for = LITE_RUNTIME; + +package com.android.dialer; + +// A phone number for use in the dialer application. It consists of a +// DialerInternalPhoneNumber, which is a copy of libphonenumber's PhoneNumber +// proto, and the raw input used to create it. +message DialerPhoneNumber { + // libphonenumber representation of the phone number. May be empty if the raw + // input failed to parse, in which case raw_input should be used. + optional DialerInternalPhoneNumber dialer_internal_phone_number = 1; + + // The raw input which was used to create a DialerPhoneNumber. + message RawInput { + // The phone number as it was entered or received. + optional string number = 1; + // The ISO 3166-1 two letter country code of the country where the user made + // or received the call. + optional string country_iso = 2; + } + // Prefer to use dialer_internal_phone_number if present. + optional RawInput raw_input = 2; +} + +// This is a copy of libphonenumber proto file for use in the dialer codebase. +// We cannot depend on the real libphonenumber proto because it is not exposed +// in any open source library. As such, this file could fall out of sync with +// that proto over time. +// +// The only difference between this proto and the libphonenumber proto (as of +// when this file was created) is the package name and proto name. +// +// If the libphonenumber proto becomes accessible some day, it may be possible +// to remove this proto and use the real libphonenumber proto assuming this +// proto is kept wire-compatible with it. +message DialerInternalPhoneNumber { + // The country calling code for this number, as defined by the International + // Telecommunication Union (ITU). For example, this would be 1 for NANPA + // countries, and 33 for France. + required int32 country_code = 1; + + // The National (significant) Number, as defined in International + // Telecommunication Union (ITU) Recommendation E.164, without any leading + // zero. The leading-zero is stored separately if required, since this is an + // uint64 and hence cannot store such information. Do not use this field + // directly: if you want the national significant number, call the + // getNationalSignificantNumber method of PhoneNumberUtil. + // + // For countries which have the concept of an "area code" or "national + // destination code", this is included in the National (significant) Number. + // Although the ITU says the maximum length should be 15, we have found longer + // numbers in some countries e.g. Germany. + // Note that the National (significant) Number does not contain the National + // (trunk) prefix. Obviously, as a uint64, it will never contain any + // formatting (hyphens, spaces, parentheses), nor any alphanumeric spellings. + required uint64 national_number = 2 [jstype = JS_NUMBER]; + + // Extension is not standardized in ITU recommendations, except for being + // defined as a series of numbers with a maximum length of 40 digits. It is + // defined as a string here to accommodate for the possible use of a leading + // zero in the extension (organizations have complete freedom to do so, as + // there is no standard defined). Other than digits, some other dialling + // characters such as "," (indicating a wait) may be stored here. + optional string extension = 3; + + // In some countries, the national (significant) number starts with one or + // more "0"s without this being a national prefix or trunk code of some kind. + // For example, the leading zero in the national (significant) number of an + // Italian phone number indicates the number is a fixed-line number. There + // have been plans to migrate fixed-line numbers to start with the digit two + // since December 2000, but it has not happened yet. See + // http://en.wikipedia.org/wiki/%2B39 for more details. + // + // These fields can be safely ignored (there is no need to set them) for most + // countries. Some limited number of countries behave like Italy - for these + // cases, if the leading zero(s) of a number would be retained even when + // dialling internationally, set this flag to true, and also set the number of + // leading zeros. + // + // Clients who use the parsing or conversion functionality of the i18n phone + // number libraries (go/phonenumbers) will have these fields set if necessary + // automatically. + optional bool italian_leading_zero = 4; + optional int32 number_of_leading_zeros = 8 [default = 1]; + + // The next few fields are non-essential fields for a phone number. They + // retain extra information about the form the phone number was in when it was + // provided to us to parse. They can be safely ignored by most clients. To + // populate them, call parseAndKeepRawInput on PhoneNumberUtil. + + // This field is used to store the raw input string containing phone numbers + // before it was canonicalized by the library. For example, it could be used + // to store alphanumerical numbers such as "1-800-GOOG-411". + optional string raw_input = 5; + + // The source from which the country_code is derived. This is not set in the + // general parsing method, but in the method that parses and keeps raw_input. + // New fields could be added upon request. + enum CountryCodeSource { + // The country_code is derived based on a phone number with a leading "+", + // e.g. the French number "+33 1 42 68 53 00". + FROM_NUMBER_WITH_PLUS_SIGN = 1; + + // The country_code is derived based on a phone number with a leading IDD, + // e.g. the French number "011 33 1 42 68 53 00", as it is dialled from US. + FROM_NUMBER_WITH_IDD = 5; + + // The country_code is derived based on a phone number without a leading + // "+", e.g. the French number "33 1 42 68 53 00" when defaultCountry is + // supplied as France. + FROM_NUMBER_WITHOUT_PLUS_SIGN = 10; + + // The country_code is derived NOT based on the phone number itself, but + // from the defaultCountry parameter provided in the parsing function by the + // clients. This happens mostly for numbers written in the national format + // (without country code). For example, this would be set when parsing the + // French number "01 42 68 53 00", when defaultCountry is supplied as + // France. + FROM_DEFAULT_COUNTRY = 20; + } + + // The source from which the country_code is derived. + optional CountryCodeSource country_code_source = 6; + + // The carrier selection code that is preferred when calling this phone number + // domestically. This also includes codes that need to be dialed in some + // countries when calling from landlines to mobiles or vice versa. For + // example, in Columbia, a "3" needs to be dialed before the phone number + // itself when calling from a mobile phone to a domestic landline phone and + // vice versa. + // + // Note this is the "preferred" code, which means other codes may work as + // well. + optional string preferred_domestic_carrier_code = 7; +} + +// Examples: +// +// Google MTV, +1 650-253-0000, (650) 253-0000 +// country_code: 1 +// national_number: 6502530000 +// +// Google Paris, +33 (0)1 42 68 53 00, 01 42 68 53 00 +// country_code: 33 +// national_number: 142685300 +// +// Google Beijing, +86-10-62503000, (010) 62503000 +// country_code: 86 +// national_number: 1062503000 +// +// Google Italy, +39 02-36618 300, 02-36618 300 +// country_code: 39 +// national_number: 236618300 +// italian_leading_zero: true \ No newline at end of file diff --git a/java/com/android/dialer/postcall/PostCall.java b/java/com/android/dialer/postcall/PostCall.java index 7eb83b133..b17a9b66d 100644 --- a/java/com/android/dialer/postcall/PostCall.java +++ b/java/com/android/dialer/postcall/PostCall.java @@ -26,22 +26,23 @@ import android.support.design.widget.Snackbar; import android.telephony.TelephonyManager; import android.view.View; import android.view.View.OnClickListener; -import com.android.dialer.common.ConfigProvider; -import com.android.dialer.common.ConfigProviderBindings; import com.android.dialer.common.LogUtil; +import com.android.dialer.configprovider.ConfigProvider; +import com.android.dialer.configprovider.ConfigProviderBindings; import com.android.dialer.enrichedcall.EnrichedCallCapabilities; import com.android.dialer.enrichedcall.EnrichedCallComponent; import com.android.dialer.enrichedcall.EnrichedCallManager; import com.android.dialer.logging.DialerImpression; import com.android.dialer.logging.Logger; +import com.android.dialer.performancereport.PerformanceReport; import com.android.dialer.util.DialerUtils; import com.android.dialer.util.IntentUtil; /** Helper class to handle all post call actions. */ public class PostCall { - private static final String KEY_POST_CALL_CALL_CONNECT_TIME = "post_call_call_connect_time"; private static final String KEY_POST_CALL_CALL_DISCONNECT_TIME = "post_call_call_disconnect_time"; + private static final String KEY_POST_CALL_CALL_CONNECT_TIME = "post_call_call_connect_time"; private static final String KEY_POST_CALL_CALL_NUMBER = "post_call_call_number"; private static final String KEY_POST_CALL_MESSAGE_SENT = "post_call_message_sent"; @@ -53,6 +54,8 @@ public class PostCall { promptUserToViewSentMessage(activity, rootView); } else if (shouldPromptUserToSendMessage(activity)) { promptUserToSendMessage(activity, rootView); + } else { + clear(activity); } } } @@ -158,6 +161,19 @@ public class PostCall { .apply(); } + /** + * Restart performance recording if there is a recent call (disconnect time to now is under + * threshold) + */ + public static void restartPerformanceRecordingIfARecentCallExist(Context context) { + long disconnectTimeMillis = + DialerUtils.getDefaultSharedPreferenceForDeviceProtectedStorageContext(context) + .getLong(PostCall.KEY_POST_CALL_CALL_DISCONNECT_TIME, -1); + if (disconnectTimeMillis != -1 && PerformanceReport.isRecording()) { + PerformanceReport.startRecording(); + } + } + private static void clear(Context context) { activeSnackbar = null; diff --git a/java/com/android/dialer/searchfragment/AndroidManifest.xml b/java/com/android/dialer/searchfragment/AndroidManifest.xml deleted file mode 100644 index 88ce67c13..000000000 --- a/java/com/android/dialer/searchfragment/AndroidManifest.xml +++ /dev/null @@ -1,16 +0,0 @@ - - \ No newline at end of file diff --git a/java/com/android/dialer/searchfragment/NewSearchFragment.java b/java/com/android/dialer/searchfragment/NewSearchFragment.java deleted file mode 100644 index e7283d0ad..000000000 --- a/java/com/android/dialer/searchfragment/NewSearchFragment.java +++ /dev/null @@ -1,83 +0,0 @@ -/* - * Copyright (C) 2017 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.dialer.searchfragment; - -import android.app.Fragment; -import android.app.LoaderManager.LoaderCallbacks; -import android.content.Loader; -import android.database.Cursor; -import android.os.Bundle; -import android.support.annotation.Nullable; -import android.support.v7.widget.LinearLayoutManager; -import android.support.v7.widget.RecyclerView; -import android.view.LayoutInflater; -import android.view.View; -import android.view.ViewGroup; - -/** Fragment used for searching contacts. */ -public final class NewSearchFragment extends Fragment implements LoaderCallbacks { - - private RecyclerView recyclerView; - private SearchAdapter adapter; - private String query; - - @Nullable - @Override - public View onCreateView( - LayoutInflater inflater, @Nullable ViewGroup parent, @Nullable Bundle bundle) { - getLoaderManager().initLoader(0, null, this); - View view = inflater.inflate(R.layout.fragment_search, parent, false); - recyclerView = view.findViewById(R.id.recycler_view); - recyclerView.setLayoutManager(new LinearLayoutManager(getContext())); - - getLoaderManager().initLoader(0, null, this); - return view; - } - - @Override - public Loader onCreateLoader(int id, Bundle bundle) { - // TODO add more loaders - return new SearchContactsCursorLoader(getContext()); - } - - @Override - public void onLoadFinished(Loader loader, Cursor cursor) { - if (adapter == null) { - adapter = new SearchAdapter(getContext()); - } - if (loader instanceof SearchContactsCursorLoader) { - adapter.setContactsCursor(new SearchContactCursor(cursor, query)); - } - recyclerView.setAdapter(adapter); - } - - @Override - public void onLoaderReset(Loader loader) { - if (adapter != null) { - adapter.clear(); - adapter = null; - } - recyclerView.setAdapter(null); - } - - public void setQuery(String query) { - this.query = query; - if (adapter != null) { - adapter.setQuery(query); - } - } -} diff --git a/java/com/android/dialer/searchfragment/QueryUtil.java b/java/com/android/dialer/searchfragment/QueryUtil.java deleted file mode 100644 index a3f44ab83..000000000 --- a/java/com/android/dialer/searchfragment/QueryUtil.java +++ /dev/null @@ -1,269 +0,0 @@ -/* - * Copyright (C) 2017 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.dialer.searchfragment; - -import android.graphics.Typeface; -import android.support.annotation.NonNull; -import android.support.annotation.Nullable; -import android.telephony.PhoneNumberUtils; -import android.text.SpannableString; -import android.text.Spanned; -import android.text.TextUtils; -import android.text.style.StyleSpan; -import java.util.regex.Pattern; - -/** Contains utility methods for comparing and filtering strings with search queries. */ -final class QueryUtil { - - /** Matches strings with "-", "(", ")", 2-9 of at least length one. */ - static final Pattern T9_PATTERN = Pattern.compile("[\\-()2-9]+"); - - /** - * Compares a name and query and returns a {@link CharSequence} with bolded characters. - * - *

      Some example: - * - *

        - *
      • "query" would bold "John [query] Smith" - *
      • "222" would bold "[AAA] Mom" - *
      • "222" would bold "[A]llen [A]lex [A]aron" - *
      - * - * @param query containing any characters - * @param name of a contact/string that query will compare to - * @return name with query bolded if query can be found in the name. - */ - static CharSequence getNameWithQueryBolded(@Nullable String query, @NonNull String name) { - if (TextUtils.isEmpty(query)) { - return name; - } - - int index = -1; - int numberOfBoldedCharacters = 0; - - if (nameMatchesT9Query(query, name)) { - // Bold the characters that match the t9 query - index = indexOfQueryNonDigitsIgnored(query, getT9Representation(name)); - if (index == -1) { - return getNameWithInitialsBolded(query, name); - } - numberOfBoldedCharacters = query.length(); - - for (int i = 0; i < query.length(); i++) { - char c = query.charAt(i); - if (!Character.isDigit(c)) { - numberOfBoldedCharacters--; - } - } - - for (int i = 0; i < index + numberOfBoldedCharacters; i++) { - if (!Character.isLetterOrDigit(name.charAt(i))) { - if (i < index) { - index++; - } else { - numberOfBoldedCharacters++; - } - } - } - } - - if (index == -1) { - // Bold the query as an exact match in the name - index = name.toLowerCase().indexOf(query); - numberOfBoldedCharacters = query.length(); - } - - return index == -1 ? name : getBoldedString(name, index, numberOfBoldedCharacters); - } - - private static CharSequence getNameWithInitialsBolded(String query, String name) { - SpannableString boldedInitials = new SpannableString(name); - name = name.toLowerCase(); - int initialsBolded = 0; - int nameIndex = -1; - - while (++nameIndex < name.length() && initialsBolded < query.length()) { - if ((nameIndex == 0 || name.charAt(nameIndex - 1) == ' ') - && getDigit(name.charAt(nameIndex)) == query.charAt(initialsBolded)) { - boldedInitials.setSpan( - new StyleSpan(Typeface.BOLD), - nameIndex, - nameIndex + 1, - Spanned.SPAN_INCLUSIVE_INCLUSIVE); - initialsBolded++; - } - } - return boldedInitials; - } - - /** - * Compares a number and a query and returns a {@link CharSequence} with bolded characters. - * - *
        - *
      • "123" would bold "(650)34[1-23]24" - *
      • "123" would bold "+1([123])111-2222 - *
      - * - * @param query containing only numbers and phone number related characters "(", ")", "-", "+" - * @param number phone number of a contact that the query will compare to. - * @return number with query bolded if query can be found in the number. - */ - static CharSequence getNumberWithQueryBolded(@Nullable String query, @NonNull String number) { - if (TextUtils.isEmpty(query) || !numberMatchesNumberQuery(query, number)) { - return number; - } - - int index = indexOfQueryNonDigitsIgnored(query, number); - int boldedCharacters = query.length(); - - for (char c : query.toCharArray()) { - if (!Character.isDigit(c)) { - boldedCharacters--; - } - } - - for (int i = 0; i < index + boldedCharacters; i++) { - if (!Character.isDigit(number.charAt(i))) { - if (i <= index) { - index++; - } else { - boldedCharacters++; - } - } - } - return getBoldedString(number, index, boldedCharacters); - } - - private static SpannableString getBoldedString(String s, int index, int numBolded) { - SpannableString span = new SpannableString(s); - span.setSpan( - new StyleSpan(Typeface.BOLD), index, index + numBolded, Spanned.SPAN_INCLUSIVE_EXCLUSIVE); - return span; - } - - /** - * @return true if the query is of T9 format and the name's T9 representation belongs to the - * query; false otherwise. - */ - static boolean nameMatchesT9Query(String query, String name) { - if (!T9_PATTERN.matcher(query).matches()) { - return false; - } - - // Substring - if (indexOfQueryNonDigitsIgnored(query, getT9Representation(name)) != -1) { - return true; - } - - // Check matches initials - // TODO investigate faster implementation - query = digitsOnly(query); - int queryIndex = 0; - - String[] names = name.toLowerCase().split("\\s"); - for (int i = 0; i < names.length && queryIndex < query.length(); i++) { - if (TextUtils.isEmpty(names[i])) { - continue; - } - - if (getDigit(names[i].charAt(0)) == query.charAt(queryIndex)) { - queryIndex++; - } - } - - return queryIndex == query.length(); - } - - /** @return true if the number belongs to the query. */ - static boolean numberMatchesNumberQuery(String query, String number) { - return PhoneNumberUtils.isGlobalPhoneNumber(query) - && indexOfQueryNonDigitsIgnored(query, number) != -1; - } - - /** - * Checks if query is contained in number while ignoring all characters in both that are not - * digits (i.e. {@link Character#isDigit(char)} returns false). - * - * @return index where query is found with all non-digits removed, -1 if it's not found. - */ - private static int indexOfQueryNonDigitsIgnored(@NonNull String query, @NonNull String number) { - return digitsOnly(number).indexOf(digitsOnly(query)); - } - - // Returns string with letters replaced with their T9 representation. - private static String getT9Representation(String s) { - StringBuilder builder = new StringBuilder(s.length()); - for (char c : s.toLowerCase().toCharArray()) { - builder.append(getDigit(c)); - } - return builder.toString(); - } - - /** @return String s with only digits recognized by Character#isDigit() remaining */ - static String digitsOnly(String s) { - StringBuilder sb = new StringBuilder(); - for (int i = 0; i < s.length(); i++) { - char c = s.charAt(i); - if (Character.isDigit(c)) { - sb.append(c); - } - } - return sb.toString(); - } - - // Returns the T9 representation of a lower case character, otherwise returns the character. - private static char getDigit(char c) { - switch (c) { - case 'a': - case 'b': - case 'c': - return '2'; - case 'd': - case 'e': - case 'f': - return '3'; - case 'g': - case 'h': - case 'i': - return '4'; - case 'j': - case 'k': - case 'l': - return '5'; - case 'm': - case 'n': - case 'o': - return '6'; - case 'p': - case 'q': - case 'r': - case 's': - return '7'; - case 't': - case 'u': - case 'v': - return '8'; - case 'w': - case 'x': - case 'y': - case 'z': - return '9'; - default: - return c; - } - } -} diff --git a/java/com/android/dialer/searchfragment/SearchAdapter.java b/java/com/android/dialer/searchfragment/SearchAdapter.java deleted file mode 100644 index 8f5241557..000000000 --- a/java/com/android/dialer/searchfragment/SearchAdapter.java +++ /dev/null @@ -1,84 +0,0 @@ -/* - * Copyright (C) 2017 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.dialer.searchfragment; - -import android.content.Context; -import android.database.Cursor; -import android.support.v7.widget.RecyclerView; -import android.support.v7.widget.RecyclerView.ViewHolder; -import android.view.LayoutInflater; -import android.view.ViewGroup; -import com.android.dialer.common.Assert; -import com.android.dialer.searchfragment.SearchCursorManager.RowType; - -/** RecyclerView adapter for {@link NewSearchFragment}. */ -class SearchAdapter extends RecyclerView.Adapter { - - private final SearchCursorManager searchCursorManager; - private final Context context; - - private String query; - - SearchAdapter(Context context) { - searchCursorManager = new SearchCursorManager(); - this.context = context; - } - - // TODO: fill in the rest of the view holders. - @Override - public ViewHolder onCreateViewHolder(ViewGroup root, int position) { - @RowType int rowType = searchCursorManager.getRowType(position); - switch (rowType) { - case RowType.CONTACT_ROW: - return new SearchContactViewHolder( - LayoutInflater.from(context).inflate(R.layout.search_contact_row, root, false)); - case RowType.DIRECTORY_HEADER: - case RowType.DIRECTORY_ROW: - case RowType.INVALID: - case RowType.NEARBY_PLACES_HEADER: - case RowType.NEARBY_PLACES_ROW: - return null; - default: - throw Assert.createIllegalStateFailException("Invalid RowType: " + rowType); - } - } - - @Override - public void onBindViewHolder(ViewHolder holder, int position) { - Cursor cursor = searchCursorManager.getCursor(position); - ((SearchContactViewHolder) holder).bind(cursor, query); - } - - void setContactsCursor(Cursor cursor) { - searchCursorManager.setContactsCursor(cursor); - } - - void clear() { - searchCursorManager.clear(); - } - - @Override - public int getItemCount() { - return searchCursorManager.getCount(); - } - - public void setQuery(String query) { - this.query = query; - searchCursorManager.setQuery(query); - notifyDataSetChanged(); - } -} diff --git a/java/com/android/dialer/searchfragment/SearchContactCursor.java b/java/com/android/dialer/searchfragment/SearchContactCursor.java deleted file mode 100644 index 5006e1a60..000000000 --- a/java/com/android/dialer/searchfragment/SearchContactCursor.java +++ /dev/null @@ -1,390 +0,0 @@ -/* - * Copyright (C) 2017 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.dialer.searchfragment; - -import android.content.ContentResolver; -import android.database.CharArrayBuffer; -import android.database.ContentObserver; -import android.database.Cursor; -import android.database.DataSetObserver; -import android.net.Uri; -import android.os.Bundle; -import android.support.annotation.IntDef; -import android.support.annotation.Nullable; -import android.text.TextUtils; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.util.ArrayList; -import java.util.List; - -/** - * Wrapper for a cursor returned by {@link SearchContactsCursorLoader}. - * - *

      This cursor removes duplicate phone numbers associated with the same contact and can filter - * contacts based on a query by calling {@link #filter(String)}. - */ -final class SearchContactCursor implements Cursor { - - private final Cursor cursor; - // List of cursor ids that are valid for displaying after filtering. - private final List queryFilteredPositions = new ArrayList<>(); - - private int currentPosition = 0; - - @Retention(RetentionPolicy.SOURCE) - @IntDef({ - Qualification.NUMBERS_ARE_NOT_DUPLICATES, - Qualification.NEW_NUMBER_IS_MORE_QUALIFIED, - Qualification.CURRENT_MORE_QUALIFIED - }) - private @interface Qualification { - /** Numbers are not duplicates (i.e. neither is more qualified than the other). */ - int NUMBERS_ARE_NOT_DUPLICATES = 0; - /** Number are duplicates and new number is more qualified than the existing number. */ - int NEW_NUMBER_IS_MORE_QUALIFIED = 1; - /** Numbers are duplicates but current/existing number is more qualified than new number. */ - int CURRENT_MORE_QUALIFIED = 2; - } - - /** - * @param cursor with projection {@link SearchContactsCursorLoader#PHONE_PROJECTION}. - * @param query to filter cursor results. - */ - SearchContactCursor(Cursor cursor, @Nullable String query) { - // TODO investigate copying this into a MatrixCursor and holding in memory - this.cursor = cursor; - filter(query); - } - - /** - * Filters out contacts that do not match the query. - * - *

      The query can have at least 1 of 3 forms: - * - *

        - *
      • A phone number - *
      • A T9 representation of a name (matches {@link QueryUtil#T9_PATTERN}). - *
      • A name - *
      - * - *

      A contact is considered a match if: - * - *

        - *
      • Its phone number contains the phone number query - *
      • Its name represented in T9 contains the T9 query - *
      • Its name contains the query - *
      - */ - void filter(@Nullable String query) { - if (query == null) { - query = ""; - } - queryFilteredPositions.clear(); - - // On some devices, contacts have multiple rows with identical phone numbers. These numbers are - // considered duplicates. Since the order might not be guaranteed, we compare all of the numbers - // and hold onto the most qualified one as the one we want to display to the user. - // See #getQualification for details on how qualification is determined. - int previousMostQualifiedPosition = 0; - String previousName = ""; - String previousMostQualifiedNumber = ""; - - query = query.toLowerCase(); - cursor.moveToPosition(-1); - - while (cursor.moveToNext()) { - int position = cursor.getPosition(); - String currentNumber = cursor.getString(SearchContactsCursorLoader.PHONE_NUMBER); - String currentName = cursor.getString(SearchContactsCursorLoader.PHONE_DISPLAY_NAME); - - if (!previousName.equals(currentName)) { - previousName = currentName; - previousMostQualifiedNumber = currentNumber; - previousMostQualifiedPosition = position; - } else { - // Since the contact name is the same, check if this number is a duplicate - switch (getQualification(currentNumber, previousMostQualifiedNumber)) { - case Qualification.CURRENT_MORE_QUALIFIED: - // Number is a less qualified duplicate, ignore it. - continue; - case Qualification.NEW_NUMBER_IS_MORE_QUALIFIED: - // If number wasn't filtered out before, remove it and add it's more qualified version. - if (queryFilteredPositions.contains(previousMostQualifiedPosition)) { - queryFilteredPositions.remove(previousMostQualifiedPosition); - queryFilteredPositions.add(position); - } - previousMostQualifiedNumber = currentNumber; - previousMostQualifiedPosition = position; - continue; - case Qualification.NUMBERS_ARE_NOT_DUPLICATES: - default: - previousMostQualifiedNumber = currentNumber; - previousMostQualifiedPosition = position; - } - } - - if (TextUtils.isEmpty(query) - || QueryUtil.nameMatchesT9Query(query, previousName) - || QueryUtil.numberMatchesNumberQuery(query, previousMostQualifiedNumber) - || previousName.contains(query)) { - queryFilteredPositions.add(previousMostQualifiedPosition); - } - } - currentPosition = 0; - cursor.moveToFirst(); - } - - /** - * @param number that may or may not be more qualified than the existing most qualified number - * @param mostQualifiedNumber currently most qualified number associated with same contact - * @return {@link Qualification} where the more qualified number is the number with the most - * digits. If the digits are the same, the number with the most formatting is more qualified. - */ - private @Qualification int getQualification(String number, String mostQualifiedNumber) { - // Ignore formatting - String numberDigits = QueryUtil.digitsOnly(number); - String qualifiedNumberDigits = QueryUtil.digitsOnly(mostQualifiedNumber); - - // If the numbers are identical, return version with more formatting - if (qualifiedNumberDigits.equals(numberDigits)) { - if (mostQualifiedNumber.length() >= number.length()) { - return Qualification.CURRENT_MORE_QUALIFIED; - } else { - return Qualification.NEW_NUMBER_IS_MORE_QUALIFIED; - } - } - - // If one number is a suffix of another, then return the longer one. - // If they are equal, then return the current most qualified number. - if (qualifiedNumberDigits.endsWith(numberDigits)) { - return Qualification.CURRENT_MORE_QUALIFIED; - } - if (numberDigits.endsWith(qualifiedNumberDigits)) { - return Qualification.NEW_NUMBER_IS_MORE_QUALIFIED; - } - return Qualification.NUMBERS_ARE_NOT_DUPLICATES; - } - - @Override - public boolean moveToPosition(int position) { - currentPosition = position; - return currentPosition < getCount() - && cursor.moveToPosition(queryFilteredPositions.get(currentPosition)); - } - - @Override - public boolean move(int offset) { - currentPosition += offset; - return moveToPosition(currentPosition); - } - - @Override - public int getCount() { - return queryFilteredPositions.size(); - } - - @Override - public boolean isFirst() { - return currentPosition == 0; - } - - @Override - public boolean isLast() { - return currentPosition == getCount() - 1; - } - - @Override - public int getPosition() { - return currentPosition; - } - - @Override - public boolean moveToFirst() { - return moveToPosition(0); - } - - @Override - public boolean moveToLast() { - return moveToPosition(getCount() - 1); - } - - @Override - public boolean moveToNext() { - return moveToPosition(++currentPosition); - } - - @Override - public boolean moveToPrevious() { - return moveToPosition(--currentPosition); - } - - // Methods below simply call the corresponding method in cursor. - @Override - public boolean isBeforeFirst() { - return cursor.isBeforeFirst(); - } - - @Override - public boolean isAfterLast() { - return cursor.isAfterLast(); - } - - @Override - public int getColumnIndex(String columnName) { - return cursor.getColumnIndex(columnName); - } - - @Override - public int getColumnIndexOrThrow(String columnName) { - return cursor.getColumnIndexOrThrow(columnName); - } - - @Override - public String getColumnName(int columnIndex) { - return cursor.getColumnName(columnIndex); - } - - @Override - public String[] getColumnNames() { - return cursor.getColumnNames(); - } - - @Override - public int getColumnCount() { - return cursor.getColumnCount(); - } - - @Override - public byte[] getBlob(int columnIndex) { - return cursor.getBlob(columnIndex); - } - - @Override - public String getString(int columnIndex) { - return cursor.getString(columnIndex); - } - - @Override - public void copyStringToBuffer(int columnIndex, CharArrayBuffer buffer) { - cursor.copyStringToBuffer(columnIndex, buffer); - } - - @Override - public short getShort(int columnIndex) { - return cursor.getShort(columnIndex); - } - - @Override - public int getInt(int columnIndex) { - return cursor.getInt(columnIndex); - } - - @Override - public long getLong(int columnIndex) { - return cursor.getLong(columnIndex); - } - - @Override - public float getFloat(int columnIndex) { - return cursor.getFloat(columnIndex); - } - - @Override - public double getDouble(int columnIndex) { - return cursor.getDouble(columnIndex); - } - - @Override - public int getType(int columnIndex) { - return cursor.getType(columnIndex); - } - - @Override - public boolean isNull(int columnIndex) { - return cursor.isNull(columnIndex); - } - - @Override - public void deactivate() { - cursor.deactivate(); - } - - @Override - public boolean requery() { - return cursor.requery(); - } - - @Override - public void close() { - cursor.close(); - } - - @Override - public boolean isClosed() { - return cursor.isClosed(); - } - - @Override - public void registerContentObserver(ContentObserver observer) { - cursor.registerContentObserver(observer); - } - - @Override - public void unregisterContentObserver(ContentObserver observer) { - cursor.unregisterContentObserver(observer); - } - - @Override - public void registerDataSetObserver(DataSetObserver observer) { - cursor.registerDataSetObserver(observer); - } - - @Override - public void unregisterDataSetObserver(DataSetObserver observer) { - cursor.unregisterDataSetObserver(observer); - } - - @Override - public void setNotificationUri(ContentResolver cr, Uri uri) { - cursor.setNotificationUri(cr, uri); - } - - @Override - public Uri getNotificationUri() { - return cursor.getNotificationUri(); - } - - @Override - public boolean getWantsAllOnMoveCalls() { - return cursor.getWantsAllOnMoveCalls(); - } - - @Override - public void setExtras(Bundle extras) { - cursor.setExtras(extras); - } - - @Override - public Bundle getExtras() { - return cursor.getExtras(); - } - - @Override - public Bundle respond(Bundle extras) { - return cursor.respond(extras); - } -} diff --git a/java/com/android/dialer/searchfragment/SearchContactViewHolder.java b/java/com/android/dialer/searchfragment/SearchContactViewHolder.java deleted file mode 100644 index 4ac6af33e..000000000 --- a/java/com/android/dialer/searchfragment/SearchContactViewHolder.java +++ /dev/null @@ -1,203 +0,0 @@ -/* - * Copyright (C) 2017 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.dialer.searchfragment; - -import android.content.Context; -import android.content.res.Resources; -import android.database.Cursor; -import android.net.Uri; -import android.provider.ContactsContract.CommonDataKinds.Phone; -import android.provider.ContactsContract.Contacts; -import android.support.annotation.IntDef; -import android.support.v7.widget.RecyclerView.ViewHolder; -import android.text.TextUtils; -import android.view.View; -import android.view.View.OnClickListener; -import android.widget.ImageView; -import android.widget.QuickContactBadge; -import android.widget.TextView; -import com.android.contacts.common.ContactPhotoManager; -import com.android.contacts.common.lettertiles.LetterTileDrawable; -import com.android.dialer.callintent.CallInitiationType.Type; -import com.android.dialer.callintent.CallIntentBuilder; -import com.android.dialer.common.Assert; -import com.android.dialer.telecom.TelecomUtil; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; - -/** ViewHolder for a contact row in {@link NewSearchFragment}. */ -final class SearchContactViewHolder extends ViewHolder implements OnClickListener { - - /** IntDef for the different types of actions that can be shown. */ - @Retention(RetentionPolicy.SOURCE) - @IntDef({ - SearchContactViewHolder.CallToAction.NONE, - SearchContactViewHolder.CallToAction.VIDEO_CALL, - SearchContactViewHolder.CallToAction.SHARE_AND_CALL - }) - @interface CallToAction { - int NONE = 0; - int VIDEO_CALL = 1; - int SHARE_AND_CALL = 2; - } - - private final QuickContactBadge photo; - private final TextView nameOrNumberView; - private final TextView numberView; - private final ImageView callToActionView; - private final Context context; - - private String number; - private @CallToAction int currentAction; - - SearchContactViewHolder(View view) { - super(view); - view.setOnClickListener(this); - photo = view.findViewById(R.id.photo); - nameOrNumberView = view.findViewById(R.id.primary); - numberView = view.findViewById(R.id.secondary); - callToActionView = view.findViewById(R.id.call_to_action); - context = view.getContext(); - } - - /** - * Binds the ViewHolder with a cursor from {@link SearchContactsCursorLoader} with the data found - * at the cursors set position. - */ - void bind(Cursor cursor, String query) { - number = cursor.getString(SearchContactsCursorLoader.PHONE_NUMBER); - String name = cursor.getString(SearchContactsCursorLoader.PHONE_DISPLAY_NAME); - String label = getLabel(context.getResources(), cursor); - String secondaryInfo = - TextUtils.isEmpty(label) - ? number - : context.getString(R.string.call_subject_type_and_number, label, number); - - nameOrNumberView.setText(QueryUtil.getNameWithQueryBolded(query, name)); - numberView.setText(QueryUtil.getNumberWithQueryBolded(query, secondaryInfo)); - setCallToAction(cursor); - - if (shouldShowPhoto(cursor, name)) { - nameOrNumberView.setVisibility(View.VISIBLE); - photo.setVisibility(View.VISIBLE); - photo.setContentDescription(context.getString(R.string.description_quick_contact_for, name)); - String photoUri = cursor.getString(SearchContactsCursorLoader.PHONE_PHOTO_URI); - ContactPhotoManager.getInstance(context) - .loadDialerThumbnailOrPhoto( - photo, - getContactUri(cursor), - cursor.getLong(SearchContactsCursorLoader.PHONE_PHOTO_ID), - photoUri == null ? null : Uri.parse(photoUri), - name, - LetterTileDrawable.TYPE_DEFAULT); - } else { - nameOrNumberView.setVisibility(View.GONE); - photo.setVisibility(View.INVISIBLE); - } - } - - private boolean shouldShowPhoto(Cursor cursor, String currentName) { - int currentPosition = cursor.getPosition(); - if (currentPosition == 0) { - return true; - } else { - cursor.moveToPosition(currentPosition - 1); - String previousName = cursor.getString(SearchContactsCursorLoader.PHONE_DISPLAY_NAME); - cursor.moveToPosition(currentPosition); - return !currentName.equals(previousName); - } - } - - private static Uri getContactUri(Cursor cursor) { - long contactId = cursor.getLong(SearchContactsCursorLoader.PHONE_ID); - String lookupKey = cursor.getString(SearchContactsCursorLoader.PHONE_LOOKUP_KEY); - return Contacts.getLookupUri(contactId, lookupKey); - } - - // TODO: handle CNAP and cequint types. - // TODO: unify this into a utility method with CallLogAdapter#getNumberType - private static String getLabel(Resources resources, Cursor cursor) { - int numberType = cursor.getInt(SearchContactsCursorLoader.PHONE_TYPE); - String numberLabel = cursor.getString(SearchContactsCursorLoader.PHONE_LABEL); - - // Returns empty label instead of "custom" if the custom label is empty. - if (numberType == Phone.TYPE_CUSTOM && TextUtils.isEmpty(numberLabel)) { - return ""; - } - return (String) Phone.getTypeLabel(resources, numberType, numberLabel); - } - - private void setCallToAction(Cursor cursor) { - currentAction = getCallToAction(cursor); - switch (currentAction) { - case CallToAction.NONE: - callToActionView.setVisibility(View.GONE); - callToActionView.setOnClickListener(null); - break; - case CallToAction.SHARE_AND_CALL: - callToActionView.setVisibility(View.VISIBLE); - callToActionView.setImageDrawable(context.getDrawable(R.drawable.ic_phone_attach)); - callToActionView.setOnClickListener(this); - break; - case CallToAction.VIDEO_CALL: - callToActionView.setVisibility(View.VISIBLE); - callToActionView.setImageDrawable( - context.getDrawable(R.drawable.quantum_ic_videocam_white_24)); - callToActionView.setOnClickListener(this); - break; - default: - throw Assert.createIllegalStateFailException( - "Invalid Call to action type: " + currentAction); - } - } - - private static @CallToAction int getCallToAction(Cursor cursor) { - int carrierPresence = cursor.getInt(SearchContactsCursorLoader.PHONE_CARRIER_PRESENCE); - if ((carrierPresence & Phone.CARRIER_PRESENCE_VT_CAPABLE) == 1) { - return CallToAction.VIDEO_CALL; - } - - // TODO: enriched calling - return CallToAction.NONE; - } - - @Override - public void onClick(View view) { - if (view == callToActionView) { - switch (currentAction) { - case CallToAction.SHARE_AND_CALL: - callToActionView.setVisibility(View.VISIBLE); - callToActionView.setImageDrawable(context.getDrawable(R.drawable.ic_phone_attach)); - // TODO: open call composer. - break; - case CallToAction.VIDEO_CALL: - callToActionView.setVisibility(View.VISIBLE); - callToActionView.setImageDrawable( - context.getDrawable(R.drawable.quantum_ic_videocam_white_24)); - // TODO: place a video call - break; - case CallToAction.NONE: - default: - throw Assert.createIllegalStateFailException( - "Invalid Call to action type: " + currentAction); - } - } else { - // TODO: set the correct call initiation type. - TelecomUtil.placeCall(context, new CallIntentBuilder(number, Type.REGULAR_SEARCH).build()); - } - } -} diff --git a/java/com/android/dialer/searchfragment/SearchContactsCursorLoader.java b/java/com/android/dialer/searchfragment/SearchContactsCursorLoader.java deleted file mode 100644 index 309dfffd9..000000000 --- a/java/com/android/dialer/searchfragment/SearchContactsCursorLoader.java +++ /dev/null @@ -1,57 +0,0 @@ -/* - * Copyright (C) 2017 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.dialer.searchfragment; - -import android.content.Context; -import android.content.CursorLoader; -import android.provider.ContactsContract.CommonDataKinds.Phone; - -/** Cursor Loader for {@link NewSearchFragment}. */ -final class SearchContactsCursorLoader extends CursorLoader { - - public static final int PHONE_ID = 0; - public static final int PHONE_TYPE = 1; - public static final int PHONE_LABEL = 2; - public static final int PHONE_NUMBER = 3; - public static final int PHONE_DISPLAY_NAME = 4; - public static final int PHONE_PHOTO_ID = 5; - public static final int PHONE_PHOTO_URI = 6; - public static final int PHONE_LOOKUP_KEY = 7; - public static final int PHONE_CARRIER_PRESENCE = 8; - - @SuppressWarnings("unused") - public static final int PHONE_SOFT_KEY = 9; - - static final String[] PHONE_PROJECTION = - new String[] { - Phone._ID, // 0 - Phone.TYPE, // 1 - Phone.LABEL, // 2 - Phone.NUMBER, // 3 - Phone.DISPLAY_NAME_PRIMARY, // 4 - Phone.PHOTO_ID, // 5 - Phone.PHOTO_THUMBNAIL_URI, // 6 - Phone.LOOKUP_KEY, // 7 - Phone.CARRIER_PRESENCE, // 8 - Phone.SORT_KEY_PRIMARY // 9 - }; - - SearchContactsCursorLoader(Context context) { - super( - context, Phone.CONTENT_URI, PHONE_PROJECTION, null, null, Phone.SORT_KEY_PRIMARY + " ASC"); - } -} diff --git a/java/com/android/dialer/searchfragment/SearchCursorManager.java b/java/com/android/dialer/searchfragment/SearchCursorManager.java deleted file mode 100644 index 64c4fc170..000000000 --- a/java/com/android/dialer/searchfragment/SearchCursorManager.java +++ /dev/null @@ -1,229 +0,0 @@ -/* - * Copyright (C) 2017 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.dialer.searchfragment; - -import android.database.Cursor; -import android.support.annotation.IntDef; -import com.android.dialer.common.Assert; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; - -/** - * Manages all of the cursors needed for {@link SearchAdapter}. - * - *

      This class accepts three cursors: - * - *

        - *
      • A contacts cursor {@link #setContactsCursor(Cursor)} - *
      • A google search results cursor {@link #setNearbyPlacesCursor(Cursor)} - *
      • A work directory cursor {@link #setCorpDirectoryCursor(Cursor)} - *
      - * - *

      The key purpose of this class is to compose three aforementioned cursors together to function - * as one cursor. The key methods needed to utilize this class as a cursor are: - * - *

        - *
      • {@link #getCursor(int)} - *
      • {@link #getCount()} - *
      • {@link #getRowType(int)} - *
      - */ -final class SearchCursorManager { - - /** IntDef for the different types of rows that can be shown when searching. */ - @Retention(RetentionPolicy.SOURCE) - @IntDef({ - SearchCursorManager.RowType.INVALID, - SearchCursorManager.RowType.CONTACT_ROW, - SearchCursorManager.RowType.NEARBY_PLACES_HEADER, - SearchCursorManager.RowType.NEARBY_PLACES_ROW, - SearchCursorManager.RowType.DIRECTORY_HEADER, - SearchCursorManager.RowType.DIRECTORY_ROW - }) - @interface RowType { - int INVALID = 0; - /** A row containing contact information for contacts stored locally on device. */ - int CONTACT_ROW = 1; - /** Header to mark the end of contact rows and start of nearby places rows. */ - int NEARBY_PLACES_HEADER = 2; - /** A row containing nearby places information/search results. */ - int NEARBY_PLACES_ROW = 3; - /** Header to mark the end of the previous row set and start of directory rows. */ - int DIRECTORY_HEADER = 4; - /** A row containing contact information for contacts stored externally in corp directories. */ - int DIRECTORY_ROW = 5; - } - - private Cursor contactsCursor = null; - private Cursor nearbyPlacesCursor = null; - private Cursor corpDirectoryCursor = null; - - void setContactsCursor(Cursor cursor) { - if (cursor != null && cursor.getCount() > 0) { - contactsCursor = cursor; - } else { - contactsCursor = null; - } - } - - void setNearbyPlacesCursor(Cursor cursor) { - if (cursor != null && cursor.getCount() > 0) { - nearbyPlacesCursor = cursor; - } else { - nearbyPlacesCursor = null; - } - } - - void setCorpDirectoryCursor(Cursor cursor) { - if (cursor != null && cursor.getCount() > 0) { - corpDirectoryCursor = cursor; - } else { - corpDirectoryCursor = null; - } - } - - void setQuery(String query) { - if (contactsCursor != null) { - ((SearchContactCursor) contactsCursor).filter(query); - } - } - - /** @return the sum of counts of all cursors, including headers. */ - int getCount() { - int count = 0; - if (contactsCursor != null) { - count += contactsCursor.getCount(); - } - - if (nearbyPlacesCursor != null) { - count++; // header - count += nearbyPlacesCursor.getCount(); - } - - if (corpDirectoryCursor != null) { - count++; // header - count += corpDirectoryCursor.getCount(); - } - - return count; - } - - @RowType - int getRowType(int position) { - if (contactsCursor != null) { - position -= contactsCursor.getCount(); - - if (position < 0) { - return SearchCursorManager.RowType.CONTACT_ROW; - } - } - - if (nearbyPlacesCursor != null) { - if (position == 0) { - return SearchCursorManager.RowType.NEARBY_PLACES_HEADER; - } else { - position--; // header - } - - position -= nearbyPlacesCursor.getCount(); - - if (position < 0) { - return SearchCursorManager.RowType.NEARBY_PLACES_ROW; - } - } - - if (corpDirectoryCursor != null) { - if (position == 0) { - return SearchCursorManager.RowType.DIRECTORY_HEADER; - } else { - position--; // header - } - - position -= corpDirectoryCursor.getCount(); - - if (position < 0) { - return SearchCursorManager.RowType.DIRECTORY_ROW; - } - } - - throw Assert.createIllegalStateFailException("No valid row type."); - } - - /** - * Gets cursor corresponding to position in coelesced list of search cursors. Callers should - * ensure that {@link #getRowType(int)} doesn't correspond to header position, otherwise an - * exception will be thrown. - * - * @param position in coalecsed list of search cursors - * @return Cursor moved to position specific to passed in position. - */ - Cursor getCursor(int position) { - if (contactsCursor != null) { - int count = contactsCursor.getCount(); - - if (position - count < 0) { - contactsCursor.moveToPosition(position); - return contactsCursor; - } - position -= count; - } - - if (nearbyPlacesCursor != null) { - Assert.checkArgument(position != 0, "No valid cursor, position is nearby places header."); - position--; // header - int count = nearbyPlacesCursor.getCount(); - - if (position - count < 0) { - nearbyPlacesCursor.moveToPosition(position); - return nearbyPlacesCursor; - } - position -= count; - } - - if (corpDirectoryCursor != null) { - Assert.checkArgument(position != 0, "No valid cursor, position is directory search header."); - position--; // header - int count = corpDirectoryCursor.getCount(); - - if (position - count < 0) { - corpDirectoryCursor.moveToPosition(position); - return corpDirectoryCursor; - } - position -= count; - } - - throw Assert.createIllegalStateFailException("No valid cursor."); - } - - /** removes all cursors. */ - void clear() { - if (contactsCursor != null) { - contactsCursor.close(); - contactsCursor = null; - } - - if (nearbyPlacesCursor != null) { - nearbyPlacesCursor.close(); - nearbyPlacesCursor = null; - } - - if (corpDirectoryCursor != null) { - corpDirectoryCursor.close(); - corpDirectoryCursor = null; - } - } -} diff --git a/java/com/android/dialer/searchfragment/common/AndroidManifest.xml b/java/com/android/dialer/searchfragment/common/AndroidManifest.xml new file mode 100644 index 000000000..178cd83c3 --- /dev/null +++ b/java/com/android/dialer/searchfragment/common/AndroidManifest.xml @@ -0,0 +1,16 @@ + + \ No newline at end of file diff --git a/java/com/android/dialer/searchfragment/common/Projections.java b/java/com/android/dialer/searchfragment/common/Projections.java new file mode 100644 index 000000000..37e20d195 --- /dev/null +++ b/java/com/android/dialer/searchfragment/common/Projections.java @@ -0,0 +1,50 @@ +/* + * Copyright (C) 2017 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.dialer.searchfragment.common; + +import android.provider.ContactsContract.CommonDataKinds.Phone; + +/** Class containing relevant projections for searching contacts. */ +public class Projections { + + public static final int PHONE_ID = 0; + public static final int PHONE_TYPE = 1; + public static final int PHONE_LABEL = 2; + public static final int PHONE_NUMBER = 3; + public static final int PHONE_DISPLAY_NAME = 4; + public static final int PHONE_PHOTO_ID = 5; + public static final int PHONE_PHOTO_URI = 6; + public static final int PHONE_LOOKUP_KEY = 7; + public static final int PHONE_CARRIER_PRESENCE = 8; + + @SuppressWarnings("unused") + public static final int PHONE_SORT_KEY = 9; + + public static final String[] PHONE_PROJECTION = + new String[] { + Phone._ID, // 0 + Phone.TYPE, // 1 + Phone.LABEL, // 2 + Phone.NUMBER, // 3 + Phone.DISPLAY_NAME_PRIMARY, // 4 + Phone.PHOTO_ID, // 5 + Phone.PHOTO_THUMBNAIL_URI, // 6 + Phone.LOOKUP_KEY, // 7 + Phone.CARRIER_PRESENCE, // 8 + Phone.SORT_KEY_PRIMARY // 9 + }; +} diff --git a/java/com/android/dialer/searchfragment/common/QueryBoldingUtil.java b/java/com/android/dialer/searchfragment/common/QueryBoldingUtil.java new file mode 100644 index 000000000..7bdd69567 --- /dev/null +++ b/java/com/android/dialer/searchfragment/common/QueryBoldingUtil.java @@ -0,0 +1,154 @@ +/* + * Copyright (C) 2017 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.dialer.searchfragment.common; + +import android.graphics.Typeface; +import android.support.annotation.NonNull; +import android.support.annotation.Nullable; +import android.text.SpannableString; +import android.text.Spanned; +import android.text.TextUtils; +import android.text.style.StyleSpan; + +/** Utility class for handling bolding queries contained in string. */ +public class QueryBoldingUtil { + + /** + * Compares a name and query and returns a {@link CharSequence} with bolded characters. + * + *

      Some example: + * + *

        + *
      • "query" would bold "John [query] Smith" + *
      • "222" would bold "[AAA] Mom" + *
      • "222" would bold "[A]llen [A]lex [A]aron" + *
      + * + * @param query containing any characters + * @param name of a contact/string that query will compare to + * @return name with query bolded if query can be found in the name. + */ + public static CharSequence getNameWithQueryBolded(@Nullable String query, @NonNull String name) { + if (TextUtils.isEmpty(query)) { + return name; + } + + int index = -1; + int numberOfBoldedCharacters = 0; + + if (QueryFilteringUtil.nameMatchesT9Query(query, name)) { + // Bold the characters that match the t9 query + String t9 = QueryFilteringUtil.getT9Representation(name); + index = QueryFilteringUtil.indexOfQueryNonDigitsIgnored(query, t9); + if (index == -1) { + return getNameWithInitialsBolded(query, name); + } + numberOfBoldedCharacters = query.length(); + + for (int i = 0; i < query.length(); i++) { + char c = query.charAt(i); + if (!Character.isDigit(c)) { + numberOfBoldedCharacters--; + } + } + + for (int i = 0; i < index + numberOfBoldedCharacters; i++) { + if (!Character.isLetterOrDigit(name.charAt(i))) { + if (i < index) { + index++; + } else { + numberOfBoldedCharacters++; + } + } + } + } + + if (index == -1) { + // Bold the query as an exact match in the name + index = name.toLowerCase().indexOf(query); + numberOfBoldedCharacters = query.length(); + } + + return index == -1 ? name : getBoldedString(name, index, numberOfBoldedCharacters); + } + + private static CharSequence getNameWithInitialsBolded(String query, String name) { + SpannableString boldedInitials = new SpannableString(name); + name = name.toLowerCase(); + int initialsBolded = 0; + int nameIndex = -1; + + while (++nameIndex < name.length() && initialsBolded < query.length()) { + if ((nameIndex == 0 || name.charAt(nameIndex - 1) == ' ') + && QueryFilteringUtil.getDigit(name.charAt(nameIndex)) == query.charAt(initialsBolded)) { + boldedInitials.setSpan( + new StyleSpan(Typeface.BOLD), + nameIndex, + nameIndex + 1, + Spanned.SPAN_INCLUSIVE_INCLUSIVE); + initialsBolded++; + } + } + return boldedInitials; + } + + /** + * Compares a number and a query and returns a {@link CharSequence} with bolded characters. + * + *
        + *
      • "123" would bold "(650)34[1-23]24" + *
      • "123" would bold "+1([123])111-2222 + *
      + * + * @param query containing only numbers and phone number related characters "(", ")", "-", "+" + * @param number phone number of a contact that the query will compare to. + * @return number with query bolded if query can be found in the number. + */ + public static CharSequence getNumberWithQueryBolded( + @Nullable String query, @NonNull String number) { + if (TextUtils.isEmpty(query) || !QueryFilteringUtil.numberMatchesNumberQuery(query, number)) { + return number; + } + + int index = QueryFilteringUtil.indexOfQueryNonDigitsIgnored(query, number); + int boldedCharacters = query.length(); + + for (char c : query.toCharArray()) { + if (!Character.isDigit(c)) { + boldedCharacters--; + } + } + + for (int i = 0; i < index + boldedCharacters; i++) { + if (!Character.isDigit(number.charAt(i))) { + if (i <= index) { + index++; + } else { + boldedCharacters++; + } + } + } + return getBoldedString(number, index, boldedCharacters); + } + + private static SpannableString getBoldedString(String s, int index, int numBolded) { + SpannableString span = new SpannableString(s); + span.setSpan( + new StyleSpan(Typeface.BOLD), index, index + numBolded, Spanned.SPAN_INCLUSIVE_EXCLUSIVE); + return span; + } +} diff --git a/java/com/android/dialer/searchfragment/common/QueryFilteringUtil.java b/java/com/android/dialer/searchfragment/common/QueryFilteringUtil.java new file mode 100644 index 000000000..b23315b15 --- /dev/null +++ b/java/com/android/dialer/searchfragment/common/QueryFilteringUtil.java @@ -0,0 +1,141 @@ +/* + * Copyright (C) 2017 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.dialer.searchfragment.common; + +import android.support.annotation.NonNull; +import android.telephony.PhoneNumberUtils; +import android.text.TextUtils; +import java.util.regex.Pattern; + +/** Utility class for filtering, comparing and handling strings and queries. */ +public class QueryFilteringUtil { + + /** Matches strings with "-", "(", ")", 2-9 of at least length one. */ + static final Pattern T9_PATTERN = Pattern.compile("[\\-()2-9]+"); + + /** + * @return true if the query is of T9 format and the name's T9 representation belongs to the + * query; false otherwise. + */ + public static boolean nameMatchesT9Query(String query, String name) { + if (!T9_PATTERN.matcher(query).matches()) { + return false; + } + + // Substring + if (indexOfQueryNonDigitsIgnored(query, getT9Representation(name)) != -1) { + return true; + } + + // Check matches initials + // TODO investigate faster implementation + query = digitsOnly(query); + int queryIndex = 0; + + String[] names = name.toLowerCase().split("\\s"); + for (int i = 0; i < names.length && queryIndex < query.length(); i++) { + if (TextUtils.isEmpty(names[i])) { + continue; + } + + if (getDigit(names[i].charAt(0)) == query.charAt(queryIndex)) { + queryIndex++; + } + } + + return queryIndex == query.length(); + } + + /** @return true if the number belongs to the query. */ + public static boolean numberMatchesNumberQuery(String query, String number) { + return PhoneNumberUtils.isGlobalPhoneNumber(query) + && indexOfQueryNonDigitsIgnored(query, number) != -1; + } + + /** + * Checks if query is contained in number while ignoring all characters in both that are not + * digits (i.e. {@link Character#isDigit(char)} returns false). + * + * @return index where query is found with all non-digits removed, -1 if it's not found. + */ + static int indexOfQueryNonDigitsIgnored(@NonNull String query, @NonNull String number) { + return digitsOnly(number).indexOf(digitsOnly(query)); + } + + // Returns string with letters replaced with their T9 representation. + static String getT9Representation(String s) { + StringBuilder builder = new StringBuilder(s.length()); + for (char c : s.toLowerCase().toCharArray()) { + builder.append(getDigit(c)); + } + return builder.toString(); + } + + /** @return String s with only digits recognized by Character#isDigit() remaining */ + public static String digitsOnly(String s) { + StringBuilder sb = new StringBuilder(); + for (int i = 0; i < s.length(); i++) { + char c = s.charAt(i); + if (Character.isDigit(c)) { + sb.append(c); + } + } + return sb.toString(); + } + + // Returns the T9 representation of a lower case character, otherwise returns the character. + static char getDigit(char c) { + switch (c) { + case 'a': + case 'b': + case 'c': + return '2'; + case 'd': + case 'e': + case 'f': + return '3'; + case 'g': + case 'h': + case 'i': + return '4'; + case 'j': + case 'k': + case 'l': + return '5'; + case 'm': + case 'n': + case 'o': + return '6'; + case 'p': + case 'q': + case 'r': + case 's': + return '7'; + case 't': + case 'u': + case 'v': + return '8'; + case 'w': + case 'x': + case 'y': + case 'z': + return '9'; + default: + return c; + } + } +} diff --git a/java/com/android/dialer/searchfragment/common/res/layout/search_contact_row.xml b/java/com/android/dialer/searchfragment/common/res/layout/search_contact_row.xml new file mode 100644 index 000000000..dd871af70 --- /dev/null +++ b/java/com/android/dialer/searchfragment/common/res/layout/search_contact_row.xml @@ -0,0 +1,69 @@ + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/java/com/android/dialer/searchfragment/common/res/values/dimens.xml b/java/com/android/dialer/searchfragment/common/res/values/dimens.xml new file mode 100644 index 000000000..d5459ddb3 --- /dev/null +++ b/java/com/android/dialer/searchfragment/common/res/values/dimens.xml @@ -0,0 +1,23 @@ + + + + 56dp + 8dp + 8dp + 16dp + 16sp + \ No newline at end of file diff --git a/java/com/android/dialer/searchfragment/cp2/SearchContactCursor.java b/java/com/android/dialer/searchfragment/cp2/SearchContactCursor.java new file mode 100644 index 000000000..a2ef58c3c --- /dev/null +++ b/java/com/android/dialer/searchfragment/cp2/SearchContactCursor.java @@ -0,0 +1,392 @@ +/* + * Copyright (C) 2017 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.dialer.searchfragment.cp2; + +import android.content.ContentResolver; +import android.database.CharArrayBuffer; +import android.database.ContentObserver; +import android.database.Cursor; +import android.database.DataSetObserver; +import android.net.Uri; +import android.os.Bundle; +import android.support.annotation.IntDef; +import android.support.annotation.Nullable; +import android.text.TextUtils; +import com.android.dialer.searchfragment.common.Projections; +import com.android.dialer.searchfragment.common.QueryFilteringUtil; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.util.ArrayList; +import java.util.List; + +/** + * Wrapper for a cursor returned by {@link SearchContactsCursorLoader}. + * + *

      This cursor removes duplicate phone numbers associated with the same contact and can filter + * contacts based on a query by calling {@link #filter(String)}. + */ +public final class SearchContactCursor implements Cursor { + + private final Cursor cursor; + // List of cursor ids that are valid for displaying after filtering. + private final List queryFilteredPositions = new ArrayList<>(); + + private int currentPosition = 0; + + @Retention(RetentionPolicy.SOURCE) + @IntDef({ + Qualification.NUMBERS_ARE_NOT_DUPLICATES, + Qualification.NEW_NUMBER_IS_MORE_QUALIFIED, + Qualification.CURRENT_MORE_QUALIFIED + }) + private @interface Qualification { + /** Numbers are not duplicates (i.e. neither is more qualified than the other). */ + int NUMBERS_ARE_NOT_DUPLICATES = 0; + /** Number are duplicates and new number is more qualified than the existing number. */ + int NEW_NUMBER_IS_MORE_QUALIFIED = 1; + /** Numbers are duplicates but current/existing number is more qualified than new number. */ + int CURRENT_MORE_QUALIFIED = 2; + } + + /** + * @param cursor with projection {@link Projections#PHONE_PROJECTION}. + * @param query to filter cursor results. + */ + public SearchContactCursor(Cursor cursor, @Nullable String query) { + // TODO investigate copying this into a MatrixCursor and holding in memory + this.cursor = cursor; + filter(query); + } + + /** + * Filters out contacts that do not match the query. + * + *

      The query can have at least 1 of 3 forms: + * + *

        + *
      • A phone number + *
      • A T9 representation of a name (matches {@link QueryFilteringUtil#T9_PATTERN}). + *
      • A name + *
      + * + *

      A contact is considered a match if: + * + *

        + *
      • Its phone number contains the phone number query + *
      • Its name represented in T9 contains the T9 query + *
      • Its name contains the query + *
      + */ + public void filter(@Nullable String query) { + if (query == null) { + query = ""; + } + queryFilteredPositions.clear(); + + // On some devices, contacts have multiple rows with identical phone numbers. These numbers are + // considered duplicates. Since the order might not be guaranteed, we compare all of the numbers + // and hold onto the most qualified one as the one we want to display to the user. + // See #getQualification for details on how qualification is determined. + int previousMostQualifiedPosition = 0; + String previousName = ""; + String previousMostQualifiedNumber = ""; + + query = query.toLowerCase(); + cursor.moveToPosition(-1); + + while (cursor.moveToNext()) { + int position = cursor.getPosition(); + String currentNumber = cursor.getString(Projections.PHONE_NUMBER); + String currentName = cursor.getString(Projections.PHONE_DISPLAY_NAME); + + if (!previousName.equals(currentName)) { + previousName = currentName; + previousMostQualifiedNumber = currentNumber; + previousMostQualifiedPosition = position; + } else { + // Since the contact name is the same, check if this number is a duplicate + switch (getQualification(currentNumber, previousMostQualifiedNumber)) { + case Qualification.CURRENT_MORE_QUALIFIED: + // Number is a less qualified duplicate, ignore it. + continue; + case Qualification.NEW_NUMBER_IS_MORE_QUALIFIED: + // If number wasn't filtered out before, remove it and add it's more qualified version. + if (queryFilteredPositions.contains(previousMostQualifiedPosition)) { + queryFilteredPositions.remove(previousMostQualifiedPosition); + queryFilteredPositions.add(position); + } + previousMostQualifiedNumber = currentNumber; + previousMostQualifiedPosition = position; + continue; + case Qualification.NUMBERS_ARE_NOT_DUPLICATES: + default: + previousMostQualifiedNumber = currentNumber; + previousMostQualifiedPosition = position; + } + } + + if (TextUtils.isEmpty(query) + || QueryFilteringUtil.nameMatchesT9Query(query, previousName) + || QueryFilteringUtil.numberMatchesNumberQuery(query, previousMostQualifiedNumber) + || previousName.contains(query)) { + queryFilteredPositions.add(previousMostQualifiedPosition); + } + } + currentPosition = 0; + cursor.moveToFirst(); + } + + /** + * @param number that may or may not be more qualified than the existing most qualified number + * @param mostQualifiedNumber currently most qualified number associated with same contact + * @return {@link Qualification} where the more qualified number is the number with the most + * digits. If the digits are the same, the number with the most formatting is more qualified. + */ + private @Qualification int getQualification(String number, String mostQualifiedNumber) { + // Ignore formatting + String numberDigits = QueryFilteringUtil.digitsOnly(number); + String qualifiedNumberDigits = QueryFilteringUtil.digitsOnly(mostQualifiedNumber); + + // If the numbers are identical, return version with more formatting + if (qualifiedNumberDigits.equals(numberDigits)) { + if (mostQualifiedNumber.length() >= number.length()) { + return Qualification.CURRENT_MORE_QUALIFIED; + } else { + return Qualification.NEW_NUMBER_IS_MORE_QUALIFIED; + } + } + + // If one number is a suffix of another, then return the longer one. + // If they are equal, then return the current most qualified number. + if (qualifiedNumberDigits.endsWith(numberDigits)) { + return Qualification.CURRENT_MORE_QUALIFIED; + } + if (numberDigits.endsWith(qualifiedNumberDigits)) { + return Qualification.NEW_NUMBER_IS_MORE_QUALIFIED; + } + return Qualification.NUMBERS_ARE_NOT_DUPLICATES; + } + + @Override + public boolean moveToPosition(int position) { + currentPosition = position; + return currentPosition < getCount() + && cursor.moveToPosition(queryFilteredPositions.get(currentPosition)); + } + + @Override + public boolean move(int offset) { + currentPosition += offset; + return moveToPosition(currentPosition); + } + + @Override + public int getCount() { + return queryFilteredPositions.size(); + } + + @Override + public boolean isFirst() { + return currentPosition == 0; + } + + @Override + public boolean isLast() { + return currentPosition == getCount() - 1; + } + + @Override + public int getPosition() { + return currentPosition; + } + + @Override + public boolean moveToFirst() { + return moveToPosition(0); + } + + @Override + public boolean moveToLast() { + return moveToPosition(getCount() - 1); + } + + @Override + public boolean moveToNext() { + return moveToPosition(++currentPosition); + } + + @Override + public boolean moveToPrevious() { + return moveToPosition(--currentPosition); + } + + // Methods below simply call the corresponding method in cursor. + @Override + public boolean isBeforeFirst() { + return cursor.isBeforeFirst(); + } + + @Override + public boolean isAfterLast() { + return cursor.isAfterLast(); + } + + @Override + public int getColumnIndex(String columnName) { + return cursor.getColumnIndex(columnName); + } + + @Override + public int getColumnIndexOrThrow(String columnName) { + return cursor.getColumnIndexOrThrow(columnName); + } + + @Override + public String getColumnName(int columnIndex) { + return cursor.getColumnName(columnIndex); + } + + @Override + public String[] getColumnNames() { + return cursor.getColumnNames(); + } + + @Override + public int getColumnCount() { + return cursor.getColumnCount(); + } + + @Override + public byte[] getBlob(int columnIndex) { + return cursor.getBlob(columnIndex); + } + + @Override + public String getString(int columnIndex) { + return cursor.getString(columnIndex); + } + + @Override + public void copyStringToBuffer(int columnIndex, CharArrayBuffer buffer) { + cursor.copyStringToBuffer(columnIndex, buffer); + } + + @Override + public short getShort(int columnIndex) { + return cursor.getShort(columnIndex); + } + + @Override + public int getInt(int columnIndex) { + return cursor.getInt(columnIndex); + } + + @Override + public long getLong(int columnIndex) { + return cursor.getLong(columnIndex); + } + + @Override + public float getFloat(int columnIndex) { + return cursor.getFloat(columnIndex); + } + + @Override + public double getDouble(int columnIndex) { + return cursor.getDouble(columnIndex); + } + + @Override + public int getType(int columnIndex) { + return cursor.getType(columnIndex); + } + + @Override + public boolean isNull(int columnIndex) { + return cursor.isNull(columnIndex); + } + + @Override + public void deactivate() { + cursor.deactivate(); + } + + @Override + public boolean requery() { + return cursor.requery(); + } + + @Override + public void close() { + cursor.close(); + } + + @Override + public boolean isClosed() { + return cursor.isClosed(); + } + + @Override + public void registerContentObserver(ContentObserver observer) { + cursor.registerContentObserver(observer); + } + + @Override + public void unregisterContentObserver(ContentObserver observer) { + cursor.unregisterContentObserver(observer); + } + + @Override + public void registerDataSetObserver(DataSetObserver observer) { + cursor.registerDataSetObserver(observer); + } + + @Override + public void unregisterDataSetObserver(DataSetObserver observer) { + cursor.unregisterDataSetObserver(observer); + } + + @Override + public void setNotificationUri(ContentResolver cr, Uri uri) { + cursor.setNotificationUri(cr, uri); + } + + @Override + public Uri getNotificationUri() { + return cursor.getNotificationUri(); + } + + @Override + public boolean getWantsAllOnMoveCalls() { + return cursor.getWantsAllOnMoveCalls(); + } + + @Override + public void setExtras(Bundle extras) { + cursor.setExtras(extras); + } + + @Override + public Bundle getExtras() { + return cursor.getExtras(); + } + + @Override + public Bundle respond(Bundle extras) { + return cursor.respond(extras); + } +} diff --git a/java/com/android/dialer/searchfragment/cp2/SearchContactViewHolder.java b/java/com/android/dialer/searchfragment/cp2/SearchContactViewHolder.java new file mode 100644 index 000000000..5f06b5991 --- /dev/null +++ b/java/com/android/dialer/searchfragment/cp2/SearchContactViewHolder.java @@ -0,0 +1,204 @@ +/* + * Copyright (C) 2017 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.dialer.searchfragment.cp2; + +import android.content.Context; +import android.content.res.Resources; +import android.database.Cursor; +import android.net.Uri; +import android.provider.ContactsContract.CommonDataKinds.Phone; +import android.provider.ContactsContract.Contacts; +import android.support.annotation.IntDef; +import android.support.v7.widget.RecyclerView.ViewHolder; +import android.text.TextUtils; +import android.view.View; +import android.view.View.OnClickListener; +import android.widget.ImageView; +import android.widget.QuickContactBadge; +import android.widget.TextView; +import com.android.contacts.common.ContactPhotoManager; +import com.android.contacts.common.lettertiles.LetterTileDrawable; +import com.android.dialer.callintent.CallInitiationType.Type; +import com.android.dialer.callintent.CallIntentBuilder; +import com.android.dialer.common.Assert; +import com.android.dialer.searchfragment.common.Projections; +import com.android.dialer.searchfragment.common.QueryBoldingUtil; +import com.android.dialer.searchfragment.common.R; +import com.android.dialer.telecom.TelecomUtil; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; + +/** ViewHolder for a contact row. */ +public final class SearchContactViewHolder extends ViewHolder implements OnClickListener { + + /** IntDef for the different types of actions that can be shown. */ + @Retention(RetentionPolicy.SOURCE) + @IntDef({CallToAction.NONE, CallToAction.VIDEO_CALL, CallToAction.SHARE_AND_CALL}) + @interface CallToAction { + int NONE = 0; + int VIDEO_CALL = 1; + int SHARE_AND_CALL = 2; + } + + private final QuickContactBadge photo; + private final TextView nameOrNumberView; + private final TextView numberView; + private final ImageView callToActionView; + private final Context context; + + private String number; + private @CallToAction int currentAction; + + public SearchContactViewHolder(View view) { + super(view); + view.setOnClickListener(this); + photo = view.findViewById(R.id.photo); + nameOrNumberView = view.findViewById(R.id.primary); + numberView = view.findViewById(R.id.secondary); + callToActionView = view.findViewById(R.id.call_to_action); + context = view.getContext(); + } + + /** + * Binds the ViewHolder with a cursor from {@link SearchContactsCursorLoader} with the data found + * at the cursors set position. + */ + public void bind(Cursor cursor, String query) { + number = cursor.getString(Projections.PHONE_NUMBER); + String name = cursor.getString(Projections.PHONE_DISPLAY_NAME); + String label = getLabel(context.getResources(), cursor); + String secondaryInfo = + TextUtils.isEmpty(label) + ? number + : context.getString( + com.android.contacts.common.R.string.call_subject_type_and_number, label, number); + + nameOrNumberView.setText(QueryBoldingUtil.getNameWithQueryBolded(query, name)); + numberView.setText(QueryBoldingUtil.getNumberWithQueryBolded(query, secondaryInfo)); + setCallToAction(cursor); + + if (shouldShowPhoto(cursor, name)) { + nameOrNumberView.setVisibility(View.VISIBLE); + photo.setVisibility(View.VISIBLE); + String photoUri = cursor.getString(Projections.PHONE_PHOTO_URI); + ContactPhotoManager.getInstance(context) + .loadDialerThumbnailOrPhoto( + photo, + getContactUri(cursor), + cursor.getLong(Projections.PHONE_PHOTO_ID), + photoUri == null ? null : Uri.parse(photoUri), + name, + LetterTileDrawable.TYPE_DEFAULT); + } else { + nameOrNumberView.setVisibility(View.GONE); + photo.setVisibility(View.INVISIBLE); + } + } + + private boolean shouldShowPhoto(Cursor cursor, String currentName) { + int currentPosition = cursor.getPosition(); + if (currentPosition == 0) { + return true; + } else { + cursor.moveToPosition(currentPosition - 1); + String previousName = cursor.getString(Projections.PHONE_DISPLAY_NAME); + cursor.moveToPosition(currentPosition); + return !currentName.equals(previousName); + } + } + + private static Uri getContactUri(Cursor cursor) { + long contactId = cursor.getLong(Projections.PHONE_ID); + String lookupKey = cursor.getString(Projections.PHONE_LOOKUP_KEY); + return Contacts.getLookupUri(contactId, lookupKey); + } + + // TODO: handle CNAP and cequint types. + // TODO: unify this into a utility method with CallLogAdapter#getNumberType + private static String getLabel(Resources resources, Cursor cursor) { + int numberType = cursor.getInt(Projections.PHONE_TYPE); + String numberLabel = cursor.getString(Projections.PHONE_LABEL); + + // Returns empty label instead of "custom" if the custom label is empty. + if (numberType == Phone.TYPE_CUSTOM && TextUtils.isEmpty(numberLabel)) { + return ""; + } + return (String) Phone.getTypeLabel(resources, numberType, numberLabel); + } + + private void setCallToAction(Cursor cursor) { + currentAction = getCallToAction(cursor); + switch (currentAction) { + case CallToAction.NONE: + callToActionView.setVisibility(View.GONE); + callToActionView.setOnClickListener(null); + break; + case CallToAction.SHARE_AND_CALL: + callToActionView.setVisibility(View.VISIBLE); + callToActionView.setImageDrawable( + context.getDrawable(com.android.contacts.common.R.drawable.ic_phone_attach)); + callToActionView.setOnClickListener(this); + break; + case CallToAction.VIDEO_CALL: + callToActionView.setVisibility(View.VISIBLE); + callToActionView.setImageDrawable( + context.getDrawable(R.drawable.quantum_ic_videocam_white_24)); + callToActionView.setOnClickListener(this); + break; + default: + throw Assert.createIllegalStateFailException( + "Invalid Call to action type: " + currentAction); + } + } + + private static @CallToAction int getCallToAction(Cursor cursor) { + int carrierPresence = cursor.getInt(Projections.PHONE_CARRIER_PRESENCE); + if ((carrierPresence & Phone.CARRIER_PRESENCE_VT_CAPABLE) == 1) { + return CallToAction.VIDEO_CALL; + } + + // TODO: enriched calling + return CallToAction.NONE; + } + + @Override + public void onClick(View view) { + if (view == callToActionView) { + switch (currentAction) { + case CallToAction.SHARE_AND_CALL: + callToActionView.setVisibility(View.VISIBLE); + callToActionView.setImageDrawable( + context.getDrawable(com.android.contacts.common.R.drawable.ic_phone_attach)); + // TODO: open call composer. + break; + case CallToAction.VIDEO_CALL: + callToActionView.setVisibility(View.VISIBLE); + callToActionView.setImageDrawable( + context.getDrawable(R.drawable.quantum_ic_videocam_white_24)); + // TODO: place a video call + break; + case CallToAction.NONE: + default: + throw Assert.createIllegalStateFailException( + "Invalid Call to action type: " + currentAction); + } + } else { + // TODO: set the correct call initiation type. + TelecomUtil.placeCall(context, new CallIntentBuilder(number, Type.REGULAR_SEARCH).build()); + } + } +} diff --git a/java/com/android/dialer/searchfragment/cp2/SearchContactsCursorLoader.java b/java/com/android/dialer/searchfragment/cp2/SearchContactsCursorLoader.java new file mode 100644 index 000000000..c72f28b25 --- /dev/null +++ b/java/com/android/dialer/searchfragment/cp2/SearchContactsCursorLoader.java @@ -0,0 +1,42 @@ +/* + * Copyright (C) 2017 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.dialer.searchfragment.cp2; + +import android.content.Context; +import android.content.CursorLoader; +import android.database.Cursor; +import android.provider.ContactsContract.CommonDataKinds.Phone; +import com.android.dialer.searchfragment.common.Projections; + +/** Cursor Loader for CP2 contacts. */ +public final class SearchContactsCursorLoader extends CursorLoader { + + public SearchContactsCursorLoader(Context context) { + super( + context, + Phone.CONTENT_URI, + Projections.PHONE_PROJECTION, + null, + null, + Phone.SORT_KEY_PRIMARY + " ASC"); + } + + @Override + public Cursor loadInBackground() { + return new SearchContactCursor(super.loadInBackground(), null); + } +} diff --git a/java/com/android/dialer/searchfragment/list/AndroidManifest.xml b/java/com/android/dialer/searchfragment/list/AndroidManifest.xml new file mode 100644 index 000000000..e0890cc2c --- /dev/null +++ b/java/com/android/dialer/searchfragment/list/AndroidManifest.xml @@ -0,0 +1,16 @@ + + \ No newline at end of file diff --git a/java/com/android/dialer/searchfragment/list/HeaderViewHolder.java b/java/com/android/dialer/searchfragment/list/HeaderViewHolder.java new file mode 100644 index 000000000..dd35b13ee --- /dev/null +++ b/java/com/android/dialer/searchfragment/list/HeaderViewHolder.java @@ -0,0 +1,36 @@ +/* + * Copyright (C) 2017 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.dialer.searchfragment.list; + +import android.support.v7.widget.RecyclerView; +import android.view.View; +import android.widget.TextView; + +/** ViewHolder for header rows in {@link NewSearchFragment}. */ +final class HeaderViewHolder extends RecyclerView.ViewHolder { + + private final TextView header; + + HeaderViewHolder(View view) { + super(view); + header = view.findViewById(R.id.header); + } + + public void setHeader(String header) { + this.header.setText(header); + } +} diff --git a/java/com/android/dialer/searchfragment/list/NewSearchFragment.java b/java/com/android/dialer/searchfragment/list/NewSearchFragment.java new file mode 100644 index 000000000..fcc87c386 --- /dev/null +++ b/java/com/android/dialer/searchfragment/list/NewSearchFragment.java @@ -0,0 +1,125 @@ +/* + * Copyright (C) 2017 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.dialer.searchfragment.list; + +import android.app.Fragment; +import android.app.LoaderManager.LoaderCallbacks; +import android.content.Loader; +import android.database.Cursor; +import android.os.Bundle; +import android.support.annotation.Nullable; +import android.support.v7.widget.LinearLayoutManager; +import android.support.v7.widget.RecyclerView; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import com.android.contacts.common.extensions.PhoneDirectoryExtenderAccessor; +import com.android.dialer.common.concurrent.ThreadUtil; +import com.android.dialer.searchfragment.cp2.SearchContactsCursorLoader; +import com.android.dialer.searchfragment.nearbyplaces.NearbyPlacesCursorLoader; + +/** Fragment used for searching contacts. */ +public final class NewSearchFragment extends Fragment implements LoaderCallbacks { + + // Since some of our queries can generate network requests, we should delay them until the user + // stops typing to prevent generating too much network traffic. + private static final int NETWORK_SEARCH_DELAY_MILLIS = 300; + + private static final int CONTACTS_LOADER_ID = 0; + private static final int NEARBY_PLACES_ID = 1; + + private RecyclerView recyclerView; + private SearchAdapter adapter; + private String query; + + private final Runnable loadNearbyPlacesRunnable = + () -> getLoaderManager().restartLoader(NEARBY_PLACES_ID, null, this); + + @Nullable + @Override + public View onCreateView( + LayoutInflater inflater, @Nullable ViewGroup parent, @Nullable Bundle bundle) { + getLoaderManager().initLoader(0, null, this); + View view = inflater.inflate(R.layout.fragment_search, parent, false); + adapter = new SearchAdapter(getContext()); + recyclerView = view.findViewById(R.id.recycler_view); + recyclerView.setLayoutManager(new LinearLayoutManager(getContext())); + recyclerView.setAdapter(adapter); + + getLoaderManager().initLoader(CONTACTS_LOADER_ID, null, this); + loadNearbyPlacesCursor(); + return view; + } + + @Override + public Loader onCreateLoader(int id, Bundle bundle) { + // TODO add enterprise loader + if (id == CONTACTS_LOADER_ID) { + return new SearchContactsCursorLoader(getContext()); + } else if (id == NEARBY_PLACES_ID) { + return new NearbyPlacesCursorLoader(getContext(), query); + } else { + throw new IllegalStateException("Invalid loader id: " + id); + } + } + + @Override + public void onLoadFinished(Loader loader, Cursor cursor) { + if (loader instanceof SearchContactsCursorLoader) { + adapter.setContactsCursor(cursor); + } else if (loader instanceof NearbyPlacesCursorLoader) { + adapter.setNearbyPlacesCursor(cursor); + } else { + throw new IllegalStateException("Invalid loader: " + loader); + } + } + + @Override + public void onLoaderReset(Loader loader) { + adapter.clear(); + recyclerView.setAdapter(null); + } + + public void setQuery(String query) { + this.query = query; + if (adapter != null) { + adapter.setQuery(query); + loadNearbyPlacesCursor(); + } + } + + @Override + public void onDestroy() { + super.onDestroy(); + // close adapters + adapter.setNearbyPlacesCursor(null); + adapter.setContactsCursor(null); + ThreadUtil.getUiThreadHandler().removeCallbacks(loadNearbyPlacesRunnable); + } + + private void loadNearbyPlacesCursor() { + // Cancel existing load if one exists. + ThreadUtil.getUiThreadHandler().removeCallbacks(loadNearbyPlacesRunnable); + + // If nearby places is not enabled, do not try to load them. + if (!PhoneDirectoryExtenderAccessor.get(getContext()).isEnabled(getContext())) { + return; + } + ThreadUtil.getUiThreadHandler() + .postDelayed(loadNearbyPlacesRunnable, NETWORK_SEARCH_DELAY_MILLIS); + } +} diff --git a/java/com/android/dialer/searchfragment/list/SearchAdapter.java b/java/com/android/dialer/searchfragment/list/SearchAdapter.java new file mode 100644 index 000000000..023513e47 --- /dev/null +++ b/java/com/android/dialer/searchfragment/list/SearchAdapter.java @@ -0,0 +1,108 @@ +/* + * Copyright (C) 2017 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.dialer.searchfragment.list; + +import android.content.Context; +import android.database.Cursor; +import android.support.v7.widget.RecyclerView; +import android.support.v7.widget.RecyclerView.ViewHolder; +import android.view.LayoutInflater; +import android.view.ViewGroup; +import com.android.dialer.common.Assert; +import com.android.dialer.searchfragment.cp2.SearchContactViewHolder; +import com.android.dialer.searchfragment.list.SearchCursorManager.RowType; +import com.android.dialer.searchfragment.nearbyplaces.NearbyPlaceViewHolder; + +/** RecyclerView adapter for {@link NewSearchFragment}. */ +class SearchAdapter extends RecyclerView.Adapter { + + private final SearchCursorManager searchCursorManager; + private final Context context; + + private String query; + + SearchAdapter(Context context) { + searchCursorManager = new SearchCursorManager(); + this.context = context; + } + + @Override + public ViewHolder onCreateViewHolder(ViewGroup root, @RowType int rowType) { + switch (rowType) { + case RowType.CONTACT_ROW: + return new SearchContactViewHolder( + LayoutInflater.from(context).inflate(R.layout.search_contact_row, root, false)); + case RowType.NEARBY_PLACES_ROW: + return new NearbyPlaceViewHolder( + LayoutInflater.from(context).inflate(R.layout.search_contact_row, root, false)); + case RowType.DIRECTORY_HEADER: + case RowType.NEARBY_PLACES_HEADER: + return new HeaderViewHolder( + LayoutInflater.from(context).inflate(R.layout.header_layout, root, false)); + case RowType.DIRECTORY_ROW: // TODO: add directory rows to search + case RowType.INVALID: + default: + throw Assert.createIllegalStateFailException("Invalid RowType: " + rowType); + } + } + + @Override + public @RowType int getItemViewType(int position) { + return searchCursorManager.getRowType(position); + } + + @Override + public void onBindViewHolder(ViewHolder holder, int position) { + if (holder instanceof SearchContactViewHolder) { + Cursor cursor = searchCursorManager.getCursor(position); + ((SearchContactViewHolder) holder).bind(cursor, query); + } else if (holder instanceof NearbyPlaceViewHolder) { + Cursor cursor = searchCursorManager.getCursor(position); + ((NearbyPlaceViewHolder) holder).bind(cursor, query); + } else if (holder instanceof HeaderViewHolder) { + String header = context.getString(searchCursorManager.getHeaderText(position)); + ((HeaderViewHolder) holder).setHeader(header); + } else { + throw Assert.createIllegalStateFailException("Invalid ViewHolder: " + holder); + } + } + + void setContactsCursor(Cursor cursor) { + searchCursorManager.setContactsCursor(cursor); + notifyDataSetChanged(); + } + + void clear() { + searchCursorManager.clear(); + } + + @Override + public int getItemCount() { + return searchCursorManager.getCount(); + } + + public void setQuery(String query) { + this.query = query; + searchCursorManager.setQuery(query); + notifyDataSetChanged(); + } + + public void setNearbyPlacesCursor(Cursor nearbyPlacesCursor) { + searchCursorManager.setNearbyPlacesCursor(nearbyPlacesCursor); + notifyDataSetChanged(); + } +} diff --git a/java/com/android/dialer/searchfragment/list/SearchCursorManager.java b/java/com/android/dialer/searchfragment/list/SearchCursorManager.java new file mode 100644 index 000000000..216a9ada9 --- /dev/null +++ b/java/com/android/dialer/searchfragment/list/SearchCursorManager.java @@ -0,0 +1,273 @@ +/* + * Copyright (C) 2017 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.dialer.searchfragment.list; + +import android.database.Cursor; +import android.support.annotation.IntDef; +import android.support.annotation.StringRes; +import com.android.dialer.common.Assert; +import com.android.dialer.searchfragment.cp2.SearchContactCursor; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; + +/** + * Manages all of the cursors needed for {@link SearchAdapter}. + * + *

      This class accepts three cursors: + * + *

        + *
      • A contacts cursor {@link #setContactsCursor(Cursor)} + *
      • A google search results cursor {@link #setNearbyPlacesCursor(Cursor)} + *
      • A work directory cursor {@link #setCorpDirectoryCursor(Cursor)} + *
      + * + *

      The key purpose of this class is to compose three aforementioned cursors together to function + * as one cursor. The key methods needed to utilize this class as a cursor are: + * + *

        + *
      • {@link #getCursor(int)} + *
      • {@link #getCount()} + *
      • {@link #getRowType(int)} + *
      + */ +final class SearchCursorManager { + + /** IntDef for the different types of rows that can be shown when searching. */ + @Retention(RetentionPolicy.SOURCE) + @IntDef({ + SearchCursorManager.RowType.INVALID, + SearchCursorManager.RowType.CONTACT_ROW, + SearchCursorManager.RowType.NEARBY_PLACES_HEADER, + SearchCursorManager.RowType.NEARBY_PLACES_ROW, + SearchCursorManager.RowType.DIRECTORY_HEADER, + SearchCursorManager.RowType.DIRECTORY_ROW + }) + @interface RowType { + int INVALID = 0; + /** A row containing contact information for contacts stored locally on device. */ + int CONTACT_ROW = 1; + /** Header to mark the end of contact rows and start of nearby places rows. */ + int NEARBY_PLACES_HEADER = 2; + /** A row containing nearby places information/search results. */ + int NEARBY_PLACES_ROW = 3; + /** Header to mark the end of the previous row set and start of directory rows. */ + int DIRECTORY_HEADER = 4; + /** A row containing contact information for contacts stored externally in corp directories. */ + int DIRECTORY_ROW = 5; + } + + private Cursor contactsCursor = null; + private Cursor nearbyPlacesCursor = null; + private Cursor corpDirectoryCursor = null; + + void setContactsCursor(Cursor cursor) { + if (cursor == contactsCursor) { + return; + } + + if (contactsCursor != null && !contactsCursor.isClosed()) { + contactsCursor.close(); + } + + if (cursor != null && cursor.getCount() > 0) { + contactsCursor = cursor; + } else { + contactsCursor = null; + } + } + + void setNearbyPlacesCursor(Cursor cursor) { + if (cursor == nearbyPlacesCursor) { + return; + } + + if (nearbyPlacesCursor != null && !nearbyPlacesCursor.isClosed()) { + nearbyPlacesCursor.close(); + } + + if (cursor != null && cursor.getCount() > 0) { + nearbyPlacesCursor = cursor; + } else { + nearbyPlacesCursor = null; + } + } + + void setCorpDirectoryCursor(Cursor cursor) { + if (cursor == corpDirectoryCursor) { + return; + } + + if (corpDirectoryCursor != null && !corpDirectoryCursor.isClosed()) { + corpDirectoryCursor.close(); + } + + if (cursor != null && cursor.getCount() > 0) { + corpDirectoryCursor = cursor; + } else { + corpDirectoryCursor = null; + } + } + + void setQuery(String query) { + if (contactsCursor != null) { + // TODO: abstract this + ((SearchContactCursor) contactsCursor).filter(query); + } + } + + /** @return the sum of counts of all cursors, including headers. */ + int getCount() { + int count = 0; + if (contactsCursor != null) { + count += contactsCursor.getCount(); + } + + if (nearbyPlacesCursor != null) { + count++; // header + count += nearbyPlacesCursor.getCount(); + } + + if (corpDirectoryCursor != null) { + count++; // header + count += corpDirectoryCursor.getCount(); + } + + return count; + } + + @RowType + int getRowType(int position) { + if (contactsCursor != null) { + position -= contactsCursor.getCount(); + + if (position < 0) { + return SearchCursorManager.RowType.CONTACT_ROW; + } + } + + if (nearbyPlacesCursor != null) { + if (position == 0) { + return SearchCursorManager.RowType.NEARBY_PLACES_HEADER; + } else { + position--; // header + } + + position -= nearbyPlacesCursor.getCount(); + + if (position < 0) { + return SearchCursorManager.RowType.NEARBY_PLACES_ROW; + } + } + + if (corpDirectoryCursor != null) { + if (position == 0) { + return SearchCursorManager.RowType.DIRECTORY_HEADER; + } else { + position--; // header + } + + position -= corpDirectoryCursor.getCount(); + + if (position < 0) { + return SearchCursorManager.RowType.DIRECTORY_ROW; + } + } + + throw Assert.createIllegalStateFailException("No valid row type."); + } + + /** + * Gets cursor corresponding to position in coelesced list of search cursors. Callers should + * ensure that {@link #getRowType(int)} doesn't correspond to header position, otherwise an + * exception will be thrown. + * + * @param position in coalecsed list of search cursors + * @return Cursor moved to position specific to passed in position. + */ + Cursor getCursor(int position) { + if (contactsCursor != null) { + int count = contactsCursor.getCount(); + + if (position - count < 0) { + contactsCursor.moveToPosition(position); + return contactsCursor; + } + position -= count; + } + + if (nearbyPlacesCursor != null) { + Assert.checkArgument(position != 0, "No valid cursor, position is nearby places header."); + position--; // header + int count = nearbyPlacesCursor.getCount(); + + if (position - count < 0) { + nearbyPlacesCursor.moveToPosition(position); + return nearbyPlacesCursor; + } + position -= count; + } + + if (corpDirectoryCursor != null) { + Assert.checkArgument(position != 0, "No valid cursor, position is directory search header."); + position--; // header + int count = corpDirectoryCursor.getCount(); + + if (position - count < 0) { + corpDirectoryCursor.moveToPosition(position); + return corpDirectoryCursor; + } + position -= count; + } + + throw Assert.createIllegalStateFailException("No valid cursor."); + } + + @StringRes + int getHeaderText(int position) { + @RowType int rowType = getRowType(position); + switch (rowType) { + case RowType.NEARBY_PLACES_HEADER: + return R.string.nearby_places; + case RowType.DIRECTORY_HEADER: // TODO + case RowType.DIRECTORY_ROW: + case RowType.CONTACT_ROW: + case RowType.NEARBY_PLACES_ROW: + case RowType.INVALID: + default: + throw Assert.createIllegalStateFailException( + "Invalid row type, position " + position + " is rowtype " + rowType); + } + } + + /** removes all cursors. */ + void clear() { + if (contactsCursor != null) { + contactsCursor.close(); + contactsCursor = null; + } + + if (nearbyPlacesCursor != null) { + nearbyPlacesCursor.close(); + nearbyPlacesCursor = null; + } + + if (corpDirectoryCursor != null) { + corpDirectoryCursor.close(); + corpDirectoryCursor = null; + } + } +} diff --git a/java/com/android/dialer/searchfragment/list/res/layout/fragment_search.xml b/java/com/android/dialer/searchfragment/list/res/layout/fragment_search.xml new file mode 100644 index 000000000..06f234889 --- /dev/null +++ b/java/com/android/dialer/searchfragment/list/res/layout/fragment_search.xml @@ -0,0 +1,21 @@ + + + diff --git a/java/com/android/dialer/searchfragment/list/res/layout/header_layout.xml b/java/com/android/dialer/searchfragment/list/res/layout/header_layout.xml new file mode 100644 index 000000000..36af42ed9 --- /dev/null +++ b/java/com/android/dialer/searchfragment/list/res/layout/header_layout.xml @@ -0,0 +1,22 @@ + + + diff --git a/java/com/android/dialer/searchfragment/nearbyplaces/AndroidManifest.xml b/java/com/android/dialer/searchfragment/nearbyplaces/AndroidManifest.xml new file mode 100644 index 000000000..178cd83c3 --- /dev/null +++ b/java/com/android/dialer/searchfragment/nearbyplaces/AndroidManifest.xml @@ -0,0 +1,16 @@ + + \ No newline at end of file diff --git a/java/com/android/dialer/searchfragment/nearbyplaces/NearbyPlaceViewHolder.java b/java/com/android/dialer/searchfragment/nearbyplaces/NearbyPlaceViewHolder.java new file mode 100644 index 000000000..b6e5a9013 --- /dev/null +++ b/java/com/android/dialer/searchfragment/nearbyplaces/NearbyPlaceViewHolder.java @@ -0,0 +1,90 @@ +/* + * Copyright (C) 2017 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.dialer.searchfragment.nearbyplaces; + +import android.content.Context; +import android.database.Cursor; +import android.net.Uri; +import android.provider.ContactsContract; +import android.support.v7.widget.RecyclerView; +import android.view.View; +import android.widget.QuickContactBadge; +import android.widget.TextView; +import com.android.contacts.common.ContactPhotoManager; +import com.android.contacts.common.lettertiles.LetterTileDrawable; +import com.android.dialer.callintent.CallInitiationType; +import com.android.dialer.callintent.CallIntentBuilder; +import com.android.dialer.searchfragment.common.Projections; +import com.android.dialer.searchfragment.common.QueryBoldingUtil; +import com.android.dialer.searchfragment.common.R; +import com.android.dialer.telecom.TelecomUtil; + +/** ViewHolder for a nearby place row. */ +public final class NearbyPlaceViewHolder extends RecyclerView.ViewHolder + implements View.OnClickListener { + + private final Context context; + private final TextView placeName; + private final TextView placeAddress; + private final QuickContactBadge photo; + + private String number; + + public NearbyPlaceViewHolder(View view) { + super(view); + view.setOnClickListener(this); + photo = view.findViewById(R.id.photo); + placeName = view.findViewById(R.id.primary); + placeAddress = view.findViewById(R.id.secondary); + context = view.getContext(); + } + + /** + * Binds the ViewHolder with a cursor from {@link NearbyPlacesCursorLoader} with the data found at + * the cursors set position. + */ + public void bind(Cursor cursor, String query) { + number = cursor.getString(Projections.PHONE_NUMBER); + String name = cursor.getString(Projections.PHONE_DISPLAY_NAME); + String address = cursor.getString(Projections.PHONE_LABEL); + + placeName.setText(QueryBoldingUtil.getNameWithQueryBolded(query, name)); + placeAddress.setText(QueryBoldingUtil.getNameWithQueryBolded(query, address)); + + String photoUri = cursor.getString(Projections.PHONE_PHOTO_URI); + ContactPhotoManager.getInstance(context) + .loadDialerThumbnailOrPhoto( + photo, + getContactUri(cursor), + cursor.getLong(Projections.PHONE_PHOTO_ID), + photoUri == null ? null : Uri.parse(photoUri), + name, + LetterTileDrawable.TYPE_DEFAULT); + } + + private static Uri getContactUri(Cursor cursor) { + long contactId = cursor.getLong(Projections.PHONE_ID); + String lookupKey = cursor.getString(Projections.PHONE_LOOKUP_KEY); + return ContactsContract.Contacts.getLookupUri(contactId, lookupKey); + } + + @Override + public void onClick(View v) { + TelecomUtil.placeCall( + context, new CallIntentBuilder(number, CallInitiationType.Type.REGULAR_SEARCH).build()); + } +} diff --git a/java/com/android/dialer/searchfragment/nearbyplaces/NearbyPlacesCursorLoader.java b/java/com/android/dialer/searchfragment/nearbyplaces/NearbyPlacesCursorLoader.java new file mode 100644 index 000000000..9f3193e92 --- /dev/null +++ b/java/com/android/dialer/searchfragment/nearbyplaces/NearbyPlacesCursorLoader.java @@ -0,0 +1,43 @@ +/* + * Copyright (C) 2017 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.dialer.searchfragment.nearbyplaces; + +import android.content.Context; +import android.content.CursorLoader; +import android.net.Uri; +import android.provider.ContactsContract; +import com.android.contacts.common.extensions.PhoneDirectoryExtenderAccessor; +import com.android.dialer.searchfragment.common.Projections; + +/** Cursor loader for nearby places search results. */ +public final class NearbyPlacesCursorLoader extends CursorLoader { + + private static final String MAX_RESULTS = "3"; + + public NearbyPlacesCursorLoader(Context context, String query) { + super(context, getContentUri(context, query), Projections.PHONE_PROJECTION, null, null, null); + } + + private static Uri getContentUri(Context context, String query) { + return PhoneDirectoryExtenderAccessor.get(context) + .getContentUri() + .buildUpon() + .appendPath(query) + .appendQueryParameter(ContactsContract.LIMIT_PARAM_KEY, MAX_RESULTS) + .build(); + } +} diff --git a/java/com/android/dialer/searchfragment/nearbyplaces/res/values-af/strings.xml b/java/com/android/dialer/searchfragment/nearbyplaces/res/values-af/strings.xml new file mode 100644 index 000000000..21eb4b11d --- /dev/null +++ b/java/com/android/dialer/searchfragment/nearbyplaces/res/values-af/strings.xml @@ -0,0 +1,21 @@ + + + + + "Nabygeleë plekke" + diff --git a/java/com/android/dialer/searchfragment/nearbyplaces/res/values-am/strings.xml b/java/com/android/dialer/searchfragment/nearbyplaces/res/values-am/strings.xml new file mode 100644 index 000000000..8039ea04a --- /dev/null +++ b/java/com/android/dialer/searchfragment/nearbyplaces/res/values-am/strings.xml @@ -0,0 +1,22 @@ + + + + + + + diff --git a/java/com/android/dialer/searchfragment/nearbyplaces/res/values-ar/strings.xml b/java/com/android/dialer/searchfragment/nearbyplaces/res/values-ar/strings.xml new file mode 100644 index 000000000..d68b4d1ee --- /dev/null +++ b/java/com/android/dialer/searchfragment/nearbyplaces/res/values-ar/strings.xml @@ -0,0 +1,21 @@ + + + + + "الأماكن المجاورة" + diff --git a/java/com/android/dialer/searchfragment/nearbyplaces/res/values-az/strings.xml b/java/com/android/dialer/searchfragment/nearbyplaces/res/values-az/strings.xml new file mode 100644 index 000000000..8039ea04a --- /dev/null +++ b/java/com/android/dialer/searchfragment/nearbyplaces/res/values-az/strings.xml @@ -0,0 +1,22 @@ + + + + + + + diff --git a/java/com/android/dialer/searchfragment/nearbyplaces/res/values-b+sr+Latn/strings.xml b/java/com/android/dialer/searchfragment/nearbyplaces/res/values-b+sr+Latn/strings.xml new file mode 100644 index 000000000..bb9f06fe7 --- /dev/null +++ b/java/com/android/dialer/searchfragment/nearbyplaces/res/values-b+sr+Latn/strings.xml @@ -0,0 +1,21 @@ + + + + + "Obližnja mesta" + diff --git a/java/com/android/dialer/searchfragment/nearbyplaces/res/values-be/strings.xml b/java/com/android/dialer/searchfragment/nearbyplaces/res/values-be/strings.xml new file mode 100644 index 000000000..8039ea04a --- /dev/null +++ b/java/com/android/dialer/searchfragment/nearbyplaces/res/values-be/strings.xml @@ -0,0 +1,22 @@ + + + + + + + diff --git a/java/com/android/dialer/searchfragment/nearbyplaces/res/values-bg/strings.xml b/java/com/android/dialer/searchfragment/nearbyplaces/res/values-bg/strings.xml new file mode 100644 index 000000000..e8839532a --- /dev/null +++ b/java/com/android/dialer/searchfragment/nearbyplaces/res/values-bg/strings.xml @@ -0,0 +1,21 @@ + + + + + "Места в района" + diff --git a/java/com/android/dialer/searchfragment/nearbyplaces/res/values-bn/strings.xml b/java/com/android/dialer/searchfragment/nearbyplaces/res/values-bn/strings.xml new file mode 100644 index 000000000..4bc3fedb4 --- /dev/null +++ b/java/com/android/dialer/searchfragment/nearbyplaces/res/values-bn/strings.xml @@ -0,0 +1,21 @@ + + + + + "আশপাশের জায়গাগুলি" + diff --git a/java/com/android/dialer/searchfragment/nearbyplaces/res/values-bs/strings.xml b/java/com/android/dialer/searchfragment/nearbyplaces/res/values-bs/strings.xml new file mode 100644 index 000000000..f3fb92187 --- /dev/null +++ b/java/com/android/dialer/searchfragment/nearbyplaces/res/values-bs/strings.xml @@ -0,0 +1,21 @@ + + + + + "Mjesta u blizini" + diff --git a/java/com/android/dialer/searchfragment/nearbyplaces/res/values-ca/strings.xml b/java/com/android/dialer/searchfragment/nearbyplaces/res/values-ca/strings.xml new file mode 100644 index 000000000..8039ea04a --- /dev/null +++ b/java/com/android/dialer/searchfragment/nearbyplaces/res/values-ca/strings.xml @@ -0,0 +1,22 @@ + + + + + + + diff --git a/java/com/android/dialer/searchfragment/nearbyplaces/res/values-cs/strings.xml b/java/com/android/dialer/searchfragment/nearbyplaces/res/values-cs/strings.xml new file mode 100644 index 000000000..8039ea04a --- /dev/null +++ b/java/com/android/dialer/searchfragment/nearbyplaces/res/values-cs/strings.xml @@ -0,0 +1,22 @@ + + + + + + + diff --git a/java/com/android/dialer/searchfragment/nearbyplaces/res/values-da/strings.xml b/java/com/android/dialer/searchfragment/nearbyplaces/res/values-da/strings.xml new file mode 100644 index 000000000..8039ea04a --- /dev/null +++ b/java/com/android/dialer/searchfragment/nearbyplaces/res/values-da/strings.xml @@ -0,0 +1,22 @@ + + + + + + + diff --git a/java/com/android/dialer/searchfragment/nearbyplaces/res/values-de/strings.xml b/java/com/android/dialer/searchfragment/nearbyplaces/res/values-de/strings.xml new file mode 100644 index 000000000..9e2db4a32 --- /dev/null +++ b/java/com/android/dialer/searchfragment/nearbyplaces/res/values-de/strings.xml @@ -0,0 +1,21 @@ + + + + + "Orte in der Nähe" + diff --git a/java/com/android/dialer/searchfragment/nearbyplaces/res/values-el/strings.xml b/java/com/android/dialer/searchfragment/nearbyplaces/res/values-el/strings.xml new file mode 100644 index 000000000..8039ea04a --- /dev/null +++ b/java/com/android/dialer/searchfragment/nearbyplaces/res/values-el/strings.xml @@ -0,0 +1,22 @@ + + + + + + + diff --git a/java/com/android/dialer/searchfragment/nearbyplaces/res/values-en-rAU/strings.xml b/java/com/android/dialer/searchfragment/nearbyplaces/res/values-en-rAU/strings.xml new file mode 100644 index 000000000..077827315 --- /dev/null +++ b/java/com/android/dialer/searchfragment/nearbyplaces/res/values-en-rAU/strings.xml @@ -0,0 +1,21 @@ + + + + + "Places nearby" + diff --git a/java/com/android/dialer/searchfragment/nearbyplaces/res/values-en-rGB/strings.xml b/java/com/android/dialer/searchfragment/nearbyplaces/res/values-en-rGB/strings.xml new file mode 100644 index 000000000..077827315 --- /dev/null +++ b/java/com/android/dialer/searchfragment/nearbyplaces/res/values-en-rGB/strings.xml @@ -0,0 +1,21 @@ + + + + + "Places nearby" + diff --git a/java/com/android/dialer/searchfragment/nearbyplaces/res/values-en-rIN/strings.xml b/java/com/android/dialer/searchfragment/nearbyplaces/res/values-en-rIN/strings.xml new file mode 100644 index 000000000..077827315 --- /dev/null +++ b/java/com/android/dialer/searchfragment/nearbyplaces/res/values-en-rIN/strings.xml @@ -0,0 +1,21 @@ + + + + + "Places nearby" + diff --git a/java/com/android/dialer/searchfragment/nearbyplaces/res/values-es-rUS/strings.xml b/java/com/android/dialer/searchfragment/nearbyplaces/res/values-es-rUS/strings.xml new file mode 100644 index 000000000..8039ea04a --- /dev/null +++ b/java/com/android/dialer/searchfragment/nearbyplaces/res/values-es-rUS/strings.xml @@ -0,0 +1,22 @@ + + + + + + + diff --git a/java/com/android/dialer/searchfragment/nearbyplaces/res/values-es/strings.xml b/java/com/android/dialer/searchfragment/nearbyplaces/res/values-es/strings.xml new file mode 100644 index 000000000..fada6bcaf --- /dev/null +++ b/java/com/android/dialer/searchfragment/nearbyplaces/res/values-es/strings.xml @@ -0,0 +1,21 @@ + + + + + "Sitios cercanos" + diff --git a/java/com/android/dialer/searchfragment/nearbyplaces/res/values-et/strings.xml b/java/com/android/dialer/searchfragment/nearbyplaces/res/values-et/strings.xml new file mode 100644 index 000000000..8039ea04a --- /dev/null +++ b/java/com/android/dialer/searchfragment/nearbyplaces/res/values-et/strings.xml @@ -0,0 +1,22 @@ + + + + + + + diff --git a/java/com/android/dialer/searchfragment/nearbyplaces/res/values-eu/strings.xml b/java/com/android/dialer/searchfragment/nearbyplaces/res/values-eu/strings.xml new file mode 100644 index 000000000..8039ea04a --- /dev/null +++ b/java/com/android/dialer/searchfragment/nearbyplaces/res/values-eu/strings.xml @@ -0,0 +1,22 @@ + + + + + + + diff --git a/java/com/android/dialer/searchfragment/nearbyplaces/res/values-fa/strings.xml b/java/com/android/dialer/searchfragment/nearbyplaces/res/values-fa/strings.xml new file mode 100644 index 000000000..8039ea04a --- /dev/null +++ b/java/com/android/dialer/searchfragment/nearbyplaces/res/values-fa/strings.xml @@ -0,0 +1,22 @@ + + + + + + + diff --git a/java/com/android/dialer/searchfragment/nearbyplaces/res/values-fi/strings.xml b/java/com/android/dialer/searchfragment/nearbyplaces/res/values-fi/strings.xml new file mode 100644 index 000000000..8039ea04a --- /dev/null +++ b/java/com/android/dialer/searchfragment/nearbyplaces/res/values-fi/strings.xml @@ -0,0 +1,22 @@ + + + + + + + diff --git a/java/com/android/dialer/searchfragment/nearbyplaces/res/values-fr-rCA/strings.xml b/java/com/android/dialer/searchfragment/nearbyplaces/res/values-fr-rCA/strings.xml new file mode 100644 index 000000000..d65e7bd55 --- /dev/null +++ b/java/com/android/dialer/searchfragment/nearbyplaces/res/values-fr-rCA/strings.xml @@ -0,0 +1,21 @@ + + + + + "Adresses à proximité" + diff --git a/java/com/android/dialer/searchfragment/nearbyplaces/res/values-fr/strings.xml b/java/com/android/dialer/searchfragment/nearbyplaces/res/values-fr/strings.xml new file mode 100644 index 000000000..d65e7bd55 --- /dev/null +++ b/java/com/android/dialer/searchfragment/nearbyplaces/res/values-fr/strings.xml @@ -0,0 +1,21 @@ + + + + + "Adresses à proximité" + diff --git a/java/com/android/dialer/searchfragment/nearbyplaces/res/values-gl/strings.xml b/java/com/android/dialer/searchfragment/nearbyplaces/res/values-gl/strings.xml new file mode 100644 index 000000000..5a4cce7e0 --- /dev/null +++ b/java/com/android/dialer/searchfragment/nearbyplaces/res/values-gl/strings.xml @@ -0,0 +1,21 @@ + + + + + "Lugares próximos" + diff --git a/java/com/android/dialer/searchfragment/nearbyplaces/res/values-gu/strings.xml b/java/com/android/dialer/searchfragment/nearbyplaces/res/values-gu/strings.xml new file mode 100644 index 000000000..ee32e466f --- /dev/null +++ b/java/com/android/dialer/searchfragment/nearbyplaces/res/values-gu/strings.xml @@ -0,0 +1,21 @@ + + + + + "નજીકના સ્થળો" + diff --git a/java/com/android/dialer/searchfragment/nearbyplaces/res/values-hi/strings.xml b/java/com/android/dialer/searchfragment/nearbyplaces/res/values-hi/strings.xml new file mode 100644 index 000000000..079c03e04 --- /dev/null +++ b/java/com/android/dialer/searchfragment/nearbyplaces/res/values-hi/strings.xml @@ -0,0 +1,21 @@ + + + + + "आस-पास के स्थल" + diff --git a/java/com/android/dialer/searchfragment/nearbyplaces/res/values-hr/strings.xml b/java/com/android/dialer/searchfragment/nearbyplaces/res/values-hr/strings.xml new file mode 100644 index 000000000..8039ea04a --- /dev/null +++ b/java/com/android/dialer/searchfragment/nearbyplaces/res/values-hr/strings.xml @@ -0,0 +1,22 @@ + + + + + + + diff --git a/java/com/android/dialer/searchfragment/nearbyplaces/res/values-hu/strings.xml b/java/com/android/dialer/searchfragment/nearbyplaces/res/values-hu/strings.xml new file mode 100644 index 000000000..8039ea04a --- /dev/null +++ b/java/com/android/dialer/searchfragment/nearbyplaces/res/values-hu/strings.xml @@ -0,0 +1,22 @@ + + + + + + + diff --git a/java/com/android/dialer/searchfragment/nearbyplaces/res/values-hy/strings.xml b/java/com/android/dialer/searchfragment/nearbyplaces/res/values-hy/strings.xml new file mode 100644 index 000000000..3a2ba3938 --- /dev/null +++ b/java/com/android/dialer/searchfragment/nearbyplaces/res/values-hy/strings.xml @@ -0,0 +1,21 @@ + + + + + "Մոտակա վայրեր" + diff --git a/java/com/android/dialer/searchfragment/nearbyplaces/res/values-in/strings.xml b/java/com/android/dialer/searchfragment/nearbyplaces/res/values-in/strings.xml new file mode 100644 index 000000000..8039ea04a --- /dev/null +++ b/java/com/android/dialer/searchfragment/nearbyplaces/res/values-in/strings.xml @@ -0,0 +1,22 @@ + + + + + + + diff --git a/java/com/android/dialer/searchfragment/nearbyplaces/res/values-is/strings.xml b/java/com/android/dialer/searchfragment/nearbyplaces/res/values-is/strings.xml new file mode 100644 index 000000000..8039ea04a --- /dev/null +++ b/java/com/android/dialer/searchfragment/nearbyplaces/res/values-is/strings.xml @@ -0,0 +1,22 @@ + + + + + + + diff --git a/java/com/android/dialer/searchfragment/nearbyplaces/res/values-it/strings.xml b/java/com/android/dialer/searchfragment/nearbyplaces/res/values-it/strings.xml new file mode 100644 index 000000000..8039ea04a --- /dev/null +++ b/java/com/android/dialer/searchfragment/nearbyplaces/res/values-it/strings.xml @@ -0,0 +1,22 @@ + + + + + + + diff --git a/java/com/android/dialer/searchfragment/nearbyplaces/res/values-iw/strings.xml b/java/com/android/dialer/searchfragment/nearbyplaces/res/values-iw/strings.xml new file mode 100644 index 000000000..0f07995f3 --- /dev/null +++ b/java/com/android/dialer/searchfragment/nearbyplaces/res/values-iw/strings.xml @@ -0,0 +1,21 @@ + + + + + "מקומות קרובים" + diff --git a/java/com/android/dialer/searchfragment/nearbyplaces/res/values-ja/strings.xml b/java/com/android/dialer/searchfragment/nearbyplaces/res/values-ja/strings.xml new file mode 100644 index 000000000..8039ea04a --- /dev/null +++ b/java/com/android/dialer/searchfragment/nearbyplaces/res/values-ja/strings.xml @@ -0,0 +1,22 @@ + + + + + + + diff --git a/java/com/android/dialer/searchfragment/nearbyplaces/res/values-ka/strings.xml b/java/com/android/dialer/searchfragment/nearbyplaces/res/values-ka/strings.xml new file mode 100644 index 000000000..8039ea04a --- /dev/null +++ b/java/com/android/dialer/searchfragment/nearbyplaces/res/values-ka/strings.xml @@ -0,0 +1,22 @@ + + + + + + + diff --git a/java/com/android/dialer/searchfragment/nearbyplaces/res/values-kk/strings.xml b/java/com/android/dialer/searchfragment/nearbyplaces/res/values-kk/strings.xml new file mode 100644 index 000000000..8039ea04a --- /dev/null +++ b/java/com/android/dialer/searchfragment/nearbyplaces/res/values-kk/strings.xml @@ -0,0 +1,22 @@ + + + + + + + diff --git a/java/com/android/dialer/searchfragment/nearbyplaces/res/values-km/strings.xml b/java/com/android/dialer/searchfragment/nearbyplaces/res/values-km/strings.xml new file mode 100644 index 000000000..8039ea04a --- /dev/null +++ b/java/com/android/dialer/searchfragment/nearbyplaces/res/values-km/strings.xml @@ -0,0 +1,22 @@ + + + + + + + diff --git a/java/com/android/dialer/searchfragment/nearbyplaces/res/values-kn/strings.xml b/java/com/android/dialer/searchfragment/nearbyplaces/res/values-kn/strings.xml new file mode 100644 index 000000000..8039ea04a --- /dev/null +++ b/java/com/android/dialer/searchfragment/nearbyplaces/res/values-kn/strings.xml @@ -0,0 +1,22 @@ + + + + + + + diff --git a/java/com/android/dialer/searchfragment/nearbyplaces/res/values-ko/strings.xml b/java/com/android/dialer/searchfragment/nearbyplaces/res/values-ko/strings.xml new file mode 100644 index 000000000..f05a33289 --- /dev/null +++ b/java/com/android/dialer/searchfragment/nearbyplaces/res/values-ko/strings.xml @@ -0,0 +1,21 @@ + + + + + "주변 장소" + diff --git a/java/com/android/dialer/searchfragment/nearbyplaces/res/values-ky/strings.xml b/java/com/android/dialer/searchfragment/nearbyplaces/res/values-ky/strings.xml new file mode 100644 index 000000000..8039ea04a --- /dev/null +++ b/java/com/android/dialer/searchfragment/nearbyplaces/res/values-ky/strings.xml @@ -0,0 +1,22 @@ + + + + + + + diff --git a/java/com/android/dialer/searchfragment/nearbyplaces/res/values-lo/strings.xml b/java/com/android/dialer/searchfragment/nearbyplaces/res/values-lo/strings.xml new file mode 100644 index 000000000..2ff0e8548 --- /dev/null +++ b/java/com/android/dialer/searchfragment/nearbyplaces/res/values-lo/strings.xml @@ -0,0 +1,21 @@ + + + + + "ສະຖານທີ່ໃກ້ຄຽງ" + diff --git a/java/com/android/dialer/searchfragment/nearbyplaces/res/values-lt/strings.xml b/java/com/android/dialer/searchfragment/nearbyplaces/res/values-lt/strings.xml new file mode 100644 index 000000000..9baf54044 --- /dev/null +++ b/java/com/android/dialer/searchfragment/nearbyplaces/res/values-lt/strings.xml @@ -0,0 +1,21 @@ + + + + + "Netoliese esančios vietos" + diff --git a/java/com/android/dialer/searchfragment/nearbyplaces/res/values-lv/strings.xml b/java/com/android/dialer/searchfragment/nearbyplaces/res/values-lv/strings.xml new file mode 100644 index 000000000..8039ea04a --- /dev/null +++ b/java/com/android/dialer/searchfragment/nearbyplaces/res/values-lv/strings.xml @@ -0,0 +1,22 @@ + + + + + + + diff --git a/java/com/android/dialer/searchfragment/nearbyplaces/res/values-mk/strings.xml b/java/com/android/dialer/searchfragment/nearbyplaces/res/values-mk/strings.xml new file mode 100644 index 000000000..8039ea04a --- /dev/null +++ b/java/com/android/dialer/searchfragment/nearbyplaces/res/values-mk/strings.xml @@ -0,0 +1,22 @@ + + + + + + + diff --git a/java/com/android/dialer/searchfragment/nearbyplaces/res/values-ml/strings.xml b/java/com/android/dialer/searchfragment/nearbyplaces/res/values-ml/strings.xml new file mode 100644 index 000000000..8039ea04a --- /dev/null +++ b/java/com/android/dialer/searchfragment/nearbyplaces/res/values-ml/strings.xml @@ -0,0 +1,22 @@ + + + + + + + diff --git a/java/com/android/dialer/searchfragment/nearbyplaces/res/values-mn/strings.xml b/java/com/android/dialer/searchfragment/nearbyplaces/res/values-mn/strings.xml new file mode 100644 index 000000000..707a6c955 --- /dev/null +++ b/java/com/android/dialer/searchfragment/nearbyplaces/res/values-mn/strings.xml @@ -0,0 +1,21 @@ + + + + + "Ойролцоох газрууд" + diff --git a/java/com/android/dialer/searchfragment/nearbyplaces/res/values-mr/strings.xml b/java/com/android/dialer/searchfragment/nearbyplaces/res/values-mr/strings.xml new file mode 100644 index 000000000..862cd0419 --- /dev/null +++ b/java/com/android/dialer/searchfragment/nearbyplaces/res/values-mr/strings.xml @@ -0,0 +1,21 @@ + + + + + "जवळपासची ठिकाणे" + diff --git a/java/com/android/dialer/searchfragment/nearbyplaces/res/values-ms/strings.xml b/java/com/android/dialer/searchfragment/nearbyplaces/res/values-ms/strings.xml new file mode 100644 index 000000000..aed0bbb4d --- /dev/null +++ b/java/com/android/dialer/searchfragment/nearbyplaces/res/values-ms/strings.xml @@ -0,0 +1,21 @@ + + + + + "Tempat berdekatan" + diff --git a/java/com/android/dialer/searchfragment/nearbyplaces/res/values-my/strings.xml b/java/com/android/dialer/searchfragment/nearbyplaces/res/values-my/strings.xml new file mode 100644 index 000000000..74e60a089 --- /dev/null +++ b/java/com/android/dialer/searchfragment/nearbyplaces/res/values-my/strings.xml @@ -0,0 +1,21 @@ + + + + + "အနီးတဝိုက်ရှိ နေရာများ" + diff --git a/java/com/android/dialer/searchfragment/nearbyplaces/res/values-nb/strings.xml b/java/com/android/dialer/searchfragment/nearbyplaces/res/values-nb/strings.xml new file mode 100644 index 000000000..8039ea04a --- /dev/null +++ b/java/com/android/dialer/searchfragment/nearbyplaces/res/values-nb/strings.xml @@ -0,0 +1,22 @@ + + + + + + + diff --git a/java/com/android/dialer/searchfragment/nearbyplaces/res/values-ne/strings.xml b/java/com/android/dialer/searchfragment/nearbyplaces/res/values-ne/strings.xml new file mode 100644 index 000000000..29b6854fe --- /dev/null +++ b/java/com/android/dialer/searchfragment/nearbyplaces/res/values-ne/strings.xml @@ -0,0 +1,21 @@ + + + + + "नजिकका स्थानहरू" + diff --git a/java/com/android/dialer/searchfragment/nearbyplaces/res/values-nl/strings.xml b/java/com/android/dialer/searchfragment/nearbyplaces/res/values-nl/strings.xml new file mode 100644 index 000000000..8039ea04a --- /dev/null +++ b/java/com/android/dialer/searchfragment/nearbyplaces/res/values-nl/strings.xml @@ -0,0 +1,22 @@ + + + + + + + diff --git a/java/com/android/dialer/searchfragment/nearbyplaces/res/values-no/strings.xml b/java/com/android/dialer/searchfragment/nearbyplaces/res/values-no/strings.xml new file mode 100644 index 000000000..8039ea04a --- /dev/null +++ b/java/com/android/dialer/searchfragment/nearbyplaces/res/values-no/strings.xml @@ -0,0 +1,22 @@ + + + + + + + diff --git a/java/com/android/dialer/searchfragment/nearbyplaces/res/values-pa/strings.xml b/java/com/android/dialer/searchfragment/nearbyplaces/res/values-pa/strings.xml new file mode 100644 index 000000000..1d4d472a3 --- /dev/null +++ b/java/com/android/dialer/searchfragment/nearbyplaces/res/values-pa/strings.xml @@ -0,0 +1,21 @@ + + + + + "ਨਜ਼ਦੀਕੀ ਸਥਾਨ" + diff --git a/java/com/android/dialer/searchfragment/nearbyplaces/res/values-pl/strings.xml b/java/com/android/dialer/searchfragment/nearbyplaces/res/values-pl/strings.xml new file mode 100644 index 000000000..c00b6081a --- /dev/null +++ b/java/com/android/dialer/searchfragment/nearbyplaces/res/values-pl/strings.xml @@ -0,0 +1,21 @@ + + + + + "Miejsca w pobliżu" + diff --git a/java/com/android/dialer/searchfragment/nearbyplaces/res/values-pt-rBR/strings.xml b/java/com/android/dialer/searchfragment/nearbyplaces/res/values-pt-rBR/strings.xml new file mode 100644 index 000000000..8039ea04a --- /dev/null +++ b/java/com/android/dialer/searchfragment/nearbyplaces/res/values-pt-rBR/strings.xml @@ -0,0 +1,22 @@ + + + + + + + diff --git a/java/com/android/dialer/searchfragment/nearbyplaces/res/values-pt-rPT/strings.xml b/java/com/android/dialer/searchfragment/nearbyplaces/res/values-pt-rPT/strings.xml new file mode 100644 index 000000000..8039ea04a --- /dev/null +++ b/java/com/android/dialer/searchfragment/nearbyplaces/res/values-pt-rPT/strings.xml @@ -0,0 +1,22 @@ + + + + + + + diff --git a/java/com/android/dialer/searchfragment/nearbyplaces/res/values-pt/strings.xml b/java/com/android/dialer/searchfragment/nearbyplaces/res/values-pt/strings.xml new file mode 100644 index 000000000..8039ea04a --- /dev/null +++ b/java/com/android/dialer/searchfragment/nearbyplaces/res/values-pt/strings.xml @@ -0,0 +1,22 @@ + + + + + + + diff --git a/java/com/android/dialer/searchfragment/nearbyplaces/res/values-ro/strings.xml b/java/com/android/dialer/searchfragment/nearbyplaces/res/values-ro/strings.xml new file mode 100644 index 000000000..8039ea04a --- /dev/null +++ b/java/com/android/dialer/searchfragment/nearbyplaces/res/values-ro/strings.xml @@ -0,0 +1,22 @@ + + + + + + + diff --git a/java/com/android/dialer/searchfragment/nearbyplaces/res/values-ru/strings.xml b/java/com/android/dialer/searchfragment/nearbyplaces/res/values-ru/strings.xml new file mode 100644 index 000000000..8039ea04a --- /dev/null +++ b/java/com/android/dialer/searchfragment/nearbyplaces/res/values-ru/strings.xml @@ -0,0 +1,22 @@ + + + + + + + diff --git a/java/com/android/dialer/searchfragment/nearbyplaces/res/values-si/strings.xml b/java/com/android/dialer/searchfragment/nearbyplaces/res/values-si/strings.xml new file mode 100644 index 000000000..8039ea04a --- /dev/null +++ b/java/com/android/dialer/searchfragment/nearbyplaces/res/values-si/strings.xml @@ -0,0 +1,22 @@ + + + + + + + diff --git a/java/com/android/dialer/searchfragment/nearbyplaces/res/values-sk/strings.xml b/java/com/android/dialer/searchfragment/nearbyplaces/res/values-sk/strings.xml new file mode 100644 index 000000000..8039ea04a --- /dev/null +++ b/java/com/android/dialer/searchfragment/nearbyplaces/res/values-sk/strings.xml @@ -0,0 +1,22 @@ + + + + + + + diff --git a/java/com/android/dialer/searchfragment/nearbyplaces/res/values-sl/strings.xml b/java/com/android/dialer/searchfragment/nearbyplaces/res/values-sl/strings.xml new file mode 100644 index 000000000..8039ea04a --- /dev/null +++ b/java/com/android/dialer/searchfragment/nearbyplaces/res/values-sl/strings.xml @@ -0,0 +1,22 @@ + + + + + + + diff --git a/java/com/android/dialer/searchfragment/nearbyplaces/res/values-sq/strings.xml b/java/com/android/dialer/searchfragment/nearbyplaces/res/values-sq/strings.xml new file mode 100644 index 000000000..8039ea04a --- /dev/null +++ b/java/com/android/dialer/searchfragment/nearbyplaces/res/values-sq/strings.xml @@ -0,0 +1,22 @@ + + + + + + + diff --git a/java/com/android/dialer/searchfragment/nearbyplaces/res/values-sr/strings.xml b/java/com/android/dialer/searchfragment/nearbyplaces/res/values-sr/strings.xml new file mode 100644 index 000000000..21af04328 --- /dev/null +++ b/java/com/android/dialer/searchfragment/nearbyplaces/res/values-sr/strings.xml @@ -0,0 +1,21 @@ + + + + + "Оближња места" + diff --git a/java/com/android/dialer/searchfragment/nearbyplaces/res/values-sv/strings.xml b/java/com/android/dialer/searchfragment/nearbyplaces/res/values-sv/strings.xml new file mode 100644 index 000000000..c309b8df4 --- /dev/null +++ b/java/com/android/dialer/searchfragment/nearbyplaces/res/values-sv/strings.xml @@ -0,0 +1,21 @@ + + + + + "Platser i närheten" + diff --git a/java/com/android/dialer/searchfragment/nearbyplaces/res/values-sw/strings.xml b/java/com/android/dialer/searchfragment/nearbyplaces/res/values-sw/strings.xml new file mode 100644 index 000000000..8039ea04a --- /dev/null +++ b/java/com/android/dialer/searchfragment/nearbyplaces/res/values-sw/strings.xml @@ -0,0 +1,22 @@ + + + + + + + diff --git a/java/com/android/dialer/searchfragment/nearbyplaces/res/values-ta/strings.xml b/java/com/android/dialer/searchfragment/nearbyplaces/res/values-ta/strings.xml new file mode 100644 index 000000000..ce7496e53 --- /dev/null +++ b/java/com/android/dialer/searchfragment/nearbyplaces/res/values-ta/strings.xml @@ -0,0 +1,21 @@ + + + + + "அருகிலுள்ள இடங்கள்" + diff --git a/java/com/android/dialer/searchfragment/nearbyplaces/res/values-te/strings.xml b/java/com/android/dialer/searchfragment/nearbyplaces/res/values-te/strings.xml new file mode 100644 index 000000000..c8229fb64 --- /dev/null +++ b/java/com/android/dialer/searchfragment/nearbyplaces/res/values-te/strings.xml @@ -0,0 +1,21 @@ + + + + + "సమీప స్థలాలు" + diff --git a/java/com/android/dialer/searchfragment/nearbyplaces/res/values-th/strings.xml b/java/com/android/dialer/searchfragment/nearbyplaces/res/values-th/strings.xml new file mode 100644 index 000000000..1167d2f57 --- /dev/null +++ b/java/com/android/dialer/searchfragment/nearbyplaces/res/values-th/strings.xml @@ -0,0 +1,21 @@ + + + + + "สถานที่ใกล้เคียง" + diff --git a/java/com/android/dialer/searchfragment/nearbyplaces/res/values-tl/strings.xml b/java/com/android/dialer/searchfragment/nearbyplaces/res/values-tl/strings.xml new file mode 100644 index 000000000..8039ea04a --- /dev/null +++ b/java/com/android/dialer/searchfragment/nearbyplaces/res/values-tl/strings.xml @@ -0,0 +1,22 @@ + + + + + + + diff --git a/java/com/android/dialer/searchfragment/nearbyplaces/res/values-tr/strings.xml b/java/com/android/dialer/searchfragment/nearbyplaces/res/values-tr/strings.xml new file mode 100644 index 000000000..8039ea04a --- /dev/null +++ b/java/com/android/dialer/searchfragment/nearbyplaces/res/values-tr/strings.xml @@ -0,0 +1,22 @@ + + + + + + + diff --git a/java/com/android/dialer/searchfragment/nearbyplaces/res/values-uk/strings.xml b/java/com/android/dialer/searchfragment/nearbyplaces/res/values-uk/strings.xml new file mode 100644 index 000000000..a3936be25 --- /dev/null +++ b/java/com/android/dialer/searchfragment/nearbyplaces/res/values-uk/strings.xml @@ -0,0 +1,21 @@ + + + + + "Місця поблизу" + diff --git a/java/com/android/dialer/searchfragment/nearbyplaces/res/values-ur/strings.xml b/java/com/android/dialer/searchfragment/nearbyplaces/res/values-ur/strings.xml new file mode 100644 index 000000000..1a220b3c2 --- /dev/null +++ b/java/com/android/dialer/searchfragment/nearbyplaces/res/values-ur/strings.xml @@ -0,0 +1,21 @@ + + + + + "قریبی مقامات" + diff --git a/java/com/android/dialer/searchfragment/nearbyplaces/res/values-uz/strings.xml b/java/com/android/dialer/searchfragment/nearbyplaces/res/values-uz/strings.xml new file mode 100644 index 000000000..8039ea04a --- /dev/null +++ b/java/com/android/dialer/searchfragment/nearbyplaces/res/values-uz/strings.xml @@ -0,0 +1,22 @@ + + + + + + + diff --git a/java/com/android/dialer/searchfragment/nearbyplaces/res/values-vi/strings.xml b/java/com/android/dialer/searchfragment/nearbyplaces/res/values-vi/strings.xml new file mode 100644 index 000000000..8039ea04a --- /dev/null +++ b/java/com/android/dialer/searchfragment/nearbyplaces/res/values-vi/strings.xml @@ -0,0 +1,22 @@ + + + + + + + diff --git a/java/com/android/dialer/searchfragment/nearbyplaces/res/values-zh-rCN/strings.xml b/java/com/android/dialer/searchfragment/nearbyplaces/res/values-zh-rCN/strings.xml new file mode 100644 index 000000000..e060cb589 --- /dev/null +++ b/java/com/android/dialer/searchfragment/nearbyplaces/res/values-zh-rCN/strings.xml @@ -0,0 +1,21 @@ + + + + + "附近的地点" + diff --git a/java/com/android/dialer/searchfragment/nearbyplaces/res/values-zh-rHK/strings.xml b/java/com/android/dialer/searchfragment/nearbyplaces/res/values-zh-rHK/strings.xml new file mode 100644 index 000000000..5cdf5b9a7 --- /dev/null +++ b/java/com/android/dialer/searchfragment/nearbyplaces/res/values-zh-rHK/strings.xml @@ -0,0 +1,21 @@ + + + + + "附近地點" + diff --git a/java/com/android/dialer/searchfragment/nearbyplaces/res/values-zh-rTW/strings.xml b/java/com/android/dialer/searchfragment/nearbyplaces/res/values-zh-rTW/strings.xml new file mode 100644 index 000000000..8039ea04a --- /dev/null +++ b/java/com/android/dialer/searchfragment/nearbyplaces/res/values-zh-rTW/strings.xml @@ -0,0 +1,22 @@ + + + + + + + diff --git a/java/com/android/dialer/searchfragment/nearbyplaces/res/values-zu/strings.xml b/java/com/android/dialer/searchfragment/nearbyplaces/res/values-zu/strings.xml new file mode 100644 index 000000000..8039ea04a --- /dev/null +++ b/java/com/android/dialer/searchfragment/nearbyplaces/res/values-zu/strings.xml @@ -0,0 +1,22 @@ + + + + + + + diff --git a/java/com/android/dialer/searchfragment/nearbyplaces/res/values/strings.xml b/java/com/android/dialer/searchfragment/nearbyplaces/res/values/strings.xml new file mode 100644 index 000000000..ed8068018 --- /dev/null +++ b/java/com/android/dialer/searchfragment/nearbyplaces/res/values/strings.xml @@ -0,0 +1,20 @@ + + + + + Nearby places + \ No newline at end of file diff --git a/java/com/android/dialer/searchfragment/res/layout/fragment_search.xml b/java/com/android/dialer/searchfragment/res/layout/fragment_search.xml deleted file mode 100644 index 06f234889..000000000 --- a/java/com/android/dialer/searchfragment/res/layout/fragment_search.xml +++ /dev/null @@ -1,21 +0,0 @@ - - - diff --git a/java/com/android/dialer/searchfragment/res/layout/search_contact_row.xml b/java/com/android/dialer/searchfragment/res/layout/search_contact_row.xml deleted file mode 100644 index efeca0e9d..000000000 --- a/java/com/android/dialer/searchfragment/res/layout/search_contact_row.xml +++ /dev/null @@ -1,75 +0,0 @@ - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/java/com/android/dialer/searchfragment/res/values/dimens.xml b/java/com/android/dialer/searchfragment/res/values/dimens.xml deleted file mode 100644 index d5459ddb3..000000000 --- a/java/com/android/dialer/searchfragment/res/values/dimens.xml +++ /dev/null @@ -1,23 +0,0 @@ - - - - 56dp - 8dp - 8dp - 16dp - 16sp - \ No newline at end of file diff --git a/java/com/android/dialer/shortcuts/Shortcuts.java b/java/com/android/dialer/shortcuts/Shortcuts.java index b6a7fa82a..c2bbb4dde 100644 --- a/java/com/android/dialer/shortcuts/Shortcuts.java +++ b/java/com/android/dialer/shortcuts/Shortcuts.java @@ -18,7 +18,7 @@ package com.android.dialer.shortcuts; import android.content.Context; import android.support.annotation.NonNull; -import com.android.dialer.common.ConfigProviderBindings; +import com.android.dialer.configprovider.ConfigProviderBindings; /** Checks if dynamic shortcuts should be enabled. */ public class Shortcuts { diff --git a/java/com/android/dialer/simulator/impl/SimulatorContacts.java b/java/com/android/dialer/simulator/impl/SimulatorContacts.java index c5e25b357..e77788f02 100644 --- a/java/com/android/dialer/simulator/impl/SimulatorContacts.java +++ b/java/com/android/dialer/simulator/impl/SimulatorContacts.java @@ -134,7 +134,7 @@ final class SimulatorContacts { ContentProviderOperation.newInsert(ContactsContract.RawContacts.CONTENT_URI) .withValue(ContactsContract.RawContacts.ACCOUNT_TYPE, contact.getAccountType()) .withValue(ContactsContract.RawContacts.ACCOUNT_NAME, contact.getAccountName()) - .withValue(ContactsContract.RawContacts.STARRED, contact.getIsStarred()) + .withValue(ContactsContract.RawContacts.STARRED, contact.getIsStarred() ? 1 : 0) .withYieldAllowed(true) .build()); diff --git a/java/com/android/dialer/telecom/TelecomUtil.java b/java/com/android/dialer/telecom/TelecomUtil.java index 82b43835f..573bfe2d9 100644 --- a/java/com/android/dialer/telecom/TelecomUtil.java +++ b/java/com/android/dialer/telecom/TelecomUtil.java @@ -29,9 +29,12 @@ import android.telecom.PhoneAccount; import android.telecom.PhoneAccountHandle; import android.telecom.TelecomManager; import android.text.TextUtils; +import android.util.Pair; import com.android.dialer.common.LogUtil; import java.util.ArrayList; import java.util.List; +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; /** * Performs permission checks before calling into TelecomManager. Each method is self-explanatory - @@ -45,6 +48,14 @@ public abstract class TelecomUtil { private static TelecomUtilImpl instance = new TelecomUtilImpl(); + /** + * Cache for {@link #isVoicemailNumber(Context, PhoneAccountHandle, String)}. Both + * PhoneAccountHandle and number are cached because multiple numbers might be mapped to true, and + * comparing with {@link #getVoicemailNumber(Context, PhoneAccountHandle)} will not suffice. + */ + private static final Map, Boolean> isVoicemailNumberCache = + new ConcurrentHashMap<>(); + @VisibleForTesting(otherwise = VisibleForTesting.NONE) public static void setInstanceForTesting(TelecomUtilImpl instanceForTesting) { instance = instanceForTesting; @@ -133,12 +144,27 @@ public abstract class TelecomUtil { return instance.isInCall(context); } + /** + * {@link TelecomManager#isVoiceMailNumber(PhoneAccountHandle, String)} takes about 10ms, which is + * way too slow for regular purposes. This method will cache the result for the life time of the + * process. The cache will not be invalidated, for example, if the voicemail number is changed by + * setting up apps like Google Voicemail, the result will be wrong. These events are rare. + */ public static boolean isVoicemailNumber( Context context, PhoneAccountHandle accountHandle, String number) { + if (TextUtils.isEmpty(number)) { + return false; + } + Pair cacheKey = new Pair<>(accountHandle, number); + if (isVoicemailNumberCache.containsKey(cacheKey)) { + return isVoicemailNumberCache.get(cacheKey); + } + boolean result = false; if (hasReadPhoneStatePermission(context)) { - return getTelecomManager(context).isVoiceMailNumber(accountHandle, number); + result = getTelecomManager(context).isVoiceMailNumber(accountHandle, number); } - return false; + isVoicemailNumberCache.put(cacheKey, result); + return result; } @Nullable diff --git a/java/com/android/dialer/util/CallUtil.java b/java/com/android/dialer/util/CallUtil.java index b6ab3b30e..0afe930c9 100644 --- a/java/com/android/dialer/util/CallUtil.java +++ b/java/com/android/dialer/util/CallUtil.java @@ -122,7 +122,7 @@ public class CallUtil { cachedIsVideoEnabledState = isVideoEnabled; } - return true; + return isVideoEnabled; } /** diff --git a/java/com/android/dialer/util/PermissionsUtil.java b/java/com/android/dialer/util/PermissionsUtil.java index 72a59eaef..34828317d 100644 --- a/java/com/android/dialer/util/PermissionsUtil.java +++ b/java/com/android/dialer/util/PermissionsUtil.java @@ -16,15 +16,33 @@ package com.android.dialer.util; +import static android.Manifest.permission.ACCESS_COARSE_LOCATION; +import static android.Manifest.permission.ACCESS_FINE_LOCATION; +import static android.Manifest.permission.ADD_VOICEMAIL; +import static android.Manifest.permission.CALL_PHONE; +import static android.Manifest.permission.MODIFY_PHONE_STATE; +import static android.Manifest.permission.READ_CALL_LOG; +import static android.Manifest.permission.READ_CONTACTS; +import static android.Manifest.permission.READ_PHONE_STATE; +import static android.Manifest.permission.READ_VOICEMAIL; +import static android.Manifest.permission.WRITE_CALL_LOG; +import static android.Manifest.permission.WRITE_CONTACTS; +import static android.Manifest.permission.WRITE_VOICEMAIL; + import android.Manifest.permission; import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; import android.content.IntentFilter; import android.content.pm.PackageManager; +import android.support.annotation.NonNull; import android.support.v4.content.ContextCompat; import android.support.v4.content.LocalBroadcastManager; import com.android.dialer.common.LogUtil; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.List; /** Utility class to help with runtime permissions. */ public class PermissionsUtil { @@ -32,6 +50,27 @@ public class PermissionsUtil { private static final String PERMISSION_PREFERENCE = "dialer_permissions"; private static final String CEQUINT_PERMISSION = "com.cequint.ecid.CALLER_ID_LOOKUP"; + // Permissions list retrieved from application manifest. + // Starting in Android O Permissions must be explicitly enumerated: + // https://developer.android.com/preview/behavior-changes.html#rmp + public static final List allPhoneGroupPermissionsUsedInDialer = + Collections.unmodifiableList( + Arrays.asList( + READ_CALL_LOG, + WRITE_CALL_LOG, + READ_PHONE_STATE, + MODIFY_PHONE_STATE, + CALL_PHONE, + ADD_VOICEMAIL, + WRITE_VOICEMAIL, + READ_VOICEMAIL)); + + public static final List allContactsGroupPermissionsUsedInDialer = + Collections.unmodifiableList(Arrays.asList(READ_CONTACTS, WRITE_CONTACTS)); + + public static final List allLocationGroupPermissionsUsedInDialer = + Collections.unmodifiableList(Arrays.asList(ACCESS_FINE_LOCATION, ACCESS_COARSE_LOCATION)); + public static boolean hasPhonePermissions(Context context) { return hasPermission(context, permission.CALL_PHONE); } @@ -72,15 +111,15 @@ public class PermissionsUtil { return hasPermission(context, permission.WRITE_VOICEMAIL); } + public static boolean hasAddVoicemailPermissions(Context context) { + return hasPermission(context, permission.ADD_VOICEMAIL); + } + public static boolean hasPermission(Context context, String permission) { return ContextCompat.checkSelfPermission(context, permission) == PackageManager.PERMISSION_GRANTED; } - public static boolean hasAddVoicemailPermissions(Context context) { - return hasPermission(context, permission.ADD_VOICEMAIL); - } - /** * Checks {@link android.content.SharedPreferences} if a permission has been requested before. * @@ -147,4 +186,25 @@ public class PermissionsUtil { final Intent intent = new Intent(permission); LocalBroadcastManager.getInstance(context).sendBroadcast(intent); } + + /** + * Returns a list of permissions currently not granted to the application from the supplied list. + * + * @param context - The Application context. + * @param permissionsList - A list of permissions to check if the current application has been + * granted. + * @return An array of permissions that are currently DENIED to the application; a subset of + * permissionsList. + */ + @NonNull + public static String[] getPermissionsCurrentlyDenied( + @NonNull Context context, @NonNull List permissionsList) { + List permissionsCurrentlyDenied = new ArrayList<>(); + for (String permission : permissionsList) { + if (!hasPermission(context, permission)) { + permissionsCurrentlyDenied.add(permission); + } + } + return permissionsCurrentlyDenied.toArray(new String[permissionsCurrentlyDenied.size()]); + } } diff --git a/java/com/android/dialer/widget/LockableViewPager.java b/java/com/android/dialer/widget/LockableViewPager.java new file mode 100644 index 000000000..b5d4022e7 --- /dev/null +++ b/java/com/android/dialer/widget/LockableViewPager.java @@ -0,0 +1,50 @@ +/* + * 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.dialer.widget; + +import android.content.Context; +import android.support.v4.view.ViewPager; +import android.util.AttributeSet; +import android.view.MotionEvent; + +/** {@link ViewPager} useful for disabled swiping between pages. */ +public class LockableViewPager extends ViewPager { + + private boolean swipingLocked; + + public LockableViewPager(Context context, AttributeSet attributeSet) { + super(context, attributeSet); + } + + public void setSwipingLocked(boolean swipingLocked) { + this.swipingLocked = swipingLocked; + } + + public boolean isSwipingLocked() { + return swipingLocked; + } + + @Override + public boolean onInterceptTouchEvent(MotionEvent motionEvent) { + return !swipingLocked && super.onInterceptTouchEvent(motionEvent); + } + + @Override + public boolean onTouchEvent(MotionEvent motionEvent) { + return !swipingLocked && super.onTouchEvent(motionEvent); + } +} diff --git a/java/com/android/dialer/widget/res/layout-land/empty_content_view.xml b/java/com/android/dialer/widget/res/layout-land/empty_content_view.xml new file mode 100644 index 000000000..00344bf44 --- /dev/null +++ b/java/com/android/dialer/widget/res/layout-land/empty_content_view.xml @@ -0,0 +1,56 @@ + + + + + + + + + + + + + diff --git a/java/com/android/dialer/widget/res/values-af/strings.xml b/java/com/android/dialer/widget/res/values-af/strings.xml index 122c84328..0c21ae9af 100644 --- a/java/com/android/dialer/widget/res/values-af/strings.xml +++ b/java/com/android/dialer/widget/res/values-af/strings.xml @@ -1,10 +1,26 @@ + + "Skryf \'n gepasmaakte boodskap" "Maak toe" "Jy het nog nie enige kontakte nie" - "Voeg \'n kontak by" + "Skep nuwe kontak" "Skakel aan" "Skakel die kontaktetoestemming aan om jou kontakte te sien." "Geen kontakte-program beskikbaar nie" diff --git a/java/com/android/dialer/widget/res/values-am/strings.xml b/java/com/android/dialer/widget/res/values-am/strings.xml index 8a5353e18..3952e83cc 100644 --- a/java/com/android/dialer/widget/res/values-am/strings.xml +++ b/java/com/android/dialer/widget/res/values-am/strings.xml @@ -1,10 +1,27 @@ + + "ብጁ መልዕክት ይጻፉ" "ዝጋ" "ገና ምንም እውቂያዎች የሉዎትም" - "እውቂያ ያክሉ" + + "አብራ" "የእርስዎን እውቂያዎች ለማየት፣ የእውቂያዎች ፍቃዱን ያብሩ።" "ምንም የእውቂያዎች መተግበሪያ አይገኝም" diff --git a/java/com/android/dialer/widget/res/values-ar/strings.xml b/java/com/android/dialer/widget/res/values-ar/strings.xml index 7947903ce..26ed748f0 100644 --- a/java/com/android/dialer/widget/res/values-ar/strings.xml +++ b/java/com/android/dialer/widget/res/values-ar/strings.xml @@ -1,10 +1,26 @@ + + "كتابة رسالة مخصصة" "إغلاق" "ليست لديك أية جهات اتصال حتى الآن" - "إضافة جهة اتصال" + "إنشاء جهة اتصال" "تشغيل" "للاطلاع على جهات الاتصال، شغِّل إذن جهات الاتصال." "لا يتوفر تطبيق لجهات الاتصال" diff --git a/java/com/android/dialer/widget/res/values-az/strings.xml b/java/com/android/dialer/widget/res/values-az/strings.xml index 7a1389a1a..cb40af6d7 100644 --- a/java/com/android/dialer/widget/res/values-az/strings.xml +++ b/java/com/android/dialer/widget/res/values-az/strings.xml @@ -1,10 +1,27 @@ + + "Fərdi mesaj yazın" "Bağlayın" "Hələ heç bir kontakt yoxdur" - "Kontakt əlavə edin" + + "Aktiv edin" "Kontaktları görmək üçün Kontakt icazəsini aktiv edin." "Kontakt tətbiqi əlçatan deyil" diff --git a/java/com/android/dialer/widget/res/values-b+sr+Latn/strings.xml b/java/com/android/dialer/widget/res/values-b+sr+Latn/strings.xml index 46b29d27c..fea3cb0ef 100644 --- a/java/com/android/dialer/widget/res/values-b+sr+Latn/strings.xml +++ b/java/com/android/dialer/widget/res/values-b+sr+Latn/strings.xml @@ -1,10 +1,26 @@ + + "Napišite prilagođenu poruku" "Zatvorite" "Još uvek nemate nijedan kontakt" - "Dodaj kontakt" + "Napravi novi kontakt" "Uključi" "Da biste videli kontakte, uključite dozvolu za Kontakte." "Nema dostupne aplikacije za kontakte" diff --git a/java/com/android/dialer/widget/res/values-be/strings.xml b/java/com/android/dialer/widget/res/values-be/strings.xml index 38c8a80ca..6805984c3 100644 --- a/java/com/android/dialer/widget/res/values-be/strings.xml +++ b/java/com/android/dialer/widget/res/values-be/strings.xml @@ -1,10 +1,27 @@ + + "Напісаць карыстальніцкае паведамленне" "Закрыць" "У вас пакуль няма ніякіх кантактаў" - "Дадаць кантакт" + + "Уключыць" "Каб бачыць свае кантакты, уключыце дазвол для Кантактаў." "Праграмы для аперацый з кантактамі няма" diff --git a/java/com/android/dialer/widget/res/values-bg/strings.xml b/java/com/android/dialer/widget/res/values-bg/strings.xml index 00ce56454..fbb87d031 100644 --- a/java/com/android/dialer/widget/res/values-bg/strings.xml +++ b/java/com/android/dialer/widget/res/values-bg/strings.xml @@ -1,10 +1,26 @@ + + "Напишете свое съобщение" "Затваряне" "Още нямате контакти" - "Добавяне на контакт" + "Създаване на нов контакт" "Включване" "За да видите контактите си, включете разрешението за Контакти." "Няма налично приложение за контакти" diff --git a/java/com/android/dialer/widget/res/values-bn/strings.xml b/java/com/android/dialer/widget/res/values-bn/strings.xml index 96b75db59..58bf44c6a 100644 --- a/java/com/android/dialer/widget/res/values-bn/strings.xml +++ b/java/com/android/dialer/widget/res/values-bn/strings.xml @@ -1,10 +1,26 @@ + + "একটি কাস্টম বার্তা লিখুন" "বন্ধ করুন" "আপনার এখনও পর্যন্ত কোনো পরিচিতি নেই" - "একটি পরিচিতি যোগ করুন" + "নতুন পরিচিতি তৈরি করুন" "চালু করুন" "আপনার পরিচিতিগুলি দেখতে, পরিচিতিগুলির অনুমতি চালু করুন।" "কোনো পরিচিতি অ্যাপ্লিকেশান উপলব্ধ নয়" diff --git a/java/com/android/dialer/widget/res/values-bs/strings.xml b/java/com/android/dialer/widget/res/values-bs/strings.xml index df24ee16b..239c07412 100644 --- a/java/com/android/dialer/widget/res/values-bs/strings.xml +++ b/java/com/android/dialer/widget/res/values-bs/strings.xml @@ -1,10 +1,26 @@ + + "Napišite prilagođenu poruku" "Zatvori" "Još nemate nijedan kontakt" - "Dodajte kontakt" + "Kreirajte novi kontakt" "Uključi" "Da vidite kontakte, uključite dozvolu za Kontakte." "Nije dostupna nijedna aplikacija za kontakte" diff --git a/java/com/android/dialer/widget/res/values-ca/strings.xml b/java/com/android/dialer/widget/res/values-ca/strings.xml index f7bbaa746..8f01cb53e 100644 --- a/java/com/android/dialer/widget/res/values-ca/strings.xml +++ b/java/com/android/dialer/widget/res/values-ca/strings.xml @@ -1,10 +1,27 @@ + + "Escriu un miss. personalitzat" "Tanca" "Encara no tens cap contacte" - "Afegeix un contacte" + + "Activa" "Activa el permís Contactes per veure els teus contactes." "No hi ha cap contacte disponible" diff --git a/java/com/android/dialer/widget/res/values-cs/strings.xml b/java/com/android/dialer/widget/res/values-cs/strings.xml index 19e5d17da..ee8d14022 100644 --- a/java/com/android/dialer/widget/res/values-cs/strings.xml +++ b/java/com/android/dialer/widget/res/values-cs/strings.xml @@ -1,10 +1,27 @@ + + "Napište vlastní zprávu" "Zavřít" "Zatím nemáte žádné kontakty" - "Přidat kontakt" + + "Povolit" "Pokud chcete zobrazit kontakty, povolte aplikaci přístup ke Kontaktům." "Není k dispozici žádná aplikace pro práci s kontakty" diff --git a/java/com/android/dialer/widget/res/values-da/strings.xml b/java/com/android/dialer/widget/res/values-da/strings.xml index 67fb244c4..0e449489d 100644 --- a/java/com/android/dialer/widget/res/values-da/strings.xml +++ b/java/com/android/dialer/widget/res/values-da/strings.xml @@ -1,10 +1,27 @@ + + "Skriv en tilpasset besked" "Luk" "Du har endnu ikke nogen kontaktpersoner" - "Tilføj en kontaktperson" + + "Slå til" "Slå tilladelsen Kontaktpersoner til for at se dine kontaktpersoner." "Der er ingen tilgængelig app til kontaktpersoner" diff --git a/java/com/android/dialer/widget/res/values-de/strings.xml b/java/com/android/dialer/widget/res/values-de/strings.xml index 14146d65f..f650df9f0 100644 --- a/java/com/android/dialer/widget/res/values-de/strings.xml +++ b/java/com/android/dialer/widget/res/values-de/strings.xml @@ -1,10 +1,26 @@ + + "Eigene Nachricht schreiben" "Schließen" "Du hast noch keine Kontakte" - "Kontakt hinzufügen" + "Neuen Kontakt erstellen" "Aktivieren" "Aktiviere die Berechtigung \"Kontakte\", um deine Kontakte abzurufen." "Keine Kontakte-App verfügbar" diff --git a/java/com/android/dialer/widget/res/values-el/strings.xml b/java/com/android/dialer/widget/res/values-el/strings.xml index 0db6b2694..849fd6a8a 100644 --- a/java/com/android/dialer/widget/res/values-el/strings.xml +++ b/java/com/android/dialer/widget/res/values-el/strings.xml @@ -1,10 +1,27 @@ + + "Γράψτε ένα προσαρμ. μήνυμα" "Κλείσιμο" "Δεν έχετε επαφές ακόμη" - "Προσθήκη επαφής" + + "Ενεργοποίηση" "Για να δείτε τις επαφές σας, ενεργοποιήστε την άδεια πρόσβασης στις Επαφές." "Δεν υπάρχει διαθέσιμη εφαρμογή επαφών" diff --git a/java/com/android/dialer/widget/res/values-en-rAU/strings.xml b/java/com/android/dialer/widget/res/values-en-rAU/strings.xml index a87cd28ff..33cba3337 100644 --- a/java/com/android/dialer/widget/res/values-en-rAU/strings.xml +++ b/java/com/android/dialer/widget/res/values-en-rAU/strings.xml @@ -1,10 +1,26 @@ + + "Write a custom message" "Close" "You don\'t have any contacts yet" - "Add a contact" + "Create new contact" "Turn on" "To see your contacts, turn on the Contacts permission." "No contacts app available" diff --git a/java/com/android/dialer/widget/res/values-en-rGB/strings.xml b/java/com/android/dialer/widget/res/values-en-rGB/strings.xml index a87cd28ff..33cba3337 100644 --- a/java/com/android/dialer/widget/res/values-en-rGB/strings.xml +++ b/java/com/android/dialer/widget/res/values-en-rGB/strings.xml @@ -1,10 +1,26 @@ + + "Write a custom message" "Close" "You don\'t have any contacts yet" - "Add a contact" + "Create new contact" "Turn on" "To see your contacts, turn on the Contacts permission." "No contacts app available" diff --git a/java/com/android/dialer/widget/res/values-en-rIN/strings.xml b/java/com/android/dialer/widget/res/values-en-rIN/strings.xml index a87cd28ff..33cba3337 100644 --- a/java/com/android/dialer/widget/res/values-en-rIN/strings.xml +++ b/java/com/android/dialer/widget/res/values-en-rIN/strings.xml @@ -1,10 +1,26 @@ + + "Write a custom message" "Close" "You don\'t have any contacts yet" - "Add a contact" + "Create new contact" "Turn on" "To see your contacts, turn on the Contacts permission." "No contacts app available" diff --git a/java/com/android/dialer/widget/res/values-es-rUS/strings.xml b/java/com/android/dialer/widget/res/values-es-rUS/strings.xml index 5ecc22b3d..8c257b2d0 100644 --- a/java/com/android/dialer/widget/res/values-es-rUS/strings.xml +++ b/java/com/android/dialer/widget/res/values-es-rUS/strings.xml @@ -1,10 +1,27 @@ + + "Escribe tu propio mensaje" "Cerrar" "Aún no tienes contactos" - "Agregar un contacto" + + "Activar" "Para ver los contactos, activa el permiso Contactos." "No hay ninguna app de contactos disponible" diff --git a/java/com/android/dialer/widget/res/values-es/strings.xml b/java/com/android/dialer/widget/res/values-es/strings.xml index e561d06f7..dcb695e20 100644 --- a/java/com/android/dialer/widget/res/values-es/strings.xml +++ b/java/com/android/dialer/widget/res/values-es/strings.xml @@ -1,10 +1,26 @@ + + "Mensaje personalizado" "Cerrar" "Aún no tienes contactos" - "Añadir un contacto" + "Crear un contacto" "Activar" "Para ver tus contactos, activa el permiso de Contactos." "No hay aplicaciones de contactos disponibles" diff --git a/java/com/android/dialer/widget/res/values-et/strings.xml b/java/com/android/dialer/widget/res/values-et/strings.xml index 054b42281..f7357c279 100644 --- a/java/com/android/dialer/widget/res/values-et/strings.xml +++ b/java/com/android/dialer/widget/res/values-et/strings.xml @@ -1,10 +1,27 @@ + + "Kirjutage kohandatud sõnum" "Sule" "Teil pole veel kontakte" - "Kontakti lisamine" + + "Lülita sisse" "Kontaktide vaatamiseks lülitage sisse kontaktide luba." "Kontaktide rakendus pole saadaval" diff --git a/java/com/android/dialer/widget/res/values-eu/strings.xml b/java/com/android/dialer/widget/res/values-eu/strings.xml index 7d191925e..f4d0d1d7a 100644 --- a/java/com/android/dialer/widget/res/values-eu/strings.xml +++ b/java/com/android/dialer/widget/res/values-eu/strings.xml @@ -1,10 +1,27 @@ + + "Idatzi mezu bat" "Itxi" "Oraindik ez duzu kontakturik" - "Gehitu kontaktu bat" + + "Aktibatu" "Kontaktuak ikusteko, aktibatu Kontaktuak atzitzeko baimena." "Ez dago kontaktu-aplikaziorik erabilgarri" diff --git a/java/com/android/dialer/widget/res/values-fa/strings.xml b/java/com/android/dialer/widget/res/values-fa/strings.xml index 5ed23131a..9168ac293 100644 --- a/java/com/android/dialer/widget/res/values-fa/strings.xml +++ b/java/com/android/dialer/widget/res/values-fa/strings.xml @@ -1,10 +1,27 @@ + + "پیام سفارشی بنویسید" "بستن" "هنوز هیچ مخاطبی ندارید" - "افزودن مخاطب" + + "فعال‌سازی" "برای دیدن مخاطبینتان، مجوز «مخاطبین» را روشن کنید." "هیچ برنامه مخاطبی در دسترس نیست" diff --git a/java/com/android/dialer/widget/res/values-fi/strings.xml b/java/com/android/dialer/widget/res/values-fi/strings.xml index 1a153072c..80f190253 100644 --- a/java/com/android/dialer/widget/res/values-fi/strings.xml +++ b/java/com/android/dialer/widget/res/values-fi/strings.xml @@ -1,10 +1,27 @@ + + "Kirjoita oma viesti" "Sulje" "Sinulla ei ole vielä yhteystietoja." - "Lisää yhteystieto." + + "Ota käyttöön" "Jos haluat katsella yhteystietojasi, ota Yhteystiedot-käyttöoikeus käyttöön." "Yhteystietosovellusta ei ole käytettävissä." diff --git a/java/com/android/dialer/widget/res/values-fr-rCA/strings.xml b/java/com/android/dialer/widget/res/values-fr-rCA/strings.xml index 62e1f37fb..778550997 100644 --- a/java/com/android/dialer/widget/res/values-fr-rCA/strings.xml +++ b/java/com/android/dialer/widget/res/values-fr-rCA/strings.xml @@ -1,10 +1,26 @@ + + "Rédiger message personnalisé" "Fermer" "Vous n\'avez pas encore de contacts" - "Ajouter un contact" + "Créer un contact" "Activer" "Pour consulter vos contacts, activez l\'autorisation Contacts." "Aucune application Contacts n\'est disponible" diff --git a/java/com/android/dialer/widget/res/values-fr/strings.xml b/java/com/android/dialer/widget/res/values-fr/strings.xml index 85a32b875..be8810fd9 100644 --- a/java/com/android/dialer/widget/res/values-fr/strings.xml +++ b/java/com/android/dialer/widget/res/values-fr/strings.xml @@ -1,10 +1,26 @@ + + "Écrire mon propre message" "Fermer" "Vous n\'avez pas encore de contacts." - "Ajouter un contact" + "Créer un contact" "Activer" "Pour consulter vos contacts, activez l\'autorisation Contacts." "Aucune application de gestion des contacts n\'est disponible" diff --git a/java/com/android/dialer/widget/res/values-gl/strings.xml b/java/com/android/dialer/widget/res/values-gl/strings.xml index 8a9089fdb..a519e68b6 100644 --- a/java/com/android/dialer/widget/res/values-gl/strings.xml +++ b/java/com/android/dialer/widget/res/values-gl/strings.xml @@ -1,10 +1,26 @@ + + "Escribe unha mensaxe personalizada" "Pechar" "Aínda non tes ningún contacto" - "Engadir un contacto" + "Crear novo contacto" "Activar" "Para ver os teus contactos, activa o permiso de Contactos." "Non hai ningunha aplicación de contactos dispoñible" diff --git a/java/com/android/dialer/widget/res/values-gu/strings.xml b/java/com/android/dialer/widget/res/values-gu/strings.xml index 794245d3d..81e6f1011 100644 --- a/java/com/android/dialer/widget/res/values-gu/strings.xml +++ b/java/com/android/dialer/widget/res/values-gu/strings.xml @@ -1,10 +1,26 @@ + + "એક કસ્ટમ સંદેશ લખો" "બંધ કરો" "તમે હજી સુધી કોઇપણ સંપર્કો ધરાવતાં નથી" - "સંપર્ક ઉમેરો" + "નવો સંપર્ક બનાવો" "ચાલુ કરો" "તમારા સંપર્કો જોવા માટે, સંપર્કોની પરવાનગી ચાલુ કરો." "કોઈ સંપર્કો ઍપ્લિકેશન ઉપલબ્ધ નથી" diff --git a/java/com/android/dialer/widget/res/values-hi/strings.xml b/java/com/android/dialer/widget/res/values-hi/strings.xml index 5cdb8bbfc..622cdca06 100644 --- a/java/com/android/dialer/widget/res/values-hi/strings.xml +++ b/java/com/android/dialer/widget/res/values-hi/strings.xml @@ -1,10 +1,26 @@ + + "कोई कस्टम संदेश लिखें" "बंद करें" "आपके पास अभी कोई भी संपर्क नहीं है" - "कोई संपर्क जोड़ें" + "नया संपर्क बनाएं" "चालू करें" "अपने संपर्क देखने के लिए, संपर्क अनुमति चालू करें." "कोई भी संपर्क ऐप उपलब्‍ध नहीं है" diff --git a/java/com/android/dialer/widget/res/values-hr/strings.xml b/java/com/android/dialer/widget/res/values-hr/strings.xml index 9ded4d4a7..7254bc062 100644 --- a/java/com/android/dialer/widget/res/values-hr/strings.xml +++ b/java/com/android/dialer/widget/res/values-hr/strings.xml @@ -1,10 +1,27 @@ + + "Napišite prilagođenu poruku" "Zatvaranje" "Još nemate nijedan kontakt" - "Dodavanje kontakta" + + "Uključi" "Da biste vidjeli svoje kontakte, uključite dopuštenje za kontakte." "Nije dostupna nijedna aplikacija za kontakte" diff --git a/java/com/android/dialer/widget/res/values-hu/strings.xml b/java/com/android/dialer/widget/res/values-hu/strings.xml index 92ae71de8..5301d6970 100644 --- a/java/com/android/dialer/widget/res/values-hu/strings.xml +++ b/java/com/android/dialer/widget/res/values-hu/strings.xml @@ -1,10 +1,27 @@ + + "Egyéni üzenet írása" "Bezárás" "Még nem rendelkezik egyetlen névjeggyel sem" - "Névjegy hozzáadása" + + "Bekapcsolás" "A névjegyek megtekintéséhez kapcsolja be a Névjegyek engedélyt." "Nincs elérhető névjegykezelő alkalmazás" diff --git a/java/com/android/dialer/widget/res/values-hy/strings.xml b/java/com/android/dialer/widget/res/values-hy/strings.xml index ffa7132c5..95d0b7303 100644 --- a/java/com/android/dialer/widget/res/values-hy/strings.xml +++ b/java/com/android/dialer/widget/res/values-hy/strings.xml @@ -1,10 +1,26 @@ + + "Գրել տեքստն ինքնուրույն" "Փակել" "Դեռ կոնտակտներ չունեք" - "Ավելացնել կոնտակտ" + "Ստեղծել նոր կոնտակտ" "Միացնել" "Ձեր կոնտակտները տեսնելու համար միացրեք Կոնտակտների թույլտվությունը:" "Կոնտակտների հավելված չկա" diff --git a/java/com/android/dialer/widget/res/values-in/strings.xml b/java/com/android/dialer/widget/res/values-in/strings.xml index 69849ae02..98dfe7be2 100644 --- a/java/com/android/dialer/widget/res/values-in/strings.xml +++ b/java/com/android/dialer/widget/res/values-in/strings.xml @@ -1,10 +1,27 @@ + + "Tulis pesan khusus" "Tutup" "Anda belum memiliki kontak" - "Tambahkan kontak" + + "Aktifkan" "Untuk melihat kontak, aktifkan izin Kontak." "Aplikasi kontak tidak tersedia" diff --git a/java/com/android/dialer/widget/res/values-is/strings.xml b/java/com/android/dialer/widget/res/values-is/strings.xml index 98a172904..22485aa46 100644 --- a/java/com/android/dialer/widget/res/values-is/strings.xml +++ b/java/com/android/dialer/widget/res/values-is/strings.xml @@ -1,10 +1,27 @@ + + "Skrifa sérsniðin skilaboð" "Loka" "Þú ert ekki með neina tengiliði enn sem komið er" - "Bæta tengilið við" + + "Kveikja" "Kveiktu á tengiliðaheimildinni til að sjá tengiliðina þína." "Ekkert tengiliðaforrit í boði" diff --git a/java/com/android/dialer/widget/res/values-it/strings.xml b/java/com/android/dialer/widget/res/values-it/strings.xml index 1a6e6c135..059a7d644 100644 --- a/java/com/android/dialer/widget/res/values-it/strings.xml +++ b/java/com/android/dialer/widget/res/values-it/strings.xml @@ -1,10 +1,27 @@ + + "Scrivi un messaggio personalizzato" "Chiudi" "Nessun contatto disponibile" - "Aggiungi un contatto" + + "Attiva" "Per accedere ai tuoi contatti, attiva l\'autorizzazione Contatti." "Nessuna app di contatti disponibile" diff --git a/java/com/android/dialer/widget/res/values-iw/strings.xml b/java/com/android/dialer/widget/res/values-iw/strings.xml index f2a732a67..48bf21911 100644 --- a/java/com/android/dialer/widget/res/values-iw/strings.xml +++ b/java/com/android/dialer/widget/res/values-iw/strings.xml @@ -1,10 +1,26 @@ + + "כתוב הודעה מותאמת אישית" "סגירה" "עדיין אין לך אנשי קשר" - "הוספה של איש קשר" + "איש קשר חדש" "הפעלה" "עליך להפעיל את ההרשאה \'אנשי קשר\' כדי להציג את אנשי הקשר שלך." "אין אף אפליקציה לניהול אנשי קשר" diff --git a/java/com/android/dialer/widget/res/values-ja/strings.xml b/java/com/android/dialer/widget/res/values-ja/strings.xml index 7994c6262..969ffbac0 100644 --- a/java/com/android/dialer/widget/res/values-ja/strings.xml +++ b/java/com/android/dialer/widget/res/values-ja/strings.xml @@ -1,10 +1,27 @@ + + "カスタム メッセージを入力" "閉じる" "連絡先はまだありません" - "連絡先を追加" + + "ON にする" "連絡先を表示するには、連絡先へのアクセスを許可する設定を ON にしてください。" "利用できる連絡先アプリがありません" diff --git a/java/com/android/dialer/widget/res/values-ka/strings.xml b/java/com/android/dialer/widget/res/values-ka/strings.xml index 865a66b45..fcd45439e 100644 --- a/java/com/android/dialer/widget/res/values-ka/strings.xml +++ b/java/com/android/dialer/widget/res/values-ka/strings.xml @@ -1,10 +1,27 @@ + + "დაწერეთ მორგებ. შეტყობინება" "დახურვა" "კონტაქტები ჯერ არ გაქვთ" - "კონტაქტის დამატება" + + "ჩართვა" "კონტაქტების სანახავად ჩართეთ კონტაქტების ნებართვა." "კონტაქტების აპი მიუწვდომელია" diff --git a/java/com/android/dialer/widget/res/values-kk/strings.xml b/java/com/android/dialer/widget/res/values-kk/strings.xml index 08856aaec..cab827192 100644 --- a/java/com/android/dialer/widget/res/values-kk/strings.xml +++ b/java/com/android/dialer/widget/res/values-kk/strings.xml @@ -1,10 +1,27 @@ + + "Арнаулы хабар жазу" "Жабу" "Әлі ешқандай контактілер жоқ" - "Контакт қосу" + + "Қосу" "Контактілерді көру үшін \"Контактілер\" рұқсатын қосыңыз." "Контактілер қолданбасы қолжетімді емес" diff --git a/java/com/android/dialer/widget/res/values-km/strings.xml b/java/com/android/dialer/widget/res/values-km/strings.xml index c09233253..2d6f2f25d 100644 --- a/java/com/android/dialer/widget/res/values-km/strings.xml +++ b/java/com/android/dialer/widget/res/values-km/strings.xml @@ -1,10 +1,27 @@ + + "សរសេរ​សារ​ផ្ទាល់ខ្លួន" "បិទ" "អ្នកមិនទាន់មានទំនាក់ទំនងនៅឡើយទេ" - "បញ្ចូល​ទំនាក់ទំនង" + + "បើក" "ដើម្បីមើលទំនាក់ទំនងរបស់អ្នក សូមបើកការ​អនុញ្ញាតកម្មវិធីទំនាក់ទំនង។" "មិនមានកម្មវិធីទំនាក់ទំនងទេ" diff --git a/java/com/android/dialer/widget/res/values-kn/strings.xml b/java/com/android/dialer/widget/res/values-kn/strings.xml index a502d087e..d449cb8b7 100644 --- a/java/com/android/dialer/widget/res/values-kn/strings.xml +++ b/java/com/android/dialer/widget/res/values-kn/strings.xml @@ -1,10 +1,27 @@ + + "ಕಸ್ಟಮ್ ಸಂದೇಶವನ್ನು ಬರೆಯಿರಿ" "ಮುಚ್ಚಿ" "ನಿಮ್ಮ ಬಳಿ ಇನ್ನೂ ಯಾವುದೇ ಸಂಪರ್ಕಗಳಿಲ್ಲ" - "ಸಂಪರ್ಕ ಸೇರಿಸಿ" + + "ಆನ್ ಮಾಡಿ" "ನಿಮ್ಮ ಸಂಪರ್ಕಗಳನ್ನು ವೀಕ್ಷಿಸಲು, ಸಂಪರ್ಕಗಳ ಅನುಮತಿಯನ್ನು ಆನ್ ಮಾಡಿ." "ಯಾವುದೇ ಸಂಪರ್ಕಗಳ ಅಪ್ಲಿಕೇಶನ್‌ ಲಭ್ಯವಿಲ್ಲ" diff --git a/java/com/android/dialer/widget/res/values-ko/strings.xml b/java/com/android/dialer/widget/res/values-ko/strings.xml index 045dc54dc..0827d3648 100644 --- a/java/com/android/dialer/widget/res/values-ko/strings.xml +++ b/java/com/android/dialer/widget/res/values-ko/strings.xml @@ -1,10 +1,26 @@ + + "맞춤 메시지를 작성하세요." "닫기" "아직 연락처가 없습니다." - "연락처 추가" + "새 연락처 만들기" "사용" "연락처를 보려면 연락처에 액세스할 권한을 부여하세요." "사용할 수 있는 연락처 앱이 없습니다." diff --git a/java/com/android/dialer/widget/res/values-ky/strings.xml b/java/com/android/dialer/widget/res/values-ky/strings.xml index 7ef10e707..62bd08851 100644 --- a/java/com/android/dialer/widget/res/values-ky/strings.xml +++ b/java/com/android/dialer/widget/res/values-ky/strings.xml @@ -1,10 +1,27 @@ + + "Башка билдирүүнү жазыңыз" "Жабуу" "Азырынча эч байланышыңыз жок" - "Байланыш кошуу" + + "Күйгүзүү" "Байланыштарыңызды көрүү үчүн, \"Байланыштар\" уруксатын күйгүзүңүз." "Жеткиликтүү байланыштар колдонмосу жок" diff --git a/java/com/android/dialer/widget/res/values-lo/strings.xml b/java/com/android/dialer/widget/res/values-lo/strings.xml index dc7ba44c1..8b7e476d9 100644 --- a/java/com/android/dialer/widget/res/values-lo/strings.xml +++ b/java/com/android/dialer/widget/res/values-lo/strings.xml @@ -1,10 +1,26 @@ + + "ຂຽນຂໍ້ຄວາມດ້ວຍຕົນເອງ" "ປິດ" "ທ່ານຍັງບໍ່ມີລາຍຊື່ຜູ້ຕິດຕໍ່ເທື່ອ" - "ເພີ່ມລາຍຊື່" + "ສ້າງລາຍຊື່ຜູ້ຕິດຕໍ່ໃໝ່" "ເປີດໃຊ້" "ເພື່ອເບິ່ງລາຍຊື່ຜູ້ຕິດຕໍ່ຂອງທ່ານ, ໃຫ້ເປີດການອະນຸຍາດລາຍຊື່ຜູ້ຕິດຕໍ່ກ່ອນ" "ບໍ່ມີແອັບລາຍຊື່ຜູ້ຕິດຕໍ່ທີ່ສາມາດໃຊ້ໄດ້" diff --git a/java/com/android/dialer/widget/res/values-lt/strings.xml b/java/com/android/dialer/widget/res/values-lt/strings.xml index be12520f8..30cc0adeb 100644 --- a/java/com/android/dialer/widget/res/values-lt/strings.xml +++ b/java/com/android/dialer/widget/res/values-lt/strings.xml @@ -1,10 +1,26 @@ + + "Parašykite tinkintą praneš." "Uždaryti" "Dar neturite jokių kontaktų" - "Pridėkite kontaktą" + "Sukurti naują kontaktą" "Įjungti" "Jei norite peržiūrėti kontaktus, įjunkite Kontaktų leidimą." "Nepasiekiama jokia kontaktų programa" diff --git a/java/com/android/dialer/widget/res/values-lv/strings.xml b/java/com/android/dialer/widget/res/values-lv/strings.xml index acefbaea4..87464c576 100644 --- a/java/com/android/dialer/widget/res/values-lv/strings.xml +++ b/java/com/android/dialer/widget/res/values-lv/strings.xml @@ -1,10 +1,27 @@ + + "Rakstīt pielāgotu ziņojumu" "Aizvērt" "Jums vēl nav nevienas kontaktpersonas." - "Pievienot kontaktpersonu" + + "Ieslēgt" "Lai skatītu savas kontaktpersonas, ieslēdziet atļauju Kontaktpersonas." "Nav pieejama neviena kontaktpersonu lietotne." diff --git a/java/com/android/dialer/widget/res/values-mk/strings.xml b/java/com/android/dialer/widget/res/values-mk/strings.xml index 20b18e8d9..cd2f86b7c 100644 --- a/java/com/android/dialer/widget/res/values-mk/strings.xml +++ b/java/com/android/dialer/widget/res/values-mk/strings.xml @@ -1,10 +1,27 @@ + + "Напиши приспособена порака" "Затвори" "Сè уште немате контакти" - "Додајте контакт" + + "Вклучи" "За да ги видите контактите, вклучете ја дозволата за контакти." "Нема достапна апликација за контакти" diff --git a/java/com/android/dialer/widget/res/values-ml/strings.xml b/java/com/android/dialer/widget/res/values-ml/strings.xml index a97a7d862..1799755d1 100644 --- a/java/com/android/dialer/widget/res/values-ml/strings.xml +++ b/java/com/android/dialer/widget/res/values-ml/strings.xml @@ -1,10 +1,27 @@ + + "ഒരു ഇ‌ഷ്‌ടാനുസൃത സന്ദേശം രചിക്കൂ" "അടയ്‌ക്കുക" "നിങ്ങൾക്ക് ഇതുവരെയും കോൺടാക്റ്റുകൾ ഒന്നുമില്ല." - "ഒരു കോണ്‍ടാക്റ്റ് ചേര്‍ക്കുക" + + "ഓൺ ചെയ്യുക" "നിങ്ങളുടെ കോൺടാക്റ്റുകൾ കാണുന്നതിന്, \'കോൺടാക്റ്റുകൾ\' അനുമതി ഓണാക്കുക." "കോൺടാക്റ്റ് അപ്ലിക്കേഷനൊന്നും ലഭ്യമല്ല" diff --git a/java/com/android/dialer/widget/res/values-mn/strings.xml b/java/com/android/dialer/widget/res/values-mn/strings.xml index bbcfc7cf6..e5f5c2162 100644 --- a/java/com/android/dialer/widget/res/values-mn/strings.xml +++ b/java/com/android/dialer/widget/res/values-mn/strings.xml @@ -1,10 +1,26 @@ + + "Тусгай зурвас бичих" "Хаах" "Танд одоогоор харилцагч байхгүй байна" - "Харилцагч нэмэх" + "Шинэ харилцагч үүсгэх" "Асаах" "Харилцагчдаа харахын тулд Харилцагчдын зөвшөөрлийг идэвхжүүлнэ үү." "Ямар ч харилцагчдын апликейшн байхгүй байна" diff --git a/java/com/android/dialer/widget/res/values-mr/strings.xml b/java/com/android/dialer/widget/res/values-mr/strings.xml index 38d913a85..63239d21d 100644 --- a/java/com/android/dialer/widget/res/values-mr/strings.xml +++ b/java/com/android/dialer/widget/res/values-mr/strings.xml @@ -1,10 +1,26 @@ + + "एक सानुकूल संदेश लिहा" "बंद करा" "आपल्‍याकडे अद्याप कोणतेही संपर्क नाहीत" - "एक संपर्क जोडा" + "नवीन संपर्क तयार करा" "चालू करा" "आपले संपर्क पाहण्‍यासाठी, संपर्क परवानगी चालू करा." "कोणताही संपर्क अॅप उपलब्ध नाही" diff --git a/java/com/android/dialer/widget/res/values-ms/strings.xml b/java/com/android/dialer/widget/res/values-ms/strings.xml index bc67c6764..cf61fc171 100644 --- a/java/com/android/dialer/widget/res/values-ms/strings.xml +++ b/java/com/android/dialer/widget/res/values-ms/strings.xml @@ -1,10 +1,26 @@ + + "Tulis mesej tersuai" "Tutup" "Anda belum mempunyai sebarang kenalan" - "Tambahkan kenalan" + "Buat kenalan baharu" "Hidupkan" "Untuk melihat kenalan anda, hidupkan kebenaran Kenalan." "Tiada apl kenalan yang tersedia" diff --git a/java/com/android/dialer/widget/res/values-my/strings.xml b/java/com/android/dialer/widget/res/values-my/strings.xml index c8e783bf4..5d3d9ebff 100644 --- a/java/com/android/dialer/widget/res/values-my/strings.xml +++ b/java/com/android/dialer/widget/res/values-my/strings.xml @@ -1,10 +1,26 @@ + + "စိတ်ကြိုက် မက်ဆေ့ဂျ်တစ်ခု ရေးပါ" "ပိတ်ရန်" "သင့်တွင် မည်သည့်အဆက်အသွယ်မျှ မရှိသေးပါ" - "အဆက်အသွယ်တစ်ယောက် ထည့်မည်" + "အဆက်အသွယ်အသစ် ပြုလုပ်ရန်" "ဖွင့်ရန်" "အဆက်အသွယ်များကိုကြည့်ရန်၊ အဆက်အသွယ်ခွင့်ပြုချက်ကို ဖွင့်ပါ။" "အဆက်အသွယ်များ app မရှိပါ" diff --git a/java/com/android/dialer/widget/res/values-nb/strings.xml b/java/com/android/dialer/widget/res/values-nb/strings.xml index 822f07ed1..441218267 100644 --- a/java/com/android/dialer/widget/res/values-nb/strings.xml +++ b/java/com/android/dialer/widget/res/values-nb/strings.xml @@ -1,10 +1,27 @@ + + "Skriv egendefinert melding" "Lukk" "Du har ingen kontakter ennå" - "Legg til en kontakt" + + "Slå på" "For å se kontaktene dine må du slå på Kontakter-tillatelsen." "Ingen kontaktapper er tilgjengelige" diff --git a/java/com/android/dialer/widget/res/values-ne/strings.xml b/java/com/android/dialer/widget/res/values-ne/strings.xml index ebb31d579..e1f6e959b 100644 --- a/java/com/android/dialer/widget/res/values-ne/strings.xml +++ b/java/com/android/dialer/widget/res/values-ne/strings.xml @@ -1,10 +1,26 @@ + + "आफू अनुकूल सन्देश लेख्‍ने" "बन्द गर्नुहोस्" "अहिलेसम्म तपाईंसँग कुनै सम्पर्कहरू छैनन्" - "कुनै सम्पर्क थप्नुहोस्" + "नयाँ सम्पर्क सिर्जना गर्नुहोस्" "सक्रिय गर्नुहोस्" "आफ्ना सम्पर्कहरू हेर्न सम्पर्क सम्बन्धी अनुमतिलाई सक्रिय गर्नुहोस्।" "सम्पर्क सम्बन्धी कुनै अनुप्रयोग उपलब्ध छैन" diff --git a/java/com/android/dialer/widget/res/values-nl/strings.xml b/java/com/android/dialer/widget/res/values-nl/strings.xml index cbc286ba3..1fb5f5ed3 100644 --- a/java/com/android/dialer/widget/res/values-nl/strings.xml +++ b/java/com/android/dialer/widget/res/values-nl/strings.xml @@ -1,10 +1,27 @@ + + "Schrijf zelf een bericht" "Sluiten" "Je hebt nog geen contacten" - "Een contact toevoegen" + + "Inschakelen" "Als je je contacten wilt bekijken, schakel je de machtiging voor Contacten in." "Geen app voor contacten beschikbaar" diff --git a/java/com/android/dialer/widget/res/values-no/strings.xml b/java/com/android/dialer/widget/res/values-no/strings.xml index 822f07ed1..441218267 100644 --- a/java/com/android/dialer/widget/res/values-no/strings.xml +++ b/java/com/android/dialer/widget/res/values-no/strings.xml @@ -1,10 +1,27 @@ + + "Skriv egendefinert melding" "Lukk" "Du har ingen kontakter ennå" - "Legg til en kontakt" + + "Slå på" "For å se kontaktene dine må du slå på Kontakter-tillatelsen." "Ingen kontaktapper er tilgjengelige" diff --git a/java/com/android/dialer/widget/res/values-pa/strings.xml b/java/com/android/dialer/widget/res/values-pa/strings.xml index 06f191e50..14b7b416b 100644 --- a/java/com/android/dialer/widget/res/values-pa/strings.xml +++ b/java/com/android/dialer/widget/res/values-pa/strings.xml @@ -1,10 +1,26 @@ + + "ਵਿਸ਼ੇਸ਼-ਵਿਉਂਤਬੱਧ ਸੰਦੇਸ਼ ਲਿਖੋ" "ਬੰਦ ਕਰੋ" "ਤੁਹਾਡੇ ਕੋਲ ਹਾਲੇ ਕੋਈ ਸੰਪਰਕ ਨਹੀਂ ਹਨ" - "ਕੋਈ ਸੰਪਰਕ ਸ਼ਾਮਲ ਕਰੋ" + "ਨਵਾਂ ਸੰਪਰਕ ਬਣਾਓ" "ਚਾਲੂ ਕਰੋ" "ਆਪਣੇ ਸੰਪਰਕਾਂ ਨੂੰ ਵੇਖਣ ਲਈ, ਸੰਪਰਕ ਇਜਾਜ਼ਤ ਚਾਲੂ ਕਰੋ।" "ਕੋਈ ਸੰਪਰਕ ਐਪ ਉਪਲਬਧ ਨਹੀਂ ਹੈ" diff --git a/java/com/android/dialer/widget/res/values-pl/strings.xml b/java/com/android/dialer/widget/res/values-pl/strings.xml index 5d62a07f1..3f0668c98 100644 --- a/java/com/android/dialer/widget/res/values-pl/strings.xml +++ b/java/com/android/dialer/widget/res/values-pl/strings.xml @@ -1,10 +1,26 @@ + + "Wpisz wiadomość" "Zamknij" "Nie masz jeszcze żadnych kontaktów" - "Dodaj kontakt" + "Utwórz nowy kontakt" "Włącz" "Aby zobaczyć swoje kontakty, włącz uprawnienia Kontakty." "Nie jest dostępna żadna aplikacja do obsługi kontaktów" diff --git a/java/com/android/dialer/widget/res/values-pt-rBR/strings.xml b/java/com/android/dialer/widget/res/values-pt-rBR/strings.xml index 0afc0f1d6..7bc501e4f 100644 --- a/java/com/android/dialer/widget/res/values-pt-rBR/strings.xml +++ b/java/com/android/dialer/widget/res/values-pt-rBR/strings.xml @@ -1,10 +1,27 @@ + + "Escreva sua mensagem" "Fechar" "Você ainda não tem contatos" - "Adicionar um contato" + + "Ativar" "Para ver seus contatos, ative a permissão para o app Contatos." "Nenhum app de contatos disponível" diff --git a/java/com/android/dialer/widget/res/values-pt-rPT/strings.xml b/java/com/android/dialer/widget/res/values-pt-rPT/strings.xml index 35f71a371..459ba5790 100644 --- a/java/com/android/dialer/widget/res/values-pt-rPT/strings.xml +++ b/java/com/android/dialer/widget/res/values-pt-rPT/strings.xml @@ -1,10 +1,27 @@ + + "Escreva uma mensagem" "Fechar" "Ainda não tem nenhum contacto" - "Adicionar um contacto" + + "Ativar" "Para ver os seus contactos, ative a autorização Contactos." "Não existe nenhuma aplicação de contactos disponível" diff --git a/java/com/android/dialer/widget/res/values-pt/strings.xml b/java/com/android/dialer/widget/res/values-pt/strings.xml index 0afc0f1d6..7bc501e4f 100644 --- a/java/com/android/dialer/widget/res/values-pt/strings.xml +++ b/java/com/android/dialer/widget/res/values-pt/strings.xml @@ -1,10 +1,27 @@ + + "Escreva sua mensagem" "Fechar" "Você ainda não tem contatos" - "Adicionar um contato" + + "Ativar" "Para ver seus contatos, ative a permissão para o app Contatos." "Nenhum app de contatos disponível" diff --git a/java/com/android/dialer/widget/res/values-ro/strings.xml b/java/com/android/dialer/widget/res/values-ro/strings.xml index 6c51d23ac..6138eb1b6 100644 --- a/java/com/android/dialer/widget/res/values-ro/strings.xml +++ b/java/com/android/dialer/widget/res/values-ro/strings.xml @@ -1,10 +1,27 @@ + + "Scrieți mesaj personalizat" "Închideți" "Nu aveți încă persoane de contact." - "Adăugați o persoană de contact" + + "Activați" "Pentru a vedea persoanele de contact, activați permisiunea pentru Agendă." "Nu este disponibilă nicio aplicație pentru agendă" diff --git a/java/com/android/dialer/widget/res/values-ru/strings.xml b/java/com/android/dialer/widget/res/values-ru/strings.xml index c36874de5..7eb9f1de1 100644 --- a/java/com/android/dialer/widget/res/values-ru/strings.xml +++ b/java/com/android/dialer/widget/res/values-ru/strings.xml @@ -1,10 +1,27 @@ + + "Добавьте свой текст" "Закрыть" "Контактов нет" - "Добавить контакт" + + "Предоставить разрешение" "Чтобы открыть список контактов, предоставьте приложению разрешение \"Контакты\"." "Нет приложения для работы с контактами" diff --git a/java/com/android/dialer/widget/res/values-si/strings.xml b/java/com/android/dialer/widget/res/values-si/strings.xml index 10eb7b5b5..fb5742576 100644 --- a/java/com/android/dialer/widget/res/values-si/strings.xml +++ b/java/com/android/dialer/widget/res/values-si/strings.xml @@ -1,10 +1,27 @@ + + "අභිරුචි පණිවිඩයක් ලියන්න" "වසන්න" "ඔබට තවම කිසිදු සම්බන්ධතාවක් නැත" - "සම්බන්ධතාවක් එක් කරන්න" + + "ක්‍රියාත්මක කරන්න" "ඔබේ සම්බන්ධතා බැලීමට, සම්බන්ධතා අවසරය ක්‍රියාත්මක කරන්න." "සබඳතා යෙදුම ලබා ගැනීමට නොහැකිය" diff --git a/java/com/android/dialer/widget/res/values-sk/strings.xml b/java/com/android/dialer/widget/res/values-sk/strings.xml index 56f7ceb97..5912b574a 100644 --- a/java/com/android/dialer/widget/res/values-sk/strings.xml +++ b/java/com/android/dialer/widget/res/values-sk/strings.xml @@ -1,10 +1,27 @@ + + "Napíšte vlastnú správu" "Zavrieť" "Zatiaľ nemáte žiadne kontakty" - "Pridať kontakt" + + "Zapnúť" "Ak si chcete zobraziť kontakty, zapnite povolenie Kontakty." "Nie je k dispozícii žiadna aplikácia na prácu s kontaktmi" diff --git a/java/com/android/dialer/widget/res/values-sl/strings.xml b/java/com/android/dialer/widget/res/values-sl/strings.xml index 52f029377..1ee87d13d 100644 --- a/java/com/android/dialer/widget/res/values-sl/strings.xml +++ b/java/com/android/dialer/widget/res/values-sl/strings.xml @@ -1,10 +1,27 @@ + + "Napišite sporočilo po meri" "Zapri" "Nimate še nobenega stika" - "Dodaj stik" + + "Vklopi" "Če si želite ogledati stike, vklopite dovoljenje za stike." "Na voljo ni nobene aplikacije za stike" diff --git a/java/com/android/dialer/widget/res/values-sq/strings.xml b/java/com/android/dialer/widget/res/values-sq/strings.xml index c7943dfd3..b55e47c89 100644 --- a/java/com/android/dialer/widget/res/values-sq/strings.xml +++ b/java/com/android/dialer/widget/res/values-sq/strings.xml @@ -1,10 +1,27 @@ + + "Shkruaj mesazh të person." "Mbyll" "Nuk ke ende kontakte" - "Shto një kontakt" + + "Aktivizo" "Për të parë kontaktet, aktivizo lejen e Kontakteve." "Nuk ka asnjë aplikacion për kontaktet" diff --git a/java/com/android/dialer/widget/res/values-sr/strings.xml b/java/com/android/dialer/widget/res/values-sr/strings.xml index 00b9b4f6c..c2f269d3f 100644 --- a/java/com/android/dialer/widget/res/values-sr/strings.xml +++ b/java/com/android/dialer/widget/res/values-sr/strings.xml @@ -1,10 +1,26 @@ + + "Напишите прилагођену поруку" "Затворите" "Још увек немате ниједан контакт" - "Додај контакт" + "Направи нови контакт" "Укључи" "Да бисте видели контакте, укључите дозволу за Контакте." "Нема доступне апликације за контакте" diff --git a/java/com/android/dialer/widget/res/values-sv/strings.xml b/java/com/android/dialer/widget/res/values-sv/strings.xml index 359397026..75add78ac 100644 --- a/java/com/android/dialer/widget/res/values-sv/strings.xml +++ b/java/com/android/dialer/widget/res/values-sv/strings.xml @@ -1,10 +1,26 @@ + + "Skriv anpassat meddelande" "Stäng" "Du har inga kontakter ännu" - "Lägg till en kontakt" + "Skapa ny kontakt" "Aktivera" "Du måste aktivera behörigheten Kontakter för att visa kontakterna." "Det finns inga appar för kontakter" diff --git a/java/com/android/dialer/widget/res/values-sw/strings.xml b/java/com/android/dialer/widget/res/values-sw/strings.xml index b0892108b..a9139809f 100644 --- a/java/com/android/dialer/widget/res/values-sw/strings.xml +++ b/java/com/android/dialer/widget/res/values-sw/strings.xml @@ -1,10 +1,27 @@ + + "Andika ujumbe maalum" "Funga" "Bado huna anwani zozote" - "Ongeza anwani" + + "Washa" "Ili uone anwani zako, washa ruhusa ya Anwani." "Hakuna programu ya anwani iliyopatikana" diff --git a/java/com/android/dialer/widget/res/values-ta/strings.xml b/java/com/android/dialer/widget/res/values-ta/strings.xml index 83ca080e5..17333304f 100644 --- a/java/com/android/dialer/widget/res/values-ta/strings.xml +++ b/java/com/android/dialer/widget/res/values-ta/strings.xml @@ -1,10 +1,26 @@ + + "தனிப்பயன் செய்தியை எழுதவும்" "மூடு" "இதுவரை தொடர்புகள் எதுவுமில்லை" - "தொடர்பைச் சேர்" + "புதிய தொடர்பை உருவாக்கு" "இயக்கு" "தொடர்புகளைப் பார்க்க, தொடர்புகள் அனுமதியை இயக்கவும்." "தொடர்புகள் பயன்பாடு எதுவுமில்லை" diff --git a/java/com/android/dialer/widget/res/values-te/strings.xml b/java/com/android/dialer/widget/res/values-te/strings.xml index 418cc3d0b..27e6b0536 100644 --- a/java/com/android/dialer/widget/res/values-te/strings.xml +++ b/java/com/android/dialer/widget/res/values-te/strings.xml @@ -1,10 +1,26 @@ + + "అనుకూల సందేశాన్ని వ్రాయండి" "మూసివేయి" "మీకు ఇప్పటికీ పరిచయాలేవీ లేవు" - "పరిచయాన్ని జోడించండి" + "కొత్త పరిచయాన్ని సృష్టించండి" "ఆన్ చేయి" "మీ పరిచయాలను చూడటానికి, పరిచయాల అనుమతిని ఆన్ చేయండి." "పరిచయాల అనువర్తనం ఏదీ అందుబాటులో లేదు" diff --git a/java/com/android/dialer/widget/res/values-th/strings.xml b/java/com/android/dialer/widget/res/values-th/strings.xml index c556d1c37..40134c84d 100644 --- a/java/com/android/dialer/widget/res/values-th/strings.xml +++ b/java/com/android/dialer/widget/res/values-th/strings.xml @@ -1,10 +1,26 @@ + + "เขียนข้อความที่กำหนดเอง" "ปิด" "คุณยังไม่มีรายชื่อติดต่อ" - "เพิ่มรายชื่อติดต่อ" + "สร้างรายชื่อติดต่อใหม่" "เปิด" "หากต้องการดูรายชื่อติดต่อ ให้เปิดสิทธิ์เข้าถึงรายชื่อติดต่อ" "ไม่มีแอปรายชื่อติดต่อที่พร้อมใช้งาน" diff --git a/java/com/android/dialer/widget/res/values-tl/strings.xml b/java/com/android/dialer/widget/res/values-tl/strings.xml index be02d1989..406f18b5e 100644 --- a/java/com/android/dialer/widget/res/values-tl/strings.xml +++ b/java/com/android/dialer/widget/res/values-tl/strings.xml @@ -1,10 +1,27 @@ + + "Sumulat ng custom na mensahe" "Isara" "Wala ka pang sinumang contact" - "Magdagdag ng contact" + + "I-on" "Upang makita ang iyong mga contact, i-on ang pahintulot ng Mga Contact." "Walang available na app ng mga contact" diff --git a/java/com/android/dialer/widget/res/values-tr/strings.xml b/java/com/android/dialer/widget/res/values-tr/strings.xml index 90d5db649..e1dcabd48 100644 --- a/java/com/android/dialer/widget/res/values-tr/strings.xml +++ b/java/com/android/dialer/widget/res/values-tr/strings.xml @@ -1,10 +1,27 @@ + + "Özel bir mesaj yazın" "Kapat" "Henüz hiç kişiniz yok" - "Kişi ekleyin" + + "Etkinleştir" "Kişilerinizi görmek için Kişiler iznini etkinleştirin." "Kullanılabilir kişi uygulaması yok" diff --git a/java/com/android/dialer/widget/res/values-uk/strings.xml b/java/com/android/dialer/widget/res/values-uk/strings.xml index cf5a7d1db..d1a281c64 100644 --- a/java/com/android/dialer/widget/res/values-uk/strings.xml +++ b/java/com/android/dialer/widget/res/values-uk/strings.xml @@ -1,10 +1,26 @@ + + "Ваше власне повідомлення" "Закрити" "Ще немає контактів" - "Додати контакт" + "Створити контакт" "Увімкнути" "Щоб переглянути контакти, увімкніть дозвіл \"Контакти\"." "Немає додатка з контактами" diff --git a/java/com/android/dialer/widget/res/values-ur/strings.xml b/java/com/android/dialer/widget/res/values-ur/strings.xml index e5199afe4..d5dcad0bd 100644 --- a/java/com/android/dialer/widget/res/values-ur/strings.xml +++ b/java/com/android/dialer/widget/res/values-ur/strings.xml @@ -1,10 +1,26 @@ + + "ایک حسب ضرورت پیغام لکھیں" "بند کریں" "آپ کے پاس ابھی تک کوئی رابطے نہیں ہیں" - "ایک رابطہ شامل کریں" + "نیا رابطہ بنائیں" "آن کریں" "اپنے رابطے دیکھنے کیلئے رابطوں کی اجازت آن کریں۔" "رابطوں کی کوئی ایپ دستیاب نہیں ہے" diff --git a/java/com/android/dialer/widget/res/values-uz/strings.xml b/java/com/android/dialer/widget/res/values-uz/strings.xml index eb0e0adae..b3003be16 100644 --- a/java/com/android/dialer/widget/res/values-uz/strings.xml +++ b/java/com/android/dialer/widget/res/values-uz/strings.xml @@ -1,10 +1,27 @@ + + "Boshqa xabar yozing" "Yopish" "Kontaktlar yo‘q" - "Kontakt qo‘shish" + + "Ruxsat berish" "Kontaktlar ro‘yxatini ko‘rish uchun ilovaga Kontaktlarga kirishga ruxsat bering." "Kontaktlarni ochadigan ilova yo‘q" diff --git a/java/com/android/dialer/widget/res/values-vi/strings.xml b/java/com/android/dialer/widget/res/values-vi/strings.xml index 62e94b82e..68669ec67 100644 --- a/java/com/android/dialer/widget/res/values-vi/strings.xml +++ b/java/com/android/dialer/widget/res/values-vi/strings.xml @@ -1,10 +1,27 @@ + + "Viết tin nhắn tùy chỉnh" "Đóng" "Bạn chưa có bất kỳ liên hệ nào" - "Thêm liên hệ" + + "Bật" "Để xem danh bạ của bạn, bật quyền đối với Danh bạ." "Không có ứng dụng danh bạ" diff --git a/java/com/android/dialer/widget/res/values-zh-rCN/strings.xml b/java/com/android/dialer/widget/res/values-zh-rCN/strings.xml index 063301ae0..4a5e45801 100644 --- a/java/com/android/dialer/widget/res/values-zh-rCN/strings.xml +++ b/java/com/android/dialer/widget/res/values-zh-rCN/strings.xml @@ -1,10 +1,26 @@ + + "自行撰写信息" "关闭" "您还没有任何联系人" - "添加联系人" + "创建新联系人" "开启" "要查看您的联系人,请开启“通讯录”权限。" "没有可用的通讯录应用" diff --git a/java/com/android/dialer/widget/res/values-zh-rHK/strings.xml b/java/com/android/dialer/widget/res/values-zh-rHK/strings.xml index e2e69b75b..3d5fe6ebb 100644 --- a/java/com/android/dialer/widget/res/values-zh-rHK/strings.xml +++ b/java/com/android/dialer/widget/res/values-zh-rHK/strings.xml @@ -1,10 +1,26 @@ + + "撰寫自訂訊息" "關閉" "您尚無任何聯絡人" - "新增聯絡人" + "建立新聯絡人" "開放" "如要查看聯絡人,請開放「通訊錄」權限。" "沒有可用的聯絡人應用程式" diff --git a/java/com/android/dialer/widget/res/values-zh-rTW/strings.xml b/java/com/android/dialer/widget/res/values-zh-rTW/strings.xml index 85768af8f..0cb8d152d 100644 --- a/java/com/android/dialer/widget/res/values-zh-rTW/strings.xml +++ b/java/com/android/dialer/widget/res/values-zh-rTW/strings.xml @@ -1,10 +1,27 @@ + + "撰寫自訂訊息" "關閉" "你還沒有任何聯絡人" - "新增聯絡人" + + "開啟" "如要查看你的聯絡人,請開啟「聯絡人」存取權限。" "沒有可用的聯絡人應用程式" diff --git a/java/com/android/dialer/widget/res/values-zu/strings.xml b/java/com/android/dialer/widget/res/values-zu/strings.xml index a3ba84a9a..ca5898341 100644 --- a/java/com/android/dialer/widget/res/values-zu/strings.xml +++ b/java/com/android/dialer/widget/res/values-zu/strings.xml @@ -1,10 +1,27 @@ + + "Bhala umlayezo wangokwezifiso" "Vala" "Awunabo oxhumana nabo okwamanje" - "Engeza oxhumana naye" + + "Vula" "Ukuze ubone oxhumana nabo, vula imvume yoxhumana nabo." "Alukho uhlelo lokusebenza loxhumana nabo olutholakalayo" diff --git a/java/com/android/dialer/widget/res/values/strings.xml b/java/com/android/dialer/widget/res/values/strings.xml index d6ea2e7cd..74a5f0f21 100644 --- a/java/com/android/dialer/widget/res/values/strings.xml +++ b/java/com/android/dialer/widget/res/values/strings.xml @@ -1,4 +1,19 @@ + Write a custom message @@ -10,7 +25,7 @@ You don\'t have any contacts yet - Add a contact + Create new contact Turn on diff --git a/java/com/android/dialershared/bubble/Bubble.java b/java/com/android/dialershared/bubble/Bubble.java index 3eb88aa22..dbb5ea759 100644 --- a/java/com/android/dialershared/bubble/Bubble.java +++ b/java/com/android/dialershared/bubble/Bubble.java @@ -26,8 +26,12 @@ import android.content.Context; import android.content.Intent; import android.content.res.ColorStateList; import android.graphics.PixelFormat; +import android.graphics.drawable.Animatable; +import android.graphics.drawable.Drawable; import android.graphics.drawable.RippleDrawable; import android.net.Uri; +import android.os.Build.VERSION; +import android.os.Build.VERSION_CODES; import android.os.Handler; import android.provider.Settings; import android.support.annotation.ColorInt; @@ -47,6 +51,7 @@ import android.view.LayoutInflater; import android.view.MotionEvent; import android.view.View; import android.view.ViewGroup; +import android.view.ViewGroup.MarginLayoutParams; import android.view.ViewPropertyAnimator; import android.view.ViewTreeObserver.OnPreDrawListener; import android.view.WindowManager; @@ -69,6 +74,8 @@ import java.util.List; * convenience) */ public class Bubble { + // This class has some odd behavior that is not immediately obvious in order to avoid jank when + // resizing. See http://go/bubble-resize for details. // How long text should show after showText(CharSequence) is called private static final int SHOW_TEXT_DURATION_MILLIS = 3000; @@ -96,6 +103,8 @@ public class Bubble { private final Handler handler = new Handler(); private ViewHolder viewHolder; + private ViewPropertyAnimator collapseAnimation; + private Integer overrideGravity; @Retention(RetentionPolicy.SOURCE) @IntDef({CollapseEnd.NOTHING, CollapseEnd.HIDE}) @@ -114,7 +123,7 @@ public class Bubble { public static boolean canShowBubbles(@NonNull Context context) { return canShowBubblesForTesting != null ? canShowBubblesForTesting - : Settings.canDrawOverlays(context); + : VERSION.SDK_INT < VERSION_CODES.M || Settings.canDrawOverlays(context); } @VisibleForTesting(otherwise = VisibleForTesting.NONE) @@ -127,7 +136,7 @@ public class Bubble { public static Intent getRequestPermissionIntent(@NonNull Context context) { return new Intent( Settings.ACTION_MANAGE_OVERLAY_PERMISSION, - new Uri.Builder().scheme("package").fragment(context.getPackageName()).build()); + Uri.fromParts("package", context.getPackageName(), null)); } /** Creates instances of Bubble. The default implementation just calls the constructor. */ @@ -183,13 +192,12 @@ public class Bubble { type, LayoutParams.FLAG_NOT_TOUCH_MODAL | LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH - | LayoutParams.FLAG_NOT_FOCUSABLE, + | LayoutParams.FLAG_NOT_FOCUSABLE + | LayoutParams.FLAG_LAYOUT_NO_LIMITS, PixelFormat.TRANSLUCENT); windowParams.gravity = Gravity.TOP | Gravity.LEFT; - windowParams.x = - context.getResources().getDimensionPixelOffset(R.dimen.bubble_initial_offset_x); - windowParams.y = - context.getResources().getDimensionPixelOffset(R.dimen.bubble_initial_offset_y); + windowParams.x = context.getResources().getDimensionPixelOffset(R.dimen.bubble_safe_margin_x); + windowParams.y = currentInfo.getStartingYPosition(); windowParams.height = LayoutParams.WRAP_CONTENT; windowParams.width = LayoutParams.WRAP_CONTENT; } @@ -203,6 +211,7 @@ public class Bubble { showAnimator.setInterpolator(new OvershootInterpolator()); showAnimator.start(); isShowing = true; + updatePrimaryIconAnimation(); } /** @@ -235,6 +244,7 @@ public class Bubble { () -> { windowManager.removeView(viewHolder.getRoot()); isShowing = false; + updatePrimaryIconAnimation(); }) .start(); } @@ -342,6 +352,11 @@ public class Bubble { SHOW_TEXT_DURATION_MILLIS); } + @Nullable + Integer getGravityOverride() { + return overrideGravity; + } + void onMoveStart() { startCollapse(CollapseEnd.NOTHING); viewHolder @@ -353,23 +368,27 @@ public class Bubble { void onMoveFinish() { viewHolder.getPrimaryButton().animate().translationZ(0); + // If it's GONE, no resize is necessary. If it's VISIBLE, it will get cleaned up when the + // collapse animation finishes + if (viewHolder.getExpandedView().getVisibility() == View.INVISIBLE) { + doResize(null); + } } void primaryButtonClick() { if (expanded || textShowing || currentInfo.getActions().isEmpty()) { try { - currentInfo.getPrimaryAction().send(); + currentInfo.getPrimaryIntent().send(); } catch (CanceledException e) { throw new RuntimeException(e); } return; } - boolean onRight = (windowParams.gravity & Gravity.RIGHT) == Gravity.RIGHT; doResize( () -> { - onLeftRightSwitch(onRight); - viewHolder.getExpandedView().setVisibility(View.VISIBLE); + onLeftRightSwitch(isDrawingFromRight()); + viewHolder.setDrawerVisibility(View.VISIBLE); }); View expandedView = viewHolder.getExpandedView(); expandedView @@ -380,7 +399,7 @@ public class Bubble { public boolean onPreDraw() { expandedView.getViewTreeObserver().removeOnPreDrawListener(this); expandedView.setTranslationX( - onRight ? expandedView.getWidth() : -expandedView.getWidth()); + isDrawingFromRight() ? expandedView.getWidth() : -expandedView.getWidth()); expandedView .animate() .setInterpolator(new LinearOutSlowInInterpolator()) @@ -393,6 +412,14 @@ public class Bubble { } void onLeftRightSwitch(boolean onRight) { + if (viewHolder.isMoving()) { + if (viewHolder.getExpandedView().getVisibility() == View.GONE) { + // If the drawer is not part of the layout we don't need to do anything. Layout flips will + // happen if necessary when opening the drawer. + return; + } + } + viewHolder .getRoot() .setLayoutDirection(onRight ? View.LAYOUT_DIRECTION_RTL : View.LAYOUT_DIRECTION_LTR); @@ -437,6 +464,7 @@ public class Bubble { viewHolder.getSecondButton().setVisibility(numButtons < 2 ? View.GONE : View.VISIBLE); viewHolder.getPrimaryIcon().setImageIcon(currentInfo.getPrimaryIcon()); + updatePrimaryIconAnimation(); viewHolder .getExpandedView() @@ -445,6 +473,17 @@ public class Bubble { updateButtonStates(); } + private void updatePrimaryIconAnimation() { + Drawable drawable = viewHolder.getPrimaryIcon().getDrawable(); + if (drawable instanceof Animatable) { + if (isShowing) { + ((Animatable) drawable).start(); + } else { + ((Animatable) drawable).stop(); + } + } + } + private void setBackgroundDrawable(CheckableImageButton view, @ColorInt int color) { RippleDrawable itemRipple = (RippleDrawable) @@ -492,7 +531,7 @@ public class Bubble { private void doAction(Action action) { try { - action.getAction().send(); + action.getIntent().send(); } catch (CanceledException e) { throw new RuntimeException(e); } @@ -504,9 +543,8 @@ public class Bubble { // would occur. To fix this, instead of resizing the window, we create a new one and destroy // the old one. There is a short delay before destroying the old view to ensure the new one has // had time to draw. - boolean onRight = (windowParams.gravity & Gravity.RIGHT) == Gravity.RIGHT; ViewHolder oldViewHolder = viewHolder; - if (onRight) { + if (isDrawingFromRight()) { viewHolder = new ViewHolder(oldViewHolder.getRoot().getContext()); update(); viewHolder @@ -519,12 +557,13 @@ public class Bubble { operation.run(); } - if (onRight) { + if (isDrawingFromRight()) { swapViewHolders(oldViewHolder); } } private void swapViewHolders(ViewHolder oldViewHolder) { + oldViewHolder.getShadowProvider().setVisibility(View.GONE); ViewGroup root = viewHolder.getRoot(); windowManager.addView(root, windowParams); root.getViewTreeObserver() @@ -542,32 +581,56 @@ public class Bubble { }); } - private ViewPropertyAnimator startCollapse(@CollapseEnd int collapseEndAction) { - setFocused(false); - boolean onRight = (windowParams.gravity & Gravity.RIGHT) == Gravity.RIGHT; + private void startCollapse(@CollapseEnd int collapseEndAction) { View expandedView = viewHolder.getExpandedView(); - return expandedView - .animate() - .translationX(onRight ? expandedView.getWidth() : -expandedView.getWidth()) - .setInterpolator(new FastOutLinearInInterpolator()) - .withEndAction( - () -> { - expanded = false; - if (collapseEndAction == CollapseEnd.HIDE) { - hide(); - } else if (!textShowing) { - // Don't swap the window while the user is moving it, even if we're on the right. - // The movement will help hide the jank of the resize. - boolean swapWindow = onRight && !viewHolder.isMoving(); - if (swapWindow) { - // We don't actually need to set the drawer to GONE since in the new window it - // will already be GONE. Just do the resize operation. - doResize(null); - } else { - expandedView.setVisibility(View.GONE); - } - } - }); + if (expandedView.getVisibility() != View.VISIBLE || collapseAnimation != null) { + // Drawer is already collapsed or animation is running. + return; + } + + overrideGravity = isDrawingFromRight() ? Gravity.RIGHT : Gravity.LEFT; + setFocused(false); + collapseAnimation = + expandedView + .animate() + .translationX(isDrawingFromRight() ? expandedView.getWidth() : -expandedView.getWidth()) + .setInterpolator(new FastOutLinearInInterpolator()) + .withEndAction( + () -> { + collapseAnimation = null; + expanded = false; + + if (textShowing) { + // Will do resize once the text is done. + return; + } + + // Hide the drawer and resize if possible. + viewHolder.setDrawerVisibility(View.INVISIBLE); + if (!viewHolder.isMoving() || !isDrawingFromRight()) { + doResize(() -> viewHolder.setDrawerVisibility(View.GONE)); + } + + // If this collapse was to come before a hide, do it now. + if (collapseEndAction == CollapseEnd.HIDE) { + hide(); + } + + // Resume normal gravity after any resizing is done. + handler.postDelayed( + () -> { + overrideGravity = null; + if (!viewHolder.isMoving()) { + viewHolder.undoGravityOverride(); + } + }, + // Need to wait twice as long for resize and layout + WINDOW_REDRAW_DELAY_MILLIS * 2); + }); + } + + private boolean isDrawingFromRight() { + return (windowParams.gravity & Gravity.RIGHT) == Gravity.RIGHT; } private void setFocused(boolean focused) { @@ -594,6 +657,7 @@ public class Bubble { private final CheckableImageButton secondButton; private final CheckableImageButton thirdButton; private final View expandedView; + private final View shadowProvider; public ViewHolder(Context context) { // Window root is not in the layout file so that the inflater has a view to inflate into @@ -604,6 +668,7 @@ public class Bubble { primaryButton = contentView.findViewById(R.id.bubble_button_primary); primaryIcon = contentView.findViewById(R.id.bubble_icon_primary); primaryText = contentView.findViewById(R.id.bubble_text); + shadowProvider = contentView.findViewById(R.id.bubble_drawer_shadow_provider); firstButton = contentView.findViewById(R.id.bubble_icon_first); secondButton = contentView.findViewById(R.id.bubble_icon_second); @@ -625,6 +690,28 @@ public class Bubble { } return false; }); + expandedView + .getViewTreeObserver() + .addOnDrawListener( + () -> { + int translationX = (int) expandedView.getTranslationX(); + int parentOffset = + ((MarginLayoutParams) ((ViewGroup) expandedView.getParent()).getLayoutParams()) + .leftMargin; + if (isDrawingFromRight()) { + int maxLeft = + shadowProvider.getRight() + - context.getResources().getDimensionPixelSize(R.dimen.bubble_size); + shadowProvider.setLeft( + Math.min(maxLeft, expandedView.getLeft() + translationX + parentOffset)); + } else { + int minRight = + shadowProvider.getLeft() + + context.getResources().getDimensionPixelSize(R.dimen.bubble_size); + shadowProvider.setRight( + Math.max(minRight, expandedView.getRight() + translationX + parentOffset)); + } + }); moveHandler = new MoveHandler(primaryButton, Bubble.this); } @@ -660,8 +747,21 @@ public class Bubble { return expandedView; } + public View getShadowProvider() { + return shadowProvider; + } + + public void setDrawerVisibility(int visibility) { + expandedView.setVisibility(visibility); + shadowProvider.setVisibility(visibility); + } + public boolean isMoving() { return moveHandler.isMoving(); } + + public void undoGravityOverride() { + moveHandler.undoGravityOverride(); + } } } diff --git a/java/com/android/dialershared/bubble/BubbleInfo.java b/java/com/android/dialershared/bubble/BubbleInfo.java index 52417ae7b..eb9abd059 100644 --- a/java/com/android/dialershared/bubble/BubbleInfo.java +++ b/java/com/android/dialershared/bubble/BubbleInfo.java @@ -20,6 +20,7 @@ import android.app.PendingIntent; import android.graphics.drawable.Icon; import android.support.annotation.ColorInt; import android.support.annotation.NonNull; +import android.support.annotation.Px; import com.google.auto.value.AutoValue; import java.util.Collections; import java.util.List; @@ -34,7 +35,10 @@ public abstract class BubbleInfo { public abstract Icon getPrimaryIcon(); @NonNull - public abstract PendingIntent getPrimaryAction(); + public abstract PendingIntent getPrimaryIntent(); + + @Px + public abstract int getStartingYPosition(); @NonNull public abstract List getActions(); @@ -45,9 +49,10 @@ public abstract class BubbleInfo { public static Builder from(@NonNull BubbleInfo bubbleInfo) { return builder() - .setPrimaryAction(bubbleInfo.getPrimaryAction()) + .setPrimaryIntent(bubbleInfo.getPrimaryIntent()) .setPrimaryColor(bubbleInfo.getPrimaryColor()) .setPrimaryIcon(bubbleInfo.getPrimaryIcon()) + .setStartingYPosition(bubbleInfo.getStartingYPosition()) .setActions(bubbleInfo.getActions()); } @@ -59,7 +64,9 @@ public abstract class BubbleInfo { public abstract Builder setPrimaryIcon(@NonNull Icon primaryIcon); - public abstract Builder setPrimaryAction(@NonNull PendingIntent primaryAction); + public abstract Builder setPrimaryIntent(@NonNull PendingIntent primaryIntent); + + public abstract Builder setStartingYPosition(@Px int startingYPosition); public abstract Builder setActions(List actions); @@ -77,7 +84,7 @@ public abstract class BubbleInfo { public abstract CharSequence getName(); @NonNull - public abstract PendingIntent getAction(); + public abstract PendingIntent getIntent(); public abstract boolean isEnabled(); @@ -89,7 +96,7 @@ public abstract class BubbleInfo { public static Builder from(@NonNull Action action) { return builder() - .setAction(action.getAction()) + .setIntent(action.getIntent()) .setChecked(action.isChecked()) .setEnabled(action.isEnabled()) .setName(action.getName()) @@ -104,7 +111,7 @@ public abstract class BubbleInfo { public abstract Builder setName(@NonNull CharSequence name); - public abstract Builder setAction(@NonNull PendingIntent action); + public abstract Builder setIntent(@NonNull PendingIntent intent); public abstract Builder setEnabled(boolean enabled); diff --git a/java/com/android/dialershared/bubble/MoveHandler.java b/java/com/android/dialershared/bubble/MoveHandler.java index 8a21cd7e1..bc6db64bc 100644 --- a/java/com/android/dialershared/bubble/MoveHandler.java +++ b/java/com/android/dialershared/bubble/MoveHandler.java @@ -39,7 +39,7 @@ class MoveHandler implements OnTouchListener { // Amount the ViewConfiguration's minFlingVelocity will be scaled by for our own minVelocity private static final int MIN_FLING_VELOCITY_FACTOR = 8; // The friction multiplier to control how slippery the bubble is when flung - private static final float SCROLL_FRICTION_MULTIPLIER = 8f; + private static final float SCROLL_FRICTION_MULTIPLIER = 4f; private final Context context; private final WindowManager windowManager; @@ -78,12 +78,22 @@ class MoveHandler implements OnTouchListener { @Override public void setValue(LayoutParams windowParams, float value) { + boolean wasOnRight = (windowParams.gravity & Gravity.RIGHT) == Gravity.RIGHT; int displayWidth = context.getResources().getDisplayMetrics().widthPixels; - boolean onRight = value > displayWidth / 2; + boolean onRight; + Integer gravityOverride = bubble.getGravityOverride(); + if (gravityOverride == null) { + onRight = value > displayWidth / 2; + } else { + onRight = (gravityOverride & Gravity.RIGHT) == Gravity.RIGHT; + } int centeringOffset = bubbleSize / 2 + shadowPaddingSize; windowParams.x = (int) (onRight ? (displayWidth - value - centeringOffset) : value - centeringOffset); windowParams.gravity = Gravity.TOP | (onRight ? Gravity.RIGHT : Gravity.LEFT); + if (wasOnRight != onRight) { + bubble.onLeftRightSwitch(onRight); + } if (bubble.isShowing()) { windowManager.updateViewLayout(bubble.getRootView(), windowParams); } @@ -134,6 +144,11 @@ class MoveHandler implements OnTouchListener { return isMoving; } + public void undoGravityOverride() { + LayoutParams windowParams = bubble.getWindowParams(); + xProperty.setValue(windowParams, xProperty.getValue(windowParams)); + } + @Override public boolean onTouch(View v, MotionEvent event) { float eventX = event.getRawX(); @@ -190,13 +205,12 @@ class MoveHandler implements OnTouchListener { } else { snapX(); } - + isMoving = false; bubble.onMoveFinish(); } else { v.performClick(); bubble.primaryButtonClick(); } - isMoving = false; break; } return true; diff --git a/java/com/android/dialershared/bubble/g3doc/INTEGRATION.md b/java/com/android/dialershared/bubble/g3doc/INTEGRATION.md new file mode 100644 index 000000000..a13a6053b --- /dev/null +++ b/java/com/android/dialershared/bubble/g3doc/INTEGRATION.md @@ -0,0 +1,69 @@ +# Floating Bubble Integration + +go/bubble-integration + +Author: keyboardr@ + +Last Updated: 2017-06-06 + +Floating bubbles provide a lightweight means of providing interactive UI while +the user is away from the app. This document details the steps necessary to +integrate these bubbles into your app. + +[TOC] + +![Floating bubble](images/bubble_collapsed.png){height=400} + +## Ensure Bubbles can be shown + +Add the `android.permission.SYSTEM_ALERT_WINDOW` permission to your manifest. +Before you show the bubble, call `Bubble.canShowBubbles(Context)` to see if the +user has granted you permission. If not, you can start an Activity from +`Bubble.getRequestPermissionIntent(Context)` to navigate the user to the system +settings to enable drawing over other apps. This is more than just a simple +runtime permission; the user must explicitly allow you to draw over other apps +via this system setting. System apps may have this allowed by default, but be +sure to test. + +## Create your initial `BubbleInfo` + +Use `BubbleInfo.builder()` to populate a `BubbleInfo` with your color, main +icon, main Intent (which should navigate back to your app), starting Y position, +and a list of `Actions` to put in the drawer. Each `Action` will define its +icon, user-displayable name (used for content description), Intent to perform +when clicked, whether it is enabled (optional, default true), and whether it is +checked (optional, default false). + +![Floating bubble expanded](images/bubble_expanded.png){height=400} + +## Create, show, and hide the Bubble + +Create the bubble using `Bubble.createBubble(Context, BubbleInfo)`. The `show()` +method is safe to call at any time. If the Bubble is already showing, it is a +no-op. `hide()` may also be called at any time and will collapse the drawer +before hiding if already open. While `show()` will show immediately, `hide()` +may need to wait for other operations or animations before the bubble is hidden. +It is unlikely you will need to keep track of this, however. The bubble will be +hidden at its next opportunity, and `hide()` will not block. + +![Floating bubble with state](images/bubble_state.png){height=400} + +## Update the Bubble's state + +Call `Bubble.setBubbleInfo(BubbleInfo)` to update all displayed state. +`BubbleInfo`s are immutable, so to make a new one using an existing +`BubbleInfo`, use `BubbleInfo.from(BubbleInfo)` to get a `Builder` with +prepopulated info. If only the `Action` state has changed, it is more efficient +to just call `Bubble.updateActions(List)` + +![Floating bubble with text](images/bubble_text.png){height=400} + +## Show text + +To temporarily replace the icon with a textual message, call +`Bubble.showText(CharSequence)`. The text will be displayed for several seconds +before transitioning back to the primary icon. The drawer will be closed if open +and cannot be reopened while the text is displayed. Any calls to `hide()` will +be deferred until after the text is done being displayed, so if you wish to show +an ending message of some sort you may call `hide()` immediately after +`showText(CharSequence)`. diff --git a/java/com/android/dialershared/bubble/g3doc/images/bubble_collapsed.png b/java/com/android/dialershared/bubble/g3doc/images/bubble_collapsed.png new file mode 100644 index 000000000..7ecc0675b Binary files /dev/null and b/java/com/android/dialershared/bubble/g3doc/images/bubble_collapsed.png differ diff --git a/java/com/android/dialershared/bubble/g3doc/images/bubble_expanded.png b/java/com/android/dialershared/bubble/g3doc/images/bubble_expanded.png new file mode 100644 index 000000000..cd477f334 Binary files /dev/null and b/java/com/android/dialershared/bubble/g3doc/images/bubble_expanded.png differ diff --git a/java/com/android/dialershared/bubble/g3doc/images/bubble_state.png b/java/com/android/dialershared/bubble/g3doc/images/bubble_state.png new file mode 100644 index 000000000..21ca8a8b5 Binary files /dev/null and b/java/com/android/dialershared/bubble/g3doc/images/bubble_state.png differ diff --git a/java/com/android/dialershared/bubble/g3doc/images/bubble_text.png b/java/com/android/dialershared/bubble/g3doc/images/bubble_text.png new file mode 100644 index 000000000..9c476dca6 Binary files /dev/null and b/java/com/android/dialershared/bubble/g3doc/images/bubble_text.png differ diff --git a/java/com/android/dialershared/bubble/res/layout/bubble_base.xml b/java/com/android/dialershared/bubble/res/layout/bubble_base.xml index 3acd2af2e..76970f020 100644 --- a/java/com/android/dialershared/bubble/res/layout/bubble_base.xml +++ b/java/com/android/dialershared/bubble/res/layout/bubble_base.xml @@ -19,24 +19,36 @@ xmlns:tools="http://schemas.android.com/tools" android:layout_width="wrap_content" android:layout_height="wrap_content" + android:clipToPadding="false" tools:theme="@style/Theme.AppCompat"> + + android:paddingEnd="@dimen/bubble_shadow_padding_size"> + android:clipToPadding="false" + android:elevation="12dp"> - 0dp - 0dp - 0dp - 120dp - 64dp - 20dp + 16dp + 64dp + 56dp + 16dp 4dp 16dp diff --git a/java/com/android/incallui/AnswerScreenPresenter.java b/java/com/android/incallui/AnswerScreenPresenter.java index ddbe6ccef..d53040145 100644 --- a/java/com/android/incallui/AnswerScreenPresenter.java +++ b/java/com/android/incallui/AnswerScreenPresenter.java @@ -17,12 +17,14 @@ package com.android.incallui; import android.content.Context; +import android.os.SystemClock; import android.support.annotation.FloatRange; import android.support.annotation.NonNull; import android.support.v4.os.UserManagerCompat; import android.telecom.VideoProfile; import com.android.dialer.common.Assert; import com.android.dialer.common.LogUtil; +import com.android.dialer.common.concurrent.ThreadUtil; import com.android.dialer.logging.DialerImpression; import com.android.dialer.logging.Logger; import com.android.incallui.answer.protocol.AnswerScreen; @@ -36,11 +38,14 @@ import com.android.incallui.call.DialerCallListener; /** Manages changes for an incoming call screen. */ public class AnswerScreenPresenter implements AnswerScreenDelegate, DialerCall.CannedTextResponsesLoadedListener { + private static final int ACCEPT_REJECT_CALL_TIME_OUT_IN_MILLIS = 5000; + @NonNull private final Context context; @NonNull private final AnswerScreen answerScreen; @NonNull private final DialerCall call; + private long actionPerformedTimeMillis; - public AnswerScreenPresenter( + AnswerScreenPresenter( @NonNull Context context, @NonNull AnswerScreen answerScreen, @NonNull DialerCall call) { LogUtil.i("AnswerScreenPresenter.constructor", null); this.context = Assert.isNotNull(context); @@ -59,6 +64,13 @@ public class AnswerScreenPresenter } } + @Override + public boolean isActionTimeout() { + return actionPerformedTimeMillis != 0 + && SystemClock.elapsedRealtime() - actionPerformedTimeMillis + >= ACCEPT_REJECT_CALL_TIME_OUT_IN_MILLIS; + } + @Override public void onAnswerScreenUnready() { call.removeCannedTextResponsesLoadedListener(this); @@ -73,6 +85,7 @@ public class AnswerScreenPresenter public void onRejectCallWithMessage(String message) { call.reject(true /* rejectWithMessage */, message); onDismissDialog(); + addTimeoutCheck(); } @Override @@ -100,6 +113,7 @@ public class AnswerScreenPresenter call.answer(); } } + addTimeoutCheck(); } @Override @@ -114,6 +128,7 @@ public class AnswerScreenPresenter } else { call.reject(false /* rejectWithMessage */, null); } + addTimeoutCheck(); } @Override @@ -128,6 +143,7 @@ public class AnswerScreenPresenter activeCall.addListener(new AnswerOnDisconnected(activeCall)); activeCall.disconnect(); } + addTimeoutCheck(); } @Override @@ -165,7 +181,7 @@ public class AnswerScreenPresenter private final DialerCall disconnectingCall; - public AnswerOnDisconnected(DialerCall disconnectingCall) { + AnswerOnDisconnected(DialerCall disconnectingCall) { this.disconnectingCall = disconnectingCall; } @@ -209,4 +225,23 @@ public class AnswerScreenPresenter return UserManagerCompat.isUserUnlocked(context) && call.can(android.telecom.Call.Details.CAPABILITY_RESPOND_VIA_TEXT); } + + private void addTimeoutCheck() { + actionPerformedTimeMillis = SystemClock.elapsedRealtime(); + if (answerScreen.getAnswerScreenFragment().isVisible()) { + ThreadUtil.postDelayedOnUiThread( + () -> { + if (!answerScreen.getAnswerScreenFragment().isVisible()) { + LogUtil.d( + "AnswerScreenPresenter.addTimeoutCheck", + "accept/reject call timed out, do nothing"); + return; + } + LogUtil.i("AnswerScreenPresenter.addTimeoutCheck", "accept/reject call timed out"); + // Force re-evaluate which fragment to show. + InCallPresenter.getInstance().refreshUi(); + }, + ACCEPT_REJECT_CALL_TIME_OUT_IN_MILLIS); + } + } } diff --git a/java/com/android/incallui/AnswerScreenPresenterStub.java b/java/com/android/incallui/AnswerScreenPresenterStub.java index d02a181c1..2f9e60818 100644 --- a/java/com/android/incallui/AnswerScreenPresenterStub.java +++ b/java/com/android/incallui/AnswerScreenPresenterStub.java @@ -50,4 +50,9 @@ public class AnswerScreenPresenterStub implements AnswerScreenDelegate { @Override public void updateWindowBackgroundColor(@FloatRange(from = -1f, to = 1.0f) float progress) {} + + @Override + public boolean isActionTimeout() { + return false; + } } diff --git a/java/com/android/incallui/CallButtonPresenter.java b/java/com/android/incallui/CallButtonPresenter.java index f758a9655..e36d9cf9e 100644 --- a/java/com/android/incallui/CallButtonPresenter.java +++ b/java/com/android/incallui/CallButtonPresenter.java @@ -306,6 +306,9 @@ public class CallButtonPresenter @Override public void toggleCameraClicked() { LogUtil.i("CallButtonPresenter.toggleCameraClicked", ""); + if (mCall == null) { + return; + } Logger.get(mContext) .logCallImpression( DialerImpression.Type.IN_CALL_SCREEN_SWAP_CAMERA, diff --git a/java/com/android/incallui/CallCardPresenter.java b/java/com/android/incallui/CallCardPresenter.java index cd06793ce..67b917767 100644 --- a/java/com/android/incallui/CallCardPresenter.java +++ b/java/com/android/incallui/CallCardPresenter.java @@ -44,9 +44,9 @@ import com.android.contacts.common.ContactsUtils; import com.android.contacts.common.preference.ContactsPreferences; import com.android.contacts.common.util.ContactDisplayUtils; import com.android.dialer.common.Assert; -import com.android.dialer.common.ConfigProviderBindings; import com.android.dialer.common.LogUtil; import com.android.dialer.compat.ActivityCompat; +import com.android.dialer.configprovider.ConfigProviderBindings; import com.android.dialer.logging.DialerImpression; import com.android.dialer.logging.Logger; import com.android.dialer.multimedia.MultimediaData; @@ -245,7 +245,7 @@ public class CallCardPresenter @Override public void onStateChange(InCallState oldState, InCallState newState, CallList callList) { - LogUtil.v("CallCardPresenter.onStateChange", "" + newState); + LogUtil.v("CallCardPresenter.onStateChange", "oldState: %s, newState: %s", oldState, newState); if (mInCallScreen == null) { return; } @@ -374,6 +374,7 @@ public class CallCardPresenter @Override public void onEnrichedCallSessionUpdate() { + LogUtil.enterBlock("CallCardPresenter.onEnrichedCallSessionUpdate"); updatePrimaryDisplayInfo(); } @@ -864,6 +865,14 @@ public class CallCardPresenter return; } + if (mSecondary.isMergeInProcess()) { + LogUtil.i( + "CallCardPresenter.updateSecondaryDisplayInfo", + "secondary call is merge in process, clearing info"); + mInCallScreen.setSecondary(SecondaryInfo.createEmptySecondaryInfo(mIsFullscreen)); + return; + } + if (mSecondary.isConferenceCall()) { mInCallScreen.setSecondary( new SecondaryInfo( diff --git a/java/com/android/incallui/ContactInfoCache.java b/java/com/android/incallui/ContactInfoCache.java index d7eea79bd..fdfba3b9f 100644 --- a/java/com/android/incallui/ContactInfoCache.java +++ b/java/com/android/incallui/ContactInfoCache.java @@ -33,6 +33,7 @@ import android.support.annotation.MainThread; import android.support.annotation.NonNull; import android.support.annotation.Nullable; import android.support.annotation.WorkerThread; +import android.support.v4.content.ContextCompat; import android.support.v4.os.UserManagerCompat; import android.telecom.TelecomManager; import android.telephony.PhoneNumberUtils; @@ -596,7 +597,7 @@ public class ContactInfoCache implements OnImageLoadCompleteListener { // This will only be true for emergency numbers if (info.photoResource != 0) { - cce.photo = context.getResources().getDrawable(info.photoResource); + cce.photo = ContextCompat.getDrawable(context, info.photoResource); } else if (info.isCachedPhotoCurrent) { if (info.cachedPhoto != null) { cce.photo = info.cachedPhoto; diff --git a/java/com/android/incallui/ExternalCallNotifier.java b/java/com/android/incallui/ExternalCallNotifier.java index 051392e2b..f01a29458 100644 --- a/java/com/android/incallui/ExternalCallNotifier.java +++ b/java/com/android/incallui/ExternalCallNotifier.java @@ -29,6 +29,7 @@ import android.net.Uri; import android.os.Build.VERSION_CODES; import android.support.annotation.NonNull; import android.support.annotation.Nullable; +import android.support.v4.os.BuildCompat; import android.telecom.Call; import android.telecom.PhoneAccount; import android.telecom.VideoProfile; @@ -41,8 +42,7 @@ import com.android.contacts.common.compat.CallCompat; 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.notification.NotificationChannelManager; -import com.android.dialer.notification.NotificationChannelManager.Channel; +import com.android.dialer.notification.NotificationChannelId; import com.android.incallui.call.DialerCall; import com.android.incallui.call.DialerCallDelegate; import com.android.incallui.call.ExternalCallList; @@ -59,9 +59,10 @@ import java.util.Map; public class ExternalCallNotifier implements ExternalCallList.ExternalCallListener { /** Tag used with the notification manager to uniquely identify external call notifications. */ - private static final int NOTIFICATION_ID = R.id.notification_external_call; + private static final String NOTIFICATION_TAG = "EXTERNAL_CALL"; + + private static final int NOTIFICATION_SUMMARY_ID = -1; - private static final String NOTIFICATION_GROUP = "ExternalCallNotifier"; private final Context mContext; private final ContactInfoCache mContactInfoCache; private Map mNotifications = new ArrayMap<>(); @@ -188,15 +189,14 @@ public class ExternalCallNotifier implements ExternalCallList.ExternalCallListen NotificationManager notificationManager = (NotificationManager) mContext.getSystemService(Context.NOTIFICATION_SERVICE); - notificationManager.cancel( - String.valueOf(mNotifications.get(call).getNotificationId()), NOTIFICATION_ID); + notificationManager.cancel(NOTIFICATION_TAG, mNotifications.get(call).getNotificationId()); mNotifications.remove(call); if (mShowingSummary && mNotifications.size() <= 1) { // Where a summary notification is showing and there is now not enough notifications to // necessitate a summary, cancel the summary. - notificationManager.cancel(NOTIFICATION_GROUP, NOTIFICATION_ID); + notificationManager.cancel(NOTIFICATION_TAG, NOTIFICATION_SUMMARY_ID); mShowingSummary = false; // If there is still a single call requiring a notification, re-post the notification as a @@ -237,7 +237,7 @@ public class ExternalCallNotifier implements ExternalCallList.ExternalCallListen builder.setOngoing(true); // Make the notification prioritized over the other normal notifications. builder.setPriority(Notification.PRIORITY_HIGH); - builder.setGroup(NOTIFICATION_GROUP); + builder.setGroup(NOTIFICATION_TAG); boolean isVideoCall = VideoProfile.isVideo(info.getCall().getDetails().getVideoState()); // Set the content ("Ongoing call on another device") @@ -251,9 +251,9 @@ public class ExternalCallNotifier implements ExternalCallList.ExternalCallListen builder.setLargeIcon(info.getLargeIcon()); builder.setColor(mContext.getResources().getColor(R.color.dialer_theme_color)); builder.addPerson(info.getPersonReference()); - - NotificationChannelManager.applyChannel( - builder, mContext, Channel.EXTERNAL_CALL, info.getCall().getDetails().getAccountHandle()); + if (BuildCompat.isAtLeastO()) { + builder.setChannelId(NotificationChannelId.DEFAULT); + } // Where the external call supports being transferred to the local device, add an action // to the notification to initiate the call pull process. @@ -286,20 +286,16 @@ public class ExternalCallNotifier implements ExternalCallList.ExternalCallListen Notification.Builder publicBuilder = new Notification.Builder(mContext); publicBuilder.setSmallIcon(R.drawable.quantum_ic_call_white_24); publicBuilder.setColor(mContext.getResources().getColor(R.color.dialer_theme_color)); - - NotificationChannelManager.applyChannel( - publicBuilder, - mContext, - Channel.EXTERNAL_CALL, - info.getCall().getDetails().getAccountHandle()); + if (BuildCompat.isAtLeastO()) { + publicBuilder.setChannelId(NotificationChannelId.DEFAULT); + } builder.setPublicVersion(publicBuilder.build()); Notification notification = builder.build(); NotificationManager notificationManager = (NotificationManager) mContext.getSystemService(Context.NOTIFICATION_SERVICE); - notificationManager.notify( - String.valueOf(info.getNotificationId()), NOTIFICATION_ID, notification); + notificationManager.notify(NOTIFICATION_TAG, info.getNotificationId(), notification); if (!mShowingSummary && mNotifications.size() > 1) { // If the number of notifications shown is > 1, and we're not already showing a group summary, @@ -310,12 +306,13 @@ public class ExternalCallNotifier implements ExternalCallList.ExternalCallListen summary.setOngoing(true); // Make the notification prioritized over the other normal notifications. summary.setPriority(Notification.PRIORITY_HIGH); - summary.setGroup(NOTIFICATION_GROUP); + summary.setGroup(NOTIFICATION_TAG); summary.setGroupSummary(true); summary.setSmallIcon(R.drawable.quantum_ic_call_white_24); - NotificationChannelManager.applyChannel( - summary, mContext, Channel.EXTERNAL_CALL, info.getCall().getDetails().getAccountHandle()); - notificationManager.notify(NOTIFICATION_GROUP, NOTIFICATION_ID, summary.build()); + if (BuildCompat.isAtLeastO()) { + summary.setChannelId(NotificationChannelId.DEFAULT); + } + notificationManager.notify(NOTIFICATION_TAG, NOTIFICATION_SUMMARY_ID, summary.build()); mShowingSummary = true; } } diff --git a/java/com/android/incallui/InCallActivity.java b/java/com/android/incallui/InCallActivity.java index bda003ccc..6ea31fc4c 100644 --- a/java/com/android/incallui/InCallActivity.java +++ b/java/com/android/incallui/InCallActivity.java @@ -35,9 +35,9 @@ import android.view.MenuItem; import android.view.MotionEvent; import android.view.View; import com.android.dialer.common.Assert; -import com.android.dialer.common.ConfigProviderBindings; import com.android.dialer.common.LogUtil; import com.android.dialer.compat.ActivityCompat; +import com.android.dialer.configprovider.ConfigProviderBindings; import com.android.dialer.logging.Logger; import com.android.dialer.logging.ScreenEvent; import com.android.incallui.answer.bindings.AnswerBindings; @@ -630,12 +630,22 @@ public class InCallActivity extends TransactionSafeFragmentActivity AnswerScreen answerScreen = getAnswerScreen(); if (answerScreen.getCallId().equals(call.getId()) && answerScreen.isVideoCall() == call.isVideoCall() - && answerScreen.isVideoUpgradeRequest() == isVideoUpgradeRequest) { + && answerScreen.isVideoUpgradeRequest() == isVideoUpgradeRequest + && !answerScreen.isActionTimeout()) { + LogUtil.d( + "InCallActivity.showAnswerScreenFragment", + "answer fragment exists for same call and has NOT been accepted/rejected/timed out"); return false; } - LogUtil.i( - "InCallActivity.showAnswerScreenFragment", - "answer fragment exists but arguments do not match"); + if (answerScreen.isActionTimeout()) { + LogUtil.i( + "InCallActivity.showAnswerScreenFragment", + "answer fragment exists but has been accepted/rejected and timed out"); + } else { + LogUtil.i( + "InCallActivity.showAnswerScreenFragment", + "answer fragment exists but arguments do not match"); + } hideAnswerScreenFragment(transaction); } diff --git a/java/com/android/incallui/InCallPresenter.java b/java/com/android/incallui/InCallPresenter.java index 7c3000144..0bfd67e87 100644 --- a/java/com/android/incallui/InCallPresenter.java +++ b/java/com/android/incallui/InCallPresenter.java @@ -1014,6 +1014,13 @@ public class InCallPresenter implements CallList.Listener { } } + public void refreshUi() { + if (mInCallActivity != null) { + // Re-evaluate which fragment is being shown. + mInCallActivity.onPrimaryCallStateChanged(); + } + } + public void addInCallUiListener(InCallUiListener listener) { mInCallUiListeners.add(listener); } diff --git a/java/com/android/incallui/InCallServiceImpl.java b/java/com/android/incallui/InCallServiceImpl.java index 1653334a1..d2b029741 100644 --- a/java/com/android/incallui/InCallServiceImpl.java +++ b/java/com/android/incallui/InCallServiceImpl.java @@ -23,7 +23,6 @@ import android.telecom.Call; import android.telecom.CallAudioState; import android.telecom.InCallService; import com.android.dialer.blocking.FilteredNumberAsyncQueryHandler; -import com.android.dialer.common.ConfigProviderBindings; import com.android.incallui.audiomode.AudioModeProvider; import com.android.incallui.call.CallList; import com.android.incallui.call.ExternalCallList; @@ -82,7 +81,7 @@ public class InCallServiceImpl extends InCallService { InCallPresenter.getInstance().onServiceBind(); InCallPresenter.getInstance().maybeStartRevealAnimation(intent); TelecomAdapter.getInstance().setInCallService(this); - if (ConfigProviderBindings.get(this).getBoolean("enable_return_to_call_bubble", false)) { + if (ReturnToCallController.isEnabled(this)) { returnToCallController = new ReturnToCallController(this); } diff --git a/java/com/android/incallui/ReturnToCallController.java b/java/com/android/incallui/ReturnToCallController.java index 4cb6aaf89..314aa45d4 100644 --- a/java/com/android/incallui/ReturnToCallController.java +++ b/java/com/android/incallui/ReturnToCallController.java @@ -24,6 +24,7 @@ import android.support.annotation.NonNull; import android.support.annotation.VisibleForTesting; import android.telecom.CallAudioState; import com.android.dialer.common.LogUtil; +import com.android.dialer.configprovider.ConfigProviderBindings; import com.android.dialer.telecom.TelecomUtil; import com.android.dialershared.bubble.Bubble; import com.android.dialershared.bubble.BubbleInfo; @@ -57,6 +58,10 @@ public class ReturnToCallController implements InCallUiListener, Listener, Audio private final PendingIntent toggleMute; private final PendingIntent endCall; + public static boolean isEnabled(Context context) { + return !ConfigProviderBindings.get(context).getBoolean("disable_return_to_call_bubble", false); + } + public ReturnToCallController(Context context) { this.context = context; @@ -108,6 +113,7 @@ public class ReturnToCallController implements InCallUiListener, Listener, Audio private Bubble startNewBubble() { if (!Bubble.canShowBubbles(context)) { LogUtil.i("ReturnToCallController.startNewBubble", "can't show bubble, no permission"); + context.startActivity(Bubble.getRequestPermissionIntent(context)); return null; } Bubble returnToCallBubble = Bubble.createBubble(context, generateBubbleInfo()); @@ -156,12 +162,14 @@ public class ReturnToCallController implements InCallUiListener, Listener, Audio } private BubbleInfo generateBubbleInfo() { + Intent activityIntent = InCallActivity.getIntent(context, false, false, false); + activityIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); return BubbleInfo.builder() .setPrimaryColor(context.getResources().getColor(R.color.dialer_theme_color, null)) - .setPrimaryIcon(Icon.createWithResource(context, R.drawable.quantum_ic_call_white_24)) - .setPrimaryAction( - PendingIntent.getActivity( - context, 0, InCallActivity.getIntent(context, false, false, false), 0)) + .setPrimaryIcon(Icon.createWithResource(context, R.drawable.on_going_call)) + .setStartingYPosition( + context.getResources().getDimensionPixelOffset(R.dimen.return_to_call_initial_offset_y)) + .setPrimaryIntent(PendingIntent.getActivity(context, 0, activityIntent, 0)) .setActions(generateActions()) .build(); } @@ -176,7 +184,7 @@ public class ReturnToCallController implements InCallUiListener, Listener, Audio .setIcon(Icon.createWithResource(context, speakerButtonInfo.icon)) .setName(context.getText(speakerButtonInfo.label)) .setChecked(speakerButtonInfo.isChecked) - .setAction(speakerButtonInfo.checkable ? toggleSpeaker : showSpeakerSelect) + .setIntent(speakerButtonInfo.checkable ? toggleSpeaker : showSpeakerSelect) .build()); actions.add( @@ -184,21 +192,21 @@ public class ReturnToCallController implements InCallUiListener, Listener, Audio .setIcon(Icon.createWithResource(context, R.drawable.quantum_ic_mic_off_white_24)) .setName(context.getText(R.string.incall_label_mute)) .setChecked(audioState.isMuted()) - .setAction(toggleMute) + .setIntent(toggleMute) .build()); actions.add( Action.builder() .setIcon(Icon.createWithResource(context, R.drawable.quantum_ic_call_end_white_24)) .setName(context.getText(R.string.incall_label_end_call)) - .setAction(endCall) + .setIntent(endCall) .build()); return actions; } @NonNull - private PendingIntent createActionIntent(String actionToggleSpeaker) { + private PendingIntent createActionIntent(String action) { Intent toggleSpeaker = new Intent(context, ReturnToCallActionReceiver.class); - toggleSpeaker.setAction(actionToggleSpeaker); + toggleSpeaker.setAction(action); return PendingIntent.getBroadcast(context, 0, toggleSpeaker, 0); } } diff --git a/java/com/android/incallui/StatusBarNotifier.java b/java/com/android/incallui/StatusBarNotifier.java index 229f08c8e..458df5149 100644 --- a/java/com/android/incallui/StatusBarNotifier.java +++ b/java/com/android/incallui/StatusBarNotifier.java @@ -28,7 +28,6 @@ import static com.android.incallui.NotificationBroadcastReceiver.ACTION_HANG_UP_ import android.Manifest; import android.app.ActivityManager; import android.app.Notification; -import android.app.Notification.Builder; import android.app.NotificationManager; import android.app.PendingIntent; import android.content.Context; @@ -70,8 +69,7 @@ import com.android.dialer.common.LogUtil; import com.android.dialer.enrichedcall.EnrichedCallManager; import com.android.dialer.enrichedcall.Session; import com.android.dialer.multimedia.MultimediaData; -import com.android.dialer.notification.NotificationChannelManager; -import com.android.dialer.notification.NotificationChannelManager.Channel; +import com.android.dialer.notification.NotificationChannelId; import com.android.dialer.oem.MotorolaUtils; import com.android.dialer.util.DrawableConverter; import com.android.incallui.ContactInfoCache.ContactCacheEntry; @@ -93,6 +91,9 @@ import java.util.Objects; public class StatusBarNotifier implements InCallPresenter.InCallStateListener, EnrichedCallManager.StateChangedListener { + private static final String NOTIFICATION_TAG = "STATUS_BAR_NOTIFIER"; + private static final int NOTIFICATION_ID = 1; + // Notification types // Indicates that no notification is currently showing. private static final int NOTIFICATION_NONE = 0; @@ -147,7 +148,7 @@ public class StatusBarNotifier NotificationManager notificationManager = backupContext.getSystemService(NotificationManager.class); - notificationManager.cancel(R.id.notification_ongoing_call); + notificationManager.cancel(NOTIFICATION_TAG, NOTIFICATION_ID); } private static int getWorkStringFromPersonalString(int resId) { @@ -173,12 +174,6 @@ public class StatusBarNotifier return PendingIntent.getBroadcast(context, 0, intent, 0); } - private static void setColorized(@NonNull Builder builder) { - if (BuildCompat.isAtLeastO()) { - builder.setColorized(true); - } - } - /** Creates notifications according to the state we receive from {@link InCallPresenter}. */ @Override @RequiresPermission(Manifest.permission.READ_PHONE_STATE) @@ -226,7 +221,7 @@ public class StatusBarNotifier } if (mCurrentNotification != NOTIFICATION_NONE) { LogUtil.i("StatusBarNotifier.cancelNotification", "cancel"); - mNotificationManager.cancel(R.id.notification_ongoing_call); + mNotificationManager.cancel(NOTIFICATION_TAG, NOTIFICATION_ID); } mCurrentNotification = NOTIFICATION_NONE; } @@ -365,13 +360,13 @@ public class StatusBarNotifier LogUtil.i("StatusBarNotifier.buildAndSendNotification", "notificationType=" + notificationType); switch (notificationType) { case NOTIFICATION_INCOMING_CALL: - NotificationChannelManager.applyChannel( - builder, mContext, Channel.INCOMING_CALL, accountHandle); + if (BuildCompat.isAtLeastO()) { + builder.setChannelId(NotificationChannelId.INCOMING_CALL); + } configureFullScreenIntent(builder, createLaunchPendingIntent(true /* isFullScreen */)); // Set the notification category and bump the priority for incoming calls builder.setCategory(Notification.CATEGORY_CALL); // This will be ignored on O+ and handled by the channel - //noinspection deprecation builder.setPriority(Notification.PRIORITY_MAX); if (mCurrentNotification != NOTIFICATION_INCOMING_CALL) { LogUtil.i( @@ -379,18 +374,20 @@ public class StatusBarNotifier "Canceling old notification so this one can be noisy"); // Moving from a non-interuptive notification (or none) to a noisy one. Cancel the old // notification (if there is one) so the fullScreenIntent or HUN will show - mNotificationManager.cancel(R.id.notification_ongoing_call); + mNotificationManager.cancel(NOTIFICATION_TAG, NOTIFICATION_ID); } break; case NOTIFICATION_INCOMING_CALL_QUIET: - NotificationChannelManager.applyChannel( - builder, mContext, Channel.ONGOING_CALL, accountHandle); + if (BuildCompat.isAtLeastO()) { + builder.setChannelId(NotificationChannelId.ONGOING_CALL); + } break; case NOTIFICATION_IN_CALL: - setColorized(publicBuilder); - setColorized(builder); - NotificationChannelManager.applyChannel( - builder, mContext, Channel.ONGOING_CALL, accountHandle); + if (BuildCompat.isAtLeastO()) { + publicBuilder.setColorized(true); + builder.setColorized(true); + builder.setChannelId(NotificationChannelId.ONGOING_CALL); + } break; } @@ -436,7 +433,7 @@ public class StatusBarNotifier "displaying notification for " + notificationType); try { - mNotificationManager.notify(R.id.notification_ongoing_call, notification); + mNotificationManager.notify(NOTIFICATION_TAG, NOTIFICATION_ID, notification); } catch (RuntimeException e) { // TODO(b/34744003): Move the memory stats into silent feedback PSD. ActivityManager activityManager = mContext.getSystemService(ActivityManager.class); @@ -660,13 +657,17 @@ public class StatusBarNotifier return R.drawable.quantum_ic_videocam_white_24; } else if (call.hasProperty(PROPERTY_HIGH_DEF_AUDIO) && MotorolaUtils.shouldShowHdIconInNotification(mContext)) { - // Normally when a call is ongoing the status bar displays an icon of a phone with animated - // lines. This is a helpful hint for users so they know how to get back to the call. - // For Sprint HD calls, we replace this icon with an icon of a phone with a HD badge. - // This is a carrier requirement. + // Normally when a call is ongoing the status bar displays an icon of a phone. This is a + // helpful hint for users so they know how to get back to the call. For Sprint HD calls, we + // replace this icon with an icon of a phone with a HD badge. This is a carrier requirement. return R.drawable.ic_hd_call; } - return R.anim.on_going_call; + // If ReturnToCall is enabled, use the static icon. The animated one will show in the bubble. + if (ReturnToCallController.isEnabled(mContext)) { + return R.drawable.quantum_ic_call_white_24; + } else { + return R.drawable.on_going_call; + } } /** Returns the message to use with the notification. */ @@ -823,13 +824,9 @@ public class StatusBarNotifier "will show \"answer\" action in the incoming call Notification"); PendingIntent answerVoicePendingIntent = createNotificationPendingIntent(mContext, ACTION_ANSWER_VOICE_INCOMING_CALL); - // We put animation resources in "anim" folder instead of "drawable", which causes Android - // Studio to complain. - // TODO: Move "anim" resources to "drawable" as recommended in AnimationDrawable doc? - //noinspection ResourceType builder.addAction( new Notification.Action.Builder( - Icon.createWithResource(mContext, R.anim.on_going_call), + Icon.createWithResource(mContext, R.drawable.quantum_ic_call_white_24), getActionText( R.string.notification_action_answer, R.color.notification_action_accept), answerVoicePendingIntent) @@ -927,7 +924,7 @@ public class StatusBarNotifier builder.setOngoing(true); builder.setOnlyAlertOnce(true); // This will be ignored on O+ and handled by the channel - //noinspection deprecation + // noinspection deprecation builder.setPriority(Notification.PRIORITY_HIGH); return builder; diff --git a/java/com/android/incallui/VideoCallPresenter.java b/java/com/android/incallui/VideoCallPresenter.java index 31999ef2e..bd9837097 100644 --- a/java/com/android/incallui/VideoCallPresenter.java +++ b/java/com/android/incallui/VideoCallPresenter.java @@ -27,9 +27,9 @@ import android.telecom.VideoProfile.CameraCapabilities; import android.view.Surface; import android.view.SurfaceView; import com.android.dialer.common.Assert; -import com.android.dialer.common.ConfigProviderBindings; import com.android.dialer.common.LogUtil; import com.android.dialer.compat.CompatUtils; +import com.android.dialer.configprovider.ConfigProviderBindings; import com.android.incallui.InCallPresenter.InCallDetailsListener; import com.android.incallui.InCallPresenter.InCallOrientationListener; import com.android.incallui.InCallPresenter.InCallStateListener; diff --git a/java/com/android/incallui/answer/impl/AnswerFragment.java b/java/com/android/incallui/answer/impl/AnswerFragment.java index 6be79305d..44310536d 100644 --- a/java/com/android/incallui/answer/impl/AnswerFragment.java +++ b/java/com/android/incallui/answer/impl/AnswerFragment.java @@ -216,6 +216,7 @@ public class AnswerFragment extends Fragment private void performAnswerAndRelease() { restoreAnswerAndReleaseButtonAnimation(); answerScreenDelegate.onAnswerAndReleaseCall(); + buttonAcceptClicked = true; } private void restoreAnswerAndReleaseButtonAnimation() { @@ -358,6 +359,11 @@ public class AnswerFragment extends Fragment return instance; } + @Override + public boolean isActionTimeout() { + return (buttonAcceptClicked || buttonRejectClicked) && answerScreenDelegate.isActionTimeout(); + } + @Override @NonNull public String getCallId() { @@ -526,6 +532,7 @@ public class AnswerFragment extends Fragment if (!isAdded()) { return; } + LogUtil.enterBlock("AnswerFragment.updateDataFragment"); Fragment current = getChildFragmentManager().findFragmentById(R.id.incall_data_container); Fragment newFragment = null; @@ -542,6 +549,7 @@ public class AnswerFragment extends Fragment || !Objects.equals(((MultimediaFragment) current).getSubject(), subject) || !Objects.equals(((MultimediaFragment) current).getImageUri(), imageUri) || !Objects.equals(((MultimediaFragment) current).getLocation(), location)) { + LogUtil.i("AnswerFragment.updateDataFragment", "Replacing multimedia fragment"); // Needs replacement newFragment = MultimediaFragment.newInstance( @@ -553,12 +561,14 @@ public class AnswerFragment extends Fragment } else if (shouldShowAvatar()) { // Needs Avatar if (!(current instanceof AvatarFragment)) { + LogUtil.i("AnswerFragment.updateDataFragment", "Replacing avatar fragment"); // Needs replacement newFragment = new AvatarFragment(); } } else { // Needs empty if (current != null) { + LogUtil.i("AnswerFragment.updateDataFragment", "Removing current fragment"); getChildFragmentManager().beginTransaction().remove(current).commitNow(); } contactGridManager.setAvatarImageView(null, 0, false); @@ -1021,7 +1031,7 @@ public class AnswerFragment extends Fragment } private void updateImportanceBadgeVisibility() { - if (!isAdded()) { + if (!isAdded() || getView() == null) { return; } diff --git a/java/com/android/incallui/answer/impl/classifier/HumanInteractionClassifier.java b/java/com/android/incallui/answer/impl/classifier/HumanInteractionClassifier.java index 1d3d7ef22..5e83dfc78 100644 --- a/java/com/android/incallui/answer/impl/classifier/HumanInteractionClassifier.java +++ b/java/com/android/incallui/answer/impl/classifier/HumanInteractionClassifier.java @@ -20,7 +20,7 @@ import android.content.Context; import android.hardware.SensorEvent; import android.util.DisplayMetrics; import android.view.MotionEvent; -import com.android.dialer.common.ConfigProviderBindings; +import com.android.dialer.configprovider.ConfigProviderBindings; /** An classifier trying to determine whether it is a human interacting with the phone or not. */ class HumanInteractionClassifier extends Classifier { diff --git a/java/com/android/incallui/answer/impl/hint/AnswerHintFactory.java b/java/com/android/incallui/answer/impl/hint/AnswerHintFactory.java index 9c33b5de6..94cf893f0 100644 --- a/java/com/android/incallui/answer/impl/hint/AnswerHintFactory.java +++ b/java/com/android/incallui/answer/impl/hint/AnswerHintFactory.java @@ -23,8 +23,8 @@ import android.os.Build; import android.support.annotation.NonNull; import android.support.annotation.VisibleForTesting; import com.android.dialer.common.Assert; -import com.android.dialer.common.ConfigProviderBindings; import com.android.dialer.common.LogUtil; +import com.android.dialer.configprovider.ConfigProviderBindings; import com.android.dialer.util.DialerUtils; import com.android.incallui.util.AccessibilityUtil; diff --git a/java/com/android/incallui/answer/impl/hint/PawSecretCodeListener.java b/java/com/android/incallui/answer/impl/hint/PawSecretCodeListener.java index 3b4512c4f..204c4e131 100644 --- a/java/com/android/incallui/answer/impl/hint/PawSecretCodeListener.java +++ b/java/com/android/incallui/answer/impl/hint/PawSecretCodeListener.java @@ -25,8 +25,8 @@ import android.support.annotation.VisibleForTesting; import android.text.TextUtils; import android.widget.Toast; import com.android.dialer.common.Assert; -import com.android.dialer.common.ConfigProviderBindings; import com.android.dialer.common.LogUtil; +import com.android.dialer.configprovider.ConfigProviderBindings; import com.android.dialer.logging.DialerImpression.Type; import com.android.dialer.logging.Logger; import com.android.dialer.util.DialerUtils; diff --git a/java/com/android/incallui/answer/protocol/AnswerScreen.java b/java/com/android/incallui/answer/protocol/AnswerScreen.java index 8bcad6e35..5ad500200 100644 --- a/java/com/android/incallui/answer/protocol/AnswerScreen.java +++ b/java/com/android/incallui/answer/protocol/AnswerScreen.java @@ -30,6 +30,8 @@ public interface AnswerScreen { boolean allowAnswerAndRelease(); + boolean isActionTimeout(); + void setTextResponses(List textResponses); boolean hasPendingDialogs(); diff --git a/java/com/android/incallui/answer/protocol/AnswerScreenDelegate.java b/java/com/android/incallui/answer/protocol/AnswerScreenDelegate.java index 10a3413af..5d2c415ed 100644 --- a/java/com/android/incallui/answer/protocol/AnswerScreenDelegate.java +++ b/java/com/android/incallui/answer/protocol/AnswerScreenDelegate.java @@ -46,4 +46,7 @@ public interface AnswerScreenDelegate { * @param progress float from -1 to 1. -1 is fully rejected, 1 is fully accepted, and 0 is neutral */ void updateWindowBackgroundColor(@FloatRange(from = -1f, to = 1.0f) float progress); + + /** Returns true if any answer/reject action timed out. */ + boolean isActionTimeout(); } diff --git a/java/com/android/incallui/answerproximitysensor/AnswerProximitySensor.java b/java/com/android/incallui/answerproximitysensor/AnswerProximitySensor.java index fe4ae9f96..536a470b0 100644 --- a/java/com/android/incallui/answerproximitysensor/AnswerProximitySensor.java +++ b/java/com/android/incallui/answerproximitysensor/AnswerProximitySensor.java @@ -20,8 +20,8 @@ import android.content.Context; import android.hardware.display.DisplayManager; import android.os.PowerManager; import android.view.Display; -import com.android.dialer.common.ConfigProviderBindings; import com.android.dialer.common.LogUtil; +import com.android.dialer.configprovider.ConfigProviderBindings; import com.android.incallui.call.DialerCall; import com.android.incallui.call.DialerCall.State; import com.android.incallui.call.DialerCallListener; diff --git a/java/com/android/incallui/call/CallList.java b/java/com/android/incallui/call/CallList.java index 3876ca64d..269fcd68b 100644 --- a/java/com/android/incallui/call/CallList.java +++ b/java/com/android/incallui/call/CallList.java @@ -299,6 +299,8 @@ public class CallList implements DialerCallDelegate { LogUtil.w( "CallList.onCallRemoved", "Removing call not previously disconnected " + call.getId()); } + + call.onRemovedFromCallList(); } if (!hasLiveCall()) { @@ -566,7 +568,8 @@ public class CallList implements DialerCallDelegate { * * @param call The call to update. */ - private void onUpdateCall(DialerCall call) { + @VisibleForTesting + void onUpdateCall(DialerCall call) { LogUtil.d("CallList.onUpdateCall", String.valueOf(call)); if (!mCallById.containsKey(call.getId()) && call.isExternalCall()) { // When a regular call becomes external, it is removed from the call list, and there may be diff --git a/java/com/android/incallui/call/DialerCall.java b/java/com/android/incallui/call/DialerCall.java index 12edb07e6..88e0dbb5e 100644 --- a/java/com/android/incallui/call/DialerCall.java +++ b/java/com/android/incallui/call/DialerCall.java @@ -47,8 +47,8 @@ import com.android.dialer.callintent.CallInitiationType; import com.android.dialer.callintent.CallIntentParser; import com.android.dialer.callintent.CallSpecificAppData; import com.android.dialer.common.Assert; -import com.android.dialer.common.ConfigProviderBindings; import com.android.dialer.common.LogUtil; +import com.android.dialer.configprovider.ConfigProviderBindings; import com.android.dialer.enrichedcall.EnrichedCallCapabilities; import com.android.dialer.enrichedcall.EnrichedCallComponent; import com.android.dialer.enrichedcall.EnrichedCallManager; @@ -163,6 +163,9 @@ public class DialerCall implements VideoTechListener, StateChangedListener, Capa */ private boolean isRemotelyHeld; + /** Indicates whether this call is currently in the process of being merged into a conference. */ + private boolean isMergeInProcess; + /** * Indicates whether the phone account associated with this call supports specifying a call * subject. @@ -265,6 +268,14 @@ public class DialerCall implements VideoTechListener, StateChangedListener, Capa case TelephonyManagerCompat.EVENT_NOTIFY_INTERNATIONAL_CALL_ON_WFC: notifyInternationalCallOnWifi(); break; + case TelephonyManagerCompat.EVENT_MERGE_START: + LogUtil.i("DialerCall.onConnectionEvent", "merge start"); + isMergeInProcess = true; + break; + case TelephonyManagerCompat.EVENT_MERGE_COMPLETE: + LogUtil.i("DialerCall.onConnectionEvent", "merge complete"); + isMergeInProcess = false; + break; default: break; } @@ -970,6 +981,10 @@ public class DialerCall implements VideoTechListener, StateChangedListener, Capa return isRemotelyHeld; } + public boolean isMergeInProcess() { + return isMergeInProcess; + } + public boolean isIncoming() { return mLogState.isIncoming; } @@ -1274,6 +1289,11 @@ public class DialerCall implements VideoTechListener, StateChangedListener, Capa } } + void onRemovedFromCallList() { + // Ensure we clean up when this call is removed. + mVideoTechManager.dispatchRemovedFromCallList(); + } + /** * Specifies whether a number is in the call history or not. {@link #CALL_HISTORY_STATUS_UNKNOWN} * means there is no result. @@ -1493,7 +1513,10 @@ public class DialerCall implements VideoTechListener, StateChangedListener, Capa videoTechs.add( new LightbringerTech( - LightbringerComponent.get(call.mContext).getLightbringer(), call, phoneNumber)); + LightbringerComponent.get(call.mContext).getLightbringer(), + call, + call.mTelecomCall, + phoneNumber)); } VideoTech getVideoTech() { @@ -1517,6 +1540,12 @@ public class DialerCall implements VideoTechListener, StateChangedListener, Capa videoTech.onCallStateChanged(context, newState); } } + + void dispatchRemovedFromCallList() { + for (VideoTech videoTech : videoTechs) { + videoTech.onRemovedFromCallList(); + } + } } /** Called when canned text responses have been loaded. */ diff --git a/java/com/android/incallui/incall/impl/InCallFragment.java b/java/com/android/incallui/incall/impl/InCallFragment.java index d329dc903..e102ee009 100644 --- a/java/com/android/incallui/incall/impl/InCallFragment.java +++ b/java/com/android/incallui/incall/impl/InCallFragment.java @@ -42,6 +42,7 @@ import com.android.dialer.common.Assert; import com.android.dialer.common.FragmentUtils; import com.android.dialer.common.LogUtil; import com.android.dialer.multimedia.MultimediaData; +import com.android.dialer.widget.LockableViewPager; import com.android.incallui.audioroute.AudioRouteSelectorDialogFragment; import com.android.incallui.audioroute.AudioRouteSelectorDialogFragment.AudioRouteSelectorPresenter; import com.android.incallui.contactgrid.ContactGridManager; diff --git a/java/com/android/incallui/incall/impl/LockableViewPager.java b/java/com/android/incallui/incall/impl/LockableViewPager.java deleted file mode 100644 index 5b8b12609..000000000 --- a/java/com/android/incallui/incall/impl/LockableViewPager.java +++ /dev/null @@ -1,46 +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.incall.impl; - -import android.content.Context; -import android.support.v4.view.ViewPager; -import android.util.AttributeSet; -import android.view.MotionEvent; - -/** {@link ViewPager} useful for disabled swiping between pages. */ -public class LockableViewPager extends ViewPager { - - private boolean swipingLocked; - - public LockableViewPager(Context context, AttributeSet attributeSet) { - super(context, attributeSet); - } - - public void setSwipingLocked(boolean swipingLocked) { - this.swipingLocked = swipingLocked; - } - - @Override - public boolean onInterceptTouchEvent(MotionEvent motionEvent) { - return !swipingLocked && super.onInterceptTouchEvent(motionEvent); - } - - @Override - public boolean onTouchEvent(MotionEvent motionEvent) { - return !swipingLocked && super.onTouchEvent(motionEvent); - } -} diff --git a/java/com/android/incallui/incall/impl/res/layout/frag_incall_voice.xml b/java/com/android/incallui/incall/impl/res/layout/frag_incall_voice.xml index 44431413c..c06f7099c 100644 --- a/java/com/android/incallui/incall/impl/res/layout/frag_incall_voice.xml +++ b/java/com/android/incallui/incall/impl/res/layout/frag_incall_voice.xml @@ -1,4 +1,19 @@ + - - - - - - - - - - - - \ No newline at end of file diff --git a/java/com/android/incallui/res/drawable/on_going_call.xml b/java/com/android/incallui/res/drawable/on_going_call.xml new file mode 100644 index 000000000..438ba8273 --- /dev/null +++ b/java/com/android/incallui/res/drawable/on_going_call.xml @@ -0,0 +1,47 @@ + + + + + + + + + + + + + + diff --git a/java/com/android/incallui/res/values-af/strings.xml b/java/com/android/incallui/res/values-af/strings.xml index 5dacaaa8d..7d260c337 100644 --- a/java/com/android/incallui/res/values-af/strings.xml +++ b/java/com/android/incallui/res/values-af/strings.xml @@ -33,8 +33,8 @@ "Gemiste oproep vanaf %s" "Oproep aan die gang" "Voortdurende werkoproep" - "Voortdurende Wi-Fi-oproep" - "Voortdurende Wi-Fi-werkoproep" + "Voortdurende Wi-Fi-oproep" + "Voortdurende Wi-Fi-werkoproep" "Hou aan" "Inkomende oproep" "Inkomende oproep met foto" @@ -55,8 +55,8 @@ "Belangrike inkomende oproep met foto, boodskap en ligging" "Belangrike inkomende oproep met aanhegsels" "Inkomende werkoproep" - "Inkomende Wi-Fi-oproep" - "Inkomende Wi-Fi-werkoproep" + "Inkomende Wi-Fi-oproep" + "Inkomende Wi-Fi-werkoproep" "Inkomende verdagte strooipos-oproep" "Inkomende videoversoek" "Geen diens nie" @@ -73,7 +73,7 @@ "Neem video-oproep" "Om \'n oproep te maak, skakel eers vliegtuigmodus af." "Nie geregistreer op netwerk nie." - "Sellulêre netwerk nie beskikbaar nie." + "Mobiele netwerk nie beskikbaar nie." "Voer \'n geldige nommer in om \'n oproep te maak." "Kan nie bel nie." "Begin MMI-volgorde…" @@ -134,8 +134,8 @@ "Beëindig oproep" "Konferensie-oproep" "Besig met oproep" - "Gaan voort met oproep deur sellulêre data te gebruik …" - "Kon nie na Wi-Fi-netwerk oorskakel nie" - "Video-oproep sal op sellulêre netwerk bly. Standaard datakoste kan dalk geld." + "Gaan voort met oproep deur mobiele data te gebruik ..." + "Kon nie na Wi-Fi-netwerk oorskakel nie" + "Video-oproep sal op mobiele netwerk bly. Standaard datakoste kan dalk geld." "Moenie dit weer wys nie" diff --git a/java/com/android/incallui/res/values-am/strings.xml b/java/com/android/incallui/res/values-am/strings.xml index 249447fee..f09fd63e4 100644 --- a/java/com/android/incallui/res/values-am/strings.xml +++ b/java/com/android/incallui/res/values-am/strings.xml @@ -33,8 +33,8 @@ "ያልተመለሰ ጥሪ ከ%s" "እየተካሄደ ያለ ጥሪ" "በሂደት ላይ ያለ የሥራ ጥሪ" - "በሂደት ላይ ያለ የWi-Fi ጥሪ" - "በሂደት ላይ ያለ የWi-Fi የሥራ ጥሪ" + "በሂደት ላይ ያለ የWi-Fi ጥሪ" + "በሂደት ላይ ያለ የWi-Fi የሥራ ጥሪ" "ያዝናቆይ" "ገቢ ጥሪ" "ገቢ ጥሪ ከፎቶ ጋር" @@ -55,8 +55,8 @@ "አስፈላጊ ገቢ ጥሪ ከፎቶ፣ መልዕክት እና አካባቢ ጋር" "አስፈላጊ ገቢ ጥሪ ከአባሪ ጋር" "ገቢ የሥራ ጥሪ" - "ገቢ የWi-Fi ጥሪ" - "ገቢ የWi-Fi የሥራ ጥሪ" + "ገቢ የWi-Fi ጥሪ" + "ገቢ የWi-Fi የሥራ ጥሪ" "መጪ የተጠረጠረ የአይፈለጌ መልዕክት ጥሪ" "ገቢ የቪዲዮ ጥያቄ" "ምንም አገልግሎት የለም" @@ -73,7 +73,7 @@ "የቪዲዮ ጥሪ ውሰድ" "ለመደወል፣ መጀመሪያየአውሮፕላኑን ሁነታ አጥፋ።" "በአውታረ መረቡ ላይ አልተመዘገበም።" - "የተንቀሳቃሽ ስልክ አውታረ መረብ አይገኝም።" + "የተንቀሳቃሽ ስልክ አውታረ መረብ አይገኝም።" "አንድ ጥሪ ለማድረግ የሚሰራ ቁጥር ያስገቡ።" "መደወል አልተቻለም።" "የMMI sequence…" @@ -134,8 +134,8 @@ "ጥሪ ጨርስ" "የስብሰባ ጥሪ" "በጥሪ ላይ" - "ሴሉላር ውሂብ በመጠቀም ጥሪውን በመቀጠል ላይ…" - "ወደ Wi-Fi አውታረ መረብ መቀየር አልተቻለም።" - "የቪዲዮ ጥሪ በሴሉላር አውታረመረቡ ላይ ይቆያል። መደበኛ የውሂብ ክፍያዎች ተፈጻሚ ሊሆኑ ይችላሉ።" + "የተንቀሳቃሽ ስልክ ውሂብን በመጠቀም ጥሪውን በመቀጠል ላይ…" + "ወደ Wi-Fi አውታረ መረብ መቀየር አልተቻለም" + "የቪዲዮ ጥሪ በተንቀሳቃሽ ስልክ አውታረ መረብ ላይ ይቆያል። መደበኛ የውሂብ ክፍያዎች ተፈጻሚ ሊሆኑ ይችላሉ።" "ይህን በድጋሚ አታሳይ" diff --git a/java/com/android/incallui/res/values-ar/strings.xml b/java/com/android/incallui/res/values-ar/strings.xml index 7c3585c7a..392829114 100644 --- a/java/com/android/incallui/res/values-ar/strings.xml +++ b/java/com/android/incallui/res/values-ar/strings.xml @@ -33,8 +33,8 @@ "مكالمة فائتة من %s" "مكالمة حالية" "مكالمة عمل جارية" - "‏اتصال جارٍ عبر Wi-Fi" - "‏مكالمة عمل جارية عبر اتصال Wi-Fi" + "‏اتصال جارٍ عبر Wi-Fi" + "‏مكالمة عمل جارية عبر اتصال Wi-Fi" "معلقة" "مكالمة واردة" "مكالمة واردة مع صورة" @@ -55,8 +55,8 @@ "مكالمة واردة مهمة مع صورة ورسالة وموقع" "مكالمة واردة مهمة مع مرفقات" "مكالمة عمل واردة" - "‏اتصال وارد عبر Wi-Fi" - "‏مكالمة عمل واردة عبر اتصال Wi-Fi" + "‏اتصال وارد عبر Wi-Fi" + "‏مكالمة عمل واردة عبر اتصال Wi-Fi" "مكالمة واردة يشتبه في كونها غير مرغوب فيها" "طلب فيديو وارد" "لا خدمة" @@ -73,7 +73,7 @@ "الرد على مكالمة فيديو" "لإجراء مكالمة، أوقف تشغيل وضع الطائرة أولاً." "غير مسجل على الشبكة." - "شبكة الجوّال غير متاحة." + "شبكة الجوال غير متاحة." "لإجراء مكالمة، أدخل رقمًا صالحًا." "يتعذر الاتصال." "‏جارٍ بدء تسلسل MMI..." @@ -134,8 +134,8 @@ "إنهاء الاتصال" "مكالمة جماعية" "قيد الاتصال" - "جارٍ استكمال المكالمة باستخدام بيانات الجوّال…" - "‏تعذر التبديل إلى شبكة Wi-Fi" - "ستظل مكالمة الفيديو على شبكة الجوّال. قد يتم فرض رسوم على البيانات القياسية للشبكة." + "جارٍ استكمال المكالمة باستخدام بيانات الجوّال…" + "‏تعذر التبديل إلى شبكة Wi-Fi" + "ستظل مكالمة الفيديو جارية على شبكة الجوال. قد يتم تطبيق رسوم قياسية على استخدام البيانات." "عدم إظهار هذا مرة أخرى" diff --git a/java/com/android/incallui/res/values-az/strings.xml b/java/com/android/incallui/res/values-az/strings.xml index dc43014fb..168dd0733 100644 --- a/java/com/android/incallui/res/values-az/strings.xml +++ b/java/com/android/incallui/res/values-az/strings.xml @@ -33,8 +33,8 @@ "%s tərəfindən zəng buraxılıb" "Davam edən zəng" "Davam edən iş çağrısı" - "Davam edən Wi-Fi zəngi" - "Davam edən Wi-Fi iş çağrısı" + "Davam edən Wi-Fi zəngi" + "Davam edən Wi-Fi iş zəngi" "Gözləmə mövqeyində" "Gələn zəng" "Foto ilə gələn zəng" @@ -55,8 +55,8 @@ "Foto, mesaj və məkan ilə gələn vacib zəng" "Qoşma ilə gələn vacib 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 Wi-Fi zəngi" + "Gələn Wi-Fi iş zəngi" "Şübhəli spam zəngi" "Gələn video çağrı" "Xidmət yoxdur" @@ -73,7 +73,7 @@ "Video Zəngə cavab verin" "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" + "Mobil şəbəkə əlçatımlı 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ığı…" @@ -134,8 +134,8 @@ "Zəngi sonlandırın" "Konfrans zəngi" "Çağrıda" - "Mobil data istifadə edərək zəng davam edir…" - "Wi-Fi şəbəkəsinə qoşulmaq olmadı" - "Video zəng mobil şəbəkə üzərində qalacaq. Standart data rüsumları tətbiq oluna bilər." + "Mobil data istifadə edərək zəngə davam edin…" + "Wi-Fi şəbəkəsinə qoşulmaq olmadı" + "Video zəng mobil şəbəkədə qalacaq. Standard data xərcləri tətbiq edilə bilər." "Bunu bi rdaha göstərməyin" diff --git a/java/com/android/incallui/res/values-b+sr+Latn/strings.xml b/java/com/android/incallui/res/values-b+sr+Latn/strings.xml index 3dddf653f..de2ad8642 100644 --- a/java/com/android/incallui/res/values-b+sr+Latn/strings.xml +++ b/java/com/android/incallui/res/values-b+sr+Latn/strings.xml @@ -33,8 +33,8 @@ "Propušten poziv od: %s" "Aktuelni poziv" "Tekući poziv za Work" - "Tekući Wi-Fi poziv" - "Tekući poziv za Work preko Wi-Fi-ja" + "Wi‑Fi poziv u toku" + "Wi‑Fi poslovni poziv u toku" "Na čekanju" "Dolazni poziv" "Dolazni poziv sa slikom" @@ -55,8 +55,8 @@ "Važan dolazni poziv sa slikom, porukom i lokacijom" "Važan dolazni poziv sa prilozima" "Dolazni poziv za Work" - "Dolazni Wi-Fi poziv" - "Dolazni poziv za Work preko Wi-Fi-ja" + "Dolazni Wi‑Fi poziv" + "Dolazni Wi‑Fi poslovni poziv" "Sumnja na nepoželjan dolazni poziv" "Zahtev za dolazni video poziv" "Nema usluge" @@ -73,7 +73,7 @@ "Preuzmi video poziv" "Da biste uputili poziv, prvo isključite režim rada u avionu." "Nije registrovano na mreži." - "Mobilna mreža nije dostupna." + "Mobilna mreža nije dostupna." "Da biste uputili poziv, unesite važeći broj." "Poziv nije uspeo." "Pokretanje MMI sekvence" @@ -134,8 +134,8 @@ "Završite poziv" "Konferencijski poziv" "U pozivu" - "Poziv se nastavlja pomoću mobilnih podataka…" - "Prebacivanje na Wi-Fi mrežu nije uspelo" - "Video poziv će ostati na mobilnoj mreži. Mogu da važe standardne naknade za prenos podataka." + "Poziv se nastavlja pomoću mobilnih podataka…" + "Prebacivanje na Wi‑Fi mrežu nije uspelo" + "Video poziv će ostati na mobilnoj mreži. Važe standardne naknade za prenos podataka." "Ne prikazuj ovo ponovo" diff --git a/java/com/android/incallui/res/values-be/strings.xml b/java/com/android/incallui/res/values-be/strings.xml index 46b5d3941..274cac17f 100644 --- a/java/com/android/incallui/res/values-be/strings.xml +++ b/java/com/android/incallui/res/values-be/strings.xml @@ -33,8 +33,8 @@ "Прапушчаны выклiк ад %s" "Бягучы выклік" "Бягучы выклік па працы" - "Бягучы выклік праз Wi-Fi" - "Бягучы выклік па працы праз Wi-Fi" + "Бягучы выклік праз Wi-Fi" + "Бягучы выклік па працы праз Wi-Fi" "У чаканні" "Уваходны выклік" "Уваходны выклік з фота" @@ -55,8 +55,8 @@ "Важны выклік з фота, паведамленнем і месцам" "Важны ўваходны выклік з далучэннямі" "Уваходны выклік па працы" - "Уваходны выклік праз Wi-Fi" - "Уваходны выклік па працы праз Wi-Fi" + "Уваходны выклік праз Wi-Fi" + "Уваходны выклік па працы праз Wi-Fi" "Уваходны выклiк ад абанента, якога падазраваюць у спаме" "Запыт уваходнага відэавыкліку" "Не абслугоўваецца" @@ -73,7 +73,7 @@ "Прыняць відэавыклік" "Каб зрабіць выклік, спачатку выключыце рэжым \"У самалёце\"." "Не зарэгістраваны ў сетцы." - "Мабільная сетка недаступная." + "Мабільная сетка недаступная." "Каб зрабіць выклік, увядзіце сапраўдны нумар." "Выклік немагчымы." "Пачатак паслядоўнасці MMI..." @@ -134,8 +134,8 @@ "Завяршыць выклік" "Канферэнц-выклік" "У выкліку" - "Працягваецца выклік з выкарыстаннем сотавай перадачы даных…" - "Немагчыма пераключыцца на сетку Wi-Fi" - "Відэавыклік застанецца ў мабільнай сетцы. Можа спаганяцца стандартная аплата за перадачу даных." + "Працягваецца выклік з выкарыстаннем мабільнай перадачы даных…" + "Немагчыма пераключыцца на сетку Wi-Fi" + "Відэавыклік застанецца ў мабільнай сетцы. Можа спаганяцца стандартная аплата за перадачу даных." "Больш не паказваць" diff --git a/java/com/android/incallui/res/values-bg/strings.xml b/java/com/android/incallui/res/values-bg/strings.xml index 84bffa02c..b3c1f3fd7 100644 --- a/java/com/android/incallui/res/values-bg/strings.xml +++ b/java/com/android/incallui/res/values-bg/strings.xml @@ -33,8 +33,8 @@ "Пропуснато обаждане от %s" "Текущо обаждане" "Текущо служебно обаждане" - "Текущо обаждане през Wi-Fi" - "Текущо служебно обаждане през Wi-Fi" + "Текущо обаждане през Wi-Fi" + "Текущо служебно обаждане през Wi-Fi" "Задържане на обаждането" "Вх. обаждане" "Входящо обаждане със снимка" @@ -55,8 +55,8 @@ "Важно обаждане с местоположение, снимка, съобщение" "Важно входящо обаждане с прикачени файлове" "Входящо служебно обаждане" - "Входящо обаждане през Wi-Fi" - "Входящо служебно обаждане през Wi-Fi" + "Входящо обаждане през Wi-Fi" + "Входящо служебно обаждане през Wi-Fi" "Входящо обаждане – възможен спам" "Входяща заявка за видеовръзка" "Няма покритие" @@ -73,7 +73,7 @@ "Приемане на видеообаждането" "Първо изключете самолетния режим, за да може да осъществите обаждане." "Няма регистрация в мрежата." - "Няма достъп до клетъчната мрежа." + "Няма мобилна мрежа." "За да извършите обаждане, въведете валиден номер." "Не може да се извърши обаждане." "Стартира се последователността MMI…" @@ -134,8 +134,8 @@ "Край на обаждането" "Конферентно обаждане" "В разговор" - "Обаждането продължава през мобилната връзка за данни…" - "Превключването към Wi-Fi мрежа не бе възможно" - "Видеообаждането ще остане в мобилната мрежа. Важат стандартните тарифи за данни." + "Обаждането продължава през мобилната връзка за данни…" + "Превключването към Wi-Fi мрежа не бе възможно" + "Видеообаждането ще остане в мобилната мрежа. Важат стандартните тарифи за данни." "Това да не се показва отново" diff --git a/java/com/android/incallui/res/values-bn/strings.xml b/java/com/android/incallui/res/values-bn/strings.xml index fc9383002..a964f81b1 100644 --- a/java/com/android/incallui/res/values-bn/strings.xml +++ b/java/com/android/incallui/res/values-bn/strings.xml @@ -33,8 +33,8 @@ "%s এর থেকে মিসড কল" "চালু থাকা কল" "চলমান কাজের কল" - "চলমান ওয়াই-ফাই কল" - "চলমান ওয়াই-ফাই কাজের কল" + "চালু থাকা ওয়াই-ফাই কল" + "চালু থাকা ওয়াই-ফাই কাজের কল" "সাময়িকভাবে স্থগিত রাখা হয়েছে" "ইনকামিং কল" "ফটো সহ ইনকামিং কল" @@ -55,8 +55,8 @@ "ফটো, বার্তা এবং অবস্থান সহ গুরুত্বপূর্ণ ইনকামিং কল" "সংযুক্তিগুলি সহ গুরুত্বপূর্ণ ইনকামিং কল" "আগত কাজের কল" - "আগত ওয়াই-ফাই কল" - "আগত ওয়াই-ফাই কাজের কল" + "আগত ওয়াই-ফাই কল" + "আগত ওয়াই-ফাই কাজের কল" "আগত সন্দেহভাজন স্প্যাম কল" "আগত ভিডিও অনুরোধ" "কোনো পরিষেবা নেই" @@ -73,7 +73,7 @@ "ভিডিও কলটি নিন" "একটি কল করতে, প্রথমে বিমান মোড বন্ধ করুন৷" "নেটওয়ার্কে নিবন্ধিত নয়৷" - "সেলুলার নেটওয়ার্ক উপলব্ধ নয়।" + "মোবাইল নেটওয়ার্ক উপলব্ধ নয়৷" "কোনো কল স্থাপন করতে, একটি বৈধ নম্বর লিখুন৷" "কল করা যাবে না৷" "MMI ক্রম চালু হচ্ছে…" @@ -134,8 +134,8 @@ "কল কেটে দিন" "কনফারেন্স কল" "কলে থাকাকালীন" - "সেলুলার ডেটা ব্যবহার করে কল করা চালিয়ে যান…" - "Wi-Fi নেটওয়ার্কে পাল্টানো গেল না" - "ভিডিও কল সেলুলার নেটওয়ার্কেই থাকবে৷ স্ট্যান্ডার্ড চার্জ প্রযোজ্য হতে পারে৷" + "মোবাইল ডেটা ব্যবহার করে কল করা চালিয়ে যান…" + "ওয়াই-ফাই নেটওয়ার্কে পাল্টানো গেল না" + "ভিডিও কল মোবাইল নেটওয়ার্কেই থাকবে৷ স্ট্যান্ডার্ড ডেটা চার্জ প্রযোজ্য হতে পারে৷" "এটি আমাকে আর দেখাবেন না" diff --git a/java/com/android/incallui/res/values-bs/strings.xml b/java/com/android/incallui/res/values-bs/strings.xml index c6950802f..996eb980c 100644 --- a/java/com/android/incallui/res/values-bs/strings.xml +++ b/java/com/android/incallui/res/values-bs/strings.xml @@ -33,8 +33,8 @@ "Propušteni poziv od kontakta %s" "Poziv u toku" "Poslovni poziv u toku" - "Wi-Fi poziv u toku" - "Wi-Fi poslovni poziv u toku" + "Wi-Fi poziv je u toku" + "Wi-Fi poslovni poziv je u toku" "Na čekanju" "Dolazni poziv" "Dolazni poziv s fotografijom" @@ -55,8 +55,8 @@ "Važan poziv s fotografijom, porukom i lokacijom" "Važan dolazni poziv s prilozima" "Dolazni poslovni poziv" - "Dolazni Wi-Fi poziv" - "Dolazni Wi-Fi poslovni poziv" + "Dolazni Wi-Fi poziv" + "Dolazni Wi-Fi poslovni poziv" "Mogući neželjeni dolazni poziv" "Zahtjev za dolazni videopoziv" "Nema mreže" @@ -73,7 +73,7 @@ "Primi videopoziv" "Da uputite poziv, isključite Način rada u avionu." "Nije registrirano na mreži." - "Mobilna mreža nije dostupna." + "Mobilna mreža nije dostupna." "Da uputite poziv, upišite važeći broj." "Nije moguće pozvati." "Pokretanje MMI sekvence u toku…" @@ -134,8 +134,8 @@ "Prekini poziv" "Konferencijski poziv" "Poziv u toku" - "Poziv se nastavlja pomoću mobilnih podataka…" - "Prebacivanje na Wi-Fi mrežu nije moguće" - "Videopoziv će ostati na mobilnoj mreži. Mogu nastati standardni troškovi prijenosa podataka." + "Nastavak poziva prijenosom mobilnih podataka…" + "Prebacivanje na Wi-Fi mrežu nije moguće" + "Videopoziv će ostati na mobilnoj mreži. Mogu nastati standardni troškovi prijenosa podataka." "Ne prikazuj ponovo" diff --git a/java/com/android/incallui/res/values-ca/strings.xml b/java/com/android/incallui/res/values-ca/strings.xml index ad34b00ef..f4d56a2a1 100644 --- a/java/com/android/incallui/res/values-ca/strings.xml +++ b/java/com/android/incallui/res/values-ca/strings.xml @@ -33,8 +33,8 @@ "Trucada perduda de %s" "Trucada en procés" "Trucada de feina en curs" - "Trucada Wi-Fi en curs" - "Trucada de feina per Wi-Fi en curs" + "Trucada per Wi-Fi en curs" + "Trucada de feina per Wi-Fi en curs" "En espera" "Trucada entrant" "Trucada entrant amb foto" @@ -55,8 +55,8 @@ "Trucada entrant important amb foto, missatge i ubicació" "Trucada entrant important amb fitxers adjunts" "Trucada de feina entrant" - "Trucada Wi-Fi entrant" - "Trucada de feina per Wi-Fi entrant" + "Trucada per Wi-Fi entrant" + "Trucada de feina per Wi-Fi entrant" "Presumpta trucada brossa entrant" "Sol·licitud de vídeo entrant" "Sense servei" @@ -73,7 +73,7 @@ "Accepta la videotrucada" "Per fer una trucada, primer apagueu el mode d\'avió." "No registrat a la xarxa." - "La xarxa mòbil no està disponible." + "La xarxa mòbil no està disponible." "Per realitzar una trucada, introdueix un número vàlid." "No es pot trucar." "S\'està iniciant la seqüència MMI..." @@ -125,7 +125,7 @@ "Segons les nostres sospites, l\'autor de la trucada és un emissor de contingut brossa. Si ens equivoquem, toca NO ÉS BROSSA per informar-nos-en." "Bloqueja i marca" "Afegeix un contacte" - "No és contingut brossa" + "No és una trucada brossa" "Bloqueja el número" "Afegeix als contactes" "Bloqueja i marca com a brossa" @@ -134,8 +134,8 @@ "Finalitza la trucada" "Conferència" "En una trucada" - "S\'està continuant la trucada mitjançant dades mòbils…" - "No s\'ha pogut canviar a la xarxa Wi-Fi" - "La videotrucada es mantindrà a la xarxa mòbil. És possible que s\'hi apliquin càrrecs de dades estàndard." + "S\'està continuant la trucada mitjançant dades mòbils…" + "No s\'ha pogut canviar a la xarxa Wi-Fi" + "La videotrucada continuarà a la xarxa mòbil. És possible que s\'hi apliquin càrrecs de dades estàndard." "No ho tornis a mostrar" diff --git a/java/com/android/incallui/res/values-cs/strings.xml b/java/com/android/incallui/res/values-cs/strings.xml index 9d69cfac7..e604a5249 100644 --- a/java/com/android/incallui/res/values-cs/strings.xml +++ b/java/com/android/incallui/res/values-cs/strings.xml @@ -33,8 +33,8 @@ "Zmeškaný hovor od volajícího %s" "Probíhající hovor" "Probíhající pracovní hovor" - "Probíhající volání přes Wi-Fi" - "Probíhající pracovní hovor (Wi-Fi)" + "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í hovor s fotkou" @@ -55,8 +55,8 @@ "Důležitý přích. hovor s fotkou, zprávou a polohou" "Důležitý příchozí hovor s přílohami" "Příchozí pracovní hovor" - "Příchozí volání přes Wi-Fi" - "Příchozí pracovní hovor (Wi-Fi)" + "Příchozí hovor přes Wi-Fi" + "Příchozí pracovní hovor přes Wi-Fi" "U příchozího hovoru máme podezření, že se jedná o spam" "Příchozí žádost o videohovor" "Žádný signál" @@ -73,7 +73,7 @@ "Převést videohovor sem" "Chcete-li telefonovat, vypněte nejprve režim Letadlo." "Přihlášení k síti nebylo úspěšné." - "Mobilní síť je nedostupná." + "Mobilní síť je nedostupná." "Chcete-li uskutečnit hovor, zadejte platné telefonní číslo." "Hovor nelze uskutečnit." "Spouštění sekvence MMI..." @@ -134,8 +134,8 @@ "Ukončit hovor" "Konferenční hovor" "Probíhá hovor" - "Hovor pokračuje přes mobilní data…" - "Přepnutí na síť Wi-Fi se nezdařilo" - "Videohovor zůstane na mobilní síti. Za datový přenos mohou být účtovány standardní poplatky." + "Hovor pokračuje přes mobilní data…" + "Přepnutí na síť Wi-Fi se nezdařilo" + "Videohovor zůstane na mobilní síti. Za datový přenos mohou být účtovány standardní poplatky." "Tuto zprávu příště nezobrazovat" diff --git a/java/com/android/incallui/res/values-da/strings.xml b/java/com/android/incallui/res/values-da/strings.xml index 19de78382..fbf7927a3 100644 --- a/java/com/android/incallui/res/values-da/strings.xml +++ b/java/com/android/incallui/res/values-da/strings.xml @@ -33,8 +33,8 @@ "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" + "Igangværende Wi-Fi-opkald" + "Igangværende Wi-Fi-opkald i forbindelse med arbejde" "Ventende" "Indgående opkald" "Indgående opkald med billede" @@ -55,8 +55,8 @@ "Vigtigt opkald med billede, besked og placering" "Vigtigt indgående opkald med vedhæftede filer" "Indgående opkald i forbindelse med arbejde" - "Indgående opkald via Wi-Fi" - "Indgående Wi-Fi-opkald i forbindelse med arbejde" + "Indgående Wi-Fi-opkald" + "Indgående Wi-Fi-opkald i forbindelse med arbejde" "Indgående formodet spamopkald" "Indgående videoanmodning" "Ingen dækning" @@ -73,7 +73,7 @@ "Besvar videoopkald" "Slå Flytilstand fra først for at foretage et opkald." "Ikke registreret på netværk." - "Mobilnetværket er ikke tilgængeligt." + "Mobilnetværket er ikke tilgængeligt." "Indtast et gyldigt nummer for at foretage et opkald." "Kan ikke ringe op." "Starter MMI-sekvens ..." @@ -134,8 +134,8 @@ "Afslut opkald" "Telefonmøde" "Opkald i gang" - "Fortsætter opkaldet med mobildata…" - "Der kan ikke skiftes til Wi-Fi-netværk" - "Videoopkaldet bliver ved med at bruge mobilnetværket. Du skal muligvis betale et standardgebyr for data." + "Opkaldet fortsættes med mobildata…" + "Du kunne ikke skifte til Wi-Fi-netværk" + "Videoopkaldet bliver ved med at bruge mobilnetværket. Du skal muligvis betale et standardgebyr for data." "Vis ikke dette igen" diff --git a/java/com/android/incallui/res/values-de/strings.xml b/java/com/android/incallui/res/values-de/strings.xml index a5f96027b..0dce3452a 100644 --- a/java/com/android/incallui/res/values-de/strings.xml +++ b/java/com/android/incallui/res/values-de/strings.xml @@ -33,8 +33,8 @@ "Verpasster Anruf von %s" "Aktueller Anruf" "Aktueller geschäftlicher Anruf" - "Aktiver WLAN-Anruf" - "Aktueller geschäftlicher WLAN-Anruf" + "Aktiver WLAN-Anruf" + "Aktiver geschäftlicher WLAN-Anruf" "Gehaltener Anruf" "Eingehender Anruf" "Eingehender Anruf mit Foto" @@ -55,8 +55,8 @@ "Wichtiger eingehender Anruf mit Foto, Nachricht und Standort" "Wichtiger eingehender Anruf mit Anhängen" "Eingehender geschäftlicher Anruf" - "Eingehender WLAN-Anruf" - "Eingehender geschäftlicher WLAN-Anruf" + "Eingehender WLAN-Anruf" + "Eingehender geschäftlicher WLAN-Anruf" "Verdacht auf eingehenden Spam-Anruf" "Eingehende Videoanfrage" "kein Dienst" @@ -73,7 +73,7 @@ "Videoanruf übernehmen" "Deaktiviere zunächst den Flugmodus, um einen Anruf zu tätigen." "Nicht in Netzwerk registriert." - "Mobilfunknetz nicht verfügbar" + "Mobilfunknetz ist nicht verfügbar." "Gib eine gültige Nummer ein." "Anruf nicht möglich." "MMI-Sequenz wird gestartet..." @@ -134,8 +134,8 @@ "Anruf beenden" "Telefonkonferenz" "Anruf" - "Anruf wird über Mobildaten fortgesetzt…" - "Wechseln zu WLAN nicht möglich" - "Der Videoanruf erfolgt weiter über das Mobilfunknetz. Es können Standardgebühren für die Datenübertragung anfallen." + "Anruf wird über mobile Daten fortgesetzt…" + "Wechseln zu WLAN nicht möglich" + "Der Videoanruf erfolgt weiter über das Mobilfunknetz. Es können Standardgebühren für die Datenübertragung anfallen." "Meldung nicht mehr anzeigen" diff --git a/java/com/android/incallui/res/values-el/strings.xml b/java/com/android/incallui/res/values-el/strings.xml index 8ff6d2f5f..bc39e2ac9 100644 --- a/java/com/android/incallui/res/values-el/strings.xml +++ b/java/com/android/incallui/res/values-el/strings.xml @@ -33,8 +33,8 @@ "Αναπάντητη κλήση από %s" "Κλήση σε εξέλιξη" "Κλήση εργασίας σε εξέλιξη" - "Κλήση Wi-Fi σε εξέλιξη" - "Κλήση εργασίας μέσω Wi-Fi σε εξέλιξη" + "Κλήση Wi-Fi σε εξέλιξη" + "Κλήση εργασίας μέσω Wi-Fi σε εξέλιξη" "Σε αναμονή" "Εισερχόμενη κλήση" "Εισερχόμενη κλήση με φωτογραφία" @@ -55,8 +55,8 @@ "Σημαντική εισερχ. κλήση με φωτο, μήνυμα, τοποθεσία" "Σημαντική εισερχόμενη κλήση με συνημμένα" "Εισερχόμενη κλήση εργασίας" - "Εισερχόμενη κλήση μέσω Wi-Fi" - "Εισερχόμενη κλήση εργασίας μέσω Wi-Fi" + "Εισερχόμενη κλήση μέσω Wi-Fi" + "Εισερχόμενη κλήση εργασίας μέσω Wi-Fi" "Πιθανώς ανεπιθύμητη εισερχόμενη κλήση" "Αίτημα εισερχόμενου βίντεο" "Δίκτυο μη διαθέσιμο" @@ -73,7 +73,7 @@ "Λήψη βιντεοκλήσης" "Για να πραγματοποιήσετε μια κλήση, απενεργοποιήστε πρώτα τη λειτουργία πτήσης." "Δεν έχετε εγγραφεί στο δίκτυο." - "Το δίκτυο κινητής τηλεφωνίας δεν είναι διαθέσιμο." + "Το δίκτυο κινητής τηλεφωνίας δεν είναι διαθέσιμο." "Για να πραγματοποιήσετε μια κλήση, εισαγάγετε έναν έγκυρο αριθμό." "Δεν είναι δυνατή η κλήση." "Έναρξη ακολουθίας MMI..." @@ -134,8 +134,8 @@ "Τερματισμός κλήσης" "Κλήση συνδιάσκεψης" "Σε κλήση" - "Συνέχεια κλήσης με χρήση δεδομένων κινητής τηλεφωνίας…" - "Δεν ήταν δυνατή η εναλλαγή σε δίκτυο Wi-Fi" - "Η βιντεοκλήση θα παραμείνει σε δίκτυο δεδομένων κινητής τηλεφωνίας; Ενδέχεται να ισχύουν βασικές χρεώσεις δεδομένων." + "Συνέχιση κλήσης με χρήση δεδομένων κινητής τηλεφωνίας…" + "Δεν ήταν δυνατή η εναλλαγή σε δίκτυο Wi-Fi" + "Η βιντεοκλήση θα παραμείνει σε δίκτυο δεδομένων κινητής τηλεφωνίας; Ενδέχεται να ισχύουν βασικές χρεώσεις δεδομένων." "Να μην εμφανιστεί ξανά αυτό" diff --git a/java/com/android/incallui/res/values-en-rAU/strings.xml b/java/com/android/incallui/res/values-en-rAU/strings.xml index 5e0d20737..68509f080 100644 --- a/java/com/android/incallui/res/values-en-rAU/strings.xml +++ b/java/com/android/incallui/res/values-en-rAU/strings.xml @@ -33,8 +33,8 @@ "Missed call from %s" "On-going call" "Ongoing work call" - "Ongoing Wi-Fi call" - "Ongoing Wi-Fi work call" + "Ongoing Wi‑Fi call" + "Ongoing Wi‑Fi work call" "On hold" "Incoming call" "Incoming call with photo" @@ -55,15 +55,15 @@ "Important call with photo, message and location" "Important incoming call with attachments" "Incoming work call" - "Incoming Wi-Fi call" - "Incoming Wi-Fi work call" + "Incoming Wi‑Fi call" + "Incoming Wi‑Fi work call" "Incoming suspected spam call" "Incoming video request" "No service" "Selected network (%s) unavailable" "Answer" "Hang up" - "In-stream video" + "Video" "Voice" "Accept" "Decline" @@ -73,7 +73,7 @@ "Take video call" "To place a call, first turn off Aeroplane mode." "Not registered on network." - "Mobile network not available." + "Mobile network not available." "To place a call, enter a valid number." "Can\'t call." "Starting MMI sequence…" @@ -134,8 +134,8 @@ "End call" "Conference call" "On a call" - "Continuing call using mobile data…" - "Couldn\'t switch to Wi-Fi network" - "Video call will remain on mobile network. Standard data charges may apply." + "Continuing call using mobile data…" + "Couldn\'t switch to Wi‑Fi network" + "Video call will remain on the mobile network. Standard data charges may apply." "Do not show this again" diff --git a/java/com/android/incallui/res/values-en-rGB/strings.xml b/java/com/android/incallui/res/values-en-rGB/strings.xml index 5e0d20737..68509f080 100644 --- a/java/com/android/incallui/res/values-en-rGB/strings.xml +++ b/java/com/android/incallui/res/values-en-rGB/strings.xml @@ -33,8 +33,8 @@ "Missed call from %s" "On-going call" "Ongoing work call" - "Ongoing Wi-Fi call" - "Ongoing Wi-Fi work call" + "Ongoing Wi‑Fi call" + "Ongoing Wi‑Fi work call" "On hold" "Incoming call" "Incoming call with photo" @@ -55,15 +55,15 @@ "Important call with photo, message and location" "Important incoming call with attachments" "Incoming work call" - "Incoming Wi-Fi call" - "Incoming Wi-Fi work call" + "Incoming Wi‑Fi call" + "Incoming Wi‑Fi work call" "Incoming suspected spam call" "Incoming video request" "No service" "Selected network (%s) unavailable" "Answer" "Hang up" - "In-stream video" + "Video" "Voice" "Accept" "Decline" @@ -73,7 +73,7 @@ "Take video call" "To place a call, first turn off Aeroplane mode." "Not registered on network." - "Mobile network not available." + "Mobile network not available." "To place a call, enter a valid number." "Can\'t call." "Starting MMI sequence…" @@ -134,8 +134,8 @@ "End call" "Conference call" "On a call" - "Continuing call using mobile data…" - "Couldn\'t switch to Wi-Fi network" - "Video call will remain on mobile network. Standard data charges may apply." + "Continuing call using mobile data…" + "Couldn\'t switch to Wi‑Fi network" + "Video call will remain on the mobile network. Standard data charges may apply." "Do not show this again" diff --git a/java/com/android/incallui/res/values-en-rIN/strings.xml b/java/com/android/incallui/res/values-en-rIN/strings.xml index 5e0d20737..68509f080 100644 --- a/java/com/android/incallui/res/values-en-rIN/strings.xml +++ b/java/com/android/incallui/res/values-en-rIN/strings.xml @@ -33,8 +33,8 @@ "Missed call from %s" "On-going call" "Ongoing work call" - "Ongoing Wi-Fi call" - "Ongoing Wi-Fi work call" + "Ongoing Wi‑Fi call" + "Ongoing Wi‑Fi work call" "On hold" "Incoming call" "Incoming call with photo" @@ -55,15 +55,15 @@ "Important call with photo, message and location" "Important incoming call with attachments" "Incoming work call" - "Incoming Wi-Fi call" - "Incoming Wi-Fi work call" + "Incoming Wi‑Fi call" + "Incoming Wi‑Fi work call" "Incoming suspected spam call" "Incoming video request" "No service" "Selected network (%s) unavailable" "Answer" "Hang up" - "In-stream video" + "Video" "Voice" "Accept" "Decline" @@ -73,7 +73,7 @@ "Take video call" "To place a call, first turn off Aeroplane mode." "Not registered on network." - "Mobile network not available." + "Mobile network not available." "To place a call, enter a valid number." "Can\'t call." "Starting MMI sequence…" @@ -134,8 +134,8 @@ "End call" "Conference call" "On a call" - "Continuing call using mobile data…" - "Couldn\'t switch to Wi-Fi network" - "Video call will remain on mobile network. Standard data charges may apply." + "Continuing call using mobile data…" + "Couldn\'t switch to Wi‑Fi network" + "Video call will remain on the mobile network. Standard data charges may apply." "Do not show this again" diff --git a/java/com/android/incallui/res/values-es-rUS/strings.xml b/java/com/android/incallui/res/values-es-rUS/strings.xml index d0167118f..b8584c765 100644 --- a/java/com/android/incallui/res/values-es-rUS/strings.xml +++ b/java/com/android/incallui/res/values-es-rUS/strings.xml @@ -33,8 +33,8 @@ "Llamada perdida de %s" "Llamada en curso" "Llamada de trabajo en curso" - "Llamada por Wi-Fi en curso" - "Llamada de trabajo con Wi-Fi en curso" + "Llamada Wi-Fi en curso" + "Llamada de trabajo Wi-Fi en curso" "En espera" "Llamada entrante" "Llamada entrante con foto" @@ -55,8 +55,8 @@ "Llamada importante con foto, mensaje y ubicación" "Llamada entrante importante con archivos adjuntos" "Llamada de trabajo entrante" - "Llamada por Wi-Fi entrante" - "Llamada de trabajo con Wi-Fi entrante" + "Llamada Wi-Fi entrante" + "Llamada de trabajo Wi-Fi entrante" "Posible llamada entrante de spam" "Solicitud de videollamada entrante" "Sin servicio" @@ -73,7 +73,7 @@ "Atender videollamada" "Para realizar una llamada, primero debes desactivar el modo avión." "No registrado en la red." - "Red móvil no disponible" + "La red móvil no está disponible." "Para realizar una llamada, ingresa un número válido." "No se puede realizar la llamada." "Iniciar la secuencia de MMI" @@ -134,8 +134,8 @@ "Finalizar llamada" "Conferencia" "En llamada" - "Continuando la llamada con datos móviles…" - "No se pudo cambiar a la red Wi-Fi" - "La videollamada permanecerá en la red móvil. Es posible que se te cobren cargos estándar por el uso de datos." + "Continuando la llamada con datos móviles…" + "No se pudo cambiar a la red Wi-Fi" + "La videollamada permanecerá en la red móvil. Es posible que se te cobren cargos estándar por el uso de datos." "No volver a mostrar esto" diff --git a/java/com/android/incallui/res/values-es/strings.xml b/java/com/android/incallui/res/values-es/strings.xml index 472ea99cb..4dc2d725c 100644 --- a/java/com/android/incallui/res/values-es/strings.xml +++ b/java/com/android/incallui/res/values-es/strings.xml @@ -33,8 +33,8 @@ "Llamada perdida de %s" "Llamada en curso" "Llamada de trabajo en curso" - "Llamada Wi-Fi en curso" - "Llamada Wi-Fi de trabajo en curso" + "Llamada por Wi-Fi en curso" + "Llamada de trabajo por Wi-Fi en curso" "En espera" "Llamada entrante" "Llamada entrante con foto" @@ -55,8 +55,8 @@ "Llamada importante con foto, mensaje y ubicación" "Llamada entrante importante con archivos adjuntos" "Llamada de trabajo entrante" - "Llamada Wi-Fi entrante" - "Llamada Wi-Fi de trabajo entrante" + "Llamada por Wi-Fi entrante" + "Llamada de trabajo por Wi-Fi entrante" "Llamada entrante sospechosa de spam" "Solicitud de videollamada entrante" "Sin servicio" @@ -73,7 +73,7 @@ "Atender videollamada" "Para realizar una llamada, primero debes desactivar el modo avión." "No se ha podido conectar a la red" - "La red móvil no está disponible." + "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..." @@ -134,8 +134,8 @@ "Finalizar llamada" "Conferencia telefónica" "En una llamada" - "Continuando la llamada con datos móviles…" - "No se ha podido cambiar a la red Wi-Fi" - "La videollamada seguirá mediante la red móvil. Es posible que se apliquen cargos por uso de datos." + "Continuando la llamada con los datos móviles…" + "No se ha podido cambiar a la red Wi-Fi" + "La videollamada seguirá a través de la red móvil. Es posible que se apliquen cargos por el uso de datos." "No volver a mostrar" diff --git a/java/com/android/incallui/res/values-et/strings.xml b/java/com/android/incallui/res/values-et/strings.xml index 9eaa65f42..ec1b230c5 100644 --- a/java/com/android/incallui/res/values-et/strings.xml +++ b/java/com/android/incallui/res/values-et/strings.xml @@ -33,8 +33,8 @@ "Vastamata kõne helistajalt %s" "Käimasolev kõne" "Käimasolev töökõne" - "Pooleliolev WiFi-kõne" - "Käimasolev töökõne WiFi kaudu" + "Käimasolev WiFi-kõne" + "Käimasolev WiFi-töökõne" "Ootel" "Sissetulev kõne" "Sissetulev kõne koos fotoga" @@ -55,8 +55,8 @@ "Tähtis sisset. kõne koos foto, sõnumi ja asukohaga" "Tähtis sissetulev kõne koos manustega" "Sissetulev töökõne" - "Sissetulev WiFi-kõne" - "Sissetulev töökõne WiFi kaudu" + "Sissetulev WiFi-kõne" + "Sissetulev WiFi-töökõne" "Arvatav sissetulev rämpskõne" "Sissetulev videotaotlus" "Teenus puudub" @@ -73,7 +73,7 @@ "Alusta videokõnet" "Helistamiseks lülitage lennurežiim välja." "Ei ole võrku registreeritud." - "Mobiilsidevõrk pole saadaval." + "Mobiilsidevõrk pole saadaval." "Helistamiseks sisestage kehtiv number." "Ei saa helistada." "MMI-jada alustamine ..." @@ -134,8 +134,8 @@ "Kõne lõpetamine" "Konverentskõne" "Pooleliolev kõne" - "Kõne jätkatakse mobiilse andmeside kaudu …" - "Ei saanud WiFi-võrgule lülitada" - "Videokõne jääb mobiilsidevõrku. Rakenduda võivad tavapärased andmetasud." + "Kõnet jätkatakse mobiilse andmeside kaudu …" + "WiFi-võrgule ei saanud lülituda" + "Videokõne jääb mobiilsidevõrku. Rakenduda võivad tavapärased andmesidetasud." "Ära seda enam näita" diff --git a/java/com/android/incallui/res/values-eu/strings.xml b/java/com/android/incallui/res/values-eu/strings.xml index 4db9e10fe..c8fe005af 100644 --- a/java/com/android/incallui/res/values-eu/strings.xml +++ b/java/com/android/incallui/res/values-eu/strings.xml @@ -33,8 +33,8 @@ "Deitzaile honen dei bat galdu duzu: %s" "Abian den deia" "Laneko dei bat abian da" - "Wi-Fi deia abian" - "Wi-Fi bidezko laneko dei bat abian da" + "Wi-Fi bidezko deia" + "Wi-Fi bidezko laneko deia" "Zain" "Sarrerako deia" "Jasotako deia, argazkia duena" @@ -55,8 +55,8 @@ "Jasotako dei garrant., arg., mez. eta kok. dituena" "Jasotako dei garrantzitsua, eranskinak dituena" "Laneko dei bat jaso da" - "Sarrerako Wi-Fi deia" - "Wi-Fi bidezko laneko dei bat jaso da" + "Jasotako Wi-Fi bidezko deia" + "Jasotako Wi-Fi bidezko laneko deia" "Ustezko spam-deia jaso duzu" "Sarrerako bideo-eskaera" "Ez dago zerbitzurik" @@ -73,7 +73,7 @@ "Erantzun bideo-deiari" "Dei bat egiteko, Hegaldi modua desaktibatu behar duzu." "Ez dago sarean erregistratuta." - "Sare mugikorra ez dago erabilgarri." + "Sare mugikorra ez dago erabilgarri." "Deitzeko, idatzi balio duen zenbaki bat." "Ezin da deitu." "MMI sekuentzia hasten…" @@ -134,8 +134,8 @@ "Amaitu deia" "Konferentzia-deia" "Deia abian da" - "Datu-konexioren bidez jarraitzen ari da deia egiten…" - "Ezin izan da aldatu Wi-Fi sarera" - "Datu mugikorren bidez egiten jarraituko da bideo-deia. Baliteke datuak erabiltzearen ondorioz ohiko kostuak kobratzea." + "Datu-konexioaren bidez egiten jarraituko da deia…" + "Ezin izan da aldatu Wi-Fi sarera" + "Datu-konexioaren bidez egiten jarraituko da bideo-deia. Baliteke datuak erabiltzearen ondorioz ohiko kostuak kobratzea." "Ez erakutsi berriro" diff --git a/java/com/android/incallui/res/values-fa/strings.xml b/java/com/android/incallui/res/values-fa/strings.xml index f816bd063..a36d164bb 100644 --- a/java/com/android/incallui/res/values-fa/strings.xml +++ b/java/com/android/incallui/res/values-fa/strings.xml @@ -33,8 +33,8 @@ "تماس بی‌پاسخ از %s" "تماس جاری" "تماس کاری خروجی" - "‏تماس از طریق Wi-Fi در حال انجام است" - "‏تماس کاری Wi-Fi خروجی" + "‏تماس Wi-Fi درحال انجام" + "‏تماس کاری Wi-Fi درحال انجام" "در انتظار" "تماس ورودی" "تماس ورودی به همراه عکس" @@ -55,8 +55,8 @@ "تماس ورودی مهم به همراه عکس، پیام و مکان" "تماس ورودی مهم به همراه پیوست" "تماس کاری ورودی" - "‏تماس Wi-Fi ورودی" - "‏تماس کاری Wi-Fi ورودی" + "‏تماس Wi-Fi ورودی" + "‏تماس کاری Wi-Fi ورودی" "تماس هرزنامه احتمالی ورودی" "درخواست تماس ویدئویی ورودی" "بدون سرویس" @@ -73,7 +73,7 @@ "انتقال تماس ویدئویی" "برای برقراری یک تماس، ابتدا حالت هواپیما را خاموش کنید." "در شبکه ثبت نشده است." - "شبکه تلفن همراه در دسترس نیست." + "شبکه تلفن همراه دردسترس نیست." "برای برقراری تماس، یک شماره معتبر وارد کنید." "نمی‌توانید تماس بگیرید." "‏شروع ترتیب MMI..." @@ -134,8 +134,8 @@ "پایان تماس" "تماس کنفرانسی" "در تماس" - "ادامه تماس با استفاده از داده شبکه تلفن همراه..." - "‏به شبکه Wi-Fi جابه‌جا نشد" - "تماس ویدئویی همچنان از شبکه تلفن همراه استفاده می‌کند. هزینه‌های داده استاندارد اعمال می‌شود." + "ادامه تماس با استفاده از داده شبکه همراه…" + "‏جابجایی به شبکه Wi-Fi انجام نشد" + "تماس ویدیویی همچنان ازطریق شبکه تلفن همراه انجام می‌شود. ممکن است هزینه‌های استاندارد داده اعمال شود." "دوباره نشان داده نشود" diff --git a/java/com/android/incallui/res/values-fi/strings.xml b/java/com/android/incallui/res/values-fi/strings.xml index 995e7a328..f13ff26a5 100644 --- a/java/com/android/incallui/res/values-fi/strings.xml +++ b/java/com/android/incallui/res/values-fi/strings.xml @@ -33,8 +33,8 @@ "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" + "Käynnissä oleva Wi-Fi-puhelu" + "Käynnissä oleva Wi-Fi-työpuhelu" "Pidossa" "Saapuva puhelu" "Kuvan sisältävä saapuva puhelu" @@ -55,8 +55,8 @@ "Tärkeä liitteitä sisältävä saapuva puhelu" "Tärkeä liitteitä sisältävä saapuva puhelu" "Saapuva työpuhelu" - "Saapuva Wi-Fi-puhelu" - "Saapuva Wi-Fi-työpuhelu" + "Saapuva Wi-Fi-puhelu" + "Saapuva Wi-Fi-työpuhelu" "Tämä puhelu saattaa olla häirikköpuhelu." "Saapuva videopyyntö" "Katvealueella" @@ -73,7 +73,7 @@ "Vastaa videopuheluun" "Poista lentokonetila käytöstä ennen puhelun soittamista." "Ei rekisteröity verkkoon." - "Matkapuhelinverkko ei ole käytettävissä." + "Mobiilidataverkko ei ole käytettävissä." "Soita antamalla kelvollinen numero." "Puhelua ei voi soittaa." "Aloitetaan MMI-koodisekvenssiä..." @@ -134,8 +134,8 @@ "Päätä puhelu" "Puhelinneuvottelu" "Puhelu käynnissä" - "Jatketaan puhelua mobiilitiedonsiirron avulla…" - "Siirtyminen Wi-Fi-verkkoon epäonnistui." - "Videopuhelu soitetaan matkapuhelinverkon kautta. Operaattori voi veloittaa tiedonsiirrosta hinnastonsa mukaan." + "Jatketaan puhelua mobiilidatayhteydellä…" + "Vaihto Wi-Fi-verkkoon epäonnistui." + "Videopuhelu soitetaan mobiilidatayhteyden kautta. Operaattori voi veloittaa tiedonsiirrosta." "Älä näytä tätä uudelleen" diff --git a/java/com/android/incallui/res/values-fr-rCA/strings.xml b/java/com/android/incallui/res/values-fr-rCA/strings.xml index 6f4d8daa4..e83658d14 100644 --- a/java/com/android/incallui/res/values-fr-rCA/strings.xml +++ b/java/com/android/incallui/res/values-fr-rCA/strings.xml @@ -33,8 +33,8 @@ "Appel manqué de %s" "Appel en cours" "Appel en cours - travail" - "Appel Wi-Fi en cours" - "Appel Wi-Fi en cours - travail" + "Appel Wi-Fi en cours" + "Appel professionnel Wi-Fi en cours" "En attente" "Appel entrant" "Appel entrant avec photo" @@ -55,8 +55,8 @@ "Appel important avec photo, message et position" "Appel entrant important avec pièces jointes" "Appel entrant - travail" - "Appel Wi-Fi entrant" - "Appel Wi-Fi entrant - travail" + "Appel Wi-Fi entrant" + "Appel professionnel Wi-Fi entrant" "L\'appel entrant est suspect" "Demande de vidéo reçue" "Aucun service" @@ -73,7 +73,7 @@ "Répondre à l\'appel vidéo" "Veuillez désactiver le mode Avion avant de passer un appel." "Non enregistré sur le réseau" - "Réseau cellulaire non disponible." + "Réseau cellulaire non disponible." "Pour faire un appel, entrez un numéro valide." "Impossible d\'appeler." "Lancement de la séquence IHM..." @@ -134,8 +134,8 @@ "Mettre fin à l\'appel" "Conférence téléphonique" "Appel en cours" - "Poursuite de l\'appel à l\'aide de données cellulaires en cours…" - "Impossible de passer à un réseau Wi-Fi" - "L\'appel vidéo restera sur le réseau cellulaire. Des frais de données standards peuvent s\'appliquer." + "Poursuite de l\'appel utilisant des données mobiles en cours…" + "Impossible de passer à un réseau Wi-Fi" + "L\'appel vidéo restera sur le réseau cellulaire. Des frais de données standards peuvent s\'appliquer." "Ne plus afficher" diff --git a/java/com/android/incallui/res/values-fr/strings.xml b/java/com/android/incallui/res/values-fr/strings.xml index c77fc190e..162c242bd 100644 --- a/java/com/android/incallui/res/values-fr/strings.xml +++ b/java/com/android/incallui/res/values-fr/strings.xml @@ -33,8 +33,8 @@ "Appel manqué de %s" "Appel en cours" "Appel professionnel en cours" - "Appel Wi-Fi en cours" - "Appel Wi-Fi professionnel en cours" + "Appel Wi-Fi en cours" + "Appel Wi-Fi professionnel en cours" "En attente" "Appel entrant" "Appel entrant avec photo" @@ -55,8 +55,8 @@ "Appel important avec photo, message et position" "Appel entrant important avec pièces jointes" "Appel professionnel entrant" - "Appel Wi-Fi entrant" - "Appel Wi-Fi professionnel entrant" + "Appel Wi-Fi entrant" + "Appel Wi-Fi professionnel entrant" "Appel entrant indésirable suspecté" "Demande de vidéo reçue" "Aucun service" @@ -73,7 +73,7 @@ "Répondre à l\'appel vidéo" "Veuillez d\'abord désactiver le mode Avion, afin d\'effectuer un appel." "Non enregistré sur le réseau." - "Réseau mobile non disponible." + "Réseau mobile non disponible" "Pour émettre un appel, veuillez saisir un numéro valide." "Impossible d\'émettre l\'appel." "Lancement de la séquence IHM..." @@ -134,8 +134,8 @@ "Mettre fin à l\'appel" "Conférence téléphonique" "Appel en cours" - "Continuer l\'appel en utilisant les données mobiles…" - "Impossible de passer au réseau Wi-Fi" - "L\'appel vidéo va continuer sur le réseau mobile. Des frais standard liés à la consommation de données peuvent être facturés." + "Poursuite de l\'appel via les données mobiles…" + "Impossible de passer au réseau Wi-Fi" + "L\'appel vidéo va continuer sur le réseau mobile. Des frais standards liés à la consommation de données peuvent être facturés." "Ne plus afficher" diff --git a/java/com/android/incallui/res/values-gl/strings.xml b/java/com/android/incallui/res/values-gl/strings.xml index 53278e58e..d926b1b1e 100644 --- a/java/com/android/incallui/res/values-gl/strings.xml +++ b/java/com/android/incallui/res/values-gl/strings.xml @@ -33,8 +33,8 @@ "Chamada perdida de %s" "Chamada en curso" "Chamada de traballo saínte" - "Chamada wifi saínte" - "Chamada wifi de traballo saínte" + "Chamada saínte por wifi" + "Chamada de traballo saínte por wifi" "En espera" "Chamada entrante" "Chamada entrante con foto" @@ -55,8 +55,8 @@ "Chamada entrante importante con foto, mensaxe e localización" "Chamada entrante importante con anexos" "Chamada de traballo entrante" - "Chamada wifi entrante" - "Chamada wifi de traballo entrante" + "Chamada entrante por wifi" + "Chamada de traballo entrante por wifi" "Chamada entrante sospeitosa de spam" "Solicitude de vídeo entrante" "Sen servizo" @@ -73,7 +73,7 @@ "Responder á videochamada" "Para facer unha chamada, primeiro desactiva o modo avión." "Sen rexistro na rede" - "Rece móbil non dispoñible." + "A rede móbil non está dispoñible." "Para realizar unha chamada, introduce un número válido." "Non se pode chamar." "Iniciando secuencia MMI..." @@ -134,8 +134,8 @@ "Finalizar chamada" "Conferencia telefónica" "Chamada en curso" - "Continuando a chamada con datos móbiles…" - "Non se puido cambiar á rede wifi" - "A videochamada permanecerá na rede móbil. É posible que o operador aplique tarifas de datos estándar." + "Continuando a chamada con datos móbiles…" + "Non se puido cambiar á rede wifi" + "A videochamada permanecerá na rede móbil. É posible que se apliquen tarifas de datos estándar." "Non mostrar de novo" diff --git a/java/com/android/incallui/res/values-gu/strings.xml b/java/com/android/incallui/res/values-gu/strings.xml index 8b1ebe8e0..4a90fc568 100644 --- a/java/com/android/incallui/res/values-gu/strings.xml +++ b/java/com/android/incallui/res/values-gu/strings.xml @@ -33,8 +33,8 @@ "%s નો કૉલ ચૂકી ગયાં" "ચાલી રહેલ કૉલ" "ચાલી રહેલ કાર્ય કૉલ" - "ચાલુ Wi-Fi કૉલ" - "ચાલી રહેલ Wi-Fi કાર્ય કૉલ" + "ચાલી રહેલ Wi-Fi કૉલ" + "ચાલી રહેલ Wi-Fi કાર્ય કૉલ" "હોલ્ડ પર" "ઇનકમિંગ કૉલ" "ફોટો સાથે ઇનકમિંગ કૉલ" @@ -55,8 +55,8 @@ "ફોટો, સંદેશ અને સ્થાન સાથે મહત્વનો ઇનકમિંગ કૉલ" "જોડાણો સાથે મહત્વનો ઇનકમિંગ કૉલ" "ઇનકમિંગ કાર્ય કૉલ" - "ઇનકમિંગ Wi-Fi કૉલ" - "ઇનકમિંગ Wi-Fi કાર્ય કૉલ" + "ઇનકમિંગ Wi-Fi કૉલ" + "ઇનકમિંગ Wi-Fi કાર્ય કૉલ" "ઇનકમિંગ શંકાસ્પદ સ્પામ કૉલ" "આવનાર વિડિઓ વિનંતી" "કોઈ સેવા નથી" @@ -73,7 +73,7 @@ "વિડિઓ કૉલ લો" "કૉલ કરવા માટે, પહેલાં એરપ્લેન મોડને બંધ કરો." "નેટવર્ક પર નોંધણી કરાયેલ નથી." - "સેલ્યુલર નેટવર્ક ઉપલબ્ધ નથી." + "મોબાઇલ નેટવર્ક ઉપલબ્ધ નથી." "કૉલ કરવા માટે, માન્ય નંબર દાખલ કરો." "કૉલ કરી શકાતો નથી." "MMI અનુક્રમ પ્રારંભ કરી રહ્યાં છે…" @@ -134,8 +134,8 @@ "કૉલ સમાપ્ત કરો" "કૉન્ફરન્સ કૉલ" "કૉલમાં" - "સેલ્યુલર ડેટાની મદદથી કૉલ ચાલુ રાખી રહ્યાં છે…" - "Wi-Fi નેટવર્ક પર સ્વિચ કરી શક્યાં નથી" - "વિડિઓ કૉલ સેલ્યુલર નેટવર્ક પર રહેશે. માનક ડેટા શુલ્ક લાગુ થઈ શકે છે." + "મોબાઇલ ડેટાની મદદથી કૉલ ચાલુ રાખી રહ્યાં છે…" + "Wi-Fi નેટવર્ક પર સ્વિચ કરી શક્યાં નથી" + "વિડિઓ કૉલ, મોબાઇલ નેટવર્ક પર રહેશે. માનક ડેટા શુલ્ક લાગુ થઈ શકે છે." "આ ફરીથી બતાવશો નહીં" diff --git a/java/com/android/incallui/res/values-hi/strings.xml b/java/com/android/incallui/res/values-hi/strings.xml index 09563dfc4..d3a4dcfa8 100644 --- a/java/com/android/incallui/res/values-hi/strings.xml +++ b/java/com/android/incallui/res/values-hi/strings.xml @@ -33,8 +33,8 @@ "%s के छूटे कॉल" "चल रही कॉल" "कार्यस्थल की जारी कॉल" - "चल रहा वाई-फ़ाई कॉल" - "कार्यस्थल की जारी वाई-फ़ाई कॉल" + "जारी Wi‑Fi कॉल" + "जारी Wi‑Fi कार्य कॉल" "होल्ड पर" "इनकमिंग कॉल" "फ़ोटो के साथ इनकमिंग कॉल" @@ -55,8 +55,8 @@ "फोटो, संदेश और स्थान के साथ महत्वपूर्ण इनकमिंग कॉल" "अटैचमेंट के साथ महत्वपूर्ण इनकमिंग कॉल" "कार्यस्थल की आवक कॉल" - "इनकमिंग वाई-फ़ाई कॉल" - "कार्यस्थल की वाई-फ़ाई आवक कॉल" + "इनकमिंग Wi‑Fi कॉल" + "इनकमिंग Wi‑Fi कार्य कॉल" "संदिग्ध आवक स्पैम कॉल" "इनकमिंग वीडियो अनुरोध" "कोई सेवा नहीं" @@ -73,7 +73,7 @@ "वीडियो कॉल लें" "कॉल करने के लिए, पहले विमान मोड बंद करें." "नेटवर्क पर पंजीकृत नहीं." - "सेल्युलर नेटवर्क उपलब्ध नहीं." + "मोबाइल नेटवर्क उपलब्ध नहीं है." "कॉल करने के लिए, मान्‍य नंबर डालें." "कॉल नहीं किया जा सकता." "MMI अनुक्रम प्रारंभ हो रहा है…" @@ -134,8 +134,8 @@ "कॉल समाप्त करें" "कॉन्फ़्रेंस कॉल" "कॉल में" - "सेल्युलर डेटा का उपयोग करके कॉल जारी रखा जा रहा है…" - "वाई-फ़ाई नेटवर्क में नहीं बदला जा सका" - "वीडियो कॉल सेल्यूलर नेटवर्क पर बना रहेगा. मानक डेटा शुल्क लागू हो सकते हैं." + "मोबाइल डेटा का उपयोग करके कॉल जारी रखा जा रहा है…" + "Wi‑Fi नेटवर्क पर स्विच नहीं कर सका" + "वीडियो कॉल मोबाइल नेटवर्क पर बना रहेगा. मानक डेटा शुल्क लागू हो सकते हैं." "इसे दोबारा न दिखाएं" diff --git a/java/com/android/incallui/res/values-hr/strings.xml b/java/com/android/incallui/res/values-hr/strings.xml index 7af16133a..2d389e666 100644 --- a/java/com/android/incallui/res/values-hr/strings.xml +++ b/java/com/android/incallui/res/values-hr/strings.xml @@ -33,8 +33,8 @@ "Propušten poziv kontakta %s" "Poziv u tijeku" "Poslovni poziv u tijeku" - "Wi-Fi poziv u tijeku" - "Poslovni Wi-Fi poziv u tijeku" + "Wi-Fi poziv u tijeku" + "Poslovni Wi-Fi poziv u tijeku" "Na čekanju" "Dolazni poziv" "Dolazni poziv s fotografijom" @@ -55,8 +55,8 @@ "Važan poziv s fotografijom, porukom i lokacijom" "Važan dolazni poziv s privicima" "Dolazni poslovni poziv" - "Dolazni Wi-Fi poziv" - "Dolazni poslovni Wi-Fi poziv" + "Dolazni Wi-Fi poziv" + "Dolazni poslovni Wi-Fi poziv" "Mogući neželjeni dolazni poziv" "Dolazni zahtjev za videopoziv" "Nema usluge" @@ -73,7 +73,7 @@ "Preuzimanje videopoziva" "Da biste uspostavili poziv, prvo isključite način rada u zrakoplovu." "Nije registrirano na mreži." - "Mobilna mreža nije dostupna." + "Mobilna mreža nije dostupna." "Unesite važeći broj da biste uspostavili poziv." "Pozivanje nije moguće." "Pokretanje MMI sekvence…" @@ -134,8 +134,8 @@ "Prekid poziva" "Konferencijski poziv" "Poziv u tijeku" - "Poziv se nastavlja pomoću mobilnih podataka..." - "Prebacivanje na Wi-Fi mrežu nije moguće" - "Videopoziv će ostati na mobilnoj mreži. Možda ćete morati platiti podatkovni promet." + "Poziv se nastavlja pomoću mobilnih podataka..." + "Prebacivanje na Wi-Fi mrežu nije moguće" + "Videopoziv će ostati na mobilnoj mreži. Možda ćete morati platiti podatkovni promet." "Ne prikazuj ponovno" diff --git a/java/com/android/incallui/res/values-hu/strings.xml b/java/com/android/incallui/res/values-hu/strings.xml index 08d374b41..fe524216c 100644 --- a/java/com/android/incallui/res/values-hu/strings.xml +++ b/java/com/android/incallui/res/values-hu/strings.xml @@ -33,8 +33,8 @@ "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-Fin keresztül" + "Folyamatban lévő Wi-Fi-hívás" + "Folyamatban lévő munkahelyi hívás Wi-Fin keresztül" "Tartásban" "Bejövő hívás" "Bejövő hívás fotóval" @@ -55,8 +55,8 @@ "Fontos bejövő hívás fotóval, üzenettel és hellyel" "Fontos bejövő hívás mellékletekkel" "Bejövő munkahelyi hívás" - "Beérkező Wi-Fi-hívás" - "Bejövő munkahelyi hívás Wi-Fin keresztül" + "Beérkező Wi-Fi-hívás" + "Bejövő munkahelyi hívás Wi-Fin keresztül" "Bejövő gyanús spamhívás" "Bejövő videokérés" "Nincs szolgáltatás" @@ -73,7 +73,7 @@ "Videohívás fogadása" "Híváskezdeményezéshez kapcsolja ki a Repülőgép üzemmódot." "Nincs regisztrálva a hálózaton." - "A mobilhálózat nem érhető el." + "A mobilhálózat nem érhető el." "Hívásindításhoz adjon meg egy érvényes számot." "A hívás sikertelen." "MMI-sorozat indítása..." @@ -134,8 +134,8 @@ "Hívás befejezése" "Konferenciahívás" "Hívásban" - "Hívás folytatása mobil-adatkapcsolaton keresztül…" - "Nem sikerült Wi-Fi-hálózatra váltani" - "A videohívást továbbra is a mobilhálózaton folytatja. A mobilszolgáltató a normál adatforgalmi díjat számítja fel." + "Hívás folytatása mobil-adatkapcsolaton keresztül…" + "Nem sikerült Wi-Fi-hálózatra váltani" + "A videohívást továbbra is a mobilhálózaton folytatja. A mobilszolgáltató a normál adatforgalmi díjat számítja fel." "Ne jelenjen meg többé" diff --git a/java/com/android/incallui/res/values-hy/strings.xml b/java/com/android/incallui/res/values-hy/strings.xml index f6496d14d..4287820c2 100644 --- a/java/com/android/incallui/res/values-hy/strings.xml +++ b/java/com/android/incallui/res/values-hy/strings.xml @@ -33,8 +33,8 @@ "Բաց թողնված զանգ %s-ից" "Ընթացիկ զանգը" "Ընթացիկ աշխատանքային զանգ" - "Ընթացիկ զանգ Wi-Fi-ի միջոցով" - "Ընթացիկ աշխատանքային Wi-Fi զանգ" + "Ընթացիկ զանգ Wi-Fi-ի միջոցով" + "Ընթացիկ աշխատանքային զանգ Wi-Fi-ի միջոցով" "Սպասում" "Մուտքային զանգ" "Մուտքային զանգ՝ լուսանկարով" @@ -55,8 +55,8 @@ "Կարևոր մուտքային զանգ՝ կցորդներով" "Կարևոր մուտքային զանգ՝ կցորդներով" "Մուտքային աշխատանքային զանգ" - "Մուտքային զանգ Wi-Fi-ի միջոցով" - "Մուտքային աշխատանքային Wi-Fi զանգ" + "Մուտքային զանգ Wi-Fi-ի միջոցով" + "Մուտքային աշխատանքային զանգ Wi-Fi-ի միջոցով" "Մուտքային զանգը հավանաբար լցոն է" "Մուտքային տեսազանգի հայցում" "Ծառայություններ չկան" @@ -73,7 +73,7 @@ "Ընդունել տեսազանգը" "Զանգի կատարման համար նախ անջատեք թռիչքային ռեժիմը:" "Ցանցում գրանցված չէ:" - "Բջջային ցանցն անհասանելի է:" + "Բջջային ցանցն անհասանելի է:" "Զանգ կատարելու համար մուտքագրեք ճիշտ համար:" "Հնարավոր չէ զանգել:" "Մեկնարկում է MMI հաջորդականությունը..." @@ -134,8 +134,8 @@ "Ավարտել զանգը" "Կոնֆերանս զանգ" "Զանգ" - "Զանգն այժմ բջջային ինտերնետով է ընթանում…" - "Չհաջողվեց միանալ Wi-Fi ցանցին" - "Տեսազանգը կշարունակվի բջջային ցանցով: Գանձումը կկատարվի ըստ ձեր սակագնային պլանի:" + "Զանգն այժմ բջջային ինտերնետով է ընթանում…" + "Չհաջողվեց միանալ Wi-Fi ցանցին" + "Տեսազանգը կշարունակվի բջջային ցանցով: Գանձումը կկատարվի ըստ ձեր սակագնային պլանի:" "Այլևս ցույց չտալ" diff --git a/java/com/android/incallui/res/values-in/strings.xml b/java/com/android/incallui/res/values-in/strings.xml index 279e72d21..6de6136fb 100644 --- a/java/com/android/incallui/res/values-in/strings.xml +++ b/java/com/android/incallui/res/values-in/strings.xml @@ -33,8 +33,8 @@ "Panggilan tak terjawab dari %s" "Panggilan yang sedang berlangsung" "Panggilan telepon kerja yang sedang berlangsung" - "Panggilan Wi-Fi keluar" - "Panggilan Wi-Fi kerja yang sedang berlangsung" + "Panggilan Wi-Fi keluar" + "Panggilan kerja Wi-Fi yang berlangsung" "Ditangguhkan" "Panggilan masuk" "Panggilan masuk dengan foto" @@ -55,8 +55,8 @@ "Panggilan penting dengan foto, pesan, dan lokasi" "Panggilan masuk penting dengan lampiran" "Panggilan telepon kerja yang masuk" - "Panggilan Wi-Fi masuk" - "Panggilan telepon Wi-Fi kerja yang masuk" + "Panggilan Wi-Fi masuk" + "Panggilan kerja Wi-Fi masuk" "Panggilan masuk yang diduga spam" "Permintaan video masuk" "Tidak ada layanan" @@ -73,7 +73,7 @@ "Lakukan Video Call" "Untuk melakukan panggilan, pertama-tama matikan mode Pesawat." "Tidak terdaftar pada jaringan." - "Jaringan seluler tidak tersedia." + "Jaringan seluler tidak tersedia." "Untuk melakukan panggilan telepon, masukkan nomor yang valid." "Tidak dapat menelepon." "Memulai urutan MMI..." @@ -134,8 +134,8 @@ "Akhiri panggilan" "Telewicara" "Sedang menelepon" - "Melanjutkan panggilan menggunakan data seluler..." - "Tidak dapat beralih ke jaringan Wi-Fi" - "Video call akan tetap di jaringan seluler. Biaya data standar mungkin berlaku." + "Melanjutkan panggilan menggunakan data seluler..." + "Tidak dapat beralih ke jaringan Wi-Fi" + "Video call akan tetap di jaringan seluler. Tarif data standar mungkin berlaku." "Jangan tampilkan ini lagi" diff --git a/java/com/android/incallui/res/values-is/strings.xml b/java/com/android/incallui/res/values-is/strings.xml index 795e952c6..8393510c6 100644 --- a/java/com/android/incallui/res/values-is/strings.xml +++ b/java/com/android/incallui/res/values-is/strings.xml @@ -33,8 +33,8 @@ "Ósvarað símtal frá %s" "Samtal í gangi" "Vinnusímtal í gangi" - "Wi-Fi símtal stendur yfir" - "Vinnusímtal í gangi um Wi-Fi" + "Wi-Fi símtal stendur yfir" + "Vinnusímtal í gangi um Wi-Fi" "Í bið" "Móttekið símtal" "Móttekið símtal með mynd" @@ -55,8 +55,8 @@ "Mikilvægt móttekið símtal með mynd, skilaboðum og staðsetningu" "Mikilvægt móttekið símtal með viðhengjum" "Vinnusímtal berst" - "Wi-Fi símtal berst" - "Vinnusímtal berst um Wi-Fi" + "Wi-Fi símtal berst" + "Vinnusímtal berst um Wi-Fi" "Símtal sem berst er hugsanlega úr ruslnúmeri" "Myndbeiðni berst" "Ekkert símasamband" @@ -73,7 +73,7 @@ "Þiggja myndsímtal" "Til að hringja símtal þarftu fyrst að slökkva á flugstillingu." "Ekki skráð á símkerfi." - "Farsímakerfi ekki til staðar." + "Farsímakerfi ekki tiltækt." "Sláðu inn gilt númer til að hringja símtal." "Ekki hægt að hringja." "Ræsir MMI-runu…" @@ -134,8 +134,8 @@ "Ljúka símtali" "Símafundur" "Í símtali" - "Símtal heldur áfram og notar farsímagögn…" - "Ekki var hægt að skipta yfir á Wi-Fi-net" - "Myndsímtal verður áfram á farsímaneti. Stöðluð gjöld fyrir gagnaflutning kunna að eiga við." + "Símtal heldur áfram og notar farsímagögn…" + "Ekki var hægt að skipta yfir á Wi-Fi-net" + "Myndsímtal verður áfram á farsímaneti. Stöðluð gjöld fyrir gagnaflutning kunna að eiga við." "Ekki birta þetta aftur" diff --git a/java/com/android/incallui/res/values-it/strings.xml b/java/com/android/incallui/res/values-it/strings.xml index 836b93452..ca2b4b14a 100644 --- a/java/com/android/incallui/res/values-it/strings.xml +++ b/java/com/android/incallui/res/values-it/strings.xml @@ -33,8 +33,8 @@ "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" + "Chiamata Wi-Fi in corso" + "Chiamata di lavoro tramite Wi-Fi in corso" "In attesa" "Chiamata in arrivo" "Chiamata in arrivo con foto" @@ -55,8 +55,8 @@ "Chiamata importante in arrivo con foto, messaggio e posizione" "Chiamata importante in arrivo con allegati" "Chiamata di lavoro in arrivo" - "Chiamata Wi-Fi in arrivo" - "Chiamata di lavoro in arrivo tramite Wi-Fi" + "Chiamata Wi-Fi in arrivo" + "Chiamata di lavoro tramite Wi-Fi in arrivo" "Chiamata di presunto spam in arrivo" "Richiesta video in arrivo" "Nessun servizio" @@ -73,7 +73,7 @@ "Ricevi videochiamata" "Per fare una telefonata, disattiva la modalità aereo." "Non registrato sulla rete." - "Rete cellulare non disponibile." + "Rete mobile non disponibile." "Per effettuare una chiamata, inserisci un numero valido." "Impossibile chiamare." "Inizio sequenza MMI..." @@ -134,8 +134,8 @@ "Termina chiamata" "Audioconferenza" "Chiamata in corso" - "Proseguimento della chiamata utilizzando la rete dati…" - "Impossibile passare alla rete Wi-Fi" - "La videochiamata rimarrà sulla rete cellulare. Potrebbero essere applicati costi standard per il traffico dati." + "Proseguimento della chiamata utilizzando i dati mobili…" + "Impossibile passare alla rete Wi-Fi" + "La videochiamata rimarrà sulla rete mobile. Potrebbero essere applicati costi standard per il traffico dati." "Non mostrare più questo messaggio" diff --git a/java/com/android/incallui/res/values-iw/strings.xml b/java/com/android/incallui/res/values-iw/strings.xml index 195cb0f25..326078ae8 100644 --- a/java/com/android/incallui/res/values-iw/strings.xml +++ b/java/com/android/incallui/res/values-iw/strings.xml @@ -33,8 +33,8 @@ "שיחה שלא נענתה מאת %s" "שיחה פעילה" "שיחת עבודה פעילה" - "‏שיחת Wi-Fi מתבצעת" - "‏שיחת עבודה פעילה ברשת WiFi" + "‏שיחת Wi-Fi פעילה" + "‏שיחת עבודה פעילה ברשת Wi‑Fi" "בהמתנה" "שיחה נכנסת" "שיחה נכנסת עם תמונה" @@ -55,8 +55,8 @@ "שיחה נכנסת חשובה עם תמונה, הודעה ומיקום" "שיחה נכנסת חשובה עם קבצים מצורפים" "שיחת עבודה נכנסת" - "‏שיחת Wi-Fi נכנסת" - "‏שיחת עבודה נכנסת ברשת WiFi" + "‏שיחת Wi-Fi נכנסת" + "‏שיחת עבודה נכנסת ברשת Wi‑Fi" "השיחה הנכנסת חשודה כספאם" "בקשת וידאו נכנסת" "אין שירות" @@ -73,7 +73,7 @@ "קבל את שיחת הווידאו" "כדי להתקשר, כבה תחילה את מצב טיסה." "לא רשום ברשת." - "רשת סלולרית אינה זמינה." + "הרשת הסלולרית אינה זמינה." "כדי להתקשר, הזן מספר טלפון חוקי." "לא ניתן להתקשר." "‏מתחיל רצף MMI…" @@ -134,8 +134,8 @@ "סיים שיחה" "שיחת ועידה" "בשיחה" - "ממשיך את השיחה באמצעות הרשת הסלולרית..." - "‏לא ניתן לעבור לרשת Wi-Fi" - "שיחת הווידאו תמשיך להיות ברשת הסלולרית. ייתכן שתחויב על ידי הספק הסלולרי בגין צריכת נתונים." + "ממשיך את השיחה באמצעות הרשת הסלולרית…" + "‏לא ניתן לעבור לרשת Wi-Fi" + "שיחת הווידאו תמשיך להיות ברשת הסלולרית. ייתכן שתחויב על שימוש בנתונים." "אל תציג זאת שוב" diff --git a/java/com/android/incallui/res/values-ja/strings.xml b/java/com/android/incallui/res/values-ja/strings.xml index 0e186fa3d..a54c4e12a 100644 --- a/java/com/android/incallui/res/values-ja/strings.xml +++ b/java/com/android/incallui/res/values-ja/strings.xml @@ -33,8 +33,8 @@ "%s さんからの不在着信" "通話中" "仕事の通話中" - "Wi-Fi通話を発信中" - "仕事の Wi-Fi 通話中" + "Wi-Fi 通話を発信中" + "仕事の Wi-Fi 通話を発信中" "保留中" "通話着信" "着信(写真あり)" @@ -55,8 +55,8 @@ "重要な着信(写真、メッセージ、位置情報あり)" "重要な着信(添付ファイルあり)" "仕事の通話が着信中" - "Wi-Fi通話が着信中" - "仕事の Wi-Fi 通話が着信中" + "Wi-Fi 通話が着信中" + "仕事の Wi-Fi 通話が着信中" "迷惑電話の疑いがある通話を着信しています" "ビデオハングアウトリクエスト着信" "通信サービスなし" @@ -73,7 +73,7 @@ "ビデオハングアウトを引き継ぐ" "機内モードをOFFにしてから発信してください。" "ご加入の通信サービスがありません" - "モバイルネットワークが利用できません。" + "モバイル ネットワークを利用できません。" "発信するには、有効な番号を入力してください。" "発信できません。" "MMIシーケンスを開始中..." @@ -134,8 +134,8 @@ "通話を終了" "グループ通話" "通話中" - "モバイルデータを使用して通話を継続しています…" - "Wi-Fi ネットワークに切り替えることができませんでした" - "引き続きモバイル ネットワークを使用してビデオ通話を続行します。通常のデータ通信料が適用される場合があります。" + "モバイルデータを使用して通話を継続しています…" + "Wi-Fi ネットワークに切り替えることができませんでした" + "引き続きモバイル ネットワークを使用してビデオハングアウトを続行します。通常のデータ通信料が適用される場合があります。" "今後このメッセージを表示しない" diff --git a/java/com/android/incallui/res/values-ka/strings.xml b/java/com/android/incallui/res/values-ka/strings.xml index 6c46bd0c7..fed398b49 100644 --- a/java/com/android/incallui/res/values-ka/strings.xml +++ b/java/com/android/incallui/res/values-ka/strings.xml @@ -33,8 +33,8 @@ "გამოტოვებული ზარი %s-ისგან" "მიმდინარე ზარი" "მიმდინარე ზარი (სამსახური)" - "მიმდინარე Wi-Fi ზარი" - "მიმდინარე Wi-Fi ზარი (სამსახური)" + "მიმდინარე Wi-Fi ზარი" + "მიმდინარე Wi-Fi ზარი (სამსახური)" "შეყოვნების რეჟიმში" "შემომავალი ზარი" "შემომავალი ზარი ფოტოთი" @@ -55,8 +55,8 @@ "ზარი ფოტოთი, შეტყობინებით და მდებარეობით" "მნიშვნელოვანი შემომავალი ზარი დანართებით" "შემომავალი ზარი (სამსახური)" - "შემომავალი Wi-Fi ზარი" - "შემომავალი Wi-Fi ზარი (სამსახური)" + "შემომავალი Wi-Fi ზარი" + "შემომავალი Wi-Fi ზარი (სამსახური)" "შემომავალი ზარი - სავარაუდოდ სპამი" "შემომავალი ვიდეოს მოთხოვნა" "სერვისი არ არის" @@ -73,7 +73,7 @@ "Take ვიდეო ზარი" "ზარის განსახორციელებლად, ჯერ თვითმფრინავის რეჟიმი უნდა გამორთოთ." "ქსელში რეგისტრირებული არ არის." - "ფიჭური ქსელი მიუწვდომელია" + "მობილური ქსელი მიუწვდომელია." "ზარის განხორციელებისათვის, შეიყვანეთ მოქმედი ნომერი." "არ ირეკება." "MMI თანმიმდევრობის დაწყება…" @@ -134,8 +134,8 @@ "ზარის დასრულება" "საკონფერენციო ზარი" "მონაწილეობს ზარში" - "ზარი გრძელდება მობილური ინტერნეტის გამოყენებით…" - "Wi-Fi ქსელზე გადართვა ვერ მოხერხდა" - "ვიდეოზარი ფიჭურ ქსელში დარჩება. შესაძლოა მოგიწიოთ მობილური ინტერნეტის სტანდარტული ფასის გადახდა." + "ზარი გრძელდება მობილური ინტერნეტის გამოყენებით…" + "Wi-Fi ქსელზე გადართვა ვერ მოხერხდა" + "ვიდეოზარი მობილური ინტერნეტის ქსელში დარჩება. შესაძლოა მოგიწიოთ მობილური ინტერნეტის სტანდარტული საფასურის გადახდა." "აღარ მაჩვენო" diff --git a/java/com/android/incallui/res/values-kk/strings.xml b/java/com/android/incallui/res/values-kk/strings.xml index 310ba4d28..42ac9b078 100644 --- a/java/com/android/incallui/res/values-kk/strings.xml +++ b/java/com/android/incallui/res/values-kk/strings.xml @@ -33,8 +33,8 @@ "%s қоңырауы өткізіп алынған" "Ағымдағы қоңырау" "Ағымдағы жұмыс қоңырауы" - "Ағымдық Wi-Fi қоңырауы" - "Ағымдағы Wi-Fi жұмыс қоңырауы" + "Қазіргі Wi-Fi қоңырауы" + "Қазіргі Wi-Fi жұмыс қоңырауы" "Күтуде" "Келген қоңырау" "Сурет тіркелген кіріс қоңырау" @@ -55,8 +55,8 @@ "Сурет, хабар және орын дерегі тіркелген маңызды кіріс қоңырау" "Тіркемелері бар маңызды кіріс қоңырау" "Кіріс жұмыс қоңырауы" - "Кіріс Wi-Fi қоңырауы" - "Кіріс Wi-Fi жұмыс қоңырауы" + "Кіріс Wi-Fi қоңырауы" + "Кіріс Wi-Fi жұмыс қоңырауы" "Кіріс қоңырауы спам болуы мүмкін" "Кіріс бейне сұрау" "Қызмет көрсетілмейді" @@ -73,7 +73,7 @@ "Бейне қоңырауды бері бұру" "Қоңырау шалу үшін алдымен Ұшақ режимін өшіріңіз." "Желіде тіркелмеген." - "Ұялы желі қол жетімді емес." + "Мобильдік желі қолжетімсіз." "Қоңырау шалу үшін жарамды нөмірді енгізіңіз." "Қоңырау шалу мүмкін емес." "MMI қатарын бастау…" @@ -134,8 +134,8 @@ "Қоңырауды аяқтау" "Мәжіліс қоңырауы" "Бос емес" - "Қоңырау ұялы дерек арқылы жалғасады..." - "Wi-Fi желісіне қосылу мүмкін болмады" - "Бейне қоңырау ұялы байланыс желісінде қалады. Стандартты деректер ақысы алынуы мүмкін." + "Қоңырау мобильдік желі арқылы жалғасуда…" + "Wi-Fi желісіне қосылу мүмкін болмады" + "Бейне қоңырау мобильдік желіде қалады. Стандартты мобильдік байланыс ақысы алынуы мүмкін." "Мұны қайтадан көрсетпеу" diff --git a/java/com/android/incallui/res/values-km/strings.xml b/java/com/android/incallui/res/values-km/strings.xml index 4fbafef71..c6238de2b 100644 --- a/java/com/android/incallui/res/values-km/strings.xml +++ b/java/com/android/incallui/res/values-km/strings.xml @@ -33,8 +33,8 @@ "ខកខាន​ទទួល​ពី %s" "កំពុង​បន្ត​ការ​ហៅ" "ការហៅពីកន្លែងការងារកំពុងដំណើរការ" - "ការហៅតាម Wi-Fi កំពុងបន្ត" - "ការហៅតាម Wi-Fi ពីកន្លែងការងារកំពុងដំណើរការ" + "ការហៅតាម Wi-Fi កំពុង​ដំណើរការ" + "ការហៅតាម Wi-Fi ពីកន្លែងការងារ​កំពុង​ដំណើរការ" "រង់ចាំ" "ការ​ហៅ​ចូល" "ការហៅ​ចូល​​ដែល​មាន​រូបថត" @@ -55,8 +55,8 @@ "ការ​ហៅ​ចូល​ដែល​សំខាន់​មាន​រូបថត សារ និង​ទីតាំង" "ការហៅ​​ចូល​ដែល​សំខាន់​មាន​ឯកសារ​ភ្ជាប់" "កំពុងហៅចូលពីកន្លែងការងារ" - "មានការហៅចូលមកតាម Wi-Fi" - "កំពុងហៅចូលពីកន្លែងការងារតាម Wi-Fi" + "មានការហៅចូលមកតាម Wi-Fi" + "មាន​ការ​ហៅ​ចូល​ពី​កន្លែង​ការងារ​តាម Wi-Fi" "ការ​ហៅ​បន្លំ​​ចូល​​​ដែល​សង្ស័យ" "សំណើ​ការ​ហៅ​ជា​វីដេអូ​ចូល" "គ្មាន​សេវា" @@ -73,7 +73,7 @@ "ទទួល​យក​ការ​ហៅ​វីដេអូ" "ដើម្បី​កំណត់​ការ​ហៅ ដំបូង​ត្រូវ​បិទ​របៀប​នៅ​ពេល​ជិះ​យន្តហោះ។" "មិន​បាន​ចុះ​ឈ្មោះ​នៅ​លើ​បណ្ដាញ។" - "បណ្ដាញ​ចល័ត​មិន​អាច​ប្រើ​បាន។" + "សេវា​ទូរសព្ទ​ចល័ត​មិន​អាច​ប្រើប្រាស់​បាន។" "ដើម្បីធ្វើការហៅ បញ្ចូលលេខដែលមានសុពលភាព។" "មិនអាចហៅបានទេ។" "កំពុង​ចាប់ផ្ដើម​លំដាប់ MMI ..." @@ -134,8 +134,8 @@ "បញ្ចប់ការហៅ" "ហៅជា​សន្និសីទ" "ស្ថិត​​ក្នុង​ការ​ហៅ" - "កំពុង​បន្ត​ហៅ​ទូរស័ព្ទ​ដោយ​ប្រើ​ទិន្នន័យ​ទូរស័ព្ទ​ចល័ត..." - "មិន​អាច​ប្ដូរ​ទៅ​បណ្ដាញ Wi-Fi" - "ការហៅ​ជា​វីដេអូ​នឹង​នៅ​តែ​​ស្ថិត​លើ​បណ្ដាញ​ទូរសព្ទ​ចល័ត។ អាច​​នឹង​​គិតថ្លៃ​ទិន្នន័យ​តាម​តម្លៃ​​ស្តង់ដារ។" + "កំពុង​បន្ត​ការហៅ​ទូរសព្ទ​ ដោយ​ប្រើប្រាស់​ទិន្នន័យ​ចល័ត…" + "មិន​អាច​ប្ដូរ​ទៅ​បណ្ដាញ Wi-Fi បាន​ទេ" + "ការហៅ​តាម​វីដេអូ​នឹង​នៅតែ​មាន​នៅ​លើ​បណ្ដាញ​ទូរសព្ទ។ អាច​នឹង​គិតថ្លៃ​ទិន្នន័យ​តាម​តម្លៃ​ស្តង់ដារ។" "កុំ​បង្ហាញ​វា​ម្ដង​ទៀត" diff --git a/java/com/android/incallui/res/values-kn/strings.xml b/java/com/android/incallui/res/values-kn/strings.xml index 5d47c7e0e..cb47e35d9 100644 --- a/java/com/android/incallui/res/values-kn/strings.xml +++ b/java/com/android/incallui/res/values-kn/strings.xml @@ -33,8 +33,8 @@ "%s ಅವರಿಂದ ಮಿಸ್ಡ್ ಕಾಲ್" "ಚಾಲ್ತಿಯಲ್ಲಿರುವ ಕರೆ" "ಚಾಲ್ತಿಯಲ್ಲಿರುವ ಕೆಲಸದ ಕರೆ" - "ಚಾಲ್ತಿಯಲ್ಲಿರುವ ವೈ-ಫೈ ಕರೆ" - "ಚಾಲ್ತಿಯಲ್ಲಿರುವ ವೈ-ಫೈ ಕೆಲಸದ ಕರೆ" + "ಚಾಲ್ತಿಯಲ್ಲಿರುವ ವೈ-ಫೈ ಕರೆ" + "ಚಾಲ್ತಿಯಲ್ಲಿರುವ ವೈ-ಫೈ ಕೆಲಸದ ಕರೆ" "ತಡೆಹಿಡಿಯಲಾಗಿದೆ" "ಒಳಬರುವ ಕರೆ" "ಫೋಟೋದೊಂದಿಗೆ ಒಳಬರುತ್ತಿರುವ ಕರೆ" @@ -55,8 +55,8 @@ "ಪೋಟೋ, ಸಂದೇಶ ಮತ್ತು ಸ್ಥಳದೊಂದಿಗೆ ಒಳಬರುತ್ತಿರುವ ಪ್ರಮುಖ ಕರೆ" "ಲಗತ್ತುಗಳೊಂದಿಗೆ ಒಳಬರುತ್ತಿರುವ ಪ್ರಮುಖ ಕರೆ" "ಒಳಬರುವ ಕೆಲಸದ ಕರೆ" - "ಒಳಬರುವ ವೈ-ಫೈ ಕರೆ" - "ಒಳಬರುವ ವೈ-ಫೈ ಕೆಲಸದ ಕರೆ" + "ಒಳಬರುವ ವೈ-ಫೈ ಕರೆ" + "ಒಳಬರುವ ವೈ-ಫೈ ಕೆಲಸದ ಕರೆ" "ಒಳಬರುವ ಶಂಕಿತ ಸ್ಪ್ಯಾಮ್ ಕರೆ" "ಒಳಬರುವ ವೀಡಿಯೊ ವಿನಂತಿ" "ಯಾವುದೇ ಸೇವೆಯಿಲ್ಲ" @@ -73,7 +73,7 @@ "ವೀಡಿಯೊ ಕರೆ ತೆಗೆದುಕೊಳ್ಳಿ" "ಕರೆ ಮಾಡಲು, ಮೊದಲು ಏರ್‌ಪ್ಲೇನ್‌‌ ಮೋಡ್‌‌ ಆಫ್‌ ಮಾಡಿ." "ನೆಟ್‌ವರ್ಕ್‌ನಲ್ಲಿ ಇನ್ನೂ ನೋಂದಣಿಯಾಗಿಲ್ಲ." - "ಸೆಲ್ಯುಲಾರ್ ನೆಟ್‌ವರ್ಕ್‌ ಲಭ್ಯವಿಲ್ಲ." + "ಮೊಬೈಲ್‌ ನೆಟ್‌ವರ್ಕ್‌ ಲಭ್ಯವಿಲ್ಲ." "ಕರೆಯನ್ನು ಮಾಡಲು, ಮಾನ್ಯವಾದ ಸಂಖ್ಯೆಯನ್ನು ನಮೂದಿಸಿ." "ಕರೆ ಮಾಡಲು ಸಾಧ್ಯವಿಲ್ಲ." "MMI ಅನುಕ್ರಮ ಪ್ರಾರಂಭವಾಗುತ್ತಿದೆ…" @@ -134,8 +134,8 @@ "ಕರೆ ಅಂತ್ಯಗೊಳಿಸಿ" "ಕಾನ್ಫರೆನ್ಸ್ ಕರೆ" "ಕರೆಯಲ್ಲಿ" - "ಸೆಲ್ಯುಲಾರ್ ಡೇಟಾ ಬಳಸಿಕೊಂಡು ಕರೆ ಮುಂದುವರಿಸಲಾಗುತ್ತಿದೆ…" - "ವೈ-ಫೈ ನೆಟ್‍ವರ್ಕ್‌ಗೆ ಬದಲಾಯಿಸಲು ಸಾಧ್ಯವಿಲ್ಲ" - "ಸೆಲ್ಯುಲಾರ್ ನೆಟ್‌ವರ್ಕ್‌ಗೆ ವೀಡಿಯೊ ಕರೆ ಹಾಗೆಯೇ ಉಳಿಯುತ್ತದೆ. ಪ್ರಮಾಣಿತ ಡೇಟಾ ಶುಲ್ಕಗಳು ಅನ್ವಯಿಸಬಹುದು." + "ಮೊಬೈಲ್ ಡೇಟಾ ಬಳಸಿಕೊಂಡು ಕರೆ ಮುಂದುವರಿಸಲಾಗುತ್ತಿದೆ…" + "ವೈ-ಫೈ ನೆಟ್‍ವರ್ಕ್‌ಗೆ ಬದಲಾಯಿಸಲು ಸಾಧ್ಯವಿಲ್ಲ" + "ವೀಡಿಯೊ ಕರೆ ಮೊಬೈಲ್ ನೆಟ್‌ವರ್ಕ್‌ನಲ್ಲಿ ಹಾಗೆಯೇ ಉಳಿಯುತ್ತದೆ. ಪ್ರಮಾಣಿತ ಡೇಟಾ ಶುಲ್ಕಗಳು ಅನ್ವಯಿಸಬಹುದು." "ಮತ್ತೆ ಇದನ್ನು ತೋರಿಸಬೇಡ" diff --git a/java/com/android/incallui/res/values-ko/strings.xml b/java/com/android/incallui/res/values-ko/strings.xml index 44c53389a..676ba08f0 100644 --- a/java/com/android/incallui/res/values-ko/strings.xml +++ b/java/com/android/incallui/res/values-ko/strings.xml @@ -33,8 +33,8 @@ "%s의 부재중 전화" "현재 통화" "발신 업무 전화" - "Wi-Fi 발신 전화" - "발신 Wi-Fi 업무 전화" + "진행 중인 Wi-Fi 통화" + "진행 중인 Wi-Fi 업무 통화" "대기 중" "수신전화" "사진이 있는 수신 전화" @@ -55,8 +55,8 @@ "사진, 메시지, 위치가 있는 중요한 수신 전화" "첨부파일이 있는 중요한 수신 전화" "수신 업무 전화" - "Wi-Fi 수신 전화" - "수신 Wi-Fi 업무 전화" + "수신 Wi-Fi 통화" + "수신 Wi-Fi 업무 통화" "의심스러운 스팸 발신자로부터 온 전화" "수신 동영상 요청" "서비스 불가" @@ -73,7 +73,7 @@ "화상 통화 받기" "전화를 걸려면 먼저 비행기 모드를 해제하세요." "네트워크에서 등록되지 않았습니다." - "사용 가능한 이동통신망이 없습니다." + "모바일 네트워크를 사용할 수 없습니다." "전화를 걸려면 올바른 번호를 입력하세요." "전화를 걸 수 없습니다." "MMI 시퀀스 시작 중..." @@ -134,8 +134,8 @@ "통화 종료" "다자간 통화" "통화 중" - "모바일 데이터를 사용하여 계속 통화 중…" - "Wi-Fi 네트워크로 전환할 수 없습니다." - "화상 통화가 모바일 네트워크에서 유지됩니다. 표준 데이터 요금이 부과될 수 있습니다." + "모바일 데이터를 사용하여 통화를 계속합니다…" + "Wi-Fi 네트워크로 전환할 수 없습니다." + "화상 통화가 모바일 네트워크에서 계속됩니다. 표준 데이터 요금이 부과될 수 있습니다." "다시 표시하지 않음" diff --git a/java/com/android/incallui/res/values-ky/strings.xml b/java/com/android/incallui/res/values-ky/strings.xml index 0f8ee3cd8..1f6060412 100644 --- a/java/com/android/incallui/res/values-ky/strings.xml +++ b/java/com/android/incallui/res/values-ky/strings.xml @@ -33,8 +33,8 @@ "%s дегенден кабыл алынбаган чалуу" "Учурдагы чалуу" "Учурда болуп жаткан чалуу (жумуш боюнча)" - "Аткаруудагы Wi-Fi чалуу" - "Учурда болуп жаткан Wi-Fi чалуу (жумуш боюнча)" + "Учурдагы Wi-Fi чалуу" + "Учурдагы Wi-Fi чалуу (жумуш боюнча)" "Күтүлүүдө" "Кирүүчү чалуу" "Сүрөтү бар кирүүчү чалуу" @@ -55,8 +55,8 @@ "Сүрөт, билдирүү жана жайгашкан жер бар маанилүү чалуу" "Тиркемелери бар маанилүү кирүүчү чалуу" "Жумуш боюнча келип жаткан чалуу" - "Кирүүчү Wi-Fi чалуу" - "Жумуш боюнча келип жаткан Wi-Fi чалуу" + "Келип жаткан Wi-Fi чалуу" + "Жумуш боюнча келип жаткан Wi-Fi чалуу" "Келип жаткан чалуу спам окшойт" "Келип жаткан видео сурамы" "Байланыш жок" @@ -73,7 +73,7 @@ "Видео чалууну кабыл алуу" "Чалуу үчүн, адегенде учак режимин өчүрүңүз." "Тармакта катталган эмес." - "Мобилдик тармак жеткиликтүү эмес." + "Мобилдик тармак жок." "Чалуу үчүн, жарактуу номер киргизиңиз." "Чалынбай жатат." "MMI кезеги башталууда…" @@ -134,8 +134,8 @@ "Чалууну бүтүрүү" "Конференц-чалуу" "Чалууда" - "Уюлдук дайындарды пайдалануу менен чалууну улантууда..." - "Wi-Fi тармагына туташа албай койдук" - "Видео чалуу уюлдук тармак аркылуу аткарылат. Стандарттык тариф боюнча акы алынышы мүмкүн." + "Мобилдик дайындарды пайдалануу менен чалууну улантууда…" + "Wi-Fi тармагына туташа албай койдук" + "Видео чалуу мобилдик тармак аркылуу аткарылат. Стандарттык тариф боюнча акы алынышы мүмкүн." "Экинчи көрсөтүлбөсүн" diff --git a/java/com/android/incallui/res/values-lo/strings.xml b/java/com/android/incallui/res/values-lo/strings.xml index 56335d416..45a2a4089 100644 --- a/java/com/android/incallui/res/values-lo/strings.xml +++ b/java/com/android/incallui/res/values-lo/strings.xml @@ -33,8 +33,8 @@ "ສາຍບໍ່ໄດ້ຮັບຈາກ %s" "ສາຍທີ່ກຳລັງໂທອອກ" "ສາຍໂທອອກຈາກບ່ອນເຮັດວຽກ" - "ການ​ໂທ Wi​-Fi ທີ່ດໍາເນີນຢູ່" - "ສາຍໂທອອກ Wi-Fi ຈາກບ່ອນເຮັດວຽກ" + "ການໂທ Wi-Fi ທີ່ດໍາເນີນຢູ່" + "ການໂທ Wi-Fi ບ່ອນເຮັດວຽກທີ່ດໍາເນີນຢູ່" "ພັກສາຍຊົ່ວຄາວ" "ສາຍໂທເຂົ້າ" "ສາຍໂທເຂົ້າພ້ອມຮູບພາບ" @@ -55,8 +55,8 @@ "ສາຍໂທເຂົ້າສຳຄັນພ້ອມຮູບພາບ, ຂໍ້ຄວາມ ແລະ ສະຖານທີ່" "ສາຍໂທເຂົ້າສຳຄັນພ້ອມໄຟລ໌ແນບ" "ສາຍໂທເຂົ້າຈາກບ່ອນເຮັດວຽກ" - "ສາຍໂທເຂົ້າ Wi-Fi" - "ສາຍໂທເຂົ້າ Wi-Fi ຈາກບ່ອນເຮັດວຽກ" + "ສາຍໂທເຂົ້າ Wi-Fi" + "ສາຍໂທເຂົ້າ Wi-Fi ບ່ອນເຮັດວຽກ" "ມີການໂທທີ່ຄາດວ່າເປັນສະແປມໂທເຂົ້າມາ" "​ຄຳ​ຮ້ອງ​ຂໍ​ວິ​ດີ​ໂອ​ເຂົ້າ​ມາ" "ບໍ່ມີບໍລິການ" @@ -73,7 +73,7 @@ "ຮັບສາຍວິດີໂອ" "ເພື່ອໂທລະສັບ, ໃຫ້ປິດໂໝດຢູ່ເທິງຍົນກ່ອນ." "ບໍ່ໄດ້ລົງທະບຽນໃນເຄືອຂ່າຍ." - "ບໍ່​ມີ​ເຄືອ​ຂ່າຍ​ມື​ຖື​ທີ່​ສາ​ມາດ​ໃຊ້​ໄດ້." + "ເຄືອຂ່າຍມືຖືບໍ່ສາມາດໃຊ້ໄດ້." "ເພື່ອ​ທີ່​ຈະ​ໂທ, ປ້ອນ​ເບີ​ໂທ​ທີ່​ໃຊ້​ໄດ້​ເຂົ້າ​ໄປ." "ບໍ່​ສາ​ມາດ​ໂທ​ໄດ້." "ກຳລັງເລີ່ມຕົ້ນລຳດັບ MMI..." @@ -134,8 +134,8 @@ "ວາງສາຍ" "ການປະຊຸມທາງໂທລະສັບ" "ຢູ່ໃນສາຍ" - "ສືບຕໍ່ການໂທໂດຍໃຊ້ອິນເຕີເນັດມືຖື…" - "ບໍ່ສາມາດສະຫຼັບໄປໃຊ້ເຄືອຂ່າຍ Wi-Fi ໄດ້" - "ການໂທດ້ວຍວິດີໂອຈະຍັງໃຊ້ຜ່ານເຄືອຂ່າຍມືຖືຢູ່ ໂດຍອາດມີການຮຽກເກັບຄ່າບໍລິການຕາມປົກກະຕິ." + "ກຳລັງສືບຕໍ່ສາຍໂດຍໃຊ້ອິນເຕີເນັດມືຖື…" + "ບໍ່ສາມາດສະຫຼັບໄປໃຊ້ເຄືອຂ່າຍ Wi-Fi ໄດ້" + "ການໂທວິດີໂອຈະຍັງຄົງຢູ່ໃນເຄືອຂ່າຍມືຖືຕໍ່ໄປ. ອາດມີການຮຽກເກັບຄ່າບໍລິການມາດຕະຖານ." "ບໍ່ຕ້ອງສະແດງຂໍ້ຄວາມນີ້ອີກ" diff --git a/java/com/android/incallui/res/values-lt/strings.xml b/java/com/android/incallui/res/values-lt/strings.xml index 4d4a0c098..e63ca7018 100644 --- a/java/com/android/incallui/res/values-lt/strings.xml +++ b/java/com/android/incallui/res/values-lt/strings.xml @@ -33,8 +33,8 @@ "Praleistas skambutis nuo %s" "Vykstantis pokalbis" "Vykstantis darbo skambutis" - "Vykstantis „Wi-Fi“ skambutis" - "Vykstantis „Wi-Fi“ darbo skambutis" + "Vykstantis „Wi-Fi“ skambutis" + "Vykstantis „Wi-Fi“ darbo skambutis" "Sulaikyta" "Gaunamasis skambutis" "Gaunamasis skambutis su nuotrauka" @@ -55,15 +55,15 @@ "Svarbus gaunam. skamb. su nuotr., praneš. ir viet." "Svarbus gaunamasis skambutis su priedais" "Gaunamasis darbo skambutis" - "Gaunamasis „Wi-Fi“ skambutis" - "Gaunamasis „Wi-Fi“ darbo skambutis" + "Gaunamasis „Wi-Fi“ skambutis" + "Gaunamasis „Wi-Fi“ darbo skambutis" "Gaunamasis įtartinas šlamšto skambutis" "Gaunama vaizdo skambučio užklausa" "Nėra paslaugos" "Pasirinktas tinklas (%s) negalimas" "Atsakyti" "Padėti ragelį" - "Vaizdo skambutis" + "Vaizdo skam." "Balsas" "Atsiliepti" "Atmesti" @@ -73,7 +73,7 @@ "Atlikti vaizdo skambutį" "Jei norite skambinti, išjunkite lėktuvo režimą." "Neregistruota tinkle." - "Korinis tinklas nepasiekiamas" + "Mobiliojo ryšio tinklas nepasiekiamas." "Kad galėtumėte paskambinti, įveskite tinkamą numerį." "Nepavyko paskambinti." "Paleidžiama MMI seka..." @@ -134,8 +134,8 @@ "Baigti skambutį" "Konferencinis skambutis" "Skambinant" - "Skambutis tęsiamas naudojant mobiliojo ryšio duomenis…" - "Nepavyko prisijungti prie „Wi-Fi“ tinklo" - "Vaizdo skambutis ir toliau bus vykdomas naudojant mobiliojo ryšio tinklą. Gali būti taikomi įprasti duomenų mokesčiai." + "Skambutis tęsiamas naudojant mobiliojo ryšio duomenis…" + "Nepavyko prisijungti prie „Wi-Fi“ tinklo" + "Vaizdo skambutis ir toliau bus vykdomas naudojant mobiliojo ryšio tinklą. Gali būti taikomi įprasti duomenų mokesčiai." "Daugiau to nerodyti" diff --git a/java/com/android/incallui/res/values-lv/strings.xml b/java/com/android/incallui/res/values-lv/strings.xml index 9be46c4fd..441733a9b 100644 --- a/java/com/android/incallui/res/values-lv/strings.xml +++ b/java/com/android/incallui/res/values-lv/strings.xml @@ -33,8 +33,8 @@ "Neatbildēts zvans no: %s" "Pašreizējā saruna" "Notiekošs darba zvans" - "Notiekošs Wi-Fi zvans" - "Notiekošs darba Wi-Fi zvans" + "Notiekošs Wi-Fi zvans" + "Notiekošs darba Wi-Fi zvans" "Aizturēts" "Ienākošais zvans" "Ienākošais zvans ar fotoattēlu" @@ -55,8 +55,8 @@ "Zvans ar fotoattēlu, ziņojumu un atrašanās vietu" "Svarīgs ienākošais zvans ar pielikumiem" "Ienākošs darba zvans" - "Ienākošs Wi-Fi zvans" - "Ienākošs darba Wi-Fi zvans" + "Ienākošs Wi-Fi zvans" + "Ienākošs darba Wi-Fi zvans" "Ienākošs, iespējams, nevēlams zvans" "Ienākošs video pieprasījums" "Nav pakalpojuma" @@ -73,7 +73,7 @@ "Pārsūtīt videozvanu" "Lai veiktu zvanu, vispirms izslēdziet lidojuma režīmu." "Tīklā nav reģistrēts." - "Mobilais tīkls nav pieejams." + "Mobilais tīkls nav pieejams." "Lai veiktu zvanu, ievadiet derīgu numuru." "Nevar veikt zvanu." "Notiek MMI secības startēšana…" @@ -134,8 +134,8 @@ "Beigt zvanu" "Konferences zvans" "Notiek zvans" - "Zvans tiek turpināts, izmantojot mobilos datus…" - "Nevarēja pārslēgt uz Wi-Fi tīklu" - "Videozvans tiks turpināts mobilo sakaru tīklā. Var tikt piemērota standarta maksa par datu pārraidi." + "Zvans tiek turpināts, izmantojot mobilos datus…" + "Nevarēja pārslēgt uz Wi-Fi tīklu" + "Videozvans tiks turpināts mobilo sakaru tīklā. Var tikt piemērota standarta maksa par datu pārraidi." "Vairs nerādīt šo ziņojumu" diff --git a/java/com/android/incallui/res/values-mcc262-mnc01/strings.xml b/java/com/android/incallui/res/values-mcc262-mnc01/strings.xml deleted file mode 100644 index 2679653a7..000000000 --- a/java/com/android/incallui/res/values-mcc262-mnc01/strings.xml +++ /dev/null @@ -1,32 +0,0 @@ - - - - - - - Ongoing WLAN Call - - Ongoing WLAN work call - - Incoming WLAN Call - - Incoming WLAN work call - \ No newline at end of file diff --git a/java/com/android/incallui/res/values-mk/strings.xml b/java/com/android/incallui/res/values-mk/strings.xml index 03be1d951..b712fe032 100644 --- a/java/com/android/incallui/res/values-mk/strings.xml +++ b/java/com/android/incallui/res/values-mk/strings.xml @@ -33,8 +33,8 @@ "Пропуштен повик од %s" "Тековен повик" "Тековен работен повик" - "Појдовен повик преку Wi-Fi" - "Тековен работен повик преку Wi-Fi" + "Тековен повик преку Wi-Fi" + "Тековен работен повик преку Wi-Fi" "На чекање" "Дојдовен повик" "Дојдовен повик со фотографија" @@ -55,8 +55,8 @@ "Важен дојдовен повик со фото., порака и локација" "Важен дојдовен повик со прилози" "Дојдовен работен повик" - "Дојдовен повик преку Wi-Fi" - "Дојдовен работен повик преку Wi-Fi" + "Дојдовен повик преку Wi-Fi" + "Дојдовен работен повик преку Wi-Fi" "Дојдовниот повик може да е спам" "Дојдовно побарување за видео" "Нема услуга" @@ -73,7 +73,7 @@ "Прифатете видеоповик" "За да воспоставите повик, прво исклучете режим на работа во авион." "Не е регистриран на мрежа." - "Не е достапна мобилна мрежа." + "Нема достапна мобилна мрежа." "За да повикате, внесете важечки број." "Не може да повика." "Започнува MMI низа..." @@ -134,8 +134,8 @@ "Завршете го повикот" "Конференциски повик" "Повик во тек" - "Повикот ќе продолжи преку мобилен интернет…" - "Не можеше да се префрли на Wi-Fi-мрежа" - "Видеоповикот ќе остане на мобилната мрежа. Може да се наплати за интернет-сообраќај." + "Повикот ќе продолжи преку мобилен интернет…" + "Не можеше да се префрли на Wi-Fi-мрежа" + "Видеоповикот ќе остане на мобилната мрежа. Може да се наплати за мобилен интернет." "Не го прикажувај ова повторно" diff --git a/java/com/android/incallui/res/values-ml/strings.xml b/java/com/android/incallui/res/values-ml/strings.xml index e207ccd45..db9f56018 100644 --- a/java/com/android/incallui/res/values-ml/strings.xml +++ b/java/com/android/incallui/res/values-ml/strings.xml @@ -33,8 +33,8 @@ "%s എന്നതിൽ നിന്നുള്ള മിസ്‌ഡ് കോൾ" "കോൾ സജീവമാണ്" "ഓൺഗോയിംഗ് ഔദ്യോഗിക കോൾ" - "ഓൺഗോയിംഗ് വൈഫൈ കോൾ" - "ഓൺഗോയിംഗ് വൈഫൈ ഔദ്യോഗിക കോൾ" + "നിലവിലുള്ള വൈഫൈ കോൾ" + "നിലവിലുള്ള വൈഫൈ ഔദ്യോഗിക കോൾ" "ഹോള്‍ഡിലാണ്" "ഇന്‍കമിംഗ് കോള്‍" "ഫോട്ടോ ഉൾപ്പെട്ട ഇൻകമിംഗ് കോൾ" @@ -55,8 +55,8 @@ "ഫോട്ടോയും സന്ദേശവും ലൊക്കേഷനും ഉൾപ്പെട്ട പ്രധാനപ്പെട്ട ഇൻകമിംഗ് കോൾ" "അറ്റാച്ച്‌മെന്റുകൾ ഉൾപ്പെട്ട പ്രധാനപ്പെട്ട ഇൻകമിംഗ് കോൾ" "ഇൻകമിംഗ് ഔദ്യോഗിക കോൾ" - "ഇൻകമിംഗ് വൈഫൈ കോൾ" - "ഇൻകമിംഗ് വൈഫൈ ഔദ്യോഗിക കോൾ" + "ഇൻകമിംഗ് വൈഫൈ കോൾ" + "ഇൻകമിംഗ് വൈഫൈ ഔദ്യോഗിക കോൾ" "സംശയാസ്‌പദമായ ഇൻകമിംഗ് സ്‌പാം കോൾ" "ഇൻകമിംഗ് വീഡിയോ അഭ്യർത്ഥന" "സേവനമില്ല" @@ -73,7 +73,7 @@ "വീഡിയോ കോൾ അറ്റൻഡ് ചെയ്യുക" "ഒരു കോൾ വിളിക്കാൻ, ആദ്യം ഫ്ലൈറ്റ് മോഡ് ഓഫുചെയ്യുക." "നെറ്റ്‌വർക്കിൽ രജിസ്റ്റർ ചെയ്‌തിട്ടില്ല." - "സെല്ലുലാർ നെറ്റ്‌വർക്ക് ലഭ്യമല്ല." + "മൊബൈൽ നെറ്റ്‌വർക്ക് ലഭ്യമല്ല." "ഒരു കോൾ ചെയ്യുന്നതിന്, സാധുതയുള്ള നമ്പർ നൽകുക." "കോൾ ചെയ്യാനായില്ല." "MMI സീക്വൻസ് ആരംഭിക്കുന്നു…" @@ -134,8 +134,8 @@ "കോള്‍ അവസാനിപ്പിക്കൂ" "കോൺഫറൻസ് കോൾ" "കോളിലാണ്" - "സെല്ലുലാർ ഡാറ്റ ഉപയോഗിച്ച് കോൾ തുടരുന്നു…" - "Wi-Fi നെറ്റ്‌വർക്കിലേക്ക് മാറാനായില്ല" - "സെല്ലുലാർ നെറ്റ്‌വർക്കിൽത്തന്നെ വീഡിയോ കോൾ തുടരും. സാധാരണ ഡാറ്റ നിരക്കുകൾ ബാധകമാകാം." + "മൊബൈൽ ഡാറ്റ ഉപയോഗിച്ച് കോൾ തുടരുന്നു…" + "വൈഫൈ നെറ്റ്‌വർക്കിലേക്ക് മാറാനായില്ല" + "മൊബൈൽ നെറ്റ്‌വർക്കിൽത്തന്നെ വീഡിയോ കോൾ തുടരും. സാധാരണ ഡാറ്റ നിരക്കുകൾ ബാധകമാകാം." "ഇത് വീണ്ടും കാണിക്കരുത്" diff --git a/java/com/android/incallui/res/values-mn/strings.xml b/java/com/android/incallui/res/values-mn/strings.xml index 0e269170b..7757af9ac 100644 --- a/java/com/android/incallui/res/values-mn/strings.xml +++ b/java/com/android/incallui/res/values-mn/strings.xml @@ -33,8 +33,8 @@ "%s-н аваагүй дуудлага" "Хийгдэж буй дуудлага" "Залгаж буй албаны дуудлага" - "Ярьж буй Wi-Fi дуудлага" - "Залгаж буй Wi-Fi албаны дуудлага" + "Холбогдсон Wi-Fi дуудлага" + "Холбогдсон Wi-Fi албаны дуудлага" "Хүлээлгэнд" "Ирж буй дуудлага" "Зураг бүхий орж ирсэн дуудлага" @@ -55,8 +55,8 @@ "Зураг, зурвас, байршилтай орж ирсэн чухал дуудлага" "Хавсралт бүхий орж ирсэн чухал дуудлага" "Ирж буй албаны дуудлага" - "Орж ирсэн Wi-Fi дуудлага" - "Ирж буй Wi-Fi албаны дуудлага" + "Ирж буй Wi-Fi дуудлага" + "Ирж буй Wi-Fi албаны дуудлага" "Орж ирсэн сэжигтэй спам дуудлага" "Ирж буй видео хүсэлт" "Үйлчилгээ байхгүй" @@ -73,7 +73,7 @@ "Видео дуудлага авах" "Дуудлага хийхийн тулд юуны өмнө Нислэгийн төлвийг идэвхгүйжүүлнэ үү." "Сүлжээнд бүртгэгдээгүй." - "Үүрэн сүлжээ байхгүй." + "Мобайл сүлжээ байхгүй." "Дуудлага хийхийн тулд хүчин төгөлдөр дугаар оруулна уу." "Дуудлага хийх боломжгүй байна." "MMI дарааллыг эхлүүлж байна…" @@ -134,8 +134,8 @@ "Дуудлагыг таслах" "Хурлын дуудлага" "Ярьж байна" - "Үүрэн дата ашиглан дуудлагыг үргэлжлүүлж байна..." - "Wi-Fi сүлжээ рүү сэлгэж чадсангүй" - "Видео дуудлага үүрэн сүлжээнд үлдэнэ. Стандарт датаны төлбөр тооцогдож магадгүй." + "Мобайл дата ашиглан дуудлагыг үргэлжлүүлж байна…" + "Wi-Fi сүлжээ рүү сэлгэж чадсангүй" + "Видео дуудлага мобайл сүлжээнд үлдэнэ. Стандарт датаны төлбөр тооцогдож магадгүй." "Үүнийг дахин бүү үзүүл" diff --git a/java/com/android/incallui/res/values-mr/strings.xml b/java/com/android/incallui/res/values-mr/strings.xml index c56c61012..e422897b0 100644 --- a/java/com/android/incallui/res/values-mr/strings.xml +++ b/java/com/android/incallui/res/values-mr/strings.xml @@ -33,8 +33,8 @@ "%s कडील सुटलेला कॉल" "सुरू असलेला कॉल" "सुरु असलेला कार्य कॉल" - "सुरु असलेला वाय-फाय कॉल" - "सुरु असलेला वाय-फाय कार्य कॉल" + "सुरु असलेला वाय-फाय कॉल" + "सुरु असलेला वाय-फाय कार्य कॉल" "होल्ड वर" "येणारा कॉल" "फोटोसह येणारा कॉल" @@ -55,8 +55,8 @@ "फोटो, संदेश आणि स्थानासह महत्त्वाचा येणारा कॉल" "संलग्नकांसह महत्त्वाचा येणारा कॉल" "येणारा कार्य कॉल" - "येणारा वाय-फाय कॉल" - "येणारा वाय-फाय कार्य कॉल" + "येणारा वाय-फाय कॉल" + "येणारा वाय-फाय कार्य कॉल" "येणारा संशयित स्पॅम कॉल" "येणारी व्हिडिओ विनंती" "सेवा नाही" @@ -73,7 +73,7 @@ "व्हिडिओ कॉल घ्या" "कॉल करण्यासाठी, प्रथम विमान मोड बंद करा." "नेटवर्कवर नोंदणीकृत नाही." - "सेल्युलर नेटवर्क उपलब्ध नाही." + "मोबाइल नेटवर्क उपलब्ध नाही." "कॉल करण्यासाठी, एक वैध नंबर प्रविष्ट करा." "कॉल करू शकत नाही." "MMI क्रम प्रारंभ करीत आहे..." @@ -134,8 +134,8 @@ "कॉल समाप्त करा" "परिषद कॉल" "कॉल मध्ये" - "मोबाइल डेटा वापरून कॉल सुरू ठेवत आहेत…" - "वाय-फाय नेटवर्कवर स्विच करणे शक्य झाले नाही" - "व्हिडिओ कॉल मोबाईल नेटवर्कवर असेल. मानक डेटा शुल्क लागू होऊ शकतात." + "मोबाइल डेटा वापरून कॉल करणे सुरु ठेवत आहे..." + "वाय-फाय नेटवर्कवर स्विच करणे शक्य झाले नाही" + "व्हिडिओ कॉल मोबाइल नेटवर्कवर असेल. मानक डेटा शुल्क लागू शकतात." "हे पुन्हा दर्शवू नका" diff --git a/java/com/android/incallui/res/values-ms/strings.xml b/java/com/android/incallui/res/values-ms/strings.xml index a5be5934d..7a5900adb 100644 --- a/java/com/android/incallui/res/values-ms/strings.xml +++ b/java/com/android/incallui/res/values-ms/strings.xml @@ -33,8 +33,8 @@ "Panggilan tidak dijawab daripada %s" "Panggilan sedang berjalan" "Panggilan sedang berlangsung daripada tempat kerja" - "Panggilan Wi-Fi sedang berlangsung" - "Panggian Wi-Fi sedang berlangsung daripada tempat kerja" + "Panggilan Wi-Fi sedang berlangsung" + "Panggilan Wi-Fi daripada tempat kerja sedang berlangsung" "Ditunda" "Panggilan masuk" "Panggilan masuk dengan foto" @@ -55,15 +55,15 @@ "Panggilan masuk penting dengan foto, mesej dan lokasi" "Panggilan masuk penting dengan lampiran" "Panggilan masuk daripada tempat kerja" - "Panggilan Wi-Fi masuk" - "Panggilan masuk melalui Wi-Fi daripada tempat kerja" + "Panggilan masuk Wi-Fi" + "Panggilan masuk Wi-Fi daripada tempat kerja" "Disyaki panggilan spam masuk" "Permintaan video masuk" "Tiada perkhidmatan" "Rangkaian pilihan (%s) tidak tersedia" "Jawapan" "Letakkan gagang" - "Video dalam strim" + "Video" "Suara" "Terima" "Tolak" @@ -73,7 +73,7 @@ "Jawab Panggilan Video" "Untuk membuat panggilan, matikan mod Pesawat terlebih dahulu." "Tidak didaftarkan pada rangkaian." - "Rangkaian selular tidak tersedia." + "Rangkaian mudah alih tidak tersedia." "Untuk membuat panggilan, masukkan nombor yang sah." "Tidak dapat memanggil." "Memulakan jujukan MMI..." @@ -134,8 +134,8 @@ "Tamatkan panggilan" "Panggilan sidang" "Dalam panggilan" - "Meneruskan panggilan menggunakan data selular…" - "Tidak dapat beralih ke rangkaian Wi-Fi" - "Panggilan video akan menggunakan rangkaian selular. Caj data standard boleh dikenakan." + "Meneruskan panggilan menggunakan data mudah alih…" + "Tidak dapat beralih ke rangkaian Wi-Fi" + "Panggilan video akan menggunakan rangkaian mudah alih. Caj data standard boleh dikenakan." "Jangan tunjukkan ini lagi" diff --git a/java/com/android/incallui/res/values-my/strings.xml b/java/com/android/incallui/res/values-my/strings.xml index 5cca49874..5513b7975 100644 --- a/java/com/android/incallui/res/values-my/strings.xml +++ b/java/com/android/incallui/res/values-my/strings.xml @@ -33,8 +33,8 @@ "%s မှလွတ်သွားသော ခေါ်ဆိုမှု" "ဆက်သွားနေသော ဖုန်းခေါ်မှု" "ခေါ်နေဆဲ အလုပ်မှ ခေါ်ဆိုမှု" - "ခေါ်နေဆဲ ဝိုင်ဖိုင်ခေါ်ဆိုမှု" - "ခေါ်နေဆဲ Wi-Fi အလုပ်မှ ခေါ်ဆိုမှု" + "လက်ရှိ Wi-Fi ဖုန်းခေါ်ဆိုမှု" + "လက်ရှိ Wi-Fi အလုပ်ဖုန်းခေါ်ဆိုမှု" "ခဏ ကိုင်ထားစဉ်" "အဝင်ခေါ်ဆိုမှု" "ဓာတ်ပုံဖြင့် အဝင်ခေါ်ဆိုမှု" @@ -55,8 +55,8 @@ "ဓာတ်ပုံ၊မက်ဆေ့ဂျ်၊တည်နေရာဖြင့် အရေးကြီးခေါ်ဆိုမှု" "ပူးတွဲပါဖိုင်များဖြင့် အရေးကြီးသော အဝင်ခေါ်ဆိုမှု" "အဝင် ခေါ်ဆိုမှု" - "ဝင်လာသော ဝိုင်ဖိုင်ခေါ်ဆိုမှု" - "Wi-Fi အလုပ်မှ အဝင် ခေါ်ဆိုမှု" + "အဝင် Wi‑Fi ဖုန်းခေါ်ဆိုမှု" + "အဝင် Wi‑Fi အလုပ်ဖုန်းခေါ်ဆိုမှု" "ခေါ်နေသော မသင်္ကာဖွယ်ရာ စပမ်းခေါ်ဆိုမှု" "အသံ ခေါ်ဆိုမှုအဖြစ် တောင်းဆိုမှု" "ဝန်ဆောင်မှု မရှိပါ" @@ -73,7 +73,7 @@ "ဗီဒီယိုခေါ်ဆိုမှုလွှဲယူပါ" "ဖုန်းခေါ်ဆိုမှုပြုရန်, လေယာဥ်ပျံပေါ်အသုံးပြုသောစနစ်ကို ပိတ်ပါ" "ကွန်ယက်ပေါ်မှာ မှတ်ပုံတင်မှု မပြုလုပ်ထားပါ" - "ဆဲလ်လူလာ ကွန်ရက် မရှိပါ။" + "မိုဘိုင်းကွန်ရက် မရနိုင်ပါ" "ဖုန်းခေါ်ရန်အတွက်၊ သင့်လျော်သည့်နံပါတ် ရိုက်ထည့်ပါ။" "မခေါ်ဆိုနိုင်ပါ။" "MMI အမှတ်စဉ်ကို စတင်နေပါသည်…" @@ -134,8 +134,8 @@ "ခေါ်ဆိုမှုအပြီးသတ်ရန်" "အစည်းအဝေးခေါ်ဆိုမှု" "ဖုန်းပြောနေသည်" - "ဆယ်လူလာဒေတာသုံးပြီး ဆက်လက်ခေါ်ဆိုနေသည်…" - "Wi-Fi ကွန်ရက်သို့ မပြောင်းနိုင်ပါ" - "ဗီဒီယိုခေါ်ဆိုမှုသည် ဆယ်လူလာကွန်ရက်တွင် ဆက်ရှိနေပါမည်။ ပုံမှန်ဒေတာသုံးစွဲခများ ကျသင့်နိုင်ပါသည်။" + "မိုဘိုင်းဒေတာသုံးပြီး ဆက်လက်ခေါ်ဆိုနေသည်…" + "Wi‑Fi ကွန်ရက်သို့ မပြောင်းနိုင်ပါ" + "ဗီဒီယိုခေါ်ဆိုမှုသည် မိုဘိုင်းကွန်ရက်တွင် ဆက်ရှိနေပါမည်။ ပုံမှန်ဒေတာသုံးစွဲခများ ကျသင့်နိုင်ပါသည်။" "ဤသည်ကို ထပ်မပြပါနှင့်" diff --git a/java/com/android/incallui/res/values-nb/strings.xml b/java/com/android/incallui/res/values-nb/strings.xml index d0883a2cc..4e8d79668 100644 --- a/java/com/android/incallui/res/values-nb/strings.xml +++ b/java/com/android/incallui/res/values-nb/strings.xml @@ -33,8 +33,8 @@ "Tapt anrop fra %s" "Pågående samtale" "Pågående jobbanrop" - "Pågående Wi-Fi-anrop" - "Pågående jobbanrop via Wi-Fi" + "Pågående Wi-Fi-samtale" + "Pågående jobbsamtale via Wi-Fi" "Parkert" "Innkommende samtale" "Innkommende anrop med bilde" @@ -55,8 +55,8 @@ "Viktig anrop med bilde, melding og posisjon" "Viktig innkommende anrop med vedlegg" "Innkommende jobbanrop" - "Innkommende anrop via Wi-Fi" - "Innkommende jobbanrop via Wi-Fi" + "Innkommende anrop via Wi-Fi" + "Innkommende jobbanrop via Wi-Fi" "Innkommende anrop fra en mulig useriøs oppringer" "Innkommende videoforespørsel" "Ingen tjeneste" @@ -73,7 +73,7 @@ "Svar på videoanropet" "For å ringe, slå av flymodus først." "Ikke registrert på nettverket." - "Mobilnettverket er ikke tilgjengelig." + "Mobilnettverket er ikke tilgjengelig." "Skriv inn et gyldig nummer for å plassere en samtale." "Kan ikke ringe." "Begynner MMI-sekvens…" @@ -134,8 +134,8 @@ "Avslutt samtalen" "Telefonmøte" "Samtale pågår" - "Fortsetter samtalen via mobildata …" - "Kan ikke bytte til Wi-Fi-nettverk" - "Videosamtalen blir værende på mobilnettet. Standard datakostnader kan påløpe." + "Fortsetter samtalen via mobildata …" + "Kunne ikke bytte til Wi-Fi-nettverk" + "Videosamtalen blir værende på mobilnettverket. Standard datakostnader kan påløpe." "Ikke vis dette igjen" diff --git a/java/com/android/incallui/res/values-ne/strings.xml b/java/com/android/incallui/res/values-ne/strings.xml index b5894797c..b19c2ae80 100644 --- a/java/com/android/incallui/res/values-ne/strings.xml +++ b/java/com/android/incallui/res/values-ne/strings.xml @@ -33,8 +33,8 @@ "%s बाट आएको छुटेको कल" "चलिरहेको कल" "चालू रहेको कार्यको कल" - "चालु रहेको WI-Fi कल" - "चालू रहेको Wi-Fi कार्यको कल" + "जारी रहेको WI-Fi कल" + "Wi-Fi मार्फत जारी रहेको कार्यालयको कल" "होल्डमा" "आगमन कल" "तस्बिरसहितको आगमन कल" @@ -55,8 +55,8 @@ "तस्बिर, सन्देश र स्थानसहितको महत्त्वपूर्ण आगमन कल" "समावेश गरिएको वस्तुसहितको महत्त्वपूर्ण आगमन कल" "आगमन कार्यको कल" - "आगमन Wi-Fi कल" - "आगमन Wi-Fi कार्यको कल" + "Wi-Fi मार्फत आगमन कल" + "Wi-Fi मार्फत कार्यालयबाट आएको कल" "शंकास्पद आगमन स्प्याम कल" "आगमन भिडियो अनुरोध" "सेवा छैन" @@ -73,7 +73,7 @@ "भिडियो कल लिनुहोस्" "कल राख्नका लागि, पहिले हवाइजहाज मोड बन्द गर्नुहोस्।" "नेटवर्कमा दर्ता भएको छैन।" - "सेलुलर सञ्जाल उपलब्ध छैन।" + "मोबाइल नेटवर्क उपलब्ध छैन।" "एक कल गर्नको लागि, एक वैध नम्बर प्रविष्ट गर्नुहोस्।" "कल गर्न सक्दैन।" "MMI अनुक्रम सुरु गर्दै..." @@ -134,8 +134,8 @@ "कल अन्त्य गर्नुहोस्" "सम्मेलन कल" "कलमा" - "सेलुलर डेटा प्रयोग गरी कललाई निरन्तरता दिइँदै…" - "Wi-Fi नेटवर्कमा स्विच गर्न सकिएन" - "भिडियो कल सेलुलर नेटवर्कमा रहने छ। मानक डेटा शुल्क लाग्न सक्छ।" + "मोबाइल डेटा प्रयोग गरी कललाई निरन्तरता दिइँदै…" + "Wi-Fi नेटवर्कमा स्विच गर्न सकिएन" + "भिडियो कल मोबाइल नेटवर्कमा रहने छ। मानक डेटा शुल्क लाग्न सक्छ।" "यसलाई फेरि नदेखाउनुहोस्" diff --git a/java/com/android/incallui/res/values-nl/strings.xml b/java/com/android/incallui/res/values-nl/strings.xml index 930acdc86..73508818e 100644 --- a/java/com/android/incallui/res/values-nl/strings.xml +++ b/java/com/android/incallui/res/values-nl/strings.xml @@ -33,8 +33,8 @@ "Gemiste oproep van %s" "Actieve oproep" "Actieve zakelijke oproep" - "Actieve wifi-oproep" - "Actieve zakelijke oproep via wifi" + "Actieve wifi-oproep" + "Actieve zakelijke oproep via wifi" "In de wacht" "Inkomende oproep" "Inkomende oproep met foto" @@ -55,15 +55,15 @@ "Belangrijke oproep met foto, bericht en locatie" "Belangrijke inkomende oproep met bijlagen" "Inkomende zakelijke oproep" - "Inkomende wifi-oproep" - "Inkomende zakelijke oproep via wifi" + "Inkomende wifi-oproep" + "Inkomende zakelijke oproep via wifi" "Inkomende vermoedelijke spamoproep" "Binnenkomend videoverzoek" "Geen service" "Geselecteerd netwerk (%s) niet beschikbaar" "Antwoord" "Ophangen" - "InStream-video" + "Video" "Spraak" "Accepteren" "Weigeren" @@ -73,7 +73,7 @@ "Videogesprek beantwoorden" "Als je wilt bellen, moet je eerst de Vliegtuigmodus uitschakelen." "Niet geregistreerd op netwerk." - "Mobiel netwerk niet beschikbaar." + "Mobiel netwerk niet beschikbaar." "Als je wilt bellen, moet je een geldig nummer invoeren." "Kan niet bellen." "MMI-reeks starten..." @@ -134,8 +134,8 @@ "Oproep beëindigen" "Telefonische vergadering" "In gesprek" - "Gesprek voortzetten via mobiele data…" - "Overschakelen naar wifi-netwerk mislukt" - "Videogesprek loopt via mobiel netwerk. Er kunnen standaard datakosten in rekening worden gebracht." + "Gesprek voortzetten via mobiele data…" + "Overschakelen naar wifi-netwerk mislukt" + "Videogesprek loopt via mobiel netwerk. Er kunnen standaard datakosten in rekening worden gebracht." "Dit niet meer weergeven" diff --git a/java/com/android/incallui/res/values-no/strings.xml b/java/com/android/incallui/res/values-no/strings.xml index d0883a2cc..4e8d79668 100644 --- a/java/com/android/incallui/res/values-no/strings.xml +++ b/java/com/android/incallui/res/values-no/strings.xml @@ -33,8 +33,8 @@ "Tapt anrop fra %s" "Pågående samtale" "Pågående jobbanrop" - "Pågående Wi-Fi-anrop" - "Pågående jobbanrop via Wi-Fi" + "Pågående Wi-Fi-samtale" + "Pågående jobbsamtale via Wi-Fi" "Parkert" "Innkommende samtale" "Innkommende anrop med bilde" @@ -55,8 +55,8 @@ "Viktig anrop med bilde, melding og posisjon" "Viktig innkommende anrop med vedlegg" "Innkommende jobbanrop" - "Innkommende anrop via Wi-Fi" - "Innkommende jobbanrop via Wi-Fi" + "Innkommende anrop via Wi-Fi" + "Innkommende jobbanrop via Wi-Fi" "Innkommende anrop fra en mulig useriøs oppringer" "Innkommende videoforespørsel" "Ingen tjeneste" @@ -73,7 +73,7 @@ "Svar på videoanropet" "For å ringe, slå av flymodus først." "Ikke registrert på nettverket." - "Mobilnettverket er ikke tilgjengelig." + "Mobilnettverket er ikke tilgjengelig." "Skriv inn et gyldig nummer for å plassere en samtale." "Kan ikke ringe." "Begynner MMI-sekvens…" @@ -134,8 +134,8 @@ "Avslutt samtalen" "Telefonmøte" "Samtale pågår" - "Fortsetter samtalen via mobildata …" - "Kan ikke bytte til Wi-Fi-nettverk" - "Videosamtalen blir værende på mobilnettet. Standard datakostnader kan påløpe." + "Fortsetter samtalen via mobildata …" + "Kunne ikke bytte til Wi-Fi-nettverk" + "Videosamtalen blir værende på mobilnettverket. Standard datakostnader kan påløpe." "Ikke vis dette igjen" diff --git a/java/com/android/incallui/res/values-pa/strings.xml b/java/com/android/incallui/res/values-pa/strings.xml index 22cd7da3b..b21cbd3a6 100644 --- a/java/com/android/incallui/res/values-pa/strings.xml +++ b/java/com/android/incallui/res/values-pa/strings.xml @@ -33,8 +33,8 @@ "%s ਤੋਂ ਖੁੰਝੀ ਹੋਈ ਕਾਲ" "ਜਾਰੀ ਕਾਲ" "ਕੰਮ ਸਬੰਧਿਤ ਜਾਰੀ ਕਾਲ" - "ਜਾਰੀ Wi-Fi ਕਾਲ" - "ਕੰਮ ਸਬੰਧਿਤ ਜਾਰੀ Wi-Fi ਕਾਲ" + "ਜਾਰੀ Wi‑Fi ਕਾਲ" + "ਕੰਮ ਸਬੰਧੀ ਜਾਰੀ Wi‑Fi ਕਾਲ" "ਹੋਲਡ ਤੇ" "ਇਨਕਮਿੰਗ ਕਾਲ" "ਫ਼ੋਟੋ ਨਾਲ ਇਨਕਮਿੰਗ ਕਾਲ" @@ -55,8 +55,8 @@ "ਫ਼ੋਟੋ, ਸੁਨੇਹੇ ਅਤੇ ਟਿਕਾਣੇ ਨਾਲ ਮਹੱਤਵਪੂਰਨ ਇਨਕਮਿੰਗ ਕਾਲ" "ਅਟੈਚਮੈਂਟਾਂ ਨਾਲ ਮਹੱਤਵਪੂਰਨ ਇਨਕਮਿੰਗ ਕਾਲ" "ਕੰਮ ਸਬੰਧਿਤ ਆ ਰਹੀ ਕਾਲ" - "ਇਨਕਮਿੰਗ Wi-Fi ਕਾਲ" - "ਕੰਮ ਸਬੰਧਿਤ ਆ ਰਹੀ Wi-Fi ਕਾਲ" + "ਆ ਰਹੀ Wi‑Fi ਕਾਲ" + "ਕੰਮ ਸਬੰਧੀ ਆ ਰਹੀ Wi‑Fi ਕਾਲ" "ਸ਼ੱਕੀ ਸਪੈਮ ਕਾਲ ਆ ਰਹੀ ਹੈ" "ਇਨਕਮਿੰਗ ਵੀਡੀਓ ਬੇਨਤੀ" "ਕੋਈ ਸੇਵਾ ਨਹੀਂ" @@ -73,7 +73,7 @@ "ਵੀਡੀਓ ਕਾਲ ਲਓ" "ਇੱਕ ਕਾਲ ਕਰਨ ਲਈ, ਪਹਿਲਾਂ ਏਅਰਪਲੇਨ ਮੋਡ ਬੰਦ ਕਰੋ।" "ਨੈਟਵਰਕ ਤੇ ਰਜਿਸਟਰ ਨਹੀਂ ਕੀਤਾ।" - "ਸੈਲਿਊਲਰ ਨੈਟਵਰਕ ਉਪਲਬਧ ਨਹੀਂ" + "ਮੋਬਾਈਲ ਨੈੱਟਵਰਕ ਉਪਲਬਧ ਨਹੀਂ ਹੈ।" "ਇੱਕ ਕਾਲ ਕਰਨ ਲਈ, ਇੱਕ ਪ੍ਰਮਾਣਿਕ ਨੰਬਰ ਦਰਜ ਕਰੋ।" "ਕਾਲ ਨਹੀਂ ਕਰ ਸਕਦਾ।" "MMI ਕੜੀ ਚਾਲੂ ਕਰ ਰਿਹਾ ਹੈ…" @@ -134,8 +134,8 @@ "ਕਾਲ ਸਮਾਪਤ ਕਰੋ" "ਕਾਨਫਰੰਸ ਕਾਲ" "ਕਾਲ ਵਿੱਚ" - "ਸੈਲਿਊਲਰ ਡੈਟੇ ਦੀ ਵਰਤੋਂ ਨਾਲ ਕਾਲ ਜਾਰੀ ਰੱਖੀ ਜਾ ਰਹੀ ਹੈ…" - "Wi-Fi ਨੈੱਟਵਰਕ \'ਤੇ ਬਦਲੀ ਨਹੀਂ ਕੀਤੀ ਜਾ ਸਕੀ" - "ਵੀਡੀਓ ਕਾਲ ਸੈਲਿਊਲਰ ਨੈੱਟਵਰਕ \'ਤੇ ਰਹੇਗੀ। ਸਧਾਰਨ ਡੈਟਾ ਖਰਚੇ ਲਾਗੂ ਹੋ ਸਕਦੇ ਹਨ।" + "ਮੋਬਾਈਲ ਡੈਟੇ ਦੀ ਵਰਤੋਂ ਕਰਕੇ ਕਾਲ ਜਾਰੀ ਰੱਖੀ ਜਾ ਰਹੀ ਹੈ…" + "Wi‑Fi ਨੈੱਟਵਰਕ \'ਤੇ ਬਦਲੀ ਨਹੀਂ ਕੀਤੀ ਜਾ ਸਕੀ" + "ਵੀਡੀਓ ਕਾਲ ਮੋਬਾਈਲ ਨੈੱਟਵਰਕ \'ਤੇ ਜਾਰੀ ਰਹੇਗੀ। ਮਿਆਰੀ ਡੈਟਾ ਖਰਚੇ ਲਾਗੂ ਹੋ ਸਕਦੇ ਹਨ।" "ਇਸ ਨੂੰ ਦੁਬਾਰਾ ਨਾ ਵਿਖਾਓ" diff --git a/java/com/android/incallui/res/values-pl/strings.xml b/java/com/android/incallui/res/values-pl/strings.xml index 77c83399f..451c8ba73 100644 --- a/java/com/android/incallui/res/values-pl/strings.xml +++ b/java/com/android/incallui/res/values-pl/strings.xml @@ -33,8 +33,8 @@ "Nieodebrane połączenie od: %s" "Trwa połączenie" "Trwa połączenie służbowe" - "Trwające połączenie przez Wi-Fi" - "Trwa połączenie służbowe przez Wi-Fi" + "Trwające połączenie przez Wi-Fi" + "Trwa połączenie służbowe przez Wi-Fi" "Oczekujące" "Połączenie" "Połączenie przychodzące ze zdjęciem" @@ -55,8 +55,8 @@ "Ważne połączenie przychodzące z załącznikami" "Ważne połączenie przychodzące z załącznikami" "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ące połączenie przez Wi-Fi" + "Przychodzące połączenie służbowe przez Wi-Fi" "Przychodzące połączenie podejrzanie o spam" "Przychodzące żądanie wideo" "Brak usługi" @@ -73,7 +73,7 @@ "Odbierz rozmowę wideo" "Aby rozpocząć połączenie, wyłącz najpierw tryb samolotowy" "Nie zarejestrowano w sieci" - "Sieć komórkowa jest niedostępna." + "Sieć komórkowa jest niedostępna." "Aby zadzwonić, wybierz prawidłowy numer." "Nie można dzwonić." "Rozpoczynanie sekwencji MMI..." @@ -134,8 +134,8 @@ "Zakończ połączenie" "Połączenie konferencyjne" "W trakcie rozmowy" - "Kontynuuję rozmowę przy użyciu transmisji danych komórkowych…" - "Nie udało się przełączyć na sieć Wi-Fi" - "Rozmowa wideo pozostanie w sieci komórkowej. Za transfer danych może zostać pobrana opłata." + "Kontynuuję rozmowę przy użyciu mobilnej transmisji danych…" + "Nie udało się przełączyć na sieć Wi-Fi" + "Rozmowa wideo będzie nadal prowadzona przez sieć komórkową. Za transfer danych może zostać pobrana opłata." "Nie pokazuj ponownie tego komunikatu" diff --git a/java/com/android/incallui/res/values-pt-rBR/strings.xml b/java/com/android/incallui/res/values-pt-rBR/strings.xml index b0e46dfa3..f3c1b2367 100644 --- a/java/com/android/incallui/res/values-pt-rBR/strings.xml +++ b/java/com/android/incallui/res/values-pt-rBR/strings.xml @@ -33,8 +33,8 @@ "Chamada perdida de %s" "Chamada em andamento" "Chamada de trabalho em andamento" - "Chamada Wi-Fi em andamento" - "Chamada trabalho por Wi-Fi em andamento" + "Chamada por Wi-Fi em andamento" + "Chamada de trabalho por Wi-Fi em andamento" "Em espera" "Chamada recebida" "Chamada recebida com foto" @@ -55,8 +55,8 @@ "Chamada recebida importante com foto, mensagem e local" "Chamada recebida importante com anexos" "Chamada de trabalho recebida" - "Chamada Wi-Fi recebida" - "Chamada de trabalho recebida por Wi-Fi" + "Chamada recebida por Wi-Fi" + "Chamada de trabalho recebida por Wi-Fi" "Chamada recebida suspeita (spam)" "Recebendo solicitação de vídeo" "Sem serviço" @@ -73,7 +73,7 @@ "Atender à videochamada" "Para fazer uma chamada, primeiro desative o modo avião." "Não registrado na rede." - "Rede celular não disponível." + "Rede móvel indisponível." "Para realizar uma chamada, digite um número válido." "Não é possível realizar chamadas." "Iniciando sequência MMI…" @@ -134,8 +134,8 @@ "Encerrar chamada" "Teleconferência" "Em chamada" - "Continuando a chamada com dados da rede celular…" - "Não foi possível alternar para a rede Wi-Fi" - "A videochamada continuará via rede celular. Sujeito a cobranças por uso de dados." + "Continuando chamada por dados móveis…" + "Não foi possível alternar para a rede Wi-Fi" + "A videochamada continuará via rede móvel. O uso de dados está sujeito a cobranças padrão." "Não exibir novamente" diff --git a/java/com/android/incallui/res/values-pt-rPT/strings.xml b/java/com/android/incallui/res/values-pt-rPT/strings.xml index b42b0e56c..104043229 100644 --- a/java/com/android/incallui/res/values-pt-rPT/strings.xml +++ b/java/com/android/incallui/res/values-pt-rPT/strings.xml @@ -33,8 +33,8 @@ "Chamada não atendida de %s" "Chamada em curso" "Chamada de trabalho em curso" - "Chamada Wi-Fi em curso" - "Chamada de trabalho por Wi-Fi em curso" + "Chamada por Wi-Fi em curso" + "Chamada de trabalho por Wi-Fi em curso" "Em espera" "Chamada recebida" "Chamada recebida com foto" @@ -55,8 +55,8 @@ "." "Chamada recebida importante com anexos" "Chamada de trabalho recebida" - "Chamada Wi-Fi recebida" - "Chamada de trabalho recebida por Wi-Fi" + "Chamada por Wi-Fi recebida" + "Chamada de trabalho por Wi-Fi recebida" "A receber chamada spam suspeita" "Pedido de vídeo recebido" "Nenhum serviço" @@ -73,7 +73,7 @@ "Aceitar videochamada" "Para efectuar uma chamada, desactive primeiro o modo para Avião." "Sem registo na rede." - "Rede móvel não disponível." + "Rede móvel não disponível." "Para telefonar, introduza um número válido." "Não é possível telefonar." "A iniciar sequência de MMI..." @@ -134,8 +134,8 @@ "Terminar chamada" "Chamada de conferência" "Numa chamada" - "A continuar a chamada com dados móveis…" - "Não foi possível mudar para a rede Wi-Fi" - "As videochamadas continuarão a ser efetuadas através de rede móvel. Poderão ser aplicados custos de dados." + "A continuar a chamada com dados móveis…" + "Não foi possível mudar para a rede Wi-Fi." + "As videochamadas irão continuar a ser efetuadas através da rede móvel. Poderão ser aplicados custos de dados padrão." "Não voltar a mostrar este aviso" diff --git a/java/com/android/incallui/res/values-pt/strings.xml b/java/com/android/incallui/res/values-pt/strings.xml index b0e46dfa3..f3c1b2367 100644 --- a/java/com/android/incallui/res/values-pt/strings.xml +++ b/java/com/android/incallui/res/values-pt/strings.xml @@ -33,8 +33,8 @@ "Chamada perdida de %s" "Chamada em andamento" "Chamada de trabalho em andamento" - "Chamada Wi-Fi em andamento" - "Chamada trabalho por Wi-Fi em andamento" + "Chamada por Wi-Fi em andamento" + "Chamada de trabalho por Wi-Fi em andamento" "Em espera" "Chamada recebida" "Chamada recebida com foto" @@ -55,8 +55,8 @@ "Chamada recebida importante com foto, mensagem e local" "Chamada recebida importante com anexos" "Chamada de trabalho recebida" - "Chamada Wi-Fi recebida" - "Chamada de trabalho recebida por Wi-Fi" + "Chamada recebida por Wi-Fi" + "Chamada de trabalho recebida por Wi-Fi" "Chamada recebida suspeita (spam)" "Recebendo solicitação de vídeo" "Sem serviço" @@ -73,7 +73,7 @@ "Atender à videochamada" "Para fazer uma chamada, primeiro desative o modo avião." "Não registrado na rede." - "Rede celular não disponível." + "Rede móvel indisponível." "Para realizar uma chamada, digite um número válido." "Não é possível realizar chamadas." "Iniciando sequência MMI…" @@ -134,8 +134,8 @@ "Encerrar chamada" "Teleconferência" "Em chamada" - "Continuando a chamada com dados da rede celular…" - "Não foi possível alternar para a rede Wi-Fi" - "A videochamada continuará via rede celular. Sujeito a cobranças por uso de dados." + "Continuando chamada por dados móveis…" + "Não foi possível alternar para a rede Wi-Fi" + "A videochamada continuará via rede móvel. O uso de dados está sujeito a cobranças padrão." "Não exibir novamente" diff --git a/java/com/android/incallui/res/values-ro/strings.xml b/java/com/android/incallui/res/values-ro/strings.xml index db8be10e2..b78be2e6a 100644 --- a/java/com/android/incallui/res/values-ro/strings.xml +++ b/java/com/android/incallui/res/values-ro/strings.xml @@ -33,8 +33,8 @@ "Apel nepreluat de la %s" "Apel în desfășurare" "Apel de serviciu în desfășurare" - "Apel Wi-Fi în desfășurare" - "Apel de serviciu prin Wi-Fi în desfășurare" + "Apel Wi-Fi în desfășurare" + "Apel de serviciu prin Wi-Fi în desfășurare" "În așteptare" "Apel de intrare" "Apel primit cu fotografie" @@ -55,8 +55,8 @@ "Apel primit important cu poză, mesaj și locație" "Apel primit important cu atașamente" "Apel de serviciu primit" - "Apel prin Wi-Fi primit" - "Apel de serviciu prin Wi-Fi primit" + "Apel primit prin Wi-Fi" + "Apel de serviciu primit prin Wi-Fi" "Un apel primit posibil spam" "Solicitare de trecere la apel video" "Fără serviciu" @@ -73,7 +73,7 @@ "Preluați apelul video" "Pentru a efectua un apel, mai întâi dezactivați modul Avion." "Neînregistrat în rețea." - "Rețeaua mobilă nu este disponibilă" + "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..." @@ -134,8 +134,8 @@ "Încheiați apelul" "Teleconferință" "Apel în desfășurare" - "Se continuă apelul folosind datele mobile…" - "Nu s-a putut comuta la rețeaua Wi-Fi" - "Apelul video rămâne în rețeaua mobilă. Se pot aplica tarife standard pentru date." + "Se continuă apelul folosind datele mobile…" + "Nu s-a putut comuta la rețeaua Wi-Fi" + "Apelul video continuă prin rețeaua mobilă. Se pot aplica tarife standard pentru date." "Nu mai afișa acest mesaj" diff --git a/java/com/android/incallui/res/values-ru/strings.xml b/java/com/android/incallui/res/values-ru/strings.xml index 8fd924ec6..06276c601 100644 --- a/java/com/android/incallui/res/values-ru/strings.xml +++ b/java/com/android/incallui/res/values-ru/strings.xml @@ -33,8 +33,8 @@ "Пропущенные вызовы от абонента %s" "Текущий вызов" "Текущий звонок (работа)" - "Текущий Wi-Fi-звонок" - "Текущий Wi-Fi-звонок (работа)" + "Текущий вызов по Wi-Fi" + "Текущий вызов по Wi-Fi (работа)" "Ждет ответа" "Входящий вызов" "Входящий вызов с фотографией" @@ -55,8 +55,8 @@ "Важный вызов с фото, сообщением и геоданными" "Важный входящий вызов с прикрепленными файлами" "Входящий звонок (работа)" - "Входящий Wi-Fi-звонок" - "Входящий Wi-Fi-звонок (работа)" + "Входящий вызов по Wi-Fi" + "Входящий вызов по Wi-Fi (работа)" "Входящий вызов: подозрение на спам" "Входящий видеовызов" "Сеть не найдена" @@ -73,7 +73,7 @@ "Продолжить на этом устройстве" "Перед тем как звонить, отключите режим полета." "Нет регистрации в сети." - "Мобильная сеть недоступна." + "Мобильная сеть недоступна." "Недействительный номер." "Не удалось позвонить." "Запуск последовательности MMI..." @@ -134,8 +134,8 @@ "Завершить вызов" "Конференц-вызов" "Вызов" - "Переключение на мобильные данные…" - "Не удалось подключиться к сети Wi-Fi" - "Видеовызов будет выполняться по мобильной сети. Может взиматься стандартная плата за передачу данных." + "Переключение на мобильный Интернет…" + "Не удалось переключиться на сеть Wi-Fi" + "Видеовызов будет выполняться по мобильной сети. Может взиматься стандартная плата за передачу данных." "Больше не показывать" diff --git a/java/com/android/incallui/res/values-si/strings.xml b/java/com/android/incallui/res/values-si/strings.xml index 989879ae0..0497b7831 100644 --- a/java/com/android/incallui/res/values-si/strings.xml +++ b/java/com/android/incallui/res/values-si/strings.xml @@ -33,8 +33,8 @@ "%s වෙතින් මඟ හැරුණු ඇමතුම" "කරගෙනය යන ඇමතුම" "කරගෙන යන කාර්යාල ඇමතුම" - "දැනට ක්‍රියාත්මක Wi-Fi ඇමතුම" - "කරගෙන යන Wi-Fi කාර්යාල ඇමතුම" + "කරගෙන යන Wi-Fi ඇමතුම" + "කරගෙන යන Wi-Fi කාර්යාල ඇමතුම" "රඳවා ගනිමින්" "එන ඇමතුම" "ඡායාරූපය සමග එන ඇමතුම" @@ -55,8 +55,8 @@ "ඡායාරූපය, පණිවිඩය සහ ස්ථානය සමග වැදගත් එන ඇමතුම" "ඇමුණුම් සමග වැදගත් එන ඇමතුම" "පැමිණෙන කාර්යාල ඇමතුම" - "පැමිණෙන Wi-Fi ඇමතුම" - "පැමිණෙන Wi-Fi කාර්යාල ඇමතුම" + "එන Wi-Fi ඇමතුම" + "එන Wi-Fi කාර්යාල ඇමතුම" "එන සැකසහිත අයාචිත තැපැල් ඇමතුම" "පැමිණෙන වීඩියෝ ඉල්ලීම" "සේවාව නැත" @@ -73,7 +73,7 @@ "වීඩියෝ ඇමතුම ගන්න" "ඇමතුමක් ගැනීමට, මුලින්ම ගුවන්යානා ආකාරය අක්‍රිය කරන්න." "ජාලය මත ලියාපදිංචි වී නැත." - "සෙලියුලර් ජාලය නොමැත" + "ජංගම ජාලය නොමැත." "ඇමතුමක් ලබාගැනීමට, වලංගු අංකයක් ලබාගන්න." "ඇමතුම් ගැනීමට නොහැක." "MMI අනුපිළිවෙල ආරම්භ කරමින්…" @@ -134,8 +134,8 @@ "ඇමතුම අවසන් කරන්න" "සම්මන්ත්‍රණ ඇමතුම" "ඇමතුමක" - "සෙලියුලර් දත්ත භාවිතයෙන් ඇමතුම දිගටම කරගෙන යමින්…" - "Wi-Fi ජාලය වෙත මාරු කිරීමට නොහැකි විය" - "වීඩියෝ ඇමතුම සෙලියුලර් ජාලයේ පවතිනු ඇත. සම්මත දත්ත ගාස්තු අදාළ විය හැකිය." + "ජංගම දත්ත භාවිතයෙන් ඇමතුම දිගටම කරගෙන යමින්…" + "Wi-Fi ජාලය වෙත මාරු කිරීමට නොහැකි විය" + "වීඩියෝ ඇමතුම ජංගම ජාලයේ පවතිනු ඇත. සම්මත දත්ත ගාස්තු අදාළ විය හැකිය." "නැවත මෙය නොපෙන්වන්න" diff --git a/java/com/android/incallui/res/values-sk/strings.xml b/java/com/android/incallui/res/values-sk/strings.xml index d09ba44d0..b83cd949b 100644 --- a/java/com/android/incallui/res/values-sk/strings.xml +++ b/java/com/android/incallui/res/values-sk/strings.xml @@ -33,8 +33,8 @@ "Zmeškaný hovor od volajúceho %s" "Prebiehajúci hovor" "Prebiehajúci pracovný hovor" - "Odchádzajúci hovor prostredníctvom siete Wi-Fi" - "Prebiehajúci pracovný hovor cez Wi-Fi" + "Prebiehajúci hovor cez Wi‑Fi" + "Prebiehajúci pracovný hovor cez Wi‑Fi" "Podržaný hovor" "Prichádzajúci hovor" "Prichádzajúci hovor s fotkou" @@ -55,8 +55,8 @@ "Dôležitý prich. hovor s fotkou, správou a polohou" "Dôležitý prichádzajúci hovor s prílohami" "Prichádzajúci pracovný hovor" - "Prichádzajúci hovor prostredníctvom siete Wi-Fi" - "Prichádzajúci pracovný hovor cez Wi-Fi" + "Prichádzajúci hovor cez Wi‑Fi" + "Prichádzajúci pracovný hovor cez Wi‑Fi" "Prichádzajúci hovor, pri ktorom je podozrenie, že ide o spam" "Prichádzajúca žiadosť o video" "Žiadny signál" @@ -73,7 +73,7 @@ "Prevziať videohovor" "Ak chcete telefonovať, vypnite najprv režim v lietadle." "Prihlásenie do siete nebolo úspešné." - "Mobilná sieť nie je k dispozícii." + "Mobilná sieť nie je k dispozícii." "Ak chcete volať, zadajte platné číslo" "Hovor nie je možné uskutočniť" "Prebieha spúšťanie sekvencie MMI..." @@ -134,8 +134,8 @@ "Ukončiť hovor" "Konferenčný hovor" "Prebieha hovor" - "Pokračuje sa v hovore pomocou mobilných dát…" - "Nepodarilo sa prepnúť na sieť Wi-Fi" - "Videohovor bude pokračovať v mobilnej sieti. Môžu sa účtovať štandardné poplatky za prenos dát." + "Pokračuje sa v hovore pomocou mobilných dát…" + "Nepodarilo sa prepnúť na sieť Wi‑Fi" + "Videohovor bude pokračovať v mobilnej sieti. Môžu sa účtovať štandardné poplatky za prenos dát." "Informácie nabudúce nezobrazovať" diff --git a/java/com/android/incallui/res/values-sl/strings.xml b/java/com/android/incallui/res/values-sl/strings.xml index b083e1bae..cf51ff55b 100644 --- a/java/com/android/incallui/res/values-sl/strings.xml +++ b/java/com/android/incallui/res/values-sl/strings.xml @@ -33,8 +33,8 @@ "Neodgovorjeni klic od: %s" "Aktivni klic" "Aktivni delovni klic" - "Odhodni klic prek Wi-Fi-ja" - "Aktivni delovni klic prek omrežja Wi-Fi" + "Aktivni klic prek omrežja Wi-Fi" + "Aktivni delovni klic prek omrežja Wi-Fi" "Zadržano" "Dohodni klic" "Dohodni klic s fotografijo" @@ -55,8 +55,8 @@ "Pomemben klic s fotografijo, sporočilom, lokacijo" "Pomemben dohodni klic s prilogami" "Dohodni delovni klic" - "Dohodni klic prek Wi-Fi-ja" - "Dohodni delovni klic prek omrežja Wi-Fi" + "Dohodni klic prek omrežja Wi-Fi" + "Dohodni delovni klic prek omrežja Wi-Fi" "Domnevno neželeni dohodni klic" "Dohodna zahteva za video" "Ni storitve" @@ -73,7 +73,7 @@ "Sprejmi videoklic" "Če želite poklicati, najprej izklopite način za letalo." "Ni registrirano v omrežju." - "Mobilno omrežje ni na voljo." + "Mobilno omrežje ni na voljo." "Če želite opraviti klic, vnesite veljavno številko." "Klicanje ni mogoče." "Začetek zaporedja MMI ..." @@ -134,8 +134,8 @@ "Končaj klic" "Konferenčni klic" "Poteka klic" - "Nadaljevanje klica prek prenosa podatkov v mobilnih omrežjih …" - "Ni bilo mogoče preklopiti v omrežje Wi-Fi" - "Videoklic bo še naprej potekal v mobilnem omrežju. Morda boste morali plačati standardne stroške prenosa podatkov." + "Nadaljevanje klica prek prenosa podatkov v mobilnem omrežju …" + "Ni bilo mogoče preklopiti v omrežje Wi-Fi" + "Videoklic bo še naprej potekal v mobilnem omrežju. Morda boste morali plačati standardne stroške prenosa podatkov." "Tega ne kaži več" diff --git a/java/com/android/incallui/res/values-sq/strings.xml b/java/com/android/incallui/res/values-sq/strings.xml index fd1964266..76bb87b80 100644 --- a/java/com/android/incallui/res/values-sq/strings.xml +++ b/java/com/android/incallui/res/values-sq/strings.xml @@ -33,8 +33,8 @@ "Telefonatë e humbur nga %s" "Telefonatë në vazhdim" "Telefonatë pune dalëse" - "Telefonatë në vazhdim me Wi-Fi" - "Telefonatë pune dalëse përmes Wi-Fi" + "Telefonatë në vazhdim me Wi-Fi" + "Telefonatë pune dalëse me Wi-Fi" "Në pritje" "Telefonatë hyrëse" "Telefonatë hyrëse me fotografi" @@ -55,8 +55,8 @@ "Tel. e rëndësishme me foto, mesazh e vendndodhje" "Telefonatë hyrëse e rëndësishme me bashkëngjitje" "Telefonatë pune hyrëse" - "Telefonatë hyrëse Wi-Fi" - "Telefonatë pune hyrëse përmes Wi-Fi" + "Telefonatë hyrëse me Wi-Fi" + "Telefonatë pune hyrëse me Wi-Fi" "Telefonatë e dyshuar si e padëshiruar" "Kërkesë për video hyrëse" "Nuk ka shërbim" @@ -73,7 +73,7 @@ "Prano telefonatën me video" "Për të kryer telefonatë, së pari çaktivizo modalitetin e aeroplanit." "I paregjistruar në rrjet." - "Rrjeti celular nuk mundësohet." + "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…" @@ -134,8 +134,8 @@ "Mbylle telefonatën" "Telefonatë konferencë" "Në telefonatë" - "Po vazhdon telefonatën duke përdorur të dhënat celulare…" - "Nuk mund të kalonte në rrjetin Wi-Fi" - "Telefonata me video do të mbetet në rrjetin celular. Mund të zbatohen tarifat standarde." + "Po vazhdon telefonatën duke përdorur të dhënat celulare…" + "Nuk mund të kalonte në rrjetin Wi-Fi" + "Telefonata me video do të mbetet në rrjetin celular. Mund të zbatohen tarifat standarde të të dhënave." "Mos e shfaq më këtë" diff --git a/java/com/android/incallui/res/values-sr/strings.xml b/java/com/android/incallui/res/values-sr/strings.xml index 4fa7a6133..85e76a9e9 100644 --- a/java/com/android/incallui/res/values-sr/strings.xml +++ b/java/com/android/incallui/res/values-sr/strings.xml @@ -33,8 +33,8 @@ "Пропуштен позив од: %s" "Актуелни позив" "Текући позив за Work" - "Текући Wi-Fi позив" - "Текући позив за Work преко Wi-Fi-ја" + "Wi‑Fi позив у току" + "Wi‑Fi пословни позив у току" "На чекању" "Долазни позив" "Долазни позив са сликом" @@ -55,8 +55,8 @@ "Важан долазни позив са сликом, поруком и локацијом" "Важан долазни позив са прилозима" "Долазни позив за Work" - "Долазни Wi-Fi позив" - "Долазни позив за Work преко Wi-Fi-ја" + "Долазни Wi‑Fi позив" + "Долазни Wi‑Fi пословни позив" "Сумња на непожељан долазни позив" "Захтев за долазни видео позив" "Нема услуге" @@ -73,7 +73,7 @@ "Преузми видео позив" "Да бисте упутили позив, прво искључите режим рада у авиону." "Није регистровано на мрежи." - "Мобилна мрежа није доступна." + "Мобилна мрежа није доступна." "Да бисте упутили позив, унесите важећи број." "Позив није успео." "Покретање MMI секвенце" @@ -134,8 +134,8 @@ "Завршите позив" "Конференцијски позив" "У позиву" - "Позив се наставља помоћу мобилних података…" - "Пребацивање на Wi-Fi мрежу није успело" - "Видео позив ће остати на мобилној мрежи. Могу да важе стандардне накнаде за пренос података." + "Позив се наставља помоћу мобилних података…" + "Пребацивање на Wi‑Fi мрежу није успело" + "Видео позив ће остати на мобилној мрежи. Важе стандардне накнаде за пренос података." "Не приказуј ово поново" diff --git a/java/com/android/incallui/res/values-sv/strings.xml b/java/com/android/incallui/res/values-sv/strings.xml index 6d58d90f3..4bbce1d6a 100644 --- a/java/com/android/incallui/res/values-sv/strings.xml +++ b/java/com/android/incallui/res/values-sv/strings.xml @@ -33,8 +33,8 @@ "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" + "Pågående Wi-Fi-samtal" + "Pågående jobbsamtal på Wi-Fi" "Parkerat" "Inkommande samtal" "Inkommande samtal med foto" @@ -55,8 +55,8 @@ "Viktigt inkommande samtal med foto, meddelande och plats" "Viktigt inkommande samtal med bilagor" "Inkommande jobbsamtal" - "Inkommande Wi-Fi-samtal" - "Inkommande jobbsamtal via Wi-Fi" + "Inkommande Wi-Fi-samtal" + "Inkommande jobbsamtal på Wi-Fi" "Inkommande misstänkt spamsamtal" "Inkommande begäran om videosamtal" "Ingen tjänst" @@ -73,7 +73,7 @@ "Svara på videosamtal" "Om du vill ringa ett samtal måste du först inaktivera flygplansläge." "Inte registrerat på nätverk." - "Det finns inget mobilnät tillgängligt." + "Inga tillgängliga mobilnätverk." "Ange ett giltigt nummer om du vill ringa ett samtal." "Det gick inte att ringa." "Startar sekvens för MMI-kod…" @@ -134,8 +134,8 @@ "Avsluta samtal" "Konferenssamtal" "I samtal" - "Samtalet fortsätter med mobildata …" - "Det gick inte att växla till Wi-Fi-nätverk" - "Videosamtalet förblir i mobilnätverket. Vanliga dataavgifter kan tillkomma." + "Samtalet fortsätter med mobildata …" + "Det gick inte att växla till Wi-Fi-nätverk" + "Videosamtalet förblir i mobilnätverket. Vanliga dataavgifter kan tillkomma." "Visa inte detta igen" diff --git a/java/com/android/incallui/res/values-sw/strings.xml b/java/com/android/incallui/res/values-sw/strings.xml index 0bb1b8cf0..17c3a52ab 100644 --- a/java/com/android/incallui/res/values-sw/strings.xml +++ b/java/com/android/incallui/res/values-sw/strings.xml @@ -33,8 +33,8 @@ "Simu ambayo hukujibu kutoka %s" "Simu inayoendelea" "Simu ya kazi inayoendelea" - "Simu ya Wi-Fi inayoendelea" - "Simu ya Wi-Fi ya kazi inayoendelea" + "Simu ya Wi-Fi inaendelea" + "Simu ya Wi-Fi ya kazi inaendelea" "Inangoja" "Unapigiwa simu" "Simu inayoingia yenye picha" @@ -55,8 +55,8 @@ "Simu muhimu yenye picha, ujumbe na mahali" "Simu muhimu inayoingia yenye viambatisho" "Simu ya kazi inayoingia" - "Simu ya Wi-Fi inayoingia" - "Simu ya Wi-Fi ya kazi inayoingia" + "Simu ya Wi-Fi inaingia" + "Simu ya Wi-Fi ya kazi inaingia" "Simu inayoingia inashukiwa kuwa taka" "Ombi linaloingia la video" "Hakuna huduma" @@ -73,7 +73,7 @@ "Pokea Simu ya Video" "Kupiga simu, kwanza zima hali ya ndegeni." "Haijasajiliwa kwa mitandao" - "Mitandao ya simu za mkononi haipatikani" + "Mtandao wa simu haupatikani." "Ili upige simu, weka nambari sahihi." "Haiwezi kupiga simu." "Inaanzisha msururu wa MMI…" @@ -134,8 +134,8 @@ "Kata simu" "Simu ya kongamano" "Mazungumzo ya simu yanaendelea" - "Endelea na mazungumzo ya simu ukitumia data ya kifaa cha mkononi…" - "Imeshindwa kuhamia mtandao wa Wi-Fi" - "Hangout ya video itaendelea kwenye mtandao wa simu. Huenda ukatozwa gharama za kawaida za data." + "Endelea na mazungumzo ya simu ukitumia data ya simu…" + "Imeshindwa kuhamia mtandao wa Wi-Fi" + "Hangout ya video itaendelea kwenye mtandao wa simu. Huenda ukatozwa gharama za kawaida za data." "Usiionyeshe tena" diff --git a/java/com/android/incallui/res/values-ta/strings.xml b/java/com/android/incallui/res/values-ta/strings.xml index bae8d6a67..bb228a0e2 100644 --- a/java/com/android/incallui/res/values-ta/strings.xml +++ b/java/com/android/incallui/res/values-ta/strings.xml @@ -33,8 +33,8 @@ "%s இடமிருந்து தவறிய அழைப்பு" "செயலில் இருக்கும் அழைப்பு" "வெளிச்செல்லும் அழைப்பு (பணி)" - "வெளிச்செல்லும் வைஃபை அழைப்பு" - "வெளிச்செல்லும் வைஃபை அழைப்பு (பணி)" + "செயலில் இருக்கும் வைஃபை அழைப்பு" + "செயலில் இருக்கும் வைஃபை அழைப்பு (பணி)" "காத்திருப்பில்" "உள்வரும் அழைப்பு" "படத்துடன் உள்வரும் அழைப்பு" @@ -55,8 +55,8 @@ "படம், செய்தி, இருப்பிடத்துடன் உள்வரும் முக்கியமான அழைப்பு" "இணைப்புகளுடன் உள்வரும் முக்கியமான அழைப்பு" "உள்வரும் அழைப்பு (பணி)" - "உள்வரும் வைஃபை அழைப்பு" - "உள்வரும் வைஃபை அழைப்பு (பணி)" + "உள்வரும் வைஃபை அழைப்பு" + "உள்வரும் வைஃபை அழைப்பு (பணி)" "உள்வரும் சந்தேகத்திற்குரிய ஸ்பேம் அழைப்பு" "உள்வரும் வீடியோ கோரிக்கை" "சேவை இல்லை" @@ -73,7 +73,7 @@ "வீடியோ அழைப்பை எடு" "அழைப்பதற்கு, முதலில் விமானப் பயன்முறையை முடக்கவும்." "நெட்வொர்க்கில் பதிவுசெய்யப்படவில்லை." - "செல்லுலார் நெட்வொர்க் கிடைக்கவில்லை." + "மொபைல் நெட்வொர்க் கிடைக்கவில்லை." "அழைக்க, சரியான எண்ணை உள்ளிடவும்." "அழைக்க முடியாது." "MMI வரிசையைத் தொடங்குகிறது..." @@ -134,8 +134,8 @@ "அழைப்பைத் துண்டிக்கும்" "குழு அழைப்பு" "அழைப்பில்" - "செல்லுலார் தரவைப் பயன்படுத்தி அழைப்பைத் தொடர்கிறது…" - "வைஃபை நெட்வொர்க்கிற்கு மாற முடியவில்லை" - "செல்லுலார் நெட்வொர்க்கைப் பயன்படுத்தி தொடர்ந்து வீடியோ அழைப்பைச் செய்யலாம். வழக்கமான தரவுக் கட்டணங்கள் விதிக்கப்படக்கூடும்." + "மொபைல் தரவைப் பயன்படுத்தி அழைப்பைத் தொடர்கிறது…" + "வைஃபை நெட்வொர்க்கிற்கு மாற முடியவில்லை" + "மொபைல் நெட்வொர்க்கைப் பயன்படுத்தி தொடர்ந்து வீடியோ அழைப்பைச் செய்யலாம். வழக்கமான தரவுக் கட்டணங்கள் விதிக்கப்படக்கூடும்." "இதை மீண்டும் காட்டாதே" diff --git a/java/com/android/incallui/res/values-te/strings.xml b/java/com/android/incallui/res/values-te/strings.xml index 6b833886b..a5da32a01 100644 --- a/java/com/android/incallui/res/values-te/strings.xml +++ b/java/com/android/incallui/res/values-te/strings.xml @@ -33,8 +33,8 @@ "%s నుండి సమాధానం ఇవ్వని కాల్" "కాల్ కొనసాగుతోంది" "కార్యాలయ కాల్ కొనసాగుతోంది" - "Wi-Fi కాల్ కొనసాగుతోంది" - "Wi-Fi కార్యాలయ కాల్ కొనసాగుతోంది" + "మాట్లాడుతున్న Wi‑Fi కాల్" + "మాట్లాడుతున్న Wi‑Fi కార్యాలయ కాల్" "హోల్డ్‌లో ఉంది" "ఇన్‌కమింగ్ కాల్" "ఫోటోతో ఇన్‌కమింగ్ కాల్" @@ -55,8 +55,8 @@ "ఫోటో, సందేశం, స్థానంతో ముఖ్యమైన ఇన్‌కమింగ్ కాల్" "జోడింపులతో ముఖ్యమైన ఇన్‌కమింగ్ కాల్" "ఇన్‌కమింగ్ కార్యాలయ కాల్" - "Wi-Fi కాల్ వస్తోంది" - "ఇన్‌కమింగ్ Wi-Fi కార్యాలయ కాల్" + "ఇన్‌కమింగ్ Wi-Fi కాల్" + "ఇన్‌కమింగ్ Wi-Fi కార్యాలయ కాల్" "అనుమానాస్పద స్పామ్ కాల్ వస్తోంది" "ఇన్‌కమింగ్ వీడియో అభ్యర్థన" "సేవ లేదు" @@ -73,7 +73,7 @@ "వీడియో కాల్‌ను తీయి" "కాల్ చేయడానికి, మొదట ఎయిర్‌ప్లైన్ మోడ్‌ను ఆపివేయండి." "నెట్‌వర్క్‌లో నమోదు కాలేదు." - "సెల్యులార్ నెట్‌వర్క్ అందుబాటులో లేదు." + "మొబైల్ నెట్‌వర్క్ అందుబాటులో లేదు." "కాల్ చేయడానికి, చెల్లుబాటు అయ్యే నంబర్‌ను నమోదు చేయండి." "కాల్ చేయలేరు." "MMI శ్రేణిని ప్రారంభిస్తోంది…" @@ -134,8 +134,8 @@ "కాల్‌ను ముగిస్తుంది" "కాన్ఫరెన్స్ కాల్" "కాల్‌లో ఉన్నారు" - "సెల్యులార్ డేటాను ఉపయోగించి కాల్‌ను కొనసాగిస్తోంది…" - "Wi-Fi నెట్‌వర్క్‌కి మార్చలేకపోయింది" - "వీడియో కాల్ సెల్యులార్ నెట్‌వర్క్‌లో కొనసాగుతుంది. ప్రామాణిక డేటా ఛార్జీలు వర్తించవచ్చు." + "మొబైల్ డేటాను ఉపయోగించి కాల్‌ను కొనసాగిస్తోంది…" + "Wi-Fi నెట్‌వర్క్‌కి మార్చడం సాధ్యపడలేదు" + "వీడియో కాల్ మొబైల్ నెట్‌వర్క్‌లో కొనసాగుతుంది. ప్రామాణిక డేటా ఛార్జీలు వర్తించవచ్చు." "దీన్ని మళ్లీ చూపవద్దు" diff --git a/java/com/android/incallui/res/values-th/strings.xml b/java/com/android/incallui/res/values-th/strings.xml index 11023b93a..102faf20a 100644 --- a/java/com/android/incallui/res/values-th/strings.xml +++ b/java/com/android/incallui/res/values-th/strings.xml @@ -33,8 +33,8 @@ "สายที่ไม่ได้รับจาก %s" "โทรต่อเนื่อง" "กำลังอยู่ในสายจากที่ทำงาน" - "กำลังโทรผ่าน Wi-Fi" - "กำลังอยู่ในสายจากที่ทำงานผ่าน Wi-Fi" + "กำลังโทรผ่าน Wi-Fi" + "กำลังอยู่ในสายจากที่ทำงานผ่าน Wi-Fi" "พักสาย" "สายเรียกเข้า" "สายเรียกเข้าพร้อมรูปภาพ" @@ -55,8 +55,8 @@ "สายเรียกเข้าที่สำคัญพร้อมรูปภาพ ข้อความ และตำแหน่ง" "สายเรียกเข้าที่สำคัญพร้อมไฟล์แนบ" "มีสายเรียกเข้าจากที่ทำงาน" - "สายโทรเข้าผ่าน Wi-Fi" - "มีสายเรียกเข้าจากที่ทำงานผ่าน Wi-Fi" + "สายโทรเข้าผ่าน Wi-Fi" + "มีสายเรียกเข้าจากที่ทำงานผ่าน Wi-Fi" "สายเรียกเข้าที่สงสัยว่าเป็นสแปม" "คำขอโทรเข้าเป็นวิดีโอ" "ไม่มีบริการ" @@ -73,7 +73,7 @@ "รับสายแฮงเอาท์วิดีโอ" "หากต้องการโทรออก ให้ปิดโหมดใช้งานบนเครื่องบินก่อน" "ยังไม่ได้ลงทะเบียนบนเครือข่าย" - "เครือข่ายมือถือใช้งานไม่ได้" + "เครือข่ายมือถือใช้งานไม่ได้" "หากต้องการโทรออก โปรดป้อนหมายเลขที่ถูกต้อง" "ไม่สามารถโทรได้" "กำลังเริ่มต้นลำดับ MMI..." @@ -134,8 +134,8 @@ "วางสาย" "การประชุมสาย" "อยู่ในสาย" - "กำลังทำการโทรต่อโดยใช้ข้อมูลเครือข่ายมือถือ…" - "ไม่สามารถเปลี่ยนไปใช้เครือข่าย Wi-Fi" - "แฮงเอาท์วิดีโอจะยังคงอยู่ในเครือข่ายมือถือ อาจมีการเรียกเก็บค่าบริการข้อมูลมาตรฐาน" + "โทรต่อโดยใช้อินเทอร์เน็ตมือถือ..." + "ไม่สามารถเปลี่ยนไปใช้เครือข่าย Wi-Fi" + "แฮงเอาท์วิดีโอจะยังคงอยู่ในเครือข่ายมือถือ อาจมีการเรียกเก็บค่าบริการข้อมูลมาตรฐาน" "อย่าแสดงสิ่งนี้อีก" diff --git a/java/com/android/incallui/res/values-tl/strings.xml b/java/com/android/incallui/res/values-tl/strings.xml index 00a4623b5..9cc2f543e 100644 --- a/java/com/android/incallui/res/values-tl/strings.xml +++ b/java/com/android/incallui/res/values-tl/strings.xml @@ -33,8 +33,8 @@ "Hindi nasagot ang tawag mula kay %s" "Kasalukuyang tawag" "Kasalukuyang tawag sa trabaho" - "Isinasagawang tawag sa Wi-Fi" - "Kasalukuyang tawag sa trabaho sa pamamagitan ng Wi-Fi" + "Kasalukuyang isinasagawang tawag sa Wi-Fi" + "Kasalukuyang isinasagawang tawag sa trabaho gamit ang Wi-Fi" "Naka-hold" "Papasok na tawag" "Papasok na tawag na may larawan" @@ -55,8 +55,8 @@ "Mahalagang papasok na tawag na may larawan, mensahe, at lokasyon" "Mahalagang papasok na tawag na may mga attachment" "Papasok na tawag sa trabaho" - "Papasok na tawag sa Wi-Fi" - "Papasok na tawag sa trabaho sa pamamagitan ng Wi-Fi" + "Papasok na tawag sa Wi-Fi" + "Papasok na tawag sa trabaho gamit ang Wi-Fi" "Papasok na pinaghihinalaang spam na tawag" "Papasok na kahilingan ng video" "Walang serbisyo" @@ -73,7 +73,7 @@ "Sagutin ang Video Call" "Upang tumawag, paki-off ang Airplane mode." "Hindi nakarehistro sa network." - "Hindi available ang cellular network" + "Hindi available ang mobile network." "Upang tumawag, maglagay ng wastong numero." "Hindi makatawag." "Sinisimulan ang pagkakasunud-sunod ng MMI…" @@ -134,8 +134,8 @@ "Tapusin ang tawag" "Conference call" "Nasa tawag" - "Ipinagpapatuloy ang tawag gamit ang cellular data…" - "Hindi makalipat sa Wi-Fi network" - "Mananatili sa cellular network ang video call. Maaaring may mga babayaran sa data." + "Ipinagpapatuloy ang tawag gamit ang mobile data…" + "Hindi makalipat sa Wi-Fi network" + "Mananatili sa mobile network ang video call. Maaaring may mga babayaran sa data." "Huwag itong ipakitang muli" diff --git a/java/com/android/incallui/res/values-tr/strings.xml b/java/com/android/incallui/res/values-tr/strings.xml index 9820a6989..9126624cf 100644 --- a/java/com/android/incallui/res/values-tr/strings.xml +++ b/java/com/android/incallui/res/values-tr/strings.xml @@ -33,8 +33,8 @@ "Cevapsız çağrı: %s" "Devam eden çağrılar" "Süren iş çağrısı" - "Giden kablosuz çağrı" - "Süren kablosuz iş çağrısı" + "Devam eden kablosuz çağrı" + "İşle ilgili devam eden kablosuz çağrı" "Beklemede" "Gelen çağrı" "Fotoğraf eklenmiş gelen çağrı" @@ -55,8 +55,8 @@ "Fotoğraf, mesaj ve konum eklenmiş önemli çağrı" "Ek iliştirilmiş önemli gelen çağrı" "Gelen iş çağrısı" - "Gelen kablosuz çağrı" - "Gelen kablosuz iş çağrısı" + "Gelen kablosuz çağrı" + "İşle ilgili gelen kablosuz çağrı" "Spam olabilecek gelen arama" "Gelen video isteği" "Hizmet yok" @@ -73,7 +73,7 @@ "Video Görüşmesini Al" "Bir çağrı yapmak için öncelikle Uçak modunu kapatın." "Ağda kayıtlı değil." - "Hücresel ağ kullanılamıyor." + "Mobil ağ kullanılamıyor." "Telefon etmek için geçerli bir numara girin." "Arama yapılamıyor." "MMI dizisi başlatılıyor..." @@ -134,8 +134,8 @@ "Çağrı sonlandırılır" "Konferans çağrısı" "Konferans çağrısında" - "Görüşmeye hücresel veri kullanılarak devam ediliyor…" - "Kablosuz ağa geçilemedi" - "Video görüşmesi hücresel ağda devam edecek. Standart veri ücretleri alınabilir." + "Görüşmeye mobil veri kullanılarak devam ediliyor…" + "Kablosuz ağa geçilemedi" + "Görüntülü görüşme mobil ağda devam edecek. Standart veri ücretleri alınabilir." "Bunu bir daha gösterme" diff --git a/java/com/android/incallui/res/values-uk/strings.xml b/java/com/android/incallui/res/values-uk/strings.xml index b3b297dc7..30c202c76 100644 --- a/java/com/android/incallui/res/values-uk/strings.xml +++ b/java/com/android/incallui/res/values-uk/strings.xml @@ -33,8 +33,8 @@ "Пропущений виклик: %s" "Поточний виклик" "Поточний дзвінок на робочий телефон" - "Активний дзвінок через Wi-Fi" - "Поточний дзвінок на робочий телефон через Wi-Fi" + "Поточний дзвінок через Wi-Fi" + "Поточний дзвінок на робочий телефон через Wi-Fi" "Очікує" "Вхідний виклик" "Вхідний дзвінок із фото" @@ -55,8 +55,8 @@ "Важливий дзвінок із фото, повідомленням і адресою" "Важливий вхідний дзвінок із вкладеними файлами" "Вхідний дзвінок на робочий телефон" - "Вхідний дзвінок через Wi-Fi" - "Вхідний дзвінок на робочий телефон через Wi-Fi" + "Вхідний дзвінок через Wi-Fi" + "Вхідний дзвінок на робочий телефон через Wi-Fi" "Цей дзвінок може бути спамом" "Запит на вхідний відеодзвінок" "Нема служби" @@ -73,7 +73,7 @@ "Прийняти відеодзвінок" "Щоб установ. з\'єднання, споч. вимк. режим польоту." "Не зареєстровано в мережі." - "Мобільна мережа недоступна." + "Мобільна мережа недоступна." "Щоб зателефонувати, введіть дійсний номер." "Неможливо зателефонувати." "Запуск ряду MMI..." @@ -134,8 +134,8 @@ "Завершити виклик" "Конференц-зв’язок" "Триває виклик" - "Продовження виклику через мобільний трафік…" - "Не вдалося перейти в мережу Wi-Fi" - "Відеодзвінок продовжиться в мобільній мережі. Діють стандартні тарифи." + "Продовження виклику з використанням мобільного Інтернету…" + "Не вдалося перейти на мережу Wi-Fi" + "Відеодзвінок продовжиться з використанням мобільного Інтернету. Діють стандартні тарифи." "Більше не показувати це" diff --git a/java/com/android/incallui/res/values-ur/strings.xml b/java/com/android/incallui/res/values-ur/strings.xml index e3326a27e..8e70bad8b 100644 --- a/java/com/android/incallui/res/values-ur/strings.xml +++ b/java/com/android/incallui/res/values-ur/strings.xml @@ -33,8 +33,8 @@ "%s کی جانب سے چھوٹی ہوئی کال" "جاری کال" "کام سے متعلق جاری کال" - "‏Wi-Fi کال جاری ہے" - "‏کام سے متعلق جاری Wi-Fi کال" + "‏جاری Wi-Fi کال" + "‏کام سے متعلق جاری Wi-Fi کال" "ہولڈ پر" "آنے والی کال" "تصویر کے ساتھ آنے والی کال" @@ -55,8 +55,8 @@ "تصویر، پیغام اور مقام کے ساتھ آنے والی اہم کال" "منسلکات کے ساتھ آنے والی اہم کال" "کام سے متعلق آنے والی کال" - "‏Wi-Fi کال آ رہی ہے" - "‏کام سے متعلق آنے والی Wi-Fi کال" + "‏Wi-Fi کال آ رہی ہے" + "‏کام سے متعلق آنے والی Wi-Fi کال" "آنے والی مشتبہ سپام کال" "اِن کمنگ ویڈیو درخواست" "کوئی سروس نہیں ہے" @@ -73,7 +73,7 @@ "ویڈیو کال لیں" "کال کرنے کیلئے، پہلے ہوائی جہاز طرز کو آف کریں۔" "نیٹ ورک پر رجسٹرڈ نہیں ہے۔" - "سیلولر نیٹ ورک دستیاب نہیں ہے۔" + "موبائل نیٹ ورک دستیاب نہیں ہے۔" "کال کرنے کیلئے، ایک درست نمبر درج کریں۔" "کال نہیں کر سکتے۔" "‏MMI ترتیب شروع ہو رہی ہے…" @@ -134,8 +134,8 @@ "کال ختم کریں" "کانفرنس کال" "کال میں" - "سیلولر ڈیٹا استعمال کرکے کال جاری ہے" - "‏Wi-Fi نیٹ ورک پر سوئچ نہیں ہو سکا" - "ویڈیو کال سیلولر نیٹ ورک پر رہے گی۔ ڈیٹا کے معیاری چارجز کا اطلاق ہو سکتا ہے۔" + "موبائل ڈیٹا استعمال کرکے کال جاری ہے" + "‏Wi-Fi نیٹ ورک پر سوئچ نہیں ہو سکا" + "ویڈیو کال موبائل نیٹ ورک پر رہے گی۔ ڈیٹا کے معیاری چارجز کا اطلاق ہو سکتا ہے۔" "اسے دوبارہ مت دکھائیں" diff --git a/java/com/android/incallui/res/values-uz/strings.xml b/java/com/android/incallui/res/values-uz/strings.xml index b04972ffd..c460f9504 100644 --- a/java/com/android/incallui/res/values-uz/strings.xml +++ b/java/com/android/incallui/res/values-uz/strings.xml @@ -33,8 +33,8 @@ "%s chaqiruvi javobsiz qoldi" "Joriy qo‘ng‘iroq" "Chiquvchi ishchi qo‘ng‘irog‘i" - "Chiquvchi Wi-Fi qo‘ng‘irog‘i" - "Chiquvchi Wi-Fi ishchi qo‘ng‘irog‘i" + "Joriy Wi-Fi qo‘ng‘iroq" + "Joriy Wi-Fi qo‘ng‘iroq (ish)" "Kutmoqda" "Kiruvchi chaqiruv" "Suratga ega kiruvchi chaqiruv" @@ -55,8 +55,8 @@ "Surat, xabar va joy. ax. ega muhim kiruv. chaqiruv" "Biriktirmalarga ega muhim kiruvchi chaqiruv" "Kiruvchi ishchi qo‘ng‘irog‘i" - "Kiruvchi Wi-Fi qo‘ng‘irog‘i" - "Kiruvchi Wi-Fi ishchi qo‘ng‘irog‘i" + "Kiruvchi Wi-Fi qo‘ng‘iroq" + "Kiruvchi Wi-Fi qo‘ng‘iroq (ish)" "Shubhali kiruvchi qo‘ng‘iroq" "Kiruvchi video so\'rovi" "Xizmat mavjud emas" @@ -73,7 +73,7 @@ "Video qo‘ng‘iroq. qabul qilish" "Qo‘ng‘iroq qilish uchun, avval \"Parvoz rejimi\" o‘chirilishi kerak." "Tarmoqda ro‘yxatdan o‘tmagan." - "Mobil tarmoq mavjud emas." + "Uyali aloqa tarmog‘i mavjud emas." "Qo‘ng‘iroq qilish uchun raqamni to‘g‘ri kiriting." "Qo‘ng‘iroq qilib bo‘lmadi." "MMI tartibi ishga tushmoqda..." @@ -134,8 +134,8 @@ "Qo‘ng‘iroqni tugatish" "Konferens-aloqa" "Qo‘ng‘iroq davom etmoqda" - "Qo‘ng‘iroq mobil internet orqali davom ettirilmoqda…" - "Wi-Fi tarmog‘iga o‘tib bo‘lmadi" - "Video qo‘ng‘iroq uyali tarmoqda davom etilaveradi. Internet uchun operator tarifi bo‘yicha haq olinishi mumkin." + "Qo‘ng‘iroq mobil internetga o‘tkazilmoqda…" + "Wi-Fi tarmog‘iga o‘tib bo‘lmadi" + "Video qo‘ng‘iroq mobil internet orqali davom ettiriladi. Internet uchun operator tarifi bo‘yicha haq olinishi mumkin." "Bu xabar boshqa ko‘rsatilmasin" diff --git a/java/com/android/incallui/res/values-vi/strings.xml b/java/com/android/incallui/res/values-vi/strings.xml index b466b020d..8c0dbceeb 100644 --- a/java/com/android/incallui/res/values-vi/strings.xml +++ b/java/com/android/incallui/res/values-vi/strings.xml @@ -33,8 +33,8 @@ "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" + "Cuộc gọi đang diễn ra qua Wi-Fi" + "Cuộc gọi về công việc đang diễn ra qua Wi-Fi" "Đang chờ" "Cuộc gọi đến" "Cuộc gọi đến có ảnh" @@ -55,8 +55,8 @@ "Cuộc gọi đến quan trọng có ảnh, tin nhắn và vị trí" "Cuộc gọi đến quan trọng có tệp đính kèm" "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 đến qua Wi-Fi" + "Cuộc gọi đến về công việc qua Wi-Fi" "Cuộc gọi spam đến bị nghi ngờ" "Yêu cầu video đến" "Không có dịch vụ nào" @@ -73,7 +73,7 @@ "Nhận cuộc gọi điện video" "Để 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." + "Mạng di động không khả dụ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." "Khởi động chuỗi MMI…" @@ -134,8 +134,8 @@ "Kết thúc cuộc gọi" "Cuộc gọi nhiều bên" "Đang trong cuộc gọi" - "Đang tiếp tục cuộc gọi bằng cách sử dụng dữ liệu di động…" - "Không thể chuyển sang mạng Wi-Fi" - "Cuộc gọi điện video sẽ duy trì trên mạng di động. Có thể áp dụng phí dữ liệu chuẩn." + "Đang tiếp tục cuộc gọi bằng cách sử dụng dữ liệu di động…" + "Không thể chuyển sang mạng Wi-Fi" + "Cuộc gọi điện video sẽ tiếp tục trên mạng di động. Bạn có thể phải trả phí dữ liệu chuẩn." "Không hiển thị lại" diff --git a/java/com/android/incallui/res/values-zh-rCN/strings.xml b/java/com/android/incallui/res/values-zh-rCN/strings.xml index e26ab0ca2..4ede0cb3e 100644 --- a/java/com/android/incallui/res/values-zh-rCN/strings.xml +++ b/java/com/android/incallui/res/values-zh-rCN/strings.xml @@ -33,8 +33,8 @@ "来自%s的未接电话" "当前通话" "工作通话进行中" - "正在进行 WLAN 通话" - "WLAN 工作通话进行中" + "正在进行 WLAN 通话" + "正在进行 WLAN 工作通话" "保持" "来电" "包含照片的来电" @@ -55,8 +55,8 @@ "包含照片、讯息和位置信息的重要来电" "包含附件的重要来电" "工作来电" - "WLAN 来电" - "WLAN 工作来电" + "WLAN 来电" + "WLAN 工作来电" "有疑似骚扰来电" "收到视频通话邀请" "无服务" @@ -73,7 +73,7 @@ "接通视频通话" "要进行呼叫,请先关闭飞行模式。" "尚未注册网络。" - "无法连接到移动网络。" + "无法连接到移动网络。" "要拨打电话,请输入有效的电话号码。" "无法拨打该电话。" "正在启动 MMI 序列..." @@ -134,8 +134,8 @@ "结束通话" "电话会议" "正在通话" - "正在使用移动数据网络继续通话…" - "无法切换到 WLAN 网络" - "系统将使用移动网络继续视频通话。这可能会产生标准数据流量费。" + "正在使用移动数据继续通话…" + "无法切换到 WLAN 网络" + "系统将使用移动网络继续视频通话。这可能会产生标准数据流量费。" "不再显示" diff --git a/java/com/android/incallui/res/values-zh-rHK/strings.xml b/java/com/android/incallui/res/values-zh-rHK/strings.xml index 5eb8892e9..c4934eade 100644 --- a/java/com/android/incallui/res/values-zh-rHK/strings.xml +++ b/java/com/android/incallui/res/values-zh-rHK/strings.xml @@ -33,8 +33,8 @@ "來自 %s 的未接來電" "通話中" "正在進行工作通話" - "正在進行 Wi-Fi 通話" - "正在進行 Wi-Fi 工作通話" + "正在進行 Wi-Fi 通話" + "正在進行 Wi-Fi 工作通話" "保留通話" "來電" "附有相片的來電" @@ -55,8 +55,8 @@ "附有相片、訊息和位置的重要來電" "附有附件的重要來電" "工作來電" - "Wi-Fi 來電" - "Wi-Fi 工作來電" + "Wi-Fi 來電" + "Wi-Fi 工作來電" "疑似收到垃圾來電" "收到視像要求" "沒有服務" @@ -73,7 +73,7 @@ "接受視像通話" "請先關閉飛行模式後再撥打電話。" "未在網絡上完成註冊。" - "無法連線至流動網絡。" + "無法使用流動網絡。" "要撥打電話,請輸入有效的號碼。" "無法通話。" "開始 MMI 序列..." @@ -134,8 +134,8 @@ "結束通話" "會議通話" "正在通話" - "使用流動數據繼續通話…" - "無法切換為 Wi-Fi 網絡" - "視像通話仍會使用流動網絡 (可能需要支付標準數據用量費用)。" + "使用流動數據繼續通話…" + "無法切換為 Wi-Fi 網絡" + "視像通話仍會使用流動網絡 (可能需要支付標準數據用量費用)。" "不要再顯示此訊息" diff --git a/java/com/android/incallui/res/values-zh-rTW/strings.xml b/java/com/android/incallui/res/values-zh-rTW/strings.xml index 9f028661e..9b85a2862 100644 --- a/java/com/android/incallui/res/values-zh-rTW/strings.xml +++ b/java/com/android/incallui/res/values-zh-rTW/strings.xml @@ -33,8 +33,8 @@ "來自 %s 的未接來電" "通話中" "進行中的公司通話" - "撥出的 Wi-Fi 電話" - "進行中的公司通話 (透過 Wi-Fi)" + "進行中的通話 (透過 Wi-Fi)" + "進行中的公司通話 (透過 Wi-Fi)" "通話保留" "來電" "包含相片的來電" @@ -55,8 +55,8 @@ "包含相片、訊息和位置資訊的重要來電" "包含附件的重要來電" "公司來電" - "撥入的 Wi-Fi 電話" - "公司來電 (透過 Wi-Fi)" + "來電 (透過 Wi-Fi)" + "公司來電 (透過 Wi-Fi)" "可疑的騷擾/廣告來電" "收到視訊要求" "沒有服務" @@ -73,7 +73,7 @@ "接聽視訊通話" "撥號前,請先關閉飛航模式。" "尚未註冊網路。" - "無法連線到行動網路。" + "無法使用行動網路。" "如要撥打電話,請輸入有效的號碼。" "無法通話。" "開始 MMI 序列…" @@ -134,8 +134,8 @@ "結束通話" "電話會議" "通話中" - "使用行動數據繼續進行通話…" - "無法切換至 Wi-Fi 網路" - "視訊通話將繼續透過行動網路進行 (可能需支付一般數據傳輸費用)。" + "使用行動網路繼續進行通話…" + "無法切換至 Wi-Fi 網路" + "視訊通話將繼續透過行動網路進行 (可能需支付一般數據傳輸費用)。" "不要再顯示這項說明" diff --git a/java/com/android/incallui/res/values-zu/strings.xml b/java/com/android/incallui/res/values-zu/strings.xml index db415cc45..bc5a92735 100644 --- a/java/com/android/incallui/res/values-zu/strings.xml +++ b/java/com/android/incallui/res/values-zu/strings.xml @@ -33,8 +33,8 @@ "Uphuthelwe ikholi kusukela ku-%s" "Ikholi eqhubekayo" "Ikholi yomsebenzi eqhubekayo" - "Ikholi ye-Wi-Fi eqhubekayo" - "Ikholi yomsebenzi eqhubekayo ye-Wi-Fi" + "Ikholi ye-Wi-Fi eqhubekayo" + "Ikholi yomsebenzi eqhubekayo ye-Wi-Fi" "Ibambile" "Ikholi engenayo" "Ikholi engenayo enesithombe" @@ -55,8 +55,8 @@ "Ikholi engenayo ebalulekile enesithombe, umlayezo nendawo" "Ikholi engenayo ebalulekile enokunamathiselwe kwi-imeyili" "Ikholi engenayo yomsebenzi" - "Ikholi ye-Wi-Fi engenayo" - "Ikholi engenayo yomsebenzi ye-Wi-Fi" + "Ikholi ye-Wi-Fi engenayo" + "Ikholi engenayo yomsebenzi ye-Wi-Fi" "Ikholi engenayo osolisayo kagaxekile" "Isicelo sevidiyo engenayo" "Ayikho isevisi" @@ -73,7 +73,7 @@ "Thatha ikholi yevidiyo" "Ukwenza ikholi, vala kuqala imodi Yendiza." "Ayibhalisiwe kwinethiwekhi." - "Inethiwekhi yeselula ayitholakali." + "Inethiwekhi yefoni ayitholakali" "Ukuze wenze ikholi, faka inombolo evumelekile." "Ayikwazi ukushaya." "Iqalisa ukulandelana kwe-MMI..." @@ -134,8 +134,8 @@ "Qeda ikholi" "Ikholi yengqungquthela" "Isecingweni" - "Iqhuba ikholi isebenzisa idatha yeselula…" - "Ayikwazanga ukushintshela kunethiwekhi ye-Wi-Fi" - "Ikholi yevidiyo izohlala kunethiwekhi yeselula. Izindleko zedatha ejwayelekile zingasebenza." + "Iqhubekisa ikholi isebenzisa idatha yeselula…" + "Ayikwazanga ukushintshela kunethiwekhi ye-Wi-Fi" + "Ikholi yevidiyo izohlala ikunethiwekhi yeselula. Amashaji edatha avamile angasebenza." "Ungabonisi lokhu futhi" diff --git a/java/com/android/incallui/res/values/dimens.xml b/java/com/android/incallui/res/values/dimens.xml index fb4934d01..56b9ae158 100644 --- a/java/com/android/incallui/res/values/dimens.xml +++ b/java/com/android/incallui/res/values/dimens.xml @@ -58,6 +58,8 @@ 48dp + 120dp + false diff --git a/java/com/android/incallui/res/values/strings.xml b/java/com/android/incallui/res/values/strings.xml index aede4289b..4113313df 100644 --- a/java/com/android/incallui/res/values/strings.xml +++ b/java/com/android/incallui/res/values/strings.xml @@ -78,10 +78,10 @@ Ongoing work call - Ongoing Wi-Fi call + Ongoing Wi\u2011Fi call - Ongoing Wi-Fi work call + Ongoing Wi\u2011Fi work call On hold @@ -126,10 +126,10 @@ Incoming work call - Incoming Wi-Fi call + Incoming Wi\u2011Fi call - Incoming Wi-Fi work call + Incoming Wi\u2011Fi work call Incoming suspected spam call @@ -190,7 +190,7 @@ This string is currently unused (see comments in InCallActivity.java.) --> Not registered on network. - Cellular network not available. + Mobile network not available. To place a call, enter a valid number. @@ -349,11 +349,11 @@ In call - Continuing call using cellular data… + Continuing call using mobile data\u2026 - Couldn\'t switch to Wi-Fi network - Video call will remain on cellular network. Standard + Couldn\'t switch to Wi\u2011Fi network + Video call will remain on the mobile network. Standard data charges may apply. Do not show this again diff --git a/java/com/android/incallui/sessiondata/MultimediaFragment.java b/java/com/android/incallui/sessiondata/MultimediaFragment.java index 85a60b6e3..3e6cdbbe0 100644 --- a/java/com/android/incallui/sessiondata/MultimediaFragment.java +++ b/java/com/android/incallui/sessiondata/MultimediaFragment.java @@ -107,6 +107,7 @@ public class MultimediaFragment extends Fragment implements AvatarPresenter { public View onCreateView( LayoutInflater layoutInflater, @Nullable ViewGroup viewGroup, @Nullable Bundle bundle) { if (isSpam) { + LogUtil.i("MultimediaFragment.onCreateView", "show spam layout"); return layoutInflater.inflate(R.layout.fragment_spam, viewGroup, false); } @@ -116,23 +117,30 @@ public class MultimediaFragment extends Fragment implements AvatarPresenter { if (hasMap && MapsComponent.get(getContext()).getMaps().isAvailable()) { if (hasImage) { if (hasSubject) { + LogUtil.i("MultimediaFragment.onCreateView", "show text, image, location layout"); return layoutInflater.inflate( R.layout.fragment_composer_text_image_frag, viewGroup, false); } else { + LogUtil.i("MultimediaFragment.onCreateView", "show image, location layout"); return layoutInflater.inflate(R.layout.fragment_composer_image_frag, viewGroup, false); } } else if (hasSubject) { + LogUtil.i("MultimediaFragment.onCreateView", "show text, location layout"); return layoutInflater.inflate(R.layout.fragment_composer_text_frag, viewGroup, false); } else { + LogUtil.i("MultimediaFragment.onCreateView", "show location layout"); return layoutInflater.inflate(R.layout.fragment_composer_frag, viewGroup, false); } } else if (hasImage) { if (hasSubject) { + LogUtil.i("MultimediaFragment.onCreateView", "show text, image layout"); return layoutInflater.inflate(R.layout.fragment_composer_text_image, viewGroup, false); } else { + LogUtil.i("MultimediaFragment.onCreateView", "show image layout"); return layoutInflater.inflate(R.layout.fragment_composer_image, viewGroup, false); } } else { + LogUtil.i("MultimediaFragment.onCreateView", "show text layout"); return layoutInflater.inflate(R.layout.fragment_composer_text, viewGroup, false); } } @@ -155,11 +163,11 @@ public class MultimediaFragment extends Fragment implements AvatarPresenter { ((TextView) view.findViewById(R.id.spam_text)).setText(R.string.spam_message_text); } - TextView messageText = (TextView) view.findViewById(R.id.answer_message_text); + TextView messageText = view.findViewById(R.id.answer_message_text); if (messageText != null) { messageText.setText(getSubject()); } - ImageView mainImage = (ImageView) view.findViewById(R.id.answer_message_image); + ImageView mainImage = view.findViewById(R.id.answer_message_image); if (mainImage != null) { Glide.with(this) .load(getImageUri()) @@ -185,6 +193,7 @@ public class MultimediaFragment extends Fragment implements AvatarPresenter { Target target, DataSource dataSource, boolean isFirstResource) { + LogUtil.enterBlock("MultimediaFragment.onResourceReady"); view.findViewById(R.id.loading_spinner).setVisibility(View.GONE); return false; } @@ -192,7 +201,7 @@ public class MultimediaFragment extends Fragment implements AvatarPresenter { .into(mainImage); mainImage.setClipToOutline(true); } - FrameLayout fragmentHolder = (FrameLayout) view.findViewById(R.id.answer_message_frag); + FrameLayout fragmentHolder = view.findViewById(R.id.answer_message_frag); if (fragmentHolder != null) { fragmentHolder.setClipToOutline(true); Fragment mapFragment = @@ -202,7 +211,7 @@ public class MultimediaFragment extends Fragment implements AvatarPresenter { .replace(R.id.answer_message_frag, mapFragment) .commitNow(); } - avatarImageView = ((ImageView) view.findViewById(R.id.answer_message_avatar)); + avatarImageView = view.findViewById(R.id.answer_message_avatar); if (avatarImageView != null) { avatarImageView.setVisibility(showAvatar ? View.VISIBLE : View.GONE); } diff --git a/java/com/android/incallui/spam/SpamCallListListener.java b/java/com/android/incallui/spam/SpamCallListListener.java index 547337eda..b9c70ebd0 100644 --- a/java/com/android/incallui/spam/SpamCallListListener.java +++ b/java/com/android/incallui/spam/SpamCallListListener.java @@ -24,6 +24,7 @@ import android.content.Context; import android.content.Intent; import android.graphics.drawable.Icon; import android.support.annotation.NonNull; +import android.support.v4.os.BuildCompat; import android.telecom.DisconnectCause; import android.telephony.PhoneNumberUtils; import android.text.TextUtils; @@ -35,8 +36,7 @@ import com.android.dialer.location.GeoUtil; import com.android.dialer.logging.ContactLookupResult; import com.android.dialer.logging.DialerImpression; import com.android.dialer.logging.Logger; -import com.android.dialer.notification.NotificationChannelManager; -import com.android.dialer.notification.NotificationChannelManager.Channel; +import com.android.dialer.notification.NotificationChannelId; import com.android.dialer.spam.Spam; import com.android.incallui.R; import com.android.incallui.call.CallList; @@ -49,9 +49,8 @@ import java.util.Random; * etc). */ public class SpamCallListListener implements CallList.Listener { + static final int NOTIFICATION_ID = 1; - static final int NOTIFICATION_ID = R.id.notification_spam_call; - private static final String TAG = "SpamCallListListener"; private final Context context; private final Random random; @@ -65,10 +64,6 @@ public class SpamCallListListener implements CallList.Listener { this.random = rand; } - private static String pii(String pii) { - return com.android.incallui.Log.pii(pii); - } - @Override public void onIncomingCall(final DialerCall call) { String number = call.getNumber(); @@ -127,7 +122,6 @@ public class SpamCallListListener implements CallList.Listener { if (call.isSpam()) { maybeShowSpamCallNotification(call); } else { - LogUtil.d(TAG, "Showing not spam notification for number=" + pii(call.getNumber())); maybeShowNonSpamCallNotification(call); } } @@ -161,7 +155,7 @@ public class SpamCallListListener implements CallList.Listener { if (callHistoryStatus == DialerCall.CALL_HISTORY_STATUS_PRESENT) { return false; } else if (callHistoryStatus == DialerCall.CALL_HISTORY_STATUS_UNKNOWN) { - LogUtil.i(TAG, "DialerCall history status is unknown, returning false"); + LogUtil.i("SpamCallListListener.shouldShowAfterCallNotification", "history status unknown"); return false; } @@ -171,7 +165,7 @@ public class SpamCallListListener implements CallList.Listener { return false; } - LogUtil.i(TAG, "shouldShowAfterCallNotification, returning true"); + LogUtil.i("SpamCallListListener.shouldShowAfterCallNotification", "returning true"); return true; } @@ -179,7 +173,7 @@ public class SpamCallListListener implements CallList.Listener { * Creates a notification builder with properties common among the two after call notifications. */ private Notification.Builder createAfterCallNotificationBuilder(DialerCall call) { - Builder builder = + Notification.Builder builder = new Builder(context) .setContentIntent( createActivityPendingIntent(call, SpamNotificationActivity.ACTION_SHOW_DIALOG)) @@ -187,7 +181,9 @@ public class SpamCallListListener implements CallList.Listener { .setPriority(Notification.PRIORITY_DEFAULT) .setColor(context.getColor(R.color.dialer_theme_color)) .setSmallIcon(R.drawable.ic_call_end_white_24dp); - NotificationChannelManager.applyChannel(builder, context, Channel.DEFAULT, null); + if (BuildCompat.isAtLeastO()) { + builder.setChannelId(NotificationChannelId.DEFAULT); + } return builder; } @@ -234,21 +230,20 @@ public class SpamCallListListener implements CallList.Listener { int thresholdForShowing = Spam.get(context).percentOfSpamNotificationsToShow(); if (thresholdForShowing == 0) { LogUtil.d( - TAG, - "shouldThrottleSpamNotification, not showing - percentOfSpamNotificationsToShow is 0"); + "SpamCallListListener.shouldThrottleSpamNotification", + "not showing - percentOfSpamNotificationsToShow is 0"); return true; } else if (randomNumber < thresholdForShowing) { LogUtil.d( - TAG, - "shouldThrottleSpamNotification, showing " + randomNumber + " < " + thresholdForShowing); + "SpamCallListListener.shouldThrottleSpamNotification", + "showing " + randomNumber + " < " + thresholdForShowing); return false; } else { LogUtil.d( - TAG, - "shouldThrottleSpamNotification, not showing " - + randomNumber - + " >= " - + thresholdForShowing); + "SpamCallListListener.shouldThrottleSpamNotification", + "not showing %d >= %d", + randomNumber, + thresholdForShowing); return true; } } @@ -257,15 +252,23 @@ public class SpamCallListListener implements CallList.Listener { int randomNumber = random.nextInt(100); int thresholdForShowing = Spam.get(context).percentOfNonSpamNotificationsToShow(); if (thresholdForShowing == 0) { - LogUtil.d(TAG, "Not showing non spam notification: percentOfNonSpamNotificationsToShow is 0"); + LogUtil.d( + "SpamCallListListener.shouldThrottleNonSpamNotification", + "not showing non spam notification: percentOfNonSpamNotificationsToShow is 0"); return true; } else if (randomNumber < thresholdForShowing) { LogUtil.d( - TAG, "Showing non spam notification: " + randomNumber + " < " + thresholdForShowing); + "SpamCallListListener.shouldThrottleNonSpamNotification", + "showing non spam notification: %d < %d", + randomNumber, + thresholdForShowing); return false; } else { LogUtil.d( - TAG, "Not showing non spam notification:" + randomNumber + " >= " + thresholdForShowing); + "SpamCallListListener.shouldThrottleNonSpamNotification", + "not showing non spam notification: %d >= %d", + randomNumber, + thresholdForShowing); return true; } } diff --git a/java/com/android/incallui/video/impl/VideoCallFragment.java b/java/com/android/incallui/video/impl/VideoCallFragment.java index 6e45f928a..609cb691e 100644 --- a/java/com/android/incallui/video/impl/VideoCallFragment.java +++ b/java/com/android/incallui/video/impl/VideoCallFragment.java @@ -122,6 +122,10 @@ public class VideoCallFragment extends Fragment outline.setOval(x - radius, y - radius, x + radius, y + radius); } }; + + // Must use a named method reference as otherwise they do not match. + // https://stackoverflow.com/questions/28190304/two-exact-method-references-are-not-equal + private final Runnable updatePreviewVideoIfSafe = this::updatePreviewVideoScaling; private InCallScreenDelegate inCallScreenDelegate; private VideoCallScreenDelegate videoCallScreenDelegate; private InCallButtonUiDelegate inCallButtonUiDelegate; @@ -350,6 +354,9 @@ public class VideoCallFragment extends Fragment super.onPause(); LogUtil.i("VideoCallFragment.onPause", null); inCallScreenDelegate.onInCallScreenPaused(); + + // If this is scheduled we should remove it + ThreadUtil.getUiThreadHandler().removeCallbacks(updatePreviewVideoIfSafe); } @Override @@ -1050,7 +1057,7 @@ public class VideoCallFragment extends Fragment previewOffBlurredImageView.setClipToOutline(true); // Wait until the layout pass has finished before updating the scaling - ThreadUtil.postOnUiThread(this::updatePreviewVideoScaling); + ThreadUtil.postOnUiThread(updatePreviewVideoIfSafe); } private void updateVideoOffViews() { diff --git a/java/com/android/incallui/videotech/VideoTech.java b/java/com/android/incallui/videotech/VideoTech.java index 7da74c057..34c3e2ca9 100644 --- a/java/com/android/incallui/videotech/VideoTech.java +++ b/java/com/android/incallui/videotech/VideoTech.java @@ -17,6 +17,7 @@ package com.android.incallui.videotech; import android.content.Context; +import android.support.annotation.Nullable; import com.android.incallui.video.protocol.VideoCallScreen; import com.android.incallui.video.protocol.VideoCallScreenDelegate; import com.android.incallui.videotech.utils.SessionModificationState; @@ -41,6 +42,8 @@ public interface VideoTech { void onCallStateChanged(Context context, int newState); + void onRemovedFromCallList(); + @SessionModificationState int getSessionModificationState(); @@ -62,7 +65,7 @@ public interface VideoTech { void unpause(); - void setCamera(String cameraId); + void setCamera(@Nullable String cameraId); void setDeviceOrientation(int rotation); diff --git a/java/com/android/incallui/videotech/empty/EmptyVideoTech.java b/java/com/android/incallui/videotech/empty/EmptyVideoTech.java index d0a111d62..85eb64ee4 100644 --- a/java/com/android/incallui/videotech/empty/EmptyVideoTech.java +++ b/java/com/android/incallui/videotech/empty/EmptyVideoTech.java @@ -17,6 +17,7 @@ package com.android.incallui.videotech.empty; import android.content.Context; +import android.support.annotation.Nullable; import com.android.dialer.common.Assert; import com.android.incallui.video.protocol.VideoCallScreen; import com.android.incallui.video.protocol.VideoCallScreenDelegate; @@ -55,6 +56,9 @@ public class EmptyVideoTech implements VideoTech { @Override public void onCallStateChanged(Context context, int newState) {} + @Override + public void onRemovedFromCallList() {} + @Override public int getSessionModificationState() { return SessionModificationState.NO_REQUEST; @@ -90,7 +94,7 @@ public class EmptyVideoTech implements VideoTech { public void unpause() {} @Override - public void setCamera(String cameraId) {} + public void setCamera(@Nullable String cameraId) {} @Override public void setDeviceOrientation(int rotation) {} diff --git a/java/com/android/incallui/videotech/ims/ImsVideoTech.java b/java/com/android/incallui/videotech/ims/ImsVideoTech.java index 2a0b7c504..a6cef7b81 100644 --- a/java/com/android/incallui/videotech/ims/ImsVideoTech.java +++ b/java/com/android/incallui/videotech/ims/ImsVideoTech.java @@ -18,6 +18,7 @@ package com.android.incallui.videotech.ims; import android.content.Context; import android.os.Build; +import android.support.annotation.Nullable; import android.telecom.Call; import android.telecom.Call.Details; import android.telecom.VideoProfile; @@ -119,6 +120,9 @@ public class ImsVideoTech implements VideoTech { previousVideoState = newVideoState; } + @Override + public void onRemovedFromCallList() {} + @Override public int getSessionModificationState() { return sessionModificationState; @@ -233,7 +237,7 @@ public class ImsVideoTech implements VideoTech { } @Override - public void setCamera(String cameraId) { + public void setCamera(@Nullable String cameraId) { call.getVideoCall().setCamera(cameraId); call.getVideoCall().requestCameraCapabilities(); } diff --git a/java/com/android/incallui/videotech/lightbringer/LightbringerTech.java b/java/com/android/incallui/videotech/lightbringer/LightbringerTech.java index 386afdc45..55ee2db21 100644 --- a/java/com/android/incallui/videotech/lightbringer/LightbringerTech.java +++ b/java/com/android/incallui/videotech/lightbringer/LightbringerTech.java @@ -17,10 +17,13 @@ package com.android.incallui.videotech.lightbringer; import android.content.Context; +import android.os.Build; import android.support.annotation.NonNull; +import android.support.annotation.Nullable; import android.telecom.Call; +import com.android.contacts.common.compat.telecom.TelecomManagerCompat; import com.android.dialer.common.Assert; -import com.android.dialer.common.ConfigProviderBindings; +import com.android.dialer.configprovider.ConfigProviderBindings; import com.android.dialer.lightbringer.Lightbringer; import com.android.dialer.lightbringer.LightbringerListener; import com.android.incallui.video.protocol.VideoCallScreen; @@ -31,15 +34,18 @@ import com.android.incallui.videotech.utils.SessionModificationState; public class LightbringerTech implements VideoTech, LightbringerListener { private final Lightbringer lightbringer; private final VideoTechListener listener; + private final Call call; private final String callingNumber; private int callState = Call.STATE_NEW; public LightbringerTech( @NonNull Lightbringer lightbringer, @NonNull VideoTechListener listener, + @NonNull Call call, @NonNull String callingNumber) { this.lightbringer = Assert.isNotNull(lightbringer); this.listener = Assert.isNotNull(listener); + this.call = Assert.isNotNull(call); this.callingNumber = Assert.isNotNull(callingNumber); lightbringer.registerListener(this); @@ -47,10 +53,11 @@ public class LightbringerTech implements VideoTech, LightbringerListener { @Override public boolean isAvailable(Context context) { - return ConfigProviderBindings.get(context) - .getBoolean("enable_lightbringer_video_upgrade", false) + return Build.VERSION.SDK_INT >= Build.VERSION_CODES.O + && ConfigProviderBindings.get(context).getBoolean("enable_lightbringer_video_upgrade", true) && callState == Call.STATE_ACTIVE - && lightbringer.isReachable(context, callingNumber); + && lightbringer.supportsUpgrade(context, callingNumber) + && TelecomManagerCompat.supportsHandover(); } @Override @@ -83,6 +90,9 @@ public class LightbringerTech implements VideoTech, LightbringerListener { callState = newState; } + @Override + public void onRemovedFromCallList() {} + @Override public int getSessionModificationState() { return SessionModificationState.NO_REQUEST; @@ -90,7 +100,7 @@ public class LightbringerTech implements VideoTech, LightbringerListener { @Override public void upgradeToVideo() { - // TODO: upgrade to a video call + lightbringer.requestUpgrade(call); } @Override @@ -124,17 +134,13 @@ public class LightbringerTech implements VideoTech, LightbringerListener { } @Override - public void pause() { - throw Assert.createUnsupportedOperationFailException(); - } + public void pause() {} @Override - public void unpause() { - throw Assert.createUnsupportedOperationFailException(); - } + public void unpause() {} @Override - public void setCamera(String cameraId) { + public void setCamera(@Nullable String cameraId) { throw Assert.createUnsupportedOperationFailException(); } diff --git a/java/com/android/voicemail/impl/TelephonyVvmConfigManager.java b/java/com/android/voicemail/impl/TelephonyVvmConfigManager.java index b4def2fc3..046113c26 100644 --- a/java/com/android/voicemail/impl/TelephonyVvmConfigManager.java +++ b/java/com/android/voicemail/impl/TelephonyVvmConfigManager.java @@ -21,7 +21,7 @@ import android.os.PersistableBundle; import android.support.annotation.Nullable; import android.support.annotation.VisibleForTesting; import android.util.ArrayMap; -import com.android.dialer.common.ConfigProviderBindings; +import com.android.dialer.configprovider.ConfigProviderBindings; import com.android.voicemail.impl.utils.XmlUtils; import java.io.IOException; import java.util.ArrayList; diff --git a/java/com/android/voicemail/impl/VoicemailClientImpl.java b/java/com/android/voicemail/impl/VoicemailClientImpl.java index 83c0523bf..83ce6c588 100644 --- a/java/com/android/voicemail/impl/VoicemailClientImpl.java +++ b/java/com/android/voicemail/impl/VoicemailClientImpl.java @@ -24,8 +24,8 @@ import android.support.v4.os.BuildCompat; import android.telecom.PhoneAccountHandle; import android.telephony.TelephonyManager; import com.android.dialer.common.Assert; -import com.android.dialer.common.ConfigProviderBindings; import com.android.dialer.common.LogUtil; +import com.android.dialer.configprovider.ConfigProviderBindings; import com.android.voicemail.VisualVoicemailTypeExtensions; import com.android.voicemail.VoicemailClient; import com.android.voicemail.impl.settings.VisualVoicemailSettingsUtil; diff --git a/java/com/android/voicemail/impl/VoicemailModule.java b/java/com/android/voicemail/impl/VoicemailModule.java index 5a4e739f5..e689e47d2 100644 --- a/java/com/android/voicemail/impl/VoicemailModule.java +++ b/java/com/android/voicemail/impl/VoicemailModule.java @@ -18,6 +18,7 @@ package com.android.voicemail.impl; import android.content.Context; import android.support.v4.os.BuildCompat; +import com.android.dialer.inject.ApplicationContext; import com.android.voicemail.VoicemailClient; import com.android.voicemail.VoicemailPermissionHelper; import com.android.voicemail.stub.StubVoicemailClient; @@ -31,7 +32,7 @@ public final class VoicemailModule { @Provides @Singleton - static VoicemailClient provideVoicemailClient(Context context) { + static VoicemailClient provideVoicemailClient(@ApplicationContext Context context) { if (!BuildCompat.isAtLeastO()) { VvmLog.i("VoicemailModule.provideVoicemailClient", "SDK below O"); return new StubVoicemailClient(); diff --git a/java/com/android/voicemail/impl/imap/ImapHelper.java b/java/com/android/voicemail/impl/imap/ImapHelper.java index f1bc8b221..94abe9bad 100644 --- a/java/com/android/voicemail/impl/imap/ImapHelper.java +++ b/java/com/android/voicemail/impl/imap/ImapHelper.java @@ -251,13 +251,18 @@ public class ImapHelper implements Closeable { long time = messageDetails.getSentDate().getTime(); String number = getNumber(messageDetails.getFrom()); boolean isRead = Arrays.asList(messageDetails.getFlags()).contains(Flag.SEEN); - return Voicemail.createForInsertion(time, number) - .setPhoneAccount(mPhoneAccount) - .setSourcePackage(mContext.getPackageName()) - .setSourceData(messageDetails.getUid()) - .setIsRead(isRead) - .setTranscription(listener.getVoicemailTranscription()) - .build(); + Long duration = messageDetails.getDuration(); + Voicemail.Builder builder = + Voicemail.createForInsertion(time, number) + .setPhoneAccount(mPhoneAccount) + .setSourcePackage(mContext.getPackageName()) + .setSourceData(messageDetails.getUid()) + .setIsRead(isRead) + .setTranscription(listener.getVoicemailTranscription()); + if (duration != null) { + builder.setDuration(duration); + } + return builder.build(); } /** diff --git a/java/com/android/voicemail/impl/mail/Message.java b/java/com/android/voicemail/impl/mail/Message.java index aea5d3ead..ca65d3d73 100644 --- a/java/com/android/voicemail/impl/mail/Message.java +++ b/java/com/android/voicemail/impl/mail/Message.java @@ -15,6 +15,7 @@ */ package com.android.voicemail.impl.mail; +import android.support.annotation.Nullable; import android.support.annotation.VisibleForTesting; import java.util.Date; import java.util.HashSet; @@ -64,6 +65,9 @@ public abstract class Message implements Part, Body { public abstract void setSentDate(Date sentDate) throws MessagingException; + @Nullable + public abstract Long getDuration() throws MessagingException; + public abstract Address[] getRecipients(String type) throws MessagingException; public abstract void setRecipients(String type, Address[] addresses) throws MessagingException; diff --git a/java/com/android/voicemail/impl/mail/internet/MimeHeader.java b/java/com/android/voicemail/impl/mail/internet/MimeHeader.java index d41cdb3e4..8f0817650 100644 --- a/java/com/android/voicemail/impl/mail/internet/MimeHeader.java +++ b/java/com/android/voicemail/impl/mail/internet/MimeHeader.java @@ -36,6 +36,7 @@ public class MimeHeader { public static final String HEADER_CONTENT_TRANSFER_ENCODING = "Content-Transfer-Encoding"; public static final String HEADER_CONTENT_DISPOSITION = "Content-Disposition"; public static final String HEADER_CONTENT_ID = "Content-ID"; + public static final String HEADER_CONTENT_DURATION = "Content-Duration"; /** Fields that should be omitted when writing the header using writeTo() */ private static final String[] WRITE_OMIT_FIELDS = { diff --git a/java/com/android/voicemail/impl/mail/internet/MimeMessage.java b/java/com/android/voicemail/impl/mail/internet/MimeMessage.java index 589720660..39378a092 100644 --- a/java/com/android/voicemail/impl/mail/internet/MimeMessage.java +++ b/java/com/android/voicemail/impl/mail/internet/MimeMessage.java @@ -15,7 +15,9 @@ */ package com.android.voicemail.impl.mail.internet; +import android.support.annotation.Nullable; import android.text.TextUtils; +import com.android.voicemail.impl.VvmLog; import com.android.voicemail.impl.mail.Address; import com.android.voicemail.impl.mail.Body; import com.android.voicemail.impl.mail.BodyPart; @@ -196,6 +198,28 @@ public class MimeMessage extends Message { this.mSentDate = sentDate; } + @Override + @Nullable + public Long getDuration() { + String durationHeader = null; + try { + durationHeader = getFirstHeader(MimeHeader.HEADER_CONTENT_DURATION); + } catch (MessagingException e) { + VvmLog.e("MimeMessage.getDuration", "cannot retrieve header: ", e); + return null; + } + if (durationHeader == null) { + VvmLog.w("MimeMessage.getDuration", "message missing Content-Duration header"); + return null; + } + try { + return Long.valueOf(durationHeader); + } catch (NumberFormatException e) { + VvmLog.w("MimeMessage.getDuration", "cannot parse duration " + durationHeader); + return null; + } + } + @Override public String getContentType() throws MessagingException { final String contentType = getFirstHeader(MimeHeader.HEADER_CONTENT_TYPE); diff --git a/java/com/android/voicemail/impl/mail/store/imap/ImapConstants.java b/java/com/android/voicemail/impl/mail/store/imap/ImapConstants.java index 88ec0ed90..fd56952d7 100644 --- a/java/com/android/voicemail/impl/mail/store/imap/ImapConstants.java +++ b/java/com/android/voicemail/impl/mail/store/imap/ImapConstants.java @@ -27,7 +27,7 @@ public final class ImapConstants { public static final String FETCH_FIELD_BODY_PEEK_SANE = String.format(Locale.US, "BODY.PEEK[]<0.%d>", ImapStore.FETCH_BODY_SANE_SUGGESTED_SIZE); public static final String FETCH_FIELD_HEADERS = - "BODY.PEEK[HEADER.FIELDS (date subject from content-type to cc message-id)]"; + "BODY.PEEK[HEADER.FIELDS (date subject from content-type to cc message-id content-duration)]"; public static final String ALERT = "ALERT"; public static final String APPEND = "APPEND"; diff --git a/java/com/android/voicemail/impl/protocol/Vvm3Subscriber.java b/java/com/android/voicemail/impl/protocol/Vvm3Subscriber.java index 1cdbbfbca..d9a06494e 100644 --- a/java/com/android/voicemail/impl/protocol/Vvm3Subscriber.java +++ b/java/com/android/voicemail/impl/protocol/Vvm3Subscriber.java @@ -31,7 +31,7 @@ import android.text.Html; import android.text.Spanned; import android.text.style.URLSpan; import android.util.ArrayMap; -import com.android.dialer.common.ConfigProviderBindings; +import com.android.dialer.configprovider.ConfigProviderBindings; import com.android.voicemail.impl.ActivationTask; import com.android.voicemail.impl.Assert; import com.android.voicemail.impl.OmtpEvents; diff --git a/java/com/android/voicemail/impl/res/xml/vvm_config.xml b/java/com/android/voicemail/impl/res/xml/vvm_config.xml index b03115abb..2bac66be5 100644 --- a/java/com/android/voicemail/impl/res/xml/vvm_config.xml +++ b/java/com/android/voicemail/impl/res/xml/vvm_config.xml @@ -21,75 +21,6 @@ - - - - vvm_carrier_flag_20610 - - - - - - 8082 - vvm_type_omtp - - - - - - - - - - - - - - - - - 21101 - - - - vvm_type_omtp - - - - - - - - - - vvm_carrier_flag_27099 - - - - - - 64085 - vvm_type_omtp - - - - - - - - diff --git a/java/com/android/voicemail/impl/settings/VoicemailSettingsFragment.java b/java/com/android/voicemail/impl/settings/VoicemailSettingsFragment.java index ac5f3cac9..4860649b3 100644 --- a/java/com/android/voicemail/impl/settings/VoicemailSettingsFragment.java +++ b/java/com/android/voicemail/impl/settings/VoicemailSettingsFragment.java @@ -22,6 +22,7 @@ import android.preference.Preference.OnPreferenceClickListener; import android.preference.PreferenceFragment; import android.preference.PreferenceScreen; import android.preference.SwitchPreference; +import android.provider.Settings; import android.support.annotation.Nullable; import android.telecom.PhoneAccountHandle; import android.telephony.TelephonyManager; @@ -29,7 +30,6 @@ import com.android.dialer.common.Assert; import com.android.dialer.logging.DialerImpression; import com.android.dialer.logging.Logger; import com.android.dialer.notification.NotificationChannelManager; -import com.android.dialer.notification.NotificationChannelManager.Channel; import com.android.voicemail.VoicemailClient; import com.android.voicemail.VoicemailComponent; import com.android.voicemail.impl.OmtpVvmCarrierConfigHelper; @@ -43,8 +43,7 @@ import com.android.voicemail.impl.sync.VvmAccountManager; */ @TargetApi(VERSION_CODES.O) public class VoicemailSettingsFragment extends PreferenceFragment - implements Preference.OnPreferenceChangeListener, - VvmAccountManager.Listener { + implements Preference.OnPreferenceChangeListener, VvmAccountManager.Listener { private static final String TAG = "VmSettingsActivity"; @@ -83,9 +82,8 @@ public class VoicemailSettingsFragment extends PreferenceFragment voicemailNotificationPreference = findPreference(getString(R.string.voicemail_notifications_key)); - voicemailNotificationPreference.setIntent( - NotificationChannelManager.getInstance() - .getSettingsIntentForChannel(getContext(), Channel.VOICEMAIL, phoneAccountHandle)); + voicemailNotificationPreference.setIntent(getNotificationSettingsIntent()); + voicemailNotificationPreference.setOnPreferenceClickListener( new OnPreferenceClickListener() { @Override @@ -233,4 +231,12 @@ public class VoicemailSettingsFragment extends PreferenceFragment updateChangePin(); } } + + private Intent getNotificationSettingsIntent() { + String channelId = + NotificationChannelManager.getVoicemailChannelId(getContext(), phoneAccountHandle); + return new Intent(Settings.ACTION_CHANNEL_NOTIFICATION_SETTINGS) + .putExtra(Settings.EXTRA_CHANNEL_ID, channelId) + .putExtra(Settings.EXTRA_APP_PACKAGE, getContext().getPackageName()); + } } diff --git a/java/com/android/voicemail/impl/transcribe/TranscriptionConfigProvider.java b/java/com/android/voicemail/impl/transcribe/TranscriptionConfigProvider.java index 17c9be73b..0c83615b4 100644 --- a/java/com/android/voicemail/impl/transcribe/TranscriptionConfigProvider.java +++ b/java/com/android/voicemail/impl/transcribe/TranscriptionConfigProvider.java @@ -16,7 +16,7 @@ package com.android.voicemail.impl.transcribe; import android.content.Context; -import com.android.dialer.common.ConfigProviderBindings; +import com.android.dialer.configprovider.ConfigProviderBindings; /** Provides configuration values needed to connect to the transcription server. */ public class TranscriptionConfigProvider { -- cgit v1.2.3