summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--apex/statsd/aidl/android/os/IStatsCompanionService.aidl6
-rw-r--r--apex/statsd/service/java/com/android/server/stats/StatsCompanionService.java81
-rw-r--r--api/current.txt192
-rw-r--r--api/module-app-current.txt4
-rwxr-xr-xapi/system-current.txt94
-rw-r--r--api/test-current.txt65
-rw-r--r--cmds/incidentd/src/IncidentService.cpp7
-rw-r--r--cmds/statsd/Android.bp1
-rw-r--r--cmds/statsd/src/external/StatsCompanionServicePuller.cpp78
-rw-r--r--cmds/statsd/src/external/StatsCompanionServicePuller.h40
-rw-r--r--cmds/statsd/src/external/StatsPullerManager.cpp11
-rw-r--r--core/java/android/bluetooth/BluetoothProfile.java6
-rw-r--r--core/java/android/content/pm/CrossProfileApps.java26
-rw-r--r--core/java/android/content/pm/ICrossProfileApps.aidl2
-rw-r--r--core/java/android/content/pm/PackageManager.java23
-rw-r--r--core/java/android/debug/AdbManager.java37
-rw-r--r--core/java/android/debug/IAdbManager.aidl11
-rw-r--r--core/java/android/hardware/camera2/CameraCaptureSession.java94
-rw-r--r--core/java/android/hardware/camera2/CameraOfflineSession.java159
-rw-r--r--core/java/android/hardware/camera2/impl/CameraCaptureSessionCore.java10
-rw-r--r--core/java/android/hardware/camera2/impl/CameraCaptureSessionImpl.java72
-rw-r--r--core/java/android/hardware/camera2/impl/CameraConstrainedHighSpeedCaptureSessionImpl.java21
-rw-r--r--core/java/android/hardware/camera2/impl/CameraDeviceImpl.java1079
-rw-r--r--core/java/android/hardware/camera2/impl/CameraOfflineSessionImpl.java840
-rw-r--r--core/java/android/hardware/camera2/impl/CaptureCallback.java124
-rw-r--r--core/java/android/hardware/camera2/impl/CaptureCallbackHolder.java119
-rw-r--r--core/java/android/hardware/camera2/impl/FrameNumberTracker.java261
-rw-r--r--core/java/android/hardware/camera2/impl/ICameraDeviceUserWrapper.java9
-rw-r--r--core/java/android/hardware/camera2/impl/RequestLastFrameNumbersHolder.java181
-rw-r--r--core/java/android/hardware/camera2/legacy/CameraDeviceUserShim.java8
-rw-r--r--core/java/android/inputmethodservice/IInputMethodWrapper.java13
-rw-r--r--core/java/android/inputmethodservice/InputMethodService.java48
-rw-r--r--core/java/android/nfc/Tag.java10
-rw-r--r--core/java/android/nfc/tech/BasicTagTechnology.java5
-rw-r--r--core/java/android/os/IncidentManager.java56
-rw-r--r--core/java/android/provider/DocumentsContract.java18
-rw-r--r--core/java/android/provider/Settings.java15
-rw-r--r--core/java/android/service/quickaccesswallet/GetWalletCardsCallback.java92
-rw-r--r--core/java/android/service/quickaccesswallet/GetWalletCardsError.aidl19
-rw-r--r--core/java/android/service/quickaccesswallet/GetWalletCardsError.java100
-rw-r--r--core/java/android/service/quickaccesswallet/GetWalletCardsRequest.aidl19
-rw-r--r--core/java/android/service/quickaccesswallet/GetWalletCardsRequest.java137
-rw-r--r--core/java/android/service/quickaccesswallet/GetWalletCardsResponse.aidl19
-rw-r--r--core/java/android/service/quickaccesswallet/GetWalletCardsResponse.java100
-rw-r--r--core/java/android/service/quickaccesswallet/IQuickAccessWalletService.aidl44
-rw-r--r--core/java/android/service/quickaccesswallet/IQuickAccessWalletServiceCallbacks.aidl37
-rw-r--r--core/java/android/service/quickaccesswallet/QuickAccessWalletClient.java89
-rw-r--r--core/java/android/service/quickaccesswallet/QuickAccessWalletClientImpl.java342
-rw-r--r--core/java/android/service/quickaccesswallet/QuickAccessWalletService.java337
-rw-r--r--core/java/android/service/quickaccesswallet/QuickAccessWalletServiceInfo.java187
-rw-r--r--core/java/android/service/quickaccesswallet/SelectWalletCardRequest.aidl19
-rw-r--r--core/java/android/service/quickaccesswallet/SelectWalletCardRequest.java74
-rw-r--r--core/java/android/service/quickaccesswallet/WalletCard.aidl19
-rw-r--r--core/java/android/service/quickaccesswallet/WalletCard.java245
-rw-r--r--core/java/android/service/quickaccesswallet/WalletServiceEvent.aidl19
-rw-r--r--core/java/android/service/quickaccesswallet/WalletServiceEvent.java92
-rw-r--r--core/java/android/service/quickaccesswallet/WalletServiceEventListenerRequest.aidl19
-rw-r--r--core/java/android/service/quickaccesswallet/WalletServiceEventListenerRequest.java78
-rw-r--r--core/java/android/telephony/PhoneStateListener.java24
-rw-r--r--core/java/android/view/ImeFocusController.java7
-rw-r--r--core/java/android/view/inputmethod/InputMethod.java36
-rw-r--r--core/java/android/view/inputmethod/InputMethodManager.java76
-rw-r--r--core/java/android/widget/Editor.java79
-rw-r--r--core/java/android/widget/Magnifier.java206
-rw-r--r--core/java/com/android/internal/inputmethod/IInputMethodPrivilegedOperations.aidl2
-rw-r--r--core/java/com/android/internal/inputmethod/InputMethodPrivilegedOperations.java9
-rw-r--r--core/java/com/android/internal/view/IInputMethod.aidl2
-rw-r--r--core/java/com/android/internal/view/IInputMethodManager.aidl2
-rw-r--r--core/jni/android_media_AudioAttributes.cpp23
-rw-r--r--core/jni/android_media_AudioSystem.cpp26
-rw-r--r--core/res/AndroidManifest.xml7
-rw-r--r--core/res/res/values/attrs.xml20
-rw-r--r--core/res/res/values/strings.xml4
-rw-r--r--core/res/res/values/symbols.xml3
-rw-r--r--graphics/java/android/graphics/drawable/AdaptiveIconDrawable.java15
-rw-r--r--identity/java/android/security/identity/WritableIdentityCredential.java5
-rw-r--r--media/java/android/media/AudioAttributes.java199
-rw-r--r--media/java/android/media/AudioManager.java34
-rw-r--r--media/java/android/media/AudioMetadata.java406
-rw-r--r--media/java/android/media/AudioSystem.java5
-rw-r--r--media/java/android/media/AudioTrack.java79
-rw-r--r--media/java/android/media/IAudioService.aidl4
-rw-r--r--media/java/android/media/MediaFile.java78
-rw-r--r--media/java/android/media/MediaPlayer.java2
-rw-r--r--media/java/android/media/Utils.java282
-rw-r--r--media/java/android/media/tv/ITvInputManager.aidl2
-rw-r--r--media/java/android/media/tv/TvInputManager.java57
-rw-r--r--media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/MediaFileTest.java11
-rw-r--r--media/tests/MediaRouter/src/com/android/mediaroutertest/MediaRouter2Test.java9
-rw-r--r--packages/SettingsLib/SearchWidget/res/values-pt-rPT/strings.xml2
-rw-r--r--packages/SettingsLib/res/values-af/arrays.xml10
-rw-r--r--packages/SettingsLib/res/values-af/strings.xml4
-rw-r--r--packages/SettingsLib/res/values-am/arrays.xml10
-rw-r--r--packages/SettingsLib/res/values-am/strings.xml4
-rw-r--r--packages/SettingsLib/res/values-ar/arrays.xml10
-rw-r--r--packages/SettingsLib/res/values-ar/strings.xml6
-rw-r--r--packages/SettingsLib/res/values-as/arrays.xml10
-rw-r--r--packages/SettingsLib/res/values-as/strings.xml4
-rw-r--r--packages/SettingsLib/res/values-az/arrays.xml10
-rw-r--r--packages/SettingsLib/res/values-az/strings.xml4
-rw-r--r--packages/SettingsLib/res/values-b+sr+Latn/arrays.xml10
-rw-r--r--packages/SettingsLib/res/values-b+sr+Latn/strings.xml4
-rw-r--r--packages/SettingsLib/res/values-be/arrays.xml10
-rw-r--r--packages/SettingsLib/res/values-be/strings.xml4
-rw-r--r--packages/SettingsLib/res/values-bg/arrays.xml10
-rw-r--r--packages/SettingsLib/res/values-bg/strings.xml4
-rw-r--r--packages/SettingsLib/res/values-bn/arrays.xml10
-rw-r--r--packages/SettingsLib/res/values-bn/strings.xml4
-rw-r--r--packages/SettingsLib/res/values-bs/arrays.xml10
-rw-r--r--packages/SettingsLib/res/values-bs/strings.xml4
-rw-r--r--packages/SettingsLib/res/values-ca/arrays.xml10
-rw-r--r--packages/SettingsLib/res/values-ca/strings.xml4
-rw-r--r--packages/SettingsLib/res/values-cs/arrays.xml10
-rw-r--r--packages/SettingsLib/res/values-cs/strings.xml4
-rw-r--r--packages/SettingsLib/res/values-da/arrays.xml10
-rw-r--r--packages/SettingsLib/res/values-da/strings.xml4
-rw-r--r--packages/SettingsLib/res/values-de/arrays.xml10
-rw-r--r--packages/SettingsLib/res/values-de/strings.xml4
-rw-r--r--packages/SettingsLib/res/values-el/arrays.xml10
-rw-r--r--packages/SettingsLib/res/values-el/strings.xml4
-rw-r--r--packages/SettingsLib/res/values-en-rAU/arrays.xml10
-rw-r--r--packages/SettingsLib/res/values-en-rAU/strings.xml4
-rw-r--r--packages/SettingsLib/res/values-en-rCA/arrays.xml10
-rw-r--r--packages/SettingsLib/res/values-en-rCA/strings.xml4
-rw-r--r--packages/SettingsLib/res/values-en-rGB/arrays.xml10
-rw-r--r--packages/SettingsLib/res/values-en-rGB/strings.xml4
-rw-r--r--packages/SettingsLib/res/values-en-rIN/arrays.xml10
-rw-r--r--packages/SettingsLib/res/values-en-rIN/strings.xml4
-rw-r--r--packages/SettingsLib/res/values-en-rXC/arrays.xml10
-rw-r--r--packages/SettingsLib/res/values-en-rXC/strings.xml4
-rw-r--r--packages/SettingsLib/res/values-es-rUS/arrays.xml10
-rw-r--r--packages/SettingsLib/res/values-es-rUS/strings.xml4
-rw-r--r--packages/SettingsLib/res/values-es/arrays.xml10
-rw-r--r--packages/SettingsLib/res/values-es/strings.xml4
-rw-r--r--packages/SettingsLib/res/values-et/arrays.xml10
-rw-r--r--packages/SettingsLib/res/values-et/strings.xml4
-rw-r--r--packages/SettingsLib/res/values-eu/arrays.xml10
-rw-r--r--packages/SettingsLib/res/values-eu/strings.xml4
-rw-r--r--packages/SettingsLib/res/values-fa/arrays.xml10
-rw-r--r--packages/SettingsLib/res/values-fa/strings.xml4
-rw-r--r--packages/SettingsLib/res/values-fi/arrays.xml10
-rw-r--r--packages/SettingsLib/res/values-fi/strings.xml4
-rw-r--r--packages/SettingsLib/res/values-fr-rCA/arrays.xml10
-rw-r--r--packages/SettingsLib/res/values-fr-rCA/strings.xml4
-rw-r--r--packages/SettingsLib/res/values-fr/arrays.xml10
-rw-r--r--packages/SettingsLib/res/values-fr/strings.xml4
-rw-r--r--packages/SettingsLib/res/values-gl/arrays.xml10
-rw-r--r--packages/SettingsLib/res/values-gl/strings.xml4
-rw-r--r--packages/SettingsLib/res/values-gu/arrays.xml10
-rw-r--r--packages/SettingsLib/res/values-gu/strings.xml4
-rw-r--r--packages/SettingsLib/res/values-hi/arrays.xml10
-rw-r--r--packages/SettingsLib/res/values-hi/strings.xml4
-rw-r--r--packages/SettingsLib/res/values-hr/arrays.xml10
-rw-r--r--packages/SettingsLib/res/values-hr/strings.xml4
-rw-r--r--packages/SettingsLib/res/values-hu/arrays.xml10
-rw-r--r--packages/SettingsLib/res/values-hu/strings.xml4
-rw-r--r--packages/SettingsLib/res/values-hy/arrays.xml10
-rw-r--r--packages/SettingsLib/res/values-hy/strings.xml4
-rw-r--r--packages/SettingsLib/res/values-in/arrays.xml10
-rw-r--r--packages/SettingsLib/res/values-in/strings.xml4
-rw-r--r--packages/SettingsLib/res/values-is/arrays.xml10
-rw-r--r--packages/SettingsLib/res/values-is/strings.xml4
-rw-r--r--packages/SettingsLib/res/values-it/arrays.xml10
-rw-r--r--packages/SettingsLib/res/values-it/strings.xml4
-rw-r--r--packages/SettingsLib/res/values-iw/arrays.xml10
-rw-r--r--packages/SettingsLib/res/values-iw/strings.xml4
-rw-r--r--packages/SettingsLib/res/values-ja/arrays.xml10
-rw-r--r--packages/SettingsLib/res/values-ja/strings.xml4
-rw-r--r--packages/SettingsLib/res/values-ka/arrays.xml10
-rw-r--r--packages/SettingsLib/res/values-ka/strings.xml4
-rw-r--r--packages/SettingsLib/res/values-kk/arrays.xml10
-rw-r--r--packages/SettingsLib/res/values-kk/strings.xml4
-rw-r--r--packages/SettingsLib/res/values-km/arrays.xml10
-rw-r--r--packages/SettingsLib/res/values-km/strings.xml4
-rw-r--r--packages/SettingsLib/res/values-kn/arrays.xml10
-rw-r--r--packages/SettingsLib/res/values-kn/strings.xml4
-rw-r--r--packages/SettingsLib/res/values-ko/arrays.xml10
-rw-r--r--packages/SettingsLib/res/values-ko/strings.xml4
-rw-r--r--packages/SettingsLib/res/values-ky/arrays.xml10
-rw-r--r--packages/SettingsLib/res/values-ky/strings.xml4
-rw-r--r--packages/SettingsLib/res/values-lo/arrays.xml10
-rw-r--r--packages/SettingsLib/res/values-lo/strings.xml4
-rw-r--r--packages/SettingsLib/res/values-lt/arrays.xml10
-rw-r--r--packages/SettingsLib/res/values-lt/strings.xml4
-rw-r--r--packages/SettingsLib/res/values-lv/arrays.xml10
-rw-r--r--packages/SettingsLib/res/values-lv/strings.xml4
-rw-r--r--packages/SettingsLib/res/values-mk/arrays.xml10
-rw-r--r--packages/SettingsLib/res/values-mk/strings.xml4
-rw-r--r--packages/SettingsLib/res/values-ml/arrays.xml10
-rw-r--r--packages/SettingsLib/res/values-ml/strings.xml4
-rw-r--r--packages/SettingsLib/res/values-mn/arrays.xml10
-rw-r--r--packages/SettingsLib/res/values-mn/strings.xml4
-rw-r--r--packages/SettingsLib/res/values-mr/arrays.xml10
-rw-r--r--packages/SettingsLib/res/values-mr/strings.xml4
-rw-r--r--packages/SettingsLib/res/values-ms/arrays.xml10
-rw-r--r--packages/SettingsLib/res/values-ms/strings.xml4
-rw-r--r--packages/SettingsLib/res/values-my/arrays.xml10
-rw-r--r--packages/SettingsLib/res/values-my/strings.xml4
-rw-r--r--packages/SettingsLib/res/values-nb/arrays.xml10
-rw-r--r--packages/SettingsLib/res/values-nb/strings.xml4
-rw-r--r--packages/SettingsLib/res/values-ne/arrays.xml10
-rw-r--r--packages/SettingsLib/res/values-ne/strings.xml4
-rw-r--r--packages/SettingsLib/res/values-nl/arrays.xml10
-rw-r--r--packages/SettingsLib/res/values-nl/strings.xml4
-rw-r--r--packages/SettingsLib/res/values-or/arrays.xml10
-rw-r--r--packages/SettingsLib/res/values-or/strings.xml4
-rw-r--r--packages/SettingsLib/res/values-pa/arrays.xml10
-rw-r--r--packages/SettingsLib/res/values-pa/strings.xml4
-rw-r--r--packages/SettingsLib/res/values-pl/arrays.xml10
-rw-r--r--packages/SettingsLib/res/values-pl/strings.xml4
-rw-r--r--packages/SettingsLib/res/values-pt-rBR/arrays.xml10
-rw-r--r--packages/SettingsLib/res/values-pt-rBR/strings.xml4
-rw-r--r--packages/SettingsLib/res/values-pt-rPT/arrays.xml10
-rw-r--r--packages/SettingsLib/res/values-pt-rPT/strings.xml6
-rw-r--r--packages/SettingsLib/res/values-pt/arrays.xml10
-rw-r--r--packages/SettingsLib/res/values-pt/strings.xml4
-rw-r--r--packages/SettingsLib/res/values-ro/arrays.xml10
-rw-r--r--packages/SettingsLib/res/values-ro/strings.xml4
-rw-r--r--packages/SettingsLib/res/values-ru/arrays.xml10
-rw-r--r--packages/SettingsLib/res/values-ru/strings.xml4
-rw-r--r--packages/SettingsLib/res/values-si/arrays.xml10
-rw-r--r--packages/SettingsLib/res/values-si/strings.xml4
-rw-r--r--packages/SettingsLib/res/values-sk/arrays.xml10
-rw-r--r--packages/SettingsLib/res/values-sk/strings.xml4
-rw-r--r--packages/SettingsLib/res/values-sl/arrays.xml10
-rw-r--r--packages/SettingsLib/res/values-sl/strings.xml4
-rw-r--r--packages/SettingsLib/res/values-sq/arrays.xml10
-rw-r--r--packages/SettingsLib/res/values-sq/strings.xml4
-rw-r--r--packages/SettingsLib/res/values-sr/arrays.xml10
-rw-r--r--packages/SettingsLib/res/values-sr/strings.xml4
-rw-r--r--packages/SettingsLib/res/values-sv/arrays.xml10
-rw-r--r--packages/SettingsLib/res/values-sv/strings.xml4
-rw-r--r--packages/SettingsLib/res/values-sw/arrays.xml10
-rw-r--r--packages/SettingsLib/res/values-sw/strings.xml4
-rw-r--r--packages/SettingsLib/res/values-ta/arrays.xml10
-rw-r--r--packages/SettingsLib/res/values-ta/strings.xml8
-rw-r--r--packages/SettingsLib/res/values-te/arrays.xml10
-rw-r--r--packages/SettingsLib/res/values-te/strings.xml4
-rw-r--r--packages/SettingsLib/res/values-th/arrays.xml10
-rw-r--r--packages/SettingsLib/res/values-th/strings.xml4
-rw-r--r--packages/SettingsLib/res/values-tl/arrays.xml10
-rw-r--r--packages/SettingsLib/res/values-tl/strings.xml4
-rw-r--r--packages/SettingsLib/res/values-tr/arrays.xml10
-rw-r--r--packages/SettingsLib/res/values-tr/strings.xml4
-rw-r--r--packages/SettingsLib/res/values-uk/arrays.xml10
-rw-r--r--packages/SettingsLib/res/values-uk/strings.xml4
-rw-r--r--packages/SettingsLib/res/values-ur/arrays.xml10
-rw-r--r--packages/SettingsLib/res/values-ur/strings.xml4
-rw-r--r--packages/SettingsLib/res/values-uz/arrays.xml10
-rw-r--r--packages/SettingsLib/res/values-uz/strings.xml4
-rw-r--r--packages/SettingsLib/res/values-vi/arrays.xml10
-rw-r--r--packages/SettingsLib/res/values-vi/strings.xml4
-rw-r--r--packages/SettingsLib/res/values-zh-rCN/arrays.xml10
-rw-r--r--packages/SettingsLib/res/values-zh-rCN/strings.xml4
-rw-r--r--packages/SettingsLib/res/values-zh-rHK/arrays.xml10
-rw-r--r--packages/SettingsLib/res/values-zh-rHK/strings.xml4
-rw-r--r--packages/SettingsLib/res/values-zh-rTW/arrays.xml10
-rw-r--r--packages/SettingsLib/res/values-zh-rTW/strings.xml4
-rw-r--r--packages/SettingsLib/res/values-zu/arrays.xml10
-rw-r--r--packages/SettingsLib/res/values-zu/strings.xml4
-rw-r--r--packages/SettingsLib/src/com/android/settingslib/deviceinfo/AbstractImsStatusPreferenceController.java76
-rw-r--r--packages/SettingsLib/src/com/android/settingslib/net/DataUsageUtils.java2
-rw-r--r--packages/SystemUI/AndroidManifest.xml3
-rw-r--r--services/core/java/com/android/server/BluetoothAirplaneModeListener.java258
-rw-r--r--services/core/java/com/android/server/BluetoothManagerService.java131
-rw-r--r--services/core/java/com/android/server/TelephonyRegistry.java30
-rw-r--r--services/core/java/com/android/server/adb/AdbService.java25
-rw-r--r--services/core/java/com/android/server/am/CarUserSwitchingDialog.java12
-rw-r--r--services/core/java/com/android/server/audio/AudioService.java100
-rw-r--r--services/core/java/com/android/server/audio/MediaFocusControl.java4
-rw-r--r--services/core/java/com/android/server/inputmethod/InputMethodManagerService.java45
-rw-r--r--services/core/java/com/android/server/inputmethod/MultiClientInputMethodManagerService.java3
-rw-r--r--services/core/java/com/android/server/pm/CrossProfileAppsServiceImpl.java70
-rw-r--r--services/core/java/com/android/server/pm/PackageManagerShellCommand.java11
-rw-r--r--services/core/java/com/android/server/soundtrigger_middleware/SoundTriggerModule.java10
-rw-r--r--services/core/java/com/android/server/stats/pull/StatsPullAtomService.java96
-rwxr-xr-xservices/core/java/com/android/server/tv/TvInputHardwareManager.java6
-rwxr-xr-xservices/core/java/com/android/server/tv/TvInputManagerService.java8
-rw-r--r--services/tests/servicestests/src/com/android/server/BluetoothAirplaneModeListenerTest.java125
-rw-r--r--telephony/java/android/telephony/AccessNetworkConstants.java16
-rw-r--r--telephony/java/android/telephony/PhoneCapability.java454
-rw-r--r--telephony/java/android/telephony/PhoneNumberUtils.java15
-rw-r--r--telephony/java/android/telephony/SimSlotCapability.java130
-rw-r--r--telephony/java/android/telephony/TelephonyManager.java83
-rw-r--r--telephony/java/android/telephony/ims/ProvisioningManager.java507
-rw-r--r--telephony/java/com/android/ims/ImsConfig.java336
-rw-r--r--telephony/java/com/android/internal/telephony/IBooleanConsumer.aidl23
-rw-r--r--telephony/java/com/android/internal/telephony/ITelephony.aidl17
-rw-r--r--telephony/java/com/android/internal/telephony/RILConstants.java1
-rw-r--r--wifi/java/android/net/wifi/rtt/ResponderLocation.java4
-rw-r--r--wifi/tests/src/android/net/wifi/rtt/ResponderLocationTest.java25
291 files changed, 9950 insertions, 1503 deletions
diff --git a/apex/statsd/aidl/android/os/IStatsCompanionService.aidl b/apex/statsd/aidl/android/os/IStatsCompanionService.aidl
index 99b9d398e30c..bdd1da7bf3d3 100644
--- a/apex/statsd/aidl/android/os/IStatsCompanionService.aidl
+++ b/apex/statsd/aidl/android/os/IStatsCompanionService.aidl
@@ -16,9 +16,6 @@
package android.os;
-import android.os.IPullAtomCallback;
-import android.os.StatsLogEventWrapper;
-
/**
* Binder interface to communicate with the Java-based statistics service helper.
* {@hide}
@@ -62,9 +59,6 @@ interface IStatsCompanionService {
/** Cancel any alarm for the purpose of subscriber triggering. */
oneway void cancelAlarmForSubscriberTriggering();
- /** Pull the specified data. Results will be sent to statsd when complete. */
- StatsLogEventWrapper[] pullData(int pullCode);
-
/** Tells StatsCompaionService to grab the uid map snapshot and send it to statsd. */
oneway void triggerUidSnapshot();
}
diff --git a/apex/statsd/service/java/com/android/server/stats/StatsCompanionService.java b/apex/statsd/service/java/com/android/server/stats/StatsCompanionService.java
index 018037ce596e..bcbb5a1407f6 100644
--- a/apex/statsd/service/java/com/android/server/stats/StatsCompanionService.java
+++ b/apex/statsd/service/java/com/android/server/stats/StatsCompanionService.java
@@ -714,87 +714,6 @@ public class StatsCompanionService extends IStatsCompanionService.Stub {
}
}
- private void pullDebugElapsedClock(int tagId,
- long elapsedNanos, final long wallClockNanos, List<StatsLogEventWrapper> pulledData) {
- final long elapsedMillis = SystemClock.elapsedRealtime();
- final long clockDiffMillis = mDebugElapsedClockPreviousValue == 0
- ? 0 : elapsedMillis - mDebugElapsedClockPreviousValue;
-
- StatsLogEventWrapper e = new StatsLogEventWrapper(tagId, elapsedNanos, wallClockNanos);
- e.writeLong(mDebugElapsedClockPullCount);
- e.writeLong(elapsedMillis);
- // Log it twice to be able to test multi-value aggregation from ValueMetric.
- e.writeLong(elapsedMillis);
- e.writeLong(clockDiffMillis);
- e.writeInt(1 /* always set */);
- pulledData.add(e);
-
- if (mDebugElapsedClockPullCount % 2 == 1) {
- StatsLogEventWrapper e2 = new StatsLogEventWrapper(tagId, elapsedNanos, wallClockNanos);
- e2.writeLong(mDebugElapsedClockPullCount);
- e2.writeLong(elapsedMillis);
- // Log it twice to be able to test multi-value aggregation from ValueMetric.
- e2.writeLong(elapsedMillis);
- e2.writeLong(clockDiffMillis);
- e2.writeInt(2 /* set on odd pulls */);
- pulledData.add(e2);
- }
-
- mDebugElapsedClockPullCount++;
- mDebugElapsedClockPreviousValue = elapsedMillis;
- }
-
- private void pullDebugFailingElapsedClock(int tagId,
- long elapsedNanos, final long wallClockNanos, List<StatsLogEventWrapper> pulledData) {
- StatsLogEventWrapper e = new StatsLogEventWrapper(tagId, elapsedNanos, wallClockNanos);
- final long elapsedMillis = SystemClock.elapsedRealtime();
- // Fails every 5 buckets.
- if (mDebugFailingElapsedClockPullCount++ % 5 == 0) {
- mDebugFailingElapsedClockPreviousValue = elapsedMillis;
- throw new RuntimeException("Failing debug elapsed clock");
- }
-
- e.writeLong(mDebugFailingElapsedClockPullCount);
- e.writeLong(elapsedMillis);
- // Log it twice to be able to test multi-value aggregation from ValueMetric.
- e.writeLong(elapsedMillis);
- e.writeLong(mDebugFailingElapsedClockPreviousValue == 0
- ? 0 : elapsedMillis - mDebugFailingElapsedClockPreviousValue);
- mDebugFailingElapsedClockPreviousValue = elapsedMillis;
- pulledData.add(e);
- }
-
- /**
- * Pulls various data.
- */
- @Override // Binder call
- public StatsLogEventWrapper[] pullData(int tagId) {
- StatsCompanion.enforceStatsCompanionPermission(mContext);
- if (DEBUG) {
- Slog.d(TAG, "Pulling " + tagId);
- }
- List<StatsLogEventWrapper> ret = new ArrayList<>();
- long elapsedNanos = SystemClock.elapsedRealtimeNanos();
- long wallClockNanos = SystemClock.currentTimeMicro() * 1000L;
- switch (tagId) {
-
- case StatsLog.DEBUG_ELAPSED_CLOCK: {
- pullDebugElapsedClock(tagId, elapsedNanos, wallClockNanos, ret);
- break;
- }
-
- case StatsLog.DEBUG_FAILING_ELAPSED_CLOCK: {
- pullDebugFailingElapsedClock(tagId, elapsedNanos, wallClockNanos, ret);
- break;
- }
-
- default:
- Slog.w(TAG, "No such tagId data as " + tagId);
- return null;
- }
- return ret.toArray(new StatsLogEventWrapper[ret.size()]);
- }
-
@Override // Binder call
public void statsdReady() {
StatsCompanion.enforceStatsCompanionPermission(mContext);
diff --git a/api/current.txt b/api/current.txt
index 1be9926358a2..53a7d495aeb3 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -39,6 +39,7 @@ package android {
field public static final String BIND_NFC_SERVICE = "android.permission.BIND_NFC_SERVICE";
field public static final String BIND_NOTIFICATION_LISTENER_SERVICE = "android.permission.BIND_NOTIFICATION_LISTENER_SERVICE";
field public static final String BIND_PRINT_SERVICE = "android.permission.BIND_PRINT_SERVICE";
+ field public static final String BIND_QUICK_ACCESS_WALLET_SERVICE = "android.permission.BIND_QUICK_ACCESS_WALLET_SERVICE";
field public static final String BIND_QUICK_SETTINGS_TILE = "android.permission.BIND_QUICK_SETTINGS_TILE";
field public static final String BIND_REMOTEVIEWS = "android.permission.BIND_REMOTEVIEWS";
field public static final String BIND_SCREENING_SERVICE = "android.permission.BIND_SCREENING_SERVICE";
@@ -11489,6 +11490,7 @@ package android.content.pm {
method @NonNull public android.graphics.drawable.Drawable getProfileSwitchingIconDrawable(@NonNull android.os.UserHandle);
method @NonNull public CharSequence getProfileSwitchingLabel(@NonNull android.os.UserHandle);
method @NonNull public java.util.List<android.os.UserHandle> getTargetUserProfiles();
+ method @RequiresPermission(anyOf={android.Manifest.permission.INTERACT_ACROSS_PROFILES, "android.permission.INTERACT_ACROSS_USERS"}) public void startActivity(@NonNull android.content.Intent, @NonNull android.os.UserHandle);
method public void startMainActivity(@NonNull android.content.ComponentName, @NonNull android.os.UserHandle);
field public static final String ACTION_CAN_INTERACT_ACROSS_PROFILES_CHANGED = "android.content.pm.action.CAN_INTERACT_ACROSS_PROFILES_CHANGED";
}
@@ -11934,6 +11936,7 @@ package android.content.pm {
method public boolean hasSigningCertificate(int, @NonNull byte[], int);
method public abstract boolean hasSystemFeature(@NonNull String);
method public abstract boolean hasSystemFeature(@NonNull String, int);
+ method public boolean isDefaultApplicationIcon(@NonNull android.graphics.drawable.Drawable);
method public boolean isDeviceUpgrading();
method public abstract boolean isInstantApp();
method public abstract boolean isInstantApp(@NonNull String);
@@ -11996,6 +11999,7 @@ package android.content.pm {
field public static final String FEATURE_COMPANION_DEVICE_SETUP = "android.software.companion_device_setup";
field public static final String FEATURE_CONNECTION_SERVICE = "android.software.connectionservice";
field public static final String FEATURE_CONSUMER_IR = "android.hardware.consumerir";
+ field public static final String FEATURE_CONTEXTHUB = "android.hardware.context_hub";
field public static final String FEATURE_DEVICE_ADMIN = "android.software.device_admin";
field public static final String FEATURE_EMBEDDED = "android.hardware.type.embedded";
field public static final String FEATURE_ETHERNET = "android.hardware.ethernet";
@@ -17048,6 +17052,8 @@ package android.hardware.camera2 {
method public abstract int setRepeatingRequest(@NonNull android.hardware.camera2.CaptureRequest, @Nullable android.hardware.camera2.CameraCaptureSession.CaptureCallback, @Nullable android.os.Handler) throws android.hardware.camera2.CameraAccessException;
method public int setSingleRepeatingRequest(@NonNull android.hardware.camera2.CaptureRequest, @NonNull java.util.concurrent.Executor, @NonNull android.hardware.camera2.CameraCaptureSession.CaptureCallback) throws android.hardware.camera2.CameraAccessException;
method public abstract void stopRepeating() throws android.hardware.camera2.CameraAccessException;
+ method public boolean supportsOfflineProcessing(@NonNull android.view.Surface);
+ method @Nullable public android.hardware.camera2.CameraOfflineSession switchToOffline(@NonNull java.util.Collection<android.view.Surface>, @NonNull java.util.concurrent.Executor, @NonNull android.hardware.camera2.CameraOfflineSession.CameraOfflineSessionCallback) throws android.hardware.camera2.CameraAccessException;
method public void updateOutputConfiguration(android.hardware.camera2.params.OutputConfiguration) throws android.hardware.camera2.CameraAccessException;
}
@@ -17472,6 +17478,20 @@ package android.hardware.camera2 {
field public static final int TONEMAP_PRESET_CURVE_SRGB = 0; // 0x0
}
+ public abstract class CameraOfflineSession extends android.hardware.camera2.CameraCaptureSession {
+ ctor public CameraOfflineSession();
+ }
+
+ public abstract static class CameraOfflineSession.CameraOfflineSessionCallback {
+ ctor public CameraOfflineSession.CameraOfflineSessionCallback();
+ method public abstract void onClosed(@NonNull android.hardware.camera2.CameraOfflineSession);
+ method public abstract void onError(@NonNull android.hardware.camera2.CameraOfflineSession, int);
+ method public abstract void onIdle(@NonNull android.hardware.camera2.CameraOfflineSession);
+ method public abstract void onReady(@NonNull android.hardware.camera2.CameraOfflineSession);
+ method public abstract void onSwitchFailed(@NonNull android.hardware.camera2.CameraOfflineSession);
+ field public static final int STATUS_INTERNAL_ERROR = 0; // 0x0
+ }
+
public class CaptureFailure {
method public long getFrameNumber();
method @Nullable public String getPhysicalCameraId();
@@ -24125,6 +24145,37 @@ package android.media {
method public void onAudioFocusChange(int);
}
+ public final class AudioMetadata {
+ method @NonNull public static android.media.AudioMetadata.Map createMap();
+ }
+
+ public static class AudioMetadata.Format {
+ field @NonNull public static final android.media.AudioMetadata.Key<java.lang.Boolean> KEY_ATMOS_PRESENT;
+ field @NonNull public static final android.media.AudioMetadata.Key<java.lang.Integer> KEY_AUDIO_ENCODING;
+ field @NonNull public static final android.media.AudioMetadata.Key<java.lang.Integer> KEY_BIT_RATE;
+ field @NonNull public static final android.media.AudioMetadata.Key<java.lang.Integer> KEY_BIT_WIDTH;
+ field @NonNull public static final android.media.AudioMetadata.Key<java.lang.Integer> KEY_CHANNEL_MASK;
+ field @NonNull public static final android.media.AudioMetadata.Key<java.lang.String> KEY_MIME;
+ field @NonNull public static final android.media.AudioMetadata.Key<java.lang.Integer> KEY_SAMPLE_RATE;
+ }
+
+ public static interface AudioMetadata.Key<T> {
+ method @NonNull public String getName();
+ method @NonNull public Class<T> getValueClass();
+ }
+
+ public static interface AudioMetadata.Map extends android.media.AudioMetadata.ReadMap {
+ method @Nullable public <T> T remove(@NonNull android.media.AudioMetadata.Key<T>);
+ method @Nullable public <T> T set(@NonNull android.media.AudioMetadata.Key<T>, @NonNull T);
+ }
+
+ public static interface AudioMetadata.ReadMap {
+ method public <T> boolean containsKey(@NonNull android.media.AudioMetadata.Key<T>);
+ method @NonNull public android.media.AudioMetadata.Map dup();
+ method @Nullable public <T> T get(@NonNull android.media.AudioMetadata.Key<T>);
+ method public int size();
+ }
+
public final class AudioPlaybackCaptureConfiguration {
method @NonNull public int[] getExcludeUids();
method @NonNull public int[] getExcludeUsages();
@@ -24310,6 +24361,7 @@ package android.media {
ctor @Deprecated public AudioTrack(int, int, int, int, int, int) throws java.lang.IllegalArgumentException;
ctor @Deprecated public AudioTrack(int, int, int, int, int, int, int) throws java.lang.IllegalArgumentException;
ctor public AudioTrack(android.media.AudioAttributes, android.media.AudioFormat, int, int, int) throws java.lang.IllegalArgumentException;
+ method public void addOnCodecFormatChangedListener(@NonNull java.util.concurrent.Executor, @NonNull android.media.AudioTrack.OnCodecFormatChangedListener);
method public void addOnRoutingChangedListener(android.media.AudioRouting.OnRoutingChangedListener, android.os.Handler);
method @Deprecated public void addOnRoutingChangedListener(android.media.AudioTrack.OnRoutingChangedListener, android.os.Handler);
method public int attachAuxEffect(int);
@@ -24353,6 +24405,7 @@ package android.media {
method public void registerStreamEventCallback(@NonNull java.util.concurrent.Executor, @NonNull android.media.AudioTrack.StreamEventCallback);
method public void release();
method public int reloadStaticData();
+ method public void removeOnCodecFormatChangedListener(@NonNull android.media.AudioTrack.OnCodecFormatChangedListener);
method public void removeOnRoutingChangedListener(android.media.AudioRouting.OnRoutingChangedListener);
method @Deprecated public void removeOnRoutingChangedListener(android.media.AudioTrack.OnRoutingChangedListener);
method public int setAuxEffectSendLevel(@FloatRange(from=0.0) float);
@@ -24426,6 +24479,10 @@ package android.media {
field public static final String USAGE = "android.media.audiotrack.usage";
}
+ public static interface AudioTrack.OnCodecFormatChangedListener {
+ method public void onCodecFormatChanged(@NonNull android.media.AudioTrack, @Nullable android.media.AudioMetadata.ReadMap);
+ }
+
public static interface AudioTrack.OnPlaybackPositionUpdateListener {
method public void onMarkerReached(android.media.AudioTrack);
method public void onPeriodicNotification(android.media.AudioTrack);
@@ -31803,7 +31860,7 @@ package android.net.wifi.rtt {
method public boolean isLciSubelementValid();
method public boolean isZaxisSubelementValid();
method @Nullable public android.location.Address toCivicLocationAddress();
- method @Nullable public android.util.SparseArray toCivicLocationSparseArray();
+ method @Nullable public android.util.SparseArray<java.lang.String> toCivicLocationSparseArray();
method @NonNull public android.location.Location toLocation();
method public void writeToParcel(android.os.Parcel, int);
field public static final int ALTITUDE_FLOORS = 2; // 0x2
@@ -40041,6 +40098,7 @@ package android.provider {
field public static final String ACTION_PRINT_SETTINGS = "android.settings.ACTION_PRINT_SETTINGS";
field public static final String ACTION_PRIVACY_SETTINGS = "android.settings.PRIVACY_SETTINGS";
field public static final String ACTION_PROCESS_WIFI_EASY_CONNECT_URI = "android.settings.PROCESS_WIFI_EASY_CONNECT_URI";
+ field public static final String ACTION_QUICK_ACCESS_WALLET_SETTINGS = "android.settings.QUICK_ACCESS_WALLET_SETTINGS";
field public static final String ACTION_QUICK_LAUNCH_SETTINGS = "android.settings.QUICK_LAUNCH_SETTINGS";
field public static final String ACTION_REQUEST_IGNORE_BATTERY_OPTIMIZATIONS = "android.settings.REQUEST_IGNORE_BATTERY_OPTIMIZATIONS";
field public static final String ACTION_REQUEST_SET_AUTOFILL_SERVICE = "android.settings.REQUEST_SET_AUTOFILL_SERVICE";
@@ -42227,7 +42285,6 @@ package android.security.identity {
}
public abstract class WritableIdentityCredential {
- ctor public WritableIdentityCredential();
method @NonNull public abstract java.util.Collection<java.security.cert.X509Certificate> getCredentialKeyCertificateChain(@NonNull byte[]);
method @NonNull public abstract byte[] personalize(@NonNull android.security.identity.PersonalizationData);
}
@@ -43217,6 +43274,94 @@ package android.service.notification {
}
+package android.service.quickaccesswallet {
+
+ public final class GetWalletCardsCallback {
+ method public void onFailure(@NonNull android.service.quickaccesswallet.GetWalletCardsError);
+ method public void onSuccess(@NonNull android.service.quickaccesswallet.GetWalletCardsResponse);
+ }
+
+ public final class GetWalletCardsError implements android.os.Parcelable {
+ ctor public GetWalletCardsError(@Nullable android.graphics.drawable.Icon, @Nullable CharSequence);
+ method public int describeContents();
+ method @Nullable public android.graphics.drawable.Icon getIcon();
+ method @Nullable public CharSequence getMessage();
+ method public void writeToParcel(@NonNull android.os.Parcel, int);
+ field @NonNull public static final android.os.Parcelable.Creator<android.service.quickaccesswallet.GetWalletCardsError> CREATOR;
+ }
+
+ public final class GetWalletCardsRequest implements android.os.Parcelable {
+ ctor public GetWalletCardsRequest(int, int, int, int);
+ method public int describeContents();
+ method public int getCardHeightPx();
+ method public int getCardWidthPx();
+ method public int getIconSizePx();
+ method public int getMaxCards();
+ method public void writeToParcel(@NonNull android.os.Parcel, int);
+ field @NonNull public static final android.os.Parcelable.Creator<android.service.quickaccesswallet.GetWalletCardsRequest> CREATOR;
+ }
+
+ public final class GetWalletCardsResponse implements android.os.Parcelable {
+ ctor public GetWalletCardsResponse(@NonNull java.util.List<android.service.quickaccesswallet.WalletCard>, int);
+ method public int describeContents();
+ method public int getSelectedIndex();
+ method @NonNull public java.util.List<android.service.quickaccesswallet.WalletCard> getWalletCards();
+ method public void writeToParcel(@NonNull android.os.Parcel, int);
+ field @NonNull public static final android.os.Parcelable.Creator<android.service.quickaccesswallet.GetWalletCardsResponse> CREATOR;
+ }
+
+ public abstract class QuickAccessWalletService extends android.app.Service {
+ ctor public QuickAccessWalletService();
+ method @Nullable public android.os.IBinder onBind(@NonNull android.content.Intent);
+ method public abstract void onWalletCardSelected(@NonNull android.service.quickaccesswallet.SelectWalletCardRequest);
+ method public abstract void onWalletCardsRequested(@NonNull android.service.quickaccesswallet.GetWalletCardsRequest, @NonNull android.service.quickaccesswallet.GetWalletCardsCallback);
+ method public abstract void onWalletDismissed();
+ method public final void sendWalletServiceEvent(@NonNull android.service.quickaccesswallet.WalletServiceEvent);
+ field public static final String ACTION_DISMISS_WALLET = "android.service.quickaccesswallet.action.DISMISS_WALLET";
+ field public static final String ACTION_VIEW_WALLET = "android.service.quickaccesswallet.action.VIEW_WALLET";
+ field public static final String ACTION_VIEW_WALLET_SETTINGS = "android.service.quickaccesswallet.action.VIEW_WALLET_SETTINGS";
+ field public static final String SERVICE_INTERFACE = "android.service.quickaccesswallet.QuickAccessWalletService";
+ field public static final String SERVICE_META_DATA = "android.quickaccesswallet";
+ }
+
+ public final class SelectWalletCardRequest implements android.os.Parcelable {
+ ctor public SelectWalletCardRequest(@NonNull String);
+ method public int describeContents();
+ method @NonNull public String getCardId();
+ method public void writeToParcel(@NonNull android.os.Parcel, int);
+ field @NonNull public static final android.os.Parcelable.Creator<android.service.quickaccesswallet.SelectWalletCardRequest> CREATOR;
+ }
+
+ public final class WalletCard implements android.os.Parcelable {
+ method public int describeContents();
+ method @Nullable public android.graphics.drawable.Icon getCardIcon();
+ method @NonNull public String getCardId();
+ method @NonNull public android.graphics.drawable.Icon getCardImage();
+ method @Nullable public CharSequence getCardLabel();
+ method @NonNull public CharSequence getContentDescription();
+ method @NonNull public android.app.PendingIntent getPendingIntent();
+ method public void writeToParcel(@NonNull android.os.Parcel, int);
+ field @NonNull public static final android.os.Parcelable.Creator<android.service.quickaccesswallet.WalletCard> CREATOR;
+ }
+
+ public static final class WalletCard.Builder {
+ ctor public WalletCard.Builder(@NonNull String, @NonNull android.graphics.drawable.Icon, @NonNull CharSequence, @NonNull android.app.PendingIntent);
+ method @NonNull public android.service.quickaccesswallet.WalletCard build();
+ method @NonNull public android.service.quickaccesswallet.WalletCard.Builder setCardIcon(@Nullable android.graphics.drawable.Icon);
+ method @NonNull public android.service.quickaccesswallet.WalletCard.Builder setCardLabel(@Nullable CharSequence);
+ }
+
+ public final class WalletServiceEvent implements android.os.Parcelable {
+ ctor public WalletServiceEvent(int);
+ method public int describeContents();
+ method public int getEventType();
+ method public void writeToParcel(@NonNull android.os.Parcel, int);
+ field @NonNull public static final android.os.Parcelable.Creator<android.service.quickaccesswallet.WalletServiceEvent> CREATOR;
+ field public static final int TYPE_NFC_PAYMENT_STARTED = 1; // 0x1
+ }
+
+}
+
package android.service.quicksettings {
public final class Tile implements android.os.Parcelable {
@@ -46394,8 +46539,32 @@ package android.telephony {
public final class PhoneCapability implements android.os.Parcelable {
method public int describeContents();
+ method @NonNull public java.util.List<java.lang.Integer> getBands(int);
+ method @NonNull public java.util.List<java.util.List<java.lang.Long>> getConcurrentFeaturesSupport();
+ method @NonNull public java.util.List<java.lang.String> getLogicalModemUuids();
+ method public int getMaxActiveDedicatedBearers();
+ method public int getMaxActiveInternetData();
+ method public int getMaxActivePsVoice();
+ method public long getPsDataConnectionLingerTimeMillis();
+ method @NonNull public java.util.List<android.telephony.SimSlotCapability> getSimSlotCapabilities();
+ method public long getSupportedRats();
+ method public int getUeCategory(boolean, int);
method public void writeToParcel(@NonNull android.os.Parcel, int);
field @NonNull public static final android.os.Parcelable.Creator<android.telephony.PhoneCapability> CREATOR;
+ field public static final long MODEM_FEATURE_3GPP2_REG = 1L; // 0x1L
+ field public static final long MODEM_FEATURE_3GPP_REG = 2L; // 0x2L
+ field public static final long MODEM_FEATURE_CDMA2000_EHRPD_REG = 4L; // 0x4L
+ field public static final long MODEM_FEATURE_CSIM = 8192L; // 0x2000L
+ field public static final long MODEM_FEATURE_CS_VOICE_SESSION = 512L; // 0x200L
+ field public static final long MODEM_FEATURE_DEDICATED_BEARER = 2048L; // 0x800L
+ field public static final long MODEM_FEATURE_EUTRAN_REG = 32L; // 0x20L
+ field public static final long MODEM_FEATURE_EUTRA_NR_DUAL_CONNECTIVITY_REG = 128L; // 0x80L
+ field public static final long MODEM_FEATURE_GERAN_REG = 8L; // 0x8L
+ field public static final long MODEM_FEATURE_INTERACTIVE_DATA_SESSION = 1024L; // 0x400L
+ field public static final long MODEM_FEATURE_NETWORK_SCAN = 4096L; // 0x1000L
+ field public static final long MODEM_FEATURE_NGRAN_REG = 64L; // 0x40L
+ field public static final long MODEM_FEATURE_PS_VOICE_REG = 256L; // 0x100L
+ field public static final long MODEM_FEATURE_UTRAN_REG = 16L; // 0x10L
}
public class PhoneNumberFormattingTextWatcher implements android.text.TextWatcher {
@@ -46498,7 +46667,7 @@ package android.telephony {
field @RequiresPermission("android.permission.READ_PRECISE_PHONE_STATE") public static final int LISTEN_IMS_CALL_DISCONNECT_CAUSES = 134217728; // 0x8000000
field public static final int LISTEN_MESSAGE_WAITING_INDICATOR = 4; // 0x4
field public static final int LISTEN_NONE = 0; // 0x0
- field @RequiresPermission("android.permission.MODIFY_PHONE_STATE") public static final int LISTEN_PRECISE_DATA_CONNECTION_STATE = 4096; // 0x1000
+ field @RequiresPermission("android.permission.READ_PRECISE_PHONE_STATE") public static final int LISTEN_PRECISE_DATA_CONNECTION_STATE = 4096; // 0x1000
field @RequiresPermission(android.Manifest.permission.READ_PHONE_STATE) public static final int LISTEN_REGISTRATION_FAILURE = 1073741824; // 0x40000000
field public static final int LISTEN_SERVICE_STATE = 1; // 0x1
field @Deprecated public static final int LISTEN_SIGNAL_STRENGTH = 2; // 0x2
@@ -46582,6 +46751,18 @@ package android.telephony {
field public static final int INVALID = 2147483647; // 0x7fffffff
}
+ public final class SimSlotCapability implements android.os.Parcelable {
+ method public int describeContents();
+ method public int getPhysicalSlotIndex();
+ method public int getSlotType();
+ method public void writeToParcel(@NonNull android.os.Parcel, int);
+ field @NonNull public static final android.os.Parcelable.Creator<android.telephony.SimSlotCapability> CREATOR;
+ field public static final int SLOT_TYPE_EUICC = 3; // 0x3
+ field public static final int SLOT_TYPE_IUICC = 2; // 0x2
+ field public static final int SLOT_TYPE_SOFT_SIM = 4; // 0x4
+ field public static final int SLOT_TYPE_UICC = 1; // 0x1
+ }
+
public final class SmsManager {
method public String createAppSpecificSmsToken(android.app.PendingIntent);
method @Nullable public String createAppSpecificSmsTokenWithPackageInfo(@Nullable String, @NonNull android.app.PendingIntent);
@@ -46934,8 +47115,10 @@ package android.telephony {
method public String getNetworkCountryIso();
method public String getNetworkOperator();
method public String getNetworkOperatorName();
+ method @RequiresPermission(anyOf={"android.permission.READ_PRIVILEGED_PHONE_STATE", android.Manifest.permission.READ_PRECISE_PHONE_STATE}) public int getNetworkSelectionMode();
method public String getNetworkSpecifier();
method @Deprecated @RequiresPermission(android.Manifest.permission.READ_PHONE_STATE) public int getNetworkType();
+ method @Nullable @RequiresPermission(android.Manifest.permission.READ_PHONE_STATE) public android.telephony.PhoneCapability getPhoneCapability();
method @Deprecated public int getPhoneCount();
method public int getPhoneType();
method @RequiresPermission(anyOf={"android.permission.READ_PRIVILEGED_PHONE_STATE", android.Manifest.permission.READ_PHONE_STATE}) public int getPreferredOpportunisticDataSubscription();
@@ -47068,6 +47251,9 @@ package android.telephony {
field public static final int MULTISIM_ALLOWED = 0; // 0x0
field public static final int MULTISIM_NOT_SUPPORTED_BY_CARRIER = 2; // 0x2
field public static final int MULTISIM_NOT_SUPPORTED_BY_HARDWARE = 1; // 0x1
+ field public static final int NETWORK_SELECTION_MODE_AUTO = 1; // 0x1
+ field public static final int NETWORK_SELECTION_MODE_MANUAL = 2; // 0x2
+ field public static final int NETWORK_SELECTION_MODE_UNKNOWN = 0; // 0x0
field public static final int NETWORK_TYPE_1xRTT = 7; // 0x7
field public static final int NETWORK_TYPE_CDMA = 4; // 0x4
field public static final int NETWORK_TYPE_EDGE = 2; // 0x2
diff --git a/api/module-app-current.txt b/api/module-app-current.txt
index db774ef8ea2e..dadbd79e0e8d 100644
--- a/api/module-app-current.txt
+++ b/api/module-app-current.txt
@@ -9,6 +9,10 @@ package android.app {
package android.provider {
+ public final class DocumentsContract {
+ method @NonNull public static android.net.Uri buildDocumentUriAsUser(@NonNull String, @NonNull String, @NonNull android.os.UserHandle);
+ }
+
public static final class Settings.Global extends android.provider.Settings.NameValueTable {
field public static final String COMMON_CRITERIA_MODE = "common_criteria_mode";
}
diff --git a/api/system-current.txt b/api/system-current.txt
index 0e5d6dd353c7..a6f4e81696a0 100755
--- a/api/system-current.txt
+++ b/api/system-current.txt
@@ -1629,10 +1629,14 @@ package android.bluetooth {
}
public interface BluetoothProfile {
+ field public static final int A2DP_SINK = 11; // 0xb
+ field public static final int AVRCP_CONTROLLER = 12; // 0xc
field public static final int CONNECTION_POLICY_ALLOWED = 100; // 0x64
field public static final int CONNECTION_POLICY_FORBIDDEN = 0; // 0x0
field public static final int CONNECTION_POLICY_UNKNOWN = -1; // 0xffffffff
+ field public static final int HEADSET_CLIENT = 16; // 0x10
field public static final int PAN = 5; // 0x5
+ field public static final int PBAP_CLIENT = 17; // 0x11
field @Deprecated public static final int PRIORITY_OFF = 0; // 0x0
field @Deprecated public static final int PRIORITY_ON = 100; // 0x64
}
@@ -2436,6 +2440,15 @@ package android.content.rollback {
}
+package android.debug {
+
+ public class AdbManager {
+ method @RequiresPermission(android.Manifest.permission.MANAGE_DEBUGGING) public boolean isAdbWifiQrSupported();
+ method @RequiresPermission(android.Manifest.permission.MANAGE_DEBUGGING) public boolean isAdbWifiSupported();
+ }
+
+}
+
package android.hardware {
public final class Sensor {
@@ -4099,17 +4112,24 @@ package android.media {
method public int getAllFlags();
method public android.os.Bundle getBundle();
method public int getCapturePreset();
+ method public int getSystemUsage();
+ method public static boolean isSystemUsage(int);
field public static final int FLAG_BEACON = 8; // 0x8
field public static final int FLAG_BYPASS_INTERRUPTION_POLICY = 64; // 0x40
field public static final int FLAG_BYPASS_MUTE = 128; // 0x80
field public static final int FLAG_HW_HOTWORD = 32; // 0x20
- field @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public static final int USAGE_CALL_ASSISTANT = 17; // 0x11
+ field @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING) public static final int USAGE_ANNOUNCEMENT = 1003; // 0x3eb
+ field @RequiresPermission(allOf={android.Manifest.permission.MODIFY_PHONE_STATE, android.Manifest.permission.MODIFY_AUDIO_ROUTING}) public static final int USAGE_CALL_ASSISTANT = 17; // 0x11
+ field @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING) public static final int USAGE_EMERGENCY = 1000; // 0x3e8
+ field @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING) public static final int USAGE_SAFETY = 1001; // 0x3e9
+ field @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING) public static final int USAGE_VEHICLE_STATUS = 1002; // 0x3ea
}
public static class AudioAttributes.Builder {
method public android.media.AudioAttributes.Builder addBundle(@NonNull android.os.Bundle);
method public android.media.AudioAttributes.Builder setCapturePreset(int);
method public android.media.AudioAttributes.Builder setInternalCapturePreset(int);
+ method @NonNull @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING) public android.media.AudioAttributes.Builder setSystemUsage(int);
}
public final class AudioDeviceAddress implements android.os.Parcelable {
@@ -4160,6 +4180,7 @@ package android.media {
method @IntRange(from=0) @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING) public int getMaxVolumeIndexForAttributes(@NonNull android.media.AudioAttributes);
method @IntRange(from=0) @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING) public int getMinVolumeIndexForAttributes(@NonNull android.media.AudioAttributes);
method @Nullable @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING) public android.media.AudioDeviceAddress getPreferredDeviceForStrategy(@NonNull android.media.audiopolicy.AudioProductStrategy);
+ method @NonNull @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING) public int[] getSupportedSystemUsages();
method @IntRange(from=0) @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING) public int getVolumeIndexForAttributes(@NonNull android.media.AudioAttributes);
method public boolean isAudioServerRunning();
method public boolean isHdmiSystemAudioSupported();
@@ -4172,6 +4193,7 @@ package android.media {
method public void setAudioServerStateCallback(@NonNull java.util.concurrent.Executor, @NonNull android.media.AudioManager.AudioServerStateCallback);
method @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING) public void setFocusRequestResult(@NonNull android.media.AudioFocusInfo, int, @NonNull android.media.audiopolicy.AudioPolicy);
method @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING) public boolean setPreferredDeviceForStrategy(@NonNull android.media.audiopolicy.AudioProductStrategy, @NonNull android.media.AudioDeviceAddress);
+ method @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING) public void setSupportedSystemUsages(@NonNull int[]);
method @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING) public void setVolumeIndexForAttributes(@NonNull android.media.AudioAttributes, int, int);
method @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING) public void unregisterAudioPolicy(@NonNull android.media.audiopolicy.AudioPolicy);
method @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING) public void unregisterAudioPolicyAsync(@NonNull android.media.audiopolicy.AudioPolicy);
@@ -4586,7 +4608,8 @@ package android.media.tv {
}
public final class TvInputManager {
- method @RequiresPermission(android.Manifest.permission.TV_INPUT_HARDWARE) public android.media.tv.TvInputManager.Hardware acquireTvInputHardware(int, android.media.tv.TvInputInfo, android.media.tv.TvInputManager.HardwareCallback);
+ method @RequiresPermission(android.Manifest.permission.TV_INPUT_HARDWARE) public android.media.tv.TvInputManager.Hardware acquireTvInputHardware(int, @NonNull android.media.tv.TvInputInfo, @NonNull android.media.tv.TvInputManager.HardwareCallback);
+ method @Nullable @RequiresPermission(android.Manifest.permission.TV_INPUT_HARDWARE) public android.media.tv.TvInputManager.Hardware acquireTvInputHardware(int, @NonNull android.media.tv.TvInputInfo, @NonNull android.media.tv.TvInputManager.HardwareCallback, @Nullable String, int);
method @RequiresPermission(android.Manifest.permission.MODIFY_PARENTAL_CONTROLS) public void addBlockedRating(@NonNull android.media.tv.TvContentRating);
method @RequiresPermission(android.Manifest.permission.CAPTURE_TV_INPUT) public boolean captureFrame(String, android.view.Surface, android.media.tv.TvStreamConfig);
method @RequiresPermission(android.Manifest.permission.CAPTURE_TV_INPUT) public java.util.List<android.media.tv.TvStreamConfig> getAvailableTvStreamConfigList(String);
@@ -8344,8 +8367,11 @@ package android.os {
method @Nullable @RequiresPermission(allOf={android.Manifest.permission.DUMP, android.Manifest.permission.PACKAGE_USAGE_STATS}) public android.os.IncidentManager.IncidentReport getIncidentReport(android.net.Uri);
method @NonNull @RequiresPermission(allOf={android.Manifest.permission.DUMP, android.Manifest.permission.PACKAGE_USAGE_STATS}) public java.util.List<android.net.Uri> getIncidentReportList(String);
method @RequiresPermission(android.Manifest.permission.APPROVE_INCIDENT_REPORTS) public java.util.List<android.os.IncidentManager.PendingReport> getPendingReports();
+ method public void registerSection(int, @NonNull String, @NonNull android.os.IncidentManager.DumpCallback);
+ method public void registerSection(int, @NonNull String, @NonNull java.util.concurrent.Executor, @NonNull android.os.IncidentManager.DumpCallback);
method @RequiresPermission(allOf={android.Manifest.permission.DUMP, android.Manifest.permission.PACKAGE_USAGE_STATS}) public void reportIncident(android.os.IncidentReportArgs);
method @RequiresPermission("android.permission.REQUEST_INCIDENT_REPORT_APPROVAL") public void requestAuthorization(int, String, int, android.os.IncidentManager.AuthListener);
+ method public void unregisterSection(int);
field public static final int FLAG_CONFIRMATION_DIALOG = 1; // 0x1
field public static final int PRIVACY_POLICY_AUTO = 200; // 0xc8
field public static final int PRIVACY_POLICY_EXPLICIT = 100; // 0x64
@@ -8358,6 +8384,11 @@ package android.os {
method public void onReportDenied();
}
+ public static class IncidentManager.DumpCallback {
+ ctor public IncidentManager.DumpCallback();
+ method public void onDumpSection(int, @NonNull java.io.OutputStream);
+ }
+
public static class IncidentManager.IncidentReport implements java.io.Closeable android.os.Parcelable {
ctor public IncidentManager.IncidentReport(android.os.Parcel);
method public void close();
@@ -11387,7 +11418,7 @@ package android.telephony {
method public void onSrvccStateChanged(int);
method public void onVoiceActivationStateChanged(int);
field @RequiresPermission(android.Manifest.permission.LISTEN_ALWAYS_REPORTED_SIGNAL_STRENGTH) public static final int LISTEN_ALWAYS_REPORTED_SIGNAL_STRENGTH = 512; // 0x200
- field public static final int LISTEN_CALL_ATTRIBUTES_CHANGED = 67108864; // 0x4000000
+ field @RequiresPermission("android.permission.READ_PRECISE_PHONE_STATE") public static final int LISTEN_CALL_ATTRIBUTES_CHANGED = 67108864; // 0x4000000
field @RequiresPermission(android.Manifest.permission.READ_ACTIVE_EMERGENCY_SESSION) public static final int LISTEN_OUTGOING_EMERGENCY_CALL = 268435456; // 0x10000000
field @RequiresPermission(android.Manifest.permission.READ_ACTIVE_EMERGENCY_SESSION) public static final int LISTEN_OUTGOING_EMERGENCY_SMS = 536870912; // 0x20000000
field @RequiresPermission("android.permission.READ_PRECISE_PHONE_STATE") public static final int LISTEN_PRECISE_CALL_STATE = 2048; // 0x800
@@ -11895,6 +11926,7 @@ package android.telephony {
method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public boolean setRadioPower(boolean);
method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void setSimPowerState(int);
method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void setSimPowerStateForSlot(int, int);
+ method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void setSystemSelectionChannels(@NonNull java.util.List<android.telephony.RadioAccessSpecifier>, @Nullable java.util.concurrent.Executor, @Nullable java.util.function.Consumer<java.lang.Boolean>);
method @Deprecated public void setVisualVoicemailEnabled(android.telecom.PhoneAccountHandle, boolean);
method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void setVoiceActivationState(int);
method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void shutdownAllRadios();
@@ -12874,7 +12906,27 @@ package android.telephony.ims {
method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) @WorkerThread public int setProvisioningStringValue(int, @NonNull String);
method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) @WorkerThread public void setRcsProvisioningStatusForCapability(int, boolean);
method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public void unregisterProvisioningChangedCallback(@NonNull android.telephony.ims.ProvisioningManager.Callback);
+ field public static final int KEY_1X_EPDG_TIMER_SEC = 64; // 0x40
+ field public static final int KEY_1X_THRESHOLD = 59; // 0x3b
+ field public static final int KEY_AMR_BANDWIDTH_EFFICIENT_PAYLOAD_TYPE = 50; // 0x32
+ field public static final int KEY_AMR_CODEC_MODE_SET_VALUES = 0; // 0x0
+ field public static final int KEY_AMR_DEFAULT_ENCODING_MODE = 53; // 0x35
+ field public static final int KEY_AMR_OCTET_ALIGNED_PAYLOAD_TYPE = 49; // 0x31
+ field public static final int KEY_AMR_WB_BANDWIDTH_EFFICIENT_PAYLOAD_TYPE = 48; // 0x30
+ field public static final int KEY_AMR_WB_CODEC_MODE_SET_VALUES = 1; // 0x1
+ field public static final int KEY_AMR_WB_OCTET_ALIGNED_PAYLOAD_TYPE = 47; // 0x2f
+ field public static final int KEY_DTMF_NB_PAYLOAD_TYPE = 52; // 0x34
+ field public static final int KEY_DTMF_WB_PAYLOAD_TYPE = 51; // 0x33
field public static final int KEY_EAB_PROVISIONING_STATUS = 25; // 0x19
+ field public static final int KEY_ENABLE_SILENT_REDIAL = 6; // 0x6
+ field public static final int KEY_LOCAL_BREAKOUT_PCSCF_ADDRESS = 31; // 0x1f
+ field public static final int KEY_LTE_EPDG_TIMER_SEC = 62; // 0x3e
+ field public static final int KEY_LTE_THRESHOLD_1 = 56; // 0x38
+ field public static final int KEY_LTE_THRESHOLD_2 = 57; // 0x39
+ field public static final int KEY_LTE_THRESHOLD_3 = 58; // 0x3a
+ field public static final int KEY_MINIMUM_SIP_SESSION_EXPIRATION_TIMER_SEC = 3; // 0x3
+ field public static final int KEY_MOBILE_DATA_ENABLED = 29; // 0x1d
+ field public static final int KEY_MULTIENDPOINT_ENABLED = 65; // 0x41
field public static final int KEY_RCS_AVAILABILITY_CACHE_EXPIRATION_SEC = 19; // 0x13
field public static final int KEY_RCS_CAPABILITIES_CACHE_EXPIRATION_SEC = 18; // 0x12
field public static final int KEY_RCS_CAPABILITIES_POLL_INTERVAL_SEC = 20; // 0x14
@@ -12884,16 +12936,52 @@ package android.telephony.ims {
field public static final int KEY_RCS_PUBLISH_SOURCE_THROTTLE_MS = 21; // 0x15
field public static final int KEY_RCS_PUBLISH_TIMER_EXTENDED_SEC = 16; // 0x10
field public static final int KEY_RCS_PUBLISH_TIMER_SEC = 15; // 0xf
+ field public static final int KEY_REGISTRATION_DOMAIN_NAME = 12; // 0xc
+ field public static final int KEY_REGISTRATION_RETRY_BASE_TIME_SEC = 33; // 0x21
+ field public static final int KEY_REGISTRATION_RETRY_MAX_TIME_SEC = 34; // 0x22
+ field public static final int KEY_RTP_SPEECH_END_PORT = 36; // 0x24
+ field public static final int KEY_RTP_SPEECH_START_PORT = 35; // 0x23
+ field public static final int KEY_RTT_ENABLED = 66; // 0x42
+ field public static final int KEY_SIP_ACK_RECEIPT_WAIT_TIME_MS = 43; // 0x2b
+ field public static final int KEY_SIP_ACK_RETRANSMIT_WAIT_TIME_MS = 44; // 0x2c
+ field public static final int KEY_SIP_INVITE_ACK_WAIT_TIME_MS = 38; // 0x26
+ field public static final int KEY_SIP_INVITE_CANCELLATION_TIMER_MS = 4; // 0x4
+ field public static final int KEY_SIP_INVITE_REQUEST_TRANSMIT_INTERVAL_MS = 37; // 0x25
+ field public static final int KEY_SIP_INVITE_RESPONSE_RETRANSMIT_INTERVAL_MS = 42; // 0x2a
+ field public static final int KEY_SIP_INVITE_RESPONSE_RETRANSMIT_WAIT_TIME_MS = 39; // 0x27
+ field public static final int KEY_SIP_KEEP_ALIVE_ENABLED = 32; // 0x20
+ field public static final int KEY_SIP_NON_INVITE_REQUEST_RETRANSMISSION_WAIT_TIME_MS = 45; // 0x2d
+ field public static final int KEY_SIP_NON_INVITE_REQUEST_RETRANSMIT_INTERVAL_MS = 40; // 0x28
+ field public static final int KEY_SIP_NON_INVITE_RESPONSE_RETRANSMISSION_WAIT_TIME_MS = 46; // 0x2e
+ field public static final int KEY_SIP_NON_INVITE_TRANSACTION_TIMEOUT_TIMER_MS = 41; // 0x29
+ field public static final int KEY_SIP_SESSION_TIMER_SEC = 2; // 0x2
+ field public static final int KEY_SMS_FORMAT = 13; // 0xd
+ field public static final int KEY_SMS_OVER_IP_ENABLED = 14; // 0xe
+ field public static final int KEY_SMS_PUBLIC_SERVICE_IDENTITY = 54; // 0x36
field public static final int KEY_T1_TIMER_VALUE_MS = 7; // 0x7
+ field public static final int KEY_T2_TIMER_VALUE_MS = 8; // 0x8
+ field public static final int KEY_TF_TIMER_VALUE_MS = 9; // 0x9
+ field public static final int KEY_TRANSITION_TO_LTE_DELAY_MS = 5; // 0x5
+ field public static final int KEY_USE_GZIP_FOR_LIST_SUBSCRIPTION = 24; // 0x18
+ field public static final int KEY_VIDEO_QUALITY = 55; // 0x37
+ field public static final int KEY_VOICE_OVER_WIFI_ENABLED_OVERRIDE = 28; // 0x1c
field public static final int KEY_VOICE_OVER_WIFI_MODE_OVERRIDE = 27; // 0x1b
field public static final int KEY_VOICE_OVER_WIFI_ROAMING_ENABLED_OVERRIDE = 26; // 0x1a
field public static final int KEY_VOLTE_PROVISIONING_STATUS = 10; // 0xa
+ field public static final int KEY_VOLTE_USER_OPT_IN_STATUS = 30; // 0x1e
field public static final int KEY_VT_PROVISIONING_STATUS = 11; // 0xb
+ field public static final int KEY_WIFI_EPDG_TIMER_SEC = 63; // 0x3f
+ field public static final int KEY_WIFI_THRESHOLD_A = 60; // 0x3c
+ field public static final int KEY_WIFI_THRESHOLD_B = 61; // 0x3d
field public static final int PROVISIONING_RESULT_UNKNOWN = -1; // 0xffffffff
field public static final int PROVISIONING_VALUE_DISABLED = 0; // 0x0
field public static final int PROVISIONING_VALUE_ENABLED = 1; // 0x1
+ field public static final int SMS_FORMAT_3GPP = 1; // 0x1
+ field public static final int SMS_FORMAT_3GPP2 = 0; // 0x0
field public static final String STRING_QUERY_RESULT_ERROR_GENERIC = "STRING_QUERY_RESULT_ERROR_GENERIC";
field public static final String STRING_QUERY_RESULT_ERROR_NOT_READY = "STRING_QUERY_RESULT_ERROR_NOT_READY";
+ field public static final int VIDEO_QUALITY_HIGH = 1; // 0x1
+ field public static final int VIDEO_QUALITY_LOW = 0; // 0x0
}
public static class ProvisioningManager.Callback {
diff --git a/api/test-current.txt b/api/test-current.txt
index 7a58da45bad0..ccadb06bc936 100644
--- a/api/test-current.txt
+++ b/api/test-current.txt
@@ -2037,8 +2037,11 @@ package android.os {
method @Nullable @RequiresPermission(allOf={android.Manifest.permission.DUMP, android.Manifest.permission.PACKAGE_USAGE_STATS}) public android.os.IncidentManager.IncidentReport getIncidentReport(android.net.Uri);
method @NonNull @RequiresPermission(allOf={android.Manifest.permission.DUMP, android.Manifest.permission.PACKAGE_USAGE_STATS}) public java.util.List<android.net.Uri> getIncidentReportList(String);
method @RequiresPermission(android.Manifest.permission.APPROVE_INCIDENT_REPORTS) public java.util.List<android.os.IncidentManager.PendingReport> getPendingReports();
+ method public void registerSection(int, @NonNull String, @NonNull android.os.IncidentManager.DumpCallback);
+ method public void registerSection(int, @NonNull String, @NonNull java.util.concurrent.Executor, @NonNull android.os.IncidentManager.DumpCallback);
method @RequiresPermission(allOf={android.Manifest.permission.DUMP, android.Manifest.permission.PACKAGE_USAGE_STATS}) public void reportIncident(android.os.IncidentReportArgs);
method @RequiresPermission("android.permission.REQUEST_INCIDENT_REPORT_APPROVAL") public void requestAuthorization(int, String, int, android.os.IncidentManager.AuthListener);
+ method public void unregisterSection(int);
field public static final int FLAG_CONFIRMATION_DIALOG = 1; // 0x1
field public static final int PRIVACY_POLICY_AUTO = 200; // 0xc8
field public static final int PRIVACY_POLICY_EXPLICIT = 100; // 0x64
@@ -2051,6 +2054,11 @@ package android.os {
method public void onReportDenied();
}
+ public static class IncidentManager.DumpCallback {
+ ctor public IncidentManager.DumpCallback();
+ method public void onDumpSection(int, @NonNull java.io.OutputStream);
+ }
+
public static class IncidentManager.IncidentReport implements java.io.Closeable android.os.Parcelable {
ctor public IncidentManager.IncidentReport(android.os.Parcel);
method public void close();
@@ -3318,6 +3326,7 @@ package android.telephony {
method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void refreshUiccProfile();
method @Deprecated public void setCarrierTestOverride(String, String, String, String, String, String, String);
method public void setCarrierTestOverride(String, String, String, String, String, String, String, String, String);
+ method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void setSystemSelectionChannels(@NonNull java.util.List<android.telephony.RadioAccessSpecifier>, @Nullable java.util.concurrent.Executor, @Nullable java.util.function.Consumer<java.lang.Boolean>);
method @RequiresPermission("android.permission.READ_ACTIVE_EMERGENCY_SESSION") public void updateTestOtaEmergencyNumberDbFilePath(@NonNull String);
field public static final int CARRIER_PRIVILEGE_STATUS_ERROR_LOADING_RULES = -2; // 0xfffffffe
field public static final int CARRIER_PRIVILEGE_STATUS_HAS_ACCESS = 1; // 0x1
@@ -3826,7 +3835,27 @@ package android.telephony.ims {
method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) @WorkerThread public int setProvisioningStringValue(int, @NonNull String);
method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) @WorkerThread public void setRcsProvisioningStatusForCapability(int, boolean);
method @RequiresPermission("android.permission.READ_PRIVILEGED_PHONE_STATE") public void unregisterProvisioningChangedCallback(@NonNull android.telephony.ims.ProvisioningManager.Callback);
+ field public static final int KEY_1X_EPDG_TIMER_SEC = 64; // 0x40
+ field public static final int KEY_1X_THRESHOLD = 59; // 0x3b
+ field public static final int KEY_AMR_BANDWIDTH_EFFICIENT_PAYLOAD_TYPE = 50; // 0x32
+ field public static final int KEY_AMR_CODEC_MODE_SET_VALUES = 0; // 0x0
+ field public static final int KEY_AMR_DEFAULT_ENCODING_MODE = 53; // 0x35
+ field public static final int KEY_AMR_OCTET_ALIGNED_PAYLOAD_TYPE = 49; // 0x31
+ field public static final int KEY_AMR_WB_BANDWIDTH_EFFICIENT_PAYLOAD_TYPE = 48; // 0x30
+ field public static final int KEY_AMR_WB_CODEC_MODE_SET_VALUES = 1; // 0x1
+ field public static final int KEY_AMR_WB_OCTET_ALIGNED_PAYLOAD_TYPE = 47; // 0x2f
+ field public static final int KEY_DTMF_NB_PAYLOAD_TYPE = 52; // 0x34
+ field public static final int KEY_DTMF_WB_PAYLOAD_TYPE = 51; // 0x33
field public static final int KEY_EAB_PROVISIONING_STATUS = 25; // 0x19
+ field public static final int KEY_ENABLE_SILENT_REDIAL = 6; // 0x6
+ field public static final int KEY_LOCAL_BREAKOUT_PCSCF_ADDRESS = 31; // 0x1f
+ field public static final int KEY_LTE_EPDG_TIMER_SEC = 62; // 0x3e
+ field public static final int KEY_LTE_THRESHOLD_1 = 56; // 0x38
+ field public static final int KEY_LTE_THRESHOLD_2 = 57; // 0x39
+ field public static final int KEY_LTE_THRESHOLD_3 = 58; // 0x3a
+ field public static final int KEY_MINIMUM_SIP_SESSION_EXPIRATION_TIMER_SEC = 3; // 0x3
+ field public static final int KEY_MOBILE_DATA_ENABLED = 29; // 0x1d
+ field public static final int KEY_MULTIENDPOINT_ENABLED = 65; // 0x41
field public static final int KEY_RCS_AVAILABILITY_CACHE_EXPIRATION_SEC = 19; // 0x13
field public static final int KEY_RCS_CAPABILITIES_CACHE_EXPIRATION_SEC = 18; // 0x12
field public static final int KEY_RCS_CAPABILITIES_POLL_INTERVAL_SEC = 20; // 0x14
@@ -3836,16 +3865,52 @@ package android.telephony.ims {
field public static final int KEY_RCS_PUBLISH_SOURCE_THROTTLE_MS = 21; // 0x15
field public static final int KEY_RCS_PUBLISH_TIMER_EXTENDED_SEC = 16; // 0x10
field public static final int KEY_RCS_PUBLISH_TIMER_SEC = 15; // 0xf
+ field public static final int KEY_REGISTRATION_DOMAIN_NAME = 12; // 0xc
+ field public static final int KEY_REGISTRATION_RETRY_BASE_TIME_SEC = 33; // 0x21
+ field public static final int KEY_REGISTRATION_RETRY_MAX_TIME_SEC = 34; // 0x22
+ field public static final int KEY_RTP_SPEECH_END_PORT = 36; // 0x24
+ field public static final int KEY_RTP_SPEECH_START_PORT = 35; // 0x23
+ field public static final int KEY_RTT_ENABLED = 66; // 0x42
+ field public static final int KEY_SIP_ACK_RECEIPT_WAIT_TIME_MS = 43; // 0x2b
+ field public static final int KEY_SIP_ACK_RETRANSMIT_WAIT_TIME_MS = 44; // 0x2c
+ field public static final int KEY_SIP_INVITE_ACK_WAIT_TIME_MS = 38; // 0x26
+ field public static final int KEY_SIP_INVITE_CANCELLATION_TIMER_MS = 4; // 0x4
+ field public static final int KEY_SIP_INVITE_REQUEST_TRANSMIT_INTERVAL_MS = 37; // 0x25
+ field public static final int KEY_SIP_INVITE_RESPONSE_RETRANSMIT_INTERVAL_MS = 42; // 0x2a
+ field public static final int KEY_SIP_INVITE_RESPONSE_RETRANSMIT_WAIT_TIME_MS = 39; // 0x27
+ field public static final int KEY_SIP_KEEP_ALIVE_ENABLED = 32; // 0x20
+ field public static final int KEY_SIP_NON_INVITE_REQUEST_RETRANSMISSION_WAIT_TIME_MS = 45; // 0x2d
+ field public static final int KEY_SIP_NON_INVITE_REQUEST_RETRANSMIT_INTERVAL_MS = 40; // 0x28
+ field public static final int KEY_SIP_NON_INVITE_RESPONSE_RETRANSMISSION_WAIT_TIME_MS = 46; // 0x2e
+ field public static final int KEY_SIP_NON_INVITE_TRANSACTION_TIMEOUT_TIMER_MS = 41; // 0x29
+ field public static final int KEY_SIP_SESSION_TIMER_SEC = 2; // 0x2
+ field public static final int KEY_SMS_FORMAT = 13; // 0xd
+ field public static final int KEY_SMS_OVER_IP_ENABLED = 14; // 0xe
+ field public static final int KEY_SMS_PUBLIC_SERVICE_IDENTITY = 54; // 0x36
field public static final int KEY_T1_TIMER_VALUE_MS = 7; // 0x7
+ field public static final int KEY_T2_TIMER_VALUE_MS = 8; // 0x8
+ field public static final int KEY_TF_TIMER_VALUE_MS = 9; // 0x9
+ field public static final int KEY_TRANSITION_TO_LTE_DELAY_MS = 5; // 0x5
+ field public static final int KEY_USE_GZIP_FOR_LIST_SUBSCRIPTION = 24; // 0x18
+ field public static final int KEY_VIDEO_QUALITY = 55; // 0x37
+ field public static final int KEY_VOICE_OVER_WIFI_ENABLED_OVERRIDE = 28; // 0x1c
field public static final int KEY_VOICE_OVER_WIFI_MODE_OVERRIDE = 27; // 0x1b
field public static final int KEY_VOICE_OVER_WIFI_ROAMING_ENABLED_OVERRIDE = 26; // 0x1a
field public static final int KEY_VOLTE_PROVISIONING_STATUS = 10; // 0xa
+ field public static final int KEY_VOLTE_USER_OPT_IN_STATUS = 30; // 0x1e
field public static final int KEY_VT_PROVISIONING_STATUS = 11; // 0xb
+ field public static final int KEY_WIFI_EPDG_TIMER_SEC = 63; // 0x3f
+ field public static final int KEY_WIFI_THRESHOLD_A = 60; // 0x3c
+ field public static final int KEY_WIFI_THRESHOLD_B = 61; // 0x3d
field public static final int PROVISIONING_RESULT_UNKNOWN = -1; // 0xffffffff
field public static final int PROVISIONING_VALUE_DISABLED = 0; // 0x0
field public static final int PROVISIONING_VALUE_ENABLED = 1; // 0x1
+ field public static final int SMS_FORMAT_3GPP = 1; // 0x1
+ field public static final int SMS_FORMAT_3GPP2 = 0; // 0x0
field public static final String STRING_QUERY_RESULT_ERROR_GENERIC = "STRING_QUERY_RESULT_ERROR_GENERIC";
field public static final String STRING_QUERY_RESULT_ERROR_NOT_READY = "STRING_QUERY_RESULT_ERROR_NOT_READY";
+ field public static final int VIDEO_QUALITY_HIGH = 1; // 0x1
+ field public static final int VIDEO_QUALITY_LOW = 0; // 0x0
}
public static class ProvisioningManager.Callback {
diff --git a/cmds/incidentd/src/IncidentService.cpp b/cmds/incidentd/src/IncidentService.cpp
index 62312d1cccaa..6c2b8551bf73 100644
--- a/cmds/incidentd/src/IncidentService.cpp
+++ b/cmds/incidentd/src/IncidentService.cpp
@@ -350,11 +350,11 @@ Status IncidentService::reportIncidentToDumpstate(unique_fd stream,
Status IncidentService::registerSection(const int id, const String16& name16,
const sp<IIncidentDumpCallback>& callback) {
const char* name = String8(name16).c_str();
- ALOGI("Register section %d: %s", id, name);
+ const uid_t callingUid = IPCThreadState::self()->getCallingUid();
+ ALOGI("Uid %d registers section %d '%s'", callingUid, id, name);
if (callback == nullptr) {
return Status::fromExceptionCode(Status::EX_NULL_POINTER);
}
- const uid_t callingUid = IPCThreadState::self()->getCallingUid();
for (int i = 0; i < mRegisteredSections.size(); i++) {
if (mRegisteredSections.at(i)->id == id) {
if (mRegisteredSections.at(i)->uid != callingUid) {
@@ -370,8 +370,9 @@ Status IncidentService::registerSection(const int id, const String16& name16,
}
Status IncidentService::unregisterSection(const int id) {
- ALOGI("Unregister section %d", id);
uid_t callingUid = IPCThreadState::self()->getCallingUid();
+ ALOGI("Uid %d unregisters section %d", callingUid, id);
+
for (auto it = mRegisteredSections.begin(); it != mRegisteredSections.end(); it++) {
if ((*it)->id == id) {
if ((*it)->uid != callingUid) {
diff --git a/cmds/statsd/Android.bp b/cmds/statsd/Android.bp
index 6eafbd8bb3f1..080b1af35059 100644
--- a/cmds/statsd/Android.bp
+++ b/cmds/statsd/Android.bp
@@ -73,7 +73,6 @@ cc_defaults {
"src/external/puller_util.cpp",
"src/external/ResourceHealthManagerPuller.cpp",
"src/external/StatsCallbackPuller.cpp",
- "src/external/StatsCompanionServicePuller.cpp",
"src/external/StatsPuller.cpp",
"src/external/StatsPullerManager.cpp",
"src/external/SubsystemSleepStatePuller.cpp",
diff --git a/cmds/statsd/src/external/StatsCompanionServicePuller.cpp b/cmds/statsd/src/external/StatsCompanionServicePuller.cpp
deleted file mode 100644
index f37d2bedf8c2..000000000000
--- a/cmds/statsd/src/external/StatsCompanionServicePuller.cpp
+++ /dev/null
@@ -1,78 +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.
- */
-
-#define DEBUG false
-#include "Log.h"
-
-#include <android/os/IStatsCompanionService.h>
-#include <binder/IPCThreadState.h>
-#include <private/android_filesystem_config.h>
-#include "../stats_log_util.h"
-#include "../statscompanion_util.h"
-#include "StatsCompanionServicePuller.h"
-
-using namespace android;
-using namespace android::base;
-using namespace android::binder;
-using namespace android::os;
-using std::make_shared;
-using std::shared_ptr;
-using std::vector;
-
-namespace android {
-namespace os {
-namespace statsd {
-
-// The reading and parsing are implemented in Java. It is not difficult to port over. But for now
-// let StatsCompanionService handle that and send the data back.
-StatsCompanionServicePuller::StatsCompanionServicePuller(int tagId) : StatsPuller(tagId) {
-}
-
-void StatsCompanionServicePuller::SetStatsCompanionService(
- sp<IStatsCompanionService> statsCompanionService) {
- AutoMutex _l(mStatsCompanionServiceLock);
- sp<IStatsCompanionService> tmpForLock = mStatsCompanionService;
- mStatsCompanionService = statsCompanionService;
-}
-
-bool StatsCompanionServicePuller::PullInternal(vector<shared_ptr<LogEvent> >* data) {
- sp<IStatsCompanionService> statsCompanionServiceCopy = mStatsCompanionService;
- if (statsCompanionServiceCopy != nullptr) {
- vector<StatsLogEventWrapper> returned_value;
- Status status = statsCompanionServiceCopy->pullData(mTagId, &returned_value);
- if (!status.isOk()) {
- ALOGW("StatsCompanionServicePuller::pull failed for %d", mTagId);
- StatsdStats::getInstance().noteStatsCompanionPullFailed(mTagId);
- if (status.exceptionCode() == Status::Exception::EX_TRANSACTION_FAILED) {
- StatsdStats::getInstance().noteStatsCompanionPullBinderTransactionFailed(mTagId);
- }
- return false;
- }
- data->clear();
- for (const StatsLogEventWrapper& it : returned_value) {
- LogEvent::createLogEvents(it, *data);
- }
- VLOG("StatsCompanionServicePuller::pull succeeded for %d", mTagId);
- return true;
- } else {
- ALOGW("statsCompanion not found!");
- return false;
- }
-}
-
-} // namespace statsd
-} // namespace os
-} // namespace android
diff --git a/cmds/statsd/src/external/StatsCompanionServicePuller.h b/cmds/statsd/src/external/StatsCompanionServicePuller.h
deleted file mode 100644
index 2e133207f01d..000000000000
--- a/cmds/statsd/src/external/StatsCompanionServicePuller.h
+++ /dev/null
@@ -1,40 +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.
- */
-
-#pragma once
-
-#include <utils/String16.h>
-#include "StatsPuller.h"
-
-namespace android {
-namespace os {
-namespace statsd {
-
-class StatsCompanionServicePuller : public StatsPuller {
-public:
- explicit StatsCompanionServicePuller(int tagId);
-
- void SetStatsCompanionService(sp<IStatsCompanionService> statsCompanionService) override;
-
-private:
- Mutex mStatsCompanionServiceLock;
- sp<IStatsCompanionService> mStatsCompanionService = nullptr;
- bool PullInternal(vector<std::shared_ptr<LogEvent> >* data) override;
-};
-
-} // namespace statsd
-} // namespace os
-} // namespace android
diff --git a/cmds/statsd/src/external/StatsPullerManager.cpp b/cmds/statsd/src/external/StatsPullerManager.cpp
index 16a65e293219..8d67b5c169f5 100644
--- a/cmds/statsd/src/external/StatsPullerManager.cpp
+++ b/cmds/statsd/src/external/StatsPullerManager.cpp
@@ -37,7 +37,6 @@
#include "PowerStatsPuller.h"
#include "ResourceHealthManagerPuller.h"
#include "StatsCallbackPuller.h"
-#include "StatsCompanionServicePuller.h"
#include "SubsystemSleepStatePuller.h"
#include "TrainInfoPuller.h"
#include "statslog.h"
@@ -86,16 +85,6 @@ std::map<PullerKey, PullAtomInfo> StatsPullerManager::kAllPullAtomInfo = {
{{.atomTag = android::util::BATTERY_CYCLE_COUNT},
{.puller = new ResourceHealthManagerPuller(android::util::BATTERY_CYCLE_COUNT)}},
- // DebugElapsedClock.
- {{.atomTag = android::util::DEBUG_ELAPSED_CLOCK},
- {.additiveFields = {1, 2, 3, 4},
- .puller = new StatsCompanionServicePuller(android::util::DEBUG_ELAPSED_CLOCK)}},
-
- // DebugFailingElapsedClock.
- {{.atomTag = android::util::DEBUG_FAILING_ELAPSED_CLOCK},
- {.additiveFields = {1, 2, 3, 4},
- .puller = new StatsCompanionServicePuller(android::util::DEBUG_FAILING_ELAPSED_CLOCK)}},
-
// TrainInfo.
{{.atomTag = android::util::TRAIN_INFO}, {.puller = new TrainInfoPuller()}},
diff --git a/core/java/android/bluetooth/BluetoothProfile.java b/core/java/android/bluetooth/BluetoothProfile.java
index 638e6de06be7..7538df8bbe5f 100644
--- a/core/java/android/bluetooth/BluetoothProfile.java
+++ b/core/java/android/bluetooth/BluetoothProfile.java
@@ -146,7 +146,7 @@ public interface BluetoothProfile {
*
* @hide
*/
- @UnsupportedAppUsage
+ @SystemApi
int A2DP_SINK = 11;
/**
@@ -154,7 +154,7 @@ public interface BluetoothProfile {
*
* @hide
*/
- @UnsupportedAppUsage
+ @SystemApi
int AVRCP_CONTROLLER = 12;
/**
@@ -169,6 +169,7 @@ public interface BluetoothProfile {
*
* @hide
*/
+ @SystemApi
int HEADSET_CLIENT = 16;
/**
@@ -176,6 +177,7 @@ public interface BluetoothProfile {
*
* @hide
*/
+ @SystemApi
int PBAP_CLIENT = 17;
/**
diff --git a/core/java/android/content/pm/CrossProfileApps.java b/core/java/android/content/pm/CrossProfileApps.java
index 5aa9c9bebc2c..48f473018127 100644
--- a/core/java/android/content/pm/CrossProfileApps.java
+++ b/core/java/android/content/pm/CrossProfileApps.java
@@ -94,6 +94,32 @@ public class CrossProfileApps {
}
/**
+ * Starts the specified activity of the caller package in the specified profile.
+ *
+ * <p>The caller must have the {@link android.Manifest.permission#INTERACT_ACROSS_PROFILES}
+ * permission and both the caller and target user profiles must be in the same profile group.
+ *
+ * @param intent The intent to launch. A component in the caller package must be specified.
+ * @param targetUser The {@link UserHandle} of the profile; must be one of the users returned by
+ * {@link #getTargetUserProfiles()} if different to the calling user, otherwise a
+ * {@link SecurityException} will be thrown.
+ */
+ @RequiresPermission(anyOf = {
+ android.Manifest.permission.INTERACT_ACROSS_PROFILES,
+ android.Manifest.permission.INTERACT_ACROSS_USERS})
+ public void startActivity(@NonNull Intent intent, @NonNull UserHandle targetUser) {
+ try {
+ mService.startActivityAsUserByIntent(
+ mContext.getIApplicationThread(),
+ mContext.getPackageName(),
+ intent,
+ targetUser.getIdentifier());
+ } catch (RemoteException ex) {
+ throw ex.rethrowFromSystemServer();
+ }
+ }
+
+ /**
* Starts the specified activity of the caller package in the specified profile. Unlike
* {@link #startMainActivity}, this can start any activity of the caller package, not just
* the main activity.
diff --git a/core/java/android/content/pm/ICrossProfileApps.aidl b/core/java/android/content/pm/ICrossProfileApps.aidl
index 694b1a3c4e73..755950cd5ebe 100644
--- a/core/java/android/content/pm/ICrossProfileApps.aidl
+++ b/core/java/android/content/pm/ICrossProfileApps.aidl
@@ -29,6 +29,8 @@ import android.os.UserHandle;
interface ICrossProfileApps {
void startActivityAsUser(in IApplicationThread caller, in String callingPackage,
in ComponentName component, int userId, boolean launchMainActivity);
+ void startActivityAsUserByIntent(in IApplicationThread caller, in String callingPackage,
+ in Intent intent, int userId);
List<UserHandle> getTargetUserProfiles(in String callingPackage);
boolean canInteractAcrossProfiles(in String callingPackage);
boolean canRequestInteractAcrossProfiles(in String callingPackage);
diff --git a/core/java/android/content/pm/PackageManager.java b/core/java/android/content/pm/PackageManager.java
index 925d70cdc855..6694335f264c 100644
--- a/core/java/android/content/pm/PackageManager.java
+++ b/core/java/android/content/pm/PackageManager.java
@@ -50,6 +50,7 @@ import android.content.pm.dex.ArtManager;
import android.content.res.Resources;
import android.content.res.XmlResourceParser;
import android.graphics.Rect;
+import android.graphics.drawable.AdaptiveIconDrawable;
import android.graphics.drawable.Drawable;
import android.net.wifi.WifiManager;
import android.os.Build;
@@ -1948,6 +1949,13 @@ public abstract class PackageManager {
@SdkConstant(SdkConstantType.FEATURE)
public static final String FEATURE_CONSUMER_IR = "android.hardware.consumerir";
+ /**
+ * Feature for {@link #getSystemAvailableFeatures} and
+ * {@link #hasSystemFeature}: The device supports a Context Hub.
+ */
+ @SdkConstant(SdkConstantType.FEATURE)
+ public static final String FEATURE_CONTEXTHUB = "android.hardware.context_hub";
+
/** {@hide} */
@SdkConstant(SdkConstantType.FEATURE)
public static final String FEATURE_CTS = "android.software.cts";
@@ -7612,4 +7620,19 @@ public abstract class PackageManager {
"sendDeviceCustomizationReadyBroadcast not implemented in subclass");
}
+ /**
+ * Returns if the provided drawable represents the default activity icon provided by the system.
+ *
+ * PackageManager provides a default icon for any package/activity if the app itself does not
+ * define one or if the system encountered any error when loading the icon.
+ *
+ * @return true if the drawable represents the default activity icon, false otherwise
+ * @see #getDefaultActivityIcon()
+ */
+ public boolean isDefaultApplicationIcon(@NonNull Drawable drawable) {
+ int resId = drawable instanceof AdaptiveIconDrawable
+ ? ((AdaptiveIconDrawable) drawable).getSourceDrawableResId() : Resources.ID_NULL;
+ return resId == com.android.internal.R.drawable.sym_def_app_icon
+ || resId == com.android.internal.R.drawable.sym_app_on_sd_unavailable_icon;
+ }
}
diff --git a/core/java/android/debug/AdbManager.java b/core/java/android/debug/AdbManager.java
index ae3d79490c98..0a76bedcd66e 100644
--- a/core/java/android/debug/AdbManager.java
+++ b/core/java/android/debug/AdbManager.java
@@ -16,15 +16,17 @@
package android.debug;
+import android.annotation.RequiresPermission;
+import android.annotation.SystemApi;
import android.annotation.SystemService;
import android.content.Context;
+import android.os.RemoteException;
/**
- * This class allows the control of ADB-related functions. Currently only ADB over USB is
- * supported, and none of the API is public.
- *
+ * This class allows the control of ADB-related functions.
* @hide
*/
+@SystemApi
@SystemService(Context.ADB_SERVICE)
public class AdbManager {
private static final String TAG = "AdbManager";
@@ -39,4 +41,33 @@ public class AdbManager {
mContext = context;
mService = service;
}
+
+ /**
+ * @return true if the device supports secure ADB over Wi-Fi.
+ * @hide
+ */
+ @SystemApi
+ @RequiresPermission(android.Manifest.permission.MANAGE_DEBUGGING)
+ public boolean isAdbWifiSupported() {
+ try {
+ return mService.isAdbWifiSupported();
+ } catch (RemoteException e) {
+ throw e.rethrowFromSystemServer();
+ }
+ }
+
+ /**
+ * @return true if the device supports secure ADB over Wi-Fi and device pairing by
+ * QR code.
+ * @hide
+ */
+ @SystemApi
+ @RequiresPermission(android.Manifest.permission.MANAGE_DEBUGGING)
+ public boolean isAdbWifiQrSupported() {
+ try {
+ return mService.isAdbWifiQrSupported();
+ } catch (RemoteException e) {
+ throw e.rethrowFromSystemServer();
+ }
+ }
}
diff --git a/core/java/android/debug/IAdbManager.aidl b/core/java/android/debug/IAdbManager.aidl
index 79e0794fd9af..c48fc07791c0 100644
--- a/core/java/android/debug/IAdbManager.aidl
+++ b/core/java/android/debug/IAdbManager.aidl
@@ -41,4 +41,15 @@ interface IAdbManager {
* Clear all public keys installed for secure ADB debugging.
*/
void clearDebuggingKeys();
+
+ /**
+ * Returns true if device supports secure Adb over Wi-Fi.
+ */
+ boolean isAdbWifiSupported();
+
+ /**
+ * Returns true if device supports secure Adb over Wi-Fi and device pairing by
+ * QR code.
+ */
+ boolean isAdbWifiQrSupported();
}
diff --git a/core/java/android/hardware/camera2/CameraCaptureSession.java b/core/java/android/hardware/camera2/CameraCaptureSession.java
index bc7ab476b01b..2e48ce955a90 100644
--- a/core/java/android/hardware/camera2/CameraCaptureSession.java
+++ b/core/java/android/hardware/camera2/CameraCaptureSession.java
@@ -19,10 +19,13 @@ package android.hardware.camera2;
import android.annotation.CallbackExecutor;
import android.annotation.NonNull;
import android.annotation.Nullable;
+import android.hardware.camera2.CameraOfflineSession;
+import android.hardware.camera2.CameraOfflineSession.CameraOfflineSessionCallback;
import android.hardware.camera2.params.OutputConfiguration;
import android.os.Handler;
import android.view.Surface;
+import java.util.Collection;
import java.util.List;
import java.util.concurrent.Executor;
@@ -855,6 +858,97 @@ public abstract class CameraCaptureSession implements AutoCloseable {
}
/**
+ * Switch the current capture session and a given set of registered camera surfaces
+ * to offline processing mode.
+ *
+ * <p>Offline processing mode and the corresponding {@link CameraOfflineSession} differ from
+ * a regular online camera capture session in several ways. Successful offline switches will
+ * close the currently active camera capture session. Camera clients are also allowed
+ * to call {@link CameraDevice#close} while offline processing of selected capture
+ * requests is still in progress. Such side effects free device close is only possible
+ * when the offline session moves to the ready state. Once this happens, closing the camera
+ * device will not affect the pending offline requests and they must complete as normal.</p>
+ *
+ * <p>Offline processing mode switches may need several hundred milliseconds to complete
+ * as the underlying camera implementation must abort all currently active repeating requests
+ * as well as all other pending requests not specified by the client. Additionally the switch
+ * will be blocked until all requests that continue processing within the offline session
+ * acquire their initial input frame from camera sensor. The call to {@link #switchToOffline}
+ * itself is not blocking and will only trigger the offline switch sequence. Clients will
+ * be notified via {@link CameraOfflineSessionCallback#onReady} once the entire sequence is
+ * complete.</p>
+ *
+ * <p>Please note that after a successful call to this method the currently active capture
+ * session will no longer be valid and clients will begin receiving capture
+ * callbacks with a corresponding {@link CameraOfflineSession} passed as a session
+ * argument.</p>
+ *
+ * @param offlineSurfaces Client-specified collection of input/output camera registered surfaces
+ * that need to be switched to offline mode along with their pending
+ * capture requests. Do note that not all camera registered
+ * surfaces can be switched to offline mode. Offline processing
+ * support for individual surfaces can be queried using
+ * {@link #supportsOfflineProcessing}. Additionally offline mode
+ * switches are not available for shared surfaces
+ * {@link OutputConfiguration#enableSurfaceSharing} and surfaces
+ * as part of a surface group.
+ *
+ * @param executor The executor which will be used for invoking the offline callback listener.
+ *
+ * @param listener The callback object to notify for offline session events.
+ *
+ * @return camera offline session which in case of successful offline switch will move in ready
+ * state after clients receive {@link CameraOfflineSessionCallback#onReady}. In case the
+ * offline switch was not successful clients will receive respective
+ * {@link CameraOfflineSessionCallback#onSwitchFailed} notification.
+ *
+ * @throws IllegalArgumentException if an attempt was made to pass a {@link Surface} that was
+ * not registered with this capture session or a shared
+ * surface {@link OutputConfiguration#enableSurfaceSharing} or
+ * surface as part of a surface group. The current capture
+ * session will remain valid and active in case of this
+ * exception.
+ *
+ * @throws CameraAccessException if the camera device is no longer connected or has
+ * encountered a fatal error.
+ *
+ * @see CameraOfflineSession
+ * @see CameraOfflineSessionCallback
+ * @see #supportsOfflineProcessing
+ */
+ @Nullable
+ public CameraOfflineSession switchToOffline(@NonNull Collection<Surface> offlineSurfaces,
+ @NonNull Executor executor, @NonNull CameraOfflineSessionCallback listener)
+ throws CameraAccessException {
+ throw new UnsupportedOperationException("Subclasses must override this method");
+ }
+
+ /**
+ * <p>Query whether a given Surface is able to support offline mode. </p>
+ *
+ * <p>Surfaces that support offline mode can be passed as arguments to {@link #switchToOffline}.
+ * </p>
+ *
+ * @param surface An input/output surface that was used to create this session or the result of
+ * {@link #getInputSurface}.
+ *
+ * @return {@code true} if the surface can support offline mode and can be passed as argument to
+ * {@link #switchToOffline}. {@code false} otherwise.
+ *
+ * @throws IllegalArgumentException if an attempt was made to pass a {@link Surface} that was
+ * not registered with this capture session.
+ * @throws UnsupportedOperationException if an attempt was made to call this method using
+ * unsupported camera capture session like
+ * {@link CameraConstrainedHighSpeedCaptureSession} or
+ * {@link CameraOfflineSession}.
+ *
+ * @see #switchToOffline
+ */
+ public boolean supportsOfflineProcessing(@NonNull Surface surface) {
+ throw new UnsupportedOperationException("Subclasses must override this method");
+ }
+
+ /**
* Close this capture session asynchronously.
*
* <p>Closing a session frees up the target output Surfaces of the session for reuse with either
diff --git a/core/java/android/hardware/camera2/CameraOfflineSession.java b/core/java/android/hardware/camera2/CameraOfflineSession.java
new file mode 100644
index 000000000000..312559c6c7df
--- /dev/null
+++ b/core/java/android/hardware/camera2/CameraOfflineSession.java
@@ -0,0 +1,159 @@
+/*
+ * Copyright 2019 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 android.hardware.camera2;
+
+import android.hardware.camera2.CameraCaptureSession;
+import android.hardware.camera2.CameraDevice;
+
+import android.annotation.IntDef;
+import android.annotation.NonNull;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+
+/**
+ * A camera capture session that was switched to offline mode via successful call to
+ * {@link CameraCaptureSession#switchToOffline}.
+ *
+ * <p>Offline capture sessions allow clients to select a set of camera registered surfaces that
+ * support offline mode. After a successful offline mode switch all non-repeating pending requests
+ * on those surfaces will continue to be processed by the camera stack even if clients close the
+ * corresponding camera device.<p>
+ *
+ * <p>Offline capture session instances will replace the previously active capture session arguments
+ * in all capture callbacks after {@link CameraCaptureSession#switchToOffline} completes.</p>
+ *
+ * <p>Processing of pending offline capture requests will begin only after the offline session
+ * moves to ready state which will be indicated by the {@link CameraOfflineSessionCallback#onReady}
+ * callback.</p>
+ *
+ * <p>In contrast to a regular {@link CameraCaptureSession} an offline capture session will
+ * not accept any further capture requests. Besides {@link CameraOfflineSession#close} all
+ * remaining methods will throw {@link UnsupportedOperationException} and are not supported.</p>
+ *
+ * @see CameraCaptureSession#supportsOfflineProcessing
+ */
+public abstract class CameraOfflineSession extends CameraCaptureSession {
+ public static abstract class CameraOfflineSessionCallback {
+ /**
+ * This method indicates that the offline switch call
+ * {@link CameraCaptureSession#switchToOffline} was successful.
+ *
+ * <p>This callback will be invoked once the offline session moves to the ready state.</p>
+ *
+ * <p>Calls to {@link CameraDevice#close} will not have impact on the processing of offline
+ * requests once the offline session moves in ready state.</p>
+ *
+ * @param session the currently ready offline session
+ *
+ */
+ public abstract void onReady(@NonNull CameraOfflineSession session);
+
+ /**
+ * This method indicates that the offline switch call
+ * {@link CameraCaptureSession#switchToOffline} was not able to complete successfully.
+ *
+ * <p>The offline switch can fail either due to internal camera error during the switch
+ * sequence or because the camera implementation was not able to find any pending capture
+ * requests that can be migrated to offline mode.</p>
+ *
+ * <p>Calling {@link CameraOfflineSession#close} is not necessary and clients will not
+ * receive any further offline session notifications.</p>
+ *
+ * @param session the offline session that failed to switch to ready state
+ */
+ public abstract void onSwitchFailed(@NonNull CameraOfflineSession session);
+
+ /**
+ * This method indicates that all pending offline requests were processed.
+ *
+ * <p>This callback will be invoked once the offline session finishes processing
+ * all of its pending offline capture requests.</p>
+ *
+ * @param session the currently ready offline session
+ *
+ */
+ public abstract void onIdle(@NonNull CameraOfflineSession session);
+
+ /**
+ * This status code indicates unexpected and fatal internal camera error.
+ *
+ * <p>Pending offline requests will be discarded and the respective registered
+ * capture callbacks may not get triggered.</p>
+ *
+ * @see #onError
+ */
+ public static final int STATUS_INTERNAL_ERROR = 0;
+
+ /** @hide */
+ @Retention(RetentionPolicy.SOURCE)
+ @IntDef(prefix = {"STATUS_"}, value = {STATUS_INTERNAL_ERROR})
+ public @interface StatusCode {};
+
+ /**
+ * This method is called when the offline session encounters an unexpected error.
+ *
+ * <p>This notification will only be invoked for sessions that reached the ready state.
+ * Clients will need to call {@link CameraOfflineSession#close} to close and release all
+ * resources. {@link #onClosed} will not be triggered automatically in error scenarios.</p>
+ *
+ * @param session the current offline session
+ * @param status error status
+ *
+ */
+ public abstract void onError(@NonNull CameraOfflineSession session, @StatusCode int status);
+
+ /**
+ * This method is called when the offline session is closed.
+ *
+ * <p>An offline session will be closed after a call to
+ * {@link CameraOfflineSession#close}.</p>
+ *
+ * <p>In case of failure to switch to offline mode, only {@link #onSwitchFailed} will be
+ * called and {@link #onClosed} will not be.</p>
+ *
+ * <p>In case there was no previous {@link #onIdle} notification any in-progress
+ * offline capture requests within the offline session will be discarded
+ * and further result callbacks will not be triggered.</p>
+ *
+ * @param session the session returned by {@link CameraCaptureSession#switchToOffline}
+ *
+ */
+ public abstract void onClosed(@NonNull CameraOfflineSession session);
+ }
+
+ /**
+ * Close this offline capture session.
+ *
+ * <p>Abort all pending offline requests and close the connection to the offline camera session
+ * as quickly as possible.</p>
+ *
+ * <p>This method can be called only after clients receive
+ * {@link CameraOfflineSessionCallback#onReady}.</p>
+ *
+ * <p>Immediately after this call, besides the final
+ * {@link CameraOfflineSessionCallback#onClosed} notification, no further callbacks from the
+ * offline session will be triggered and all remaining offline capture requests will be
+ * discarded.</p>
+ *
+ * <p>Closing a session is idempotent; closing more than once has no effect.</p>
+ *
+ * @throws IllegalStateException if the offline sesion is not ready.
+ */
+ @Override
+ public abstract void close();
+}
diff --git a/core/java/android/hardware/camera2/impl/CameraCaptureSessionCore.java b/core/java/android/hardware/camera2/impl/CameraCaptureSessionCore.java
index 116f0f1724b5..44408c2d274b 100644
--- a/core/java/android/hardware/camera2/impl/CameraCaptureSessionCore.java
+++ b/core/java/android/hardware/camera2/impl/CameraCaptureSessionCore.java
@@ -61,4 +61,14 @@ public interface CameraCaptureSessionCore {
*/
boolean isAborting();
+ /**
+ * Close the capture session without draining the pending requests.
+ *
+ * <p>This is usually used when switching to offline session mode. Depending
+ * on the client input, some of the pending requests will be flushed and some
+ * will remain for further processing. In either case, the regular drain logic
+ * needs to be skipped.</p>
+ *
+ */
+ void closeWithoutDraining();
}
diff --git a/core/java/android/hardware/camera2/impl/CameraCaptureSessionImpl.java b/core/java/android/hardware/camera2/impl/CameraCaptureSessionImpl.java
index a4640c1fa519..b6f4bd3c4c28 100644
--- a/core/java/android/hardware/camera2/impl/CameraCaptureSessionImpl.java
+++ b/core/java/android/hardware/camera2/impl/CameraCaptureSessionImpl.java
@@ -18,6 +18,8 @@ package android.hardware.camera2.impl;
import android.hardware.camera2.CameraAccessException;
import android.hardware.camera2.CameraCaptureSession;
import android.hardware.camera2.CameraDevice;
+import android.hardware.camera2.CameraOfflineSession;
+import android.hardware.camera2.CameraOfflineSession.CameraOfflineSessionCallback;
import android.hardware.camera2.CaptureRequest;
import android.hardware.camera2.ICameraDeviceUser;
import android.hardware.camera2.params.OutputConfiguration;
@@ -29,6 +31,7 @@ import android.util.Log;
import android.view.Surface;
import java.util.Arrays;
+import java.util.Collection;
import java.util.List;
import java.util.concurrent.Executor;
@@ -106,7 +109,7 @@ public class CameraCaptureSessionImpl extends CameraCaptureSession
* Use the same handler as the device's StateCallback for all the internal coming events
*
* This ensures total ordering between CameraDevice.StateCallback and
- * CameraDeviceImpl.CaptureCallback events.
+ * CaptureCallback events.
*/
mSequenceDrainer = new TaskDrainer<>(mDeviceExecutor, new SequenceDrainListener(),
/*name*/"seq");
@@ -136,23 +139,35 @@ public class CameraCaptureSessionImpl extends CameraCaptureSession
@Override
public void prepare(Surface surface) throws CameraAccessException {
- mDeviceImpl.prepare(surface);
+ synchronized (mDeviceImpl.mInterfaceLock) {
+ checkNotClosed();
+ mDeviceImpl.prepare(surface);
+ }
}
@Override
public void prepare(int maxCount, Surface surface) throws CameraAccessException {
- mDeviceImpl.prepare(maxCount, surface);
+ synchronized (mDeviceImpl.mInterfaceLock) {
+ checkNotClosed();
+ mDeviceImpl.prepare(maxCount, surface);
+ }
}
@Override
public void tearDown(Surface surface) throws CameraAccessException {
- mDeviceImpl.tearDown(surface);
+ synchronized (mDeviceImpl.mInterfaceLock) {
+ checkNotClosed();
+ mDeviceImpl.tearDown(surface);
+ }
}
@Override
public void finalizeOutputConfigurations(
List<OutputConfiguration> outputConfigs) throws CameraAccessException {
- mDeviceImpl.finalizeOutputConfigs(outputConfigs);
+ synchronized (mDeviceImpl.mInterfaceLock) {
+ checkNotClosed();
+ mDeviceImpl.finalizeOutputConfigs(outputConfigs);
+ }
}
@Override
@@ -446,6 +461,24 @@ public class CameraCaptureSessionImpl extends CameraCaptureSession
}
@Override
+ public CameraOfflineSession switchToOffline(Collection<Surface> offlineOutputs,
+ Executor executor, CameraOfflineSessionCallback listener) throws CameraAccessException {
+ synchronized (mDeviceImpl.mInterfaceLock) {
+ checkNotClosed();
+ }
+ return mDeviceImpl.switchToOffline(offlineOutputs, executor, listener);
+ }
+
+
+ @Override
+ public boolean supportsOfflineProcessing(Surface surface) {
+ synchronized (mDeviceImpl.mInterfaceLock) {
+ checkNotClosed();
+ }
+ return mDeviceImpl.supportsOfflineProcessing(surface);
+ }
+
+ @Override
public boolean isReprocessable() {
return mInput != null;
}
@@ -501,6 +534,25 @@ public class CameraCaptureSessionImpl extends CameraCaptureSession
}
@Override
+ public void closeWithoutDraining() {
+ synchronized (mDeviceImpl.mInterfaceLock) {
+ if (mClosed) {
+ if (DEBUG) Log.v(TAG, mIdString + "close - reentering");
+ return;
+ }
+
+ if (DEBUG) Log.v(TAG, mIdString + "close - first time");
+
+ mClosed = true;
+ mStateCallback.onClosed(this);
+ }
+
+ if (mInput != null) {
+ mInput.release();
+ }
+ }
+
+ @Override
public void close() {
synchronized (mDeviceImpl.mInterfaceLock) {
if (mClosed) {
@@ -571,13 +623,13 @@ public class CameraCaptureSessionImpl extends CameraCaptureSession
}
/**
- * Forward callbacks from
- * CameraDeviceImpl.CaptureCallback to the CameraCaptureSession.CaptureCallback.
+ * Forward callbacks that usually originate from
+ * CameraDeviceImpl.CameraDeviceCallbacks to the CameraCaptureSession.CaptureCallback.
*
* <p>When a capture sequence finishes, update the pending checked sequences set.</p>
*/
@SuppressWarnings("deprecation")
- private CameraDeviceImpl.CaptureCallback createCaptureCallbackProxy(
+ private android.hardware.camera2.impl.CaptureCallback createCaptureCallbackProxy(
Handler handler, CaptureCallback callback) {
final Executor executor = (callback != null) ? CameraDeviceImpl.checkAndWrapHandler(
handler) : null;
@@ -585,9 +637,9 @@ public class CameraCaptureSessionImpl extends CameraCaptureSession
return createCaptureCallbackProxyWithExecutor(executor, callback);
}
- private CameraDeviceImpl.CaptureCallback createCaptureCallbackProxyWithExecutor(
+ private android.hardware.camera2.impl.CaptureCallback createCaptureCallbackProxyWithExecutor(
Executor executor, CaptureCallback callback) {
- return new CameraDeviceImpl.CaptureCallback() {
+ return new android.hardware.camera2.impl.CaptureCallback(executor, callback) {
@Override
public void onCaptureStarted(CameraDevice camera,
CaptureRequest request, long timestamp, long frameNumber) {
diff --git a/core/java/android/hardware/camera2/impl/CameraConstrainedHighSpeedCaptureSessionImpl.java b/core/java/android/hardware/camera2/impl/CameraConstrainedHighSpeedCaptureSessionImpl.java
index eb331373e691..0a4298162027 100644
--- a/core/java/android/hardware/camera2/impl/CameraConstrainedHighSpeedCaptureSessionImpl.java
+++ b/core/java/android/hardware/camera2/impl/CameraConstrainedHighSpeedCaptureSessionImpl.java
@@ -20,6 +20,8 @@ import android.hardware.camera2.CameraCaptureSession;
import android.hardware.camera2.CameraCharacteristics;
import android.hardware.camera2.CameraConstrainedHighSpeedCaptureSession;
import android.hardware.camera2.CameraDevice;
+import android.hardware.camera2.CameraOfflineSession;
+import android.hardware.camera2.CameraOfflineSession.CameraOfflineSessionCallback;
import android.hardware.camera2.CaptureRequest;
import android.hardware.camera2.params.OutputConfiguration;
import android.hardware.camera2.params.StreamConfigurationMap;
@@ -283,6 +285,25 @@ public class CameraConstrainedHighSpeedCaptureSessionImpl
}
@Override
+ public CameraOfflineSession switchToOffline(Collection<Surface> offlineOutputs,
+ Executor executor, CameraOfflineSessionCallback listener) throws CameraAccessException {
+ throw new UnsupportedOperationException("Constrained high speed session doesn't support"
+ + " this method");
+ }
+
+ @Override
+ public boolean supportsOfflineProcessing(Surface surface) {
+ throw new UnsupportedOperationException("Constrained high speed session doesn't support" +
+ " offline mode");
+ }
+
+ @Override
+ public void closeWithoutDraining() {
+ throw new UnsupportedOperationException("Constrained high speed session doesn't support"
+ + " this method");
+ }
+
+ @Override
public void close() {
mSessionImpl.close();
}
diff --git a/core/java/android/hardware/camera2/impl/CameraDeviceImpl.java b/core/java/android/hardware/camera2/impl/CameraDeviceImpl.java
index 67e7a4c821e7..a385771484fd 100644
--- a/core/java/android/hardware/camera2/impl/CameraDeviceImpl.java
+++ b/core/java/android/hardware/camera2/impl/CameraDeviceImpl.java
@@ -23,6 +23,7 @@ import android.hardware.ICameraService;
import android.hardware.camera2.CameraAccessException;
import android.hardware.camera2.CameraCaptureSession;
import android.hardware.camera2.CameraCharacteristics;
+import android.hardware.camera2.CameraOfflineSession;
import android.hardware.camera2.CameraDevice;
import android.hardware.camera2.CaptureFailure;
import android.hardware.camera2.CaptureRequest;
@@ -52,18 +53,17 @@ import android.view.Surface;
import java.util.AbstractMap.SimpleEntry;
import java.util.ArrayList;
+import java.util.Arrays;
import java.util.Collection;
-import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
-import java.util.LinkedList;
import java.util.List;
import java.util.Objects;
import java.util.Set;
-import java.util.TreeMap;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.Executor;
-
+import java.util.concurrent.Executors;
+import java.util.concurrent.ExecutorService;
/**
* HAL2.1+ implementation of CameraDevice. Use CameraManager#open to instantiate
@@ -103,6 +103,9 @@ public class CameraDeviceImpl extends CameraDevice
private final SparseArray<OutputConfiguration> mConfiguredOutputs =
new SparseArray<>();
+ // Cache all stream IDs capable of supporting offline mode.
+ private final HashSet<Integer> mOfflineSupport = new HashSet<>();
+
private final String mCameraId;
private final CameraCharacteristics mCharacteristics;
private final int mTotalPartialCount;
@@ -127,6 +130,9 @@ public class CameraDeviceImpl extends CameraDevice
private final int mAppTargetSdkVersion;
+ private ExecutorService mOfflineSwitchService;
+ private CameraOfflineSessionImpl mOfflineSessionImpl;
+
// Runnables for all state transitions, except error, which needs the
// error code argument
@@ -470,10 +476,19 @@ public class CameraDeviceImpl extends CameraDevice
}
}
+ int offlineStreamIds[];
if (sessionParams != null) {
- mRemoteDevice.endConfigure(operatingMode, sessionParams.getNativeCopy());
+ offlineStreamIds = mRemoteDevice.endConfigure(operatingMode,
+ sessionParams.getNativeCopy());
} else {
- mRemoteDevice.endConfigure(operatingMode, null);
+ offlineStreamIds = mRemoteDevice.endConfigure(operatingMode, null);
+ }
+
+ mOfflineSupport.clear();
+ if ((offlineStreamIds != null) && (offlineStreamIds.length > 0)) {
+ for (int offlineStreamId : offlineStreamIds) {
+ mOfflineSupport.add(offlineStreamId);
+ }
}
success = true;
@@ -866,22 +881,29 @@ public class CameraDeviceImpl extends CameraDevice
}
}
- public void switchToOffline(ICameraDeviceCallbacks cbs, Surface[] offlineOutputs)
+ public CameraOfflineSession switchToOffline(
+ @NonNull Collection<Surface> offlineOutputs, @NonNull Executor executor,
+ @NonNull CameraOfflineSession.CameraOfflineSessionCallback listener)
throws CameraAccessException {
- if ((offlineOutputs == null) || (offlineOutputs.length == 0)) {
- throw new IllegalArgumentException("Invalid offline outputs!");
- }
- if (cbs == null) {
- throw new IllegalArgumentException("Invalid device callbacks!");
+ if (offlineOutputs.isEmpty()) {
+ throw new IllegalArgumentException("Invalid offline surfaces!");
}
- ICameraOfflineSession offlineSession = null;
+ HashSet<Integer> offlineStreamIds = new HashSet<Integer>();
+ SparseArray<OutputConfiguration> offlineConfiguredOutputs =
+ new SparseArray<OutputConfiguration>();
+
synchronized(mInterfaceLock) {
- int streamId = -1;
+ if (mOfflineSessionImpl != null) {
+ throw new IllegalStateException("Switch to offline mode already in progress");
+ }
+
for (Surface surface : offlineOutputs) {
+ int streamId = -1;
for (int i = 0; i < mConfiguredOutputs.size(); i++) {
if (surface == mConfiguredOutputs.valueAt(i).getSurface()) {
streamId = mConfiguredOutputs.keyAt(i);
+ offlineConfiguredOutputs.append(streamId, mConfiguredOutputs.valueAt(i));
break;
}
}
@@ -889,12 +911,67 @@ public class CameraDeviceImpl extends CameraDevice
throw new IllegalArgumentException("Offline surface is not part of this" +
" session");
}
+
+ if (!mOfflineSupport.contains(streamId)) {
+ throw new IllegalArgumentException("Surface: " + surface + " does not " +
+ " support offline mode");
+ }
+
+ offlineStreamIds.add(streamId);
+ }
+
+ mOfflineSessionImpl = new CameraOfflineSessionImpl(mCameraId,
+ mCharacteristics, executor, listener, offlineConfiguredOutputs,
+ mConfiguredInput, mFrameNumberTracker, mCaptureCallbackMap,
+ mRequestLastFrameNumbersList);
+
+ mOfflineSwitchService = Executors.newSingleThreadExecutor();
+ mConfiguredOutputs.clear();
+ mConfiguredInput = new SimpleEntry<Integer, InputConfiguration>(REQUEST_ID_NONE, null);
+
+ mCurrentSession.closeWithoutDraining();
+ mCurrentSession = null;
+ }
+
+ mOfflineSwitchService.execute(new Runnable() {
+ @Override
+ public void run() {
+ // We cannot hold 'mInterfaceLock' during the remote IPC in 'switchToOffline'.
+ // The call will block until all non-offline requests are completed and/or flushed.
+ // The results/errors need to be handled by 'CameraDeviceCallbacks' which also sync
+ // on 'mInterfaceLock'.
+ try {
+ ICameraOfflineSession remoteOfflineSession = mRemoteDevice.switchToOffline(
+ mOfflineSessionImpl.getCallbacks(),
+ Arrays.stream(offlineStreamIds.toArray(
+ new Integer[offlineStreamIds.size()])).mapToInt(
+ Integer::intValue).toArray());
+ mOfflineSessionImpl.setRemoteSession(remoteOfflineSession);
+ } catch (CameraAccessException e) {
+ mOfflineSessionImpl.notifyFailedSwitch();
+ }
+ }
+ });
+
+ return mOfflineSessionImpl;
+ }
+
+ public boolean supportsOfflineProcessing(Surface surface) {
+ if (surface == null) throw new IllegalArgumentException("Surface is null");
+
+ synchronized(mInterfaceLock) {
+ int streamId = -1;
+ for (int i = 0; i < mConfiguredOutputs.size(); i++) {
+ if (surface == mConfiguredOutputs.valueAt(i).getSurface()) {
+ streamId = mConfiguredOutputs.keyAt(i);
+ break;
+ }
+ }
+ if (streamId == -1) {
+ throw new IllegalArgumentException("Surface is not part of this session");
}
- offlineSession = mRemoteDevice.switchToOffline(cbs,
- offlineOutputs);
- // TODO: Initialize CameraOfflineSession wrapper, clear 'mConfiguredOutputs',
- // and update request tracking
+ return mOfflineSupport.contains(streamId);
}
}
@@ -985,7 +1062,7 @@ public class CameraDeviceImpl extends CameraDevice
final int[] repeatingRequestTypes) {
// lastFrameNumber being equal to NO_FRAMES_CAPTURED means that the request
// was never sent to HAL. Should trigger onCaptureSequenceAborted immediately.
- if (lastFrameNumber == CaptureCallback.NO_FRAMES_CAPTURED) {
+ if (lastFrameNumber == CameraCaptureSession.CaptureCallback.NO_FRAMES_CAPTURED) {
final CaptureCallbackHolder holder;
int index = mCaptureCallbackMap.indexOfKey(requestId);
holder = (index >= 0) ? mCaptureCallbackMap.valueAt(index) : null;
@@ -1225,6 +1302,11 @@ public class CameraDeviceImpl extends CameraDevice
return;
}
+ if (mOfflineSwitchService != null) {
+ mOfflineSwitchService.shutdownNow();
+ mOfflineSwitchService = null;
+ }
+
if (mRemoteDevice != null) {
mRemoteDevice.disconnect();
mRemoteDevice.unlinkToDeath(this, /*flags*/0);
@@ -1286,91 +1368,6 @@ public class CameraDeviceImpl extends CameraDevice
}
/**
- * <p>A callback for tracking the progress of a {@link CaptureRequest}
- * submitted to the camera device.</p>
- *
- * An interface instead of an abstract class because this is internal and
- * we want to make sure we always implement all its callbacks until we reach
- * the public layer.
- */
- public interface CaptureCallback {
-
- /**
- * This constant is used to indicate that no images were captured for
- * the request.
- *
- * @hide
- */
- public static final int NO_FRAMES_CAPTURED = -1;
-
- /**
- * This method is called when the camera device has started capturing
- * the output image for the request, at the beginning of image exposure.
- *
- * @see android.media.MediaActionSound
- */
- public void onCaptureStarted(CameraDevice camera,
- CaptureRequest request, long timestamp, long frameNumber);
-
- /**
- * This method is called when some results from an image capture are
- * available.
- *
- * @hide
- */
- public void onCapturePartial(CameraDevice camera,
- CaptureRequest request, CaptureResult result);
-
- /**
- * This method is called when an image capture makes partial forward progress; some
- * (but not all) results from an image capture are available.
- *
- */
- public void onCaptureProgressed(CameraDevice camera,
- CaptureRequest request, CaptureResult partialResult);
-
- /**
- * This method is called when an image capture has fully completed and all the
- * result metadata is available.
- */
- public void onCaptureCompleted(CameraDevice camera,
- CaptureRequest request, TotalCaptureResult result);
-
- /**
- * This method is called instead of {@link #onCaptureCompleted} when the
- * camera device failed to produce a {@link CaptureResult} for the
- * request.
- */
- public void onCaptureFailed(CameraDevice camera,
- CaptureRequest request, CaptureFailure failure);
-
- /**
- * This method is called independently of the others in CaptureCallback,
- * when a capture sequence finishes and all {@link CaptureResult}
- * or {@link CaptureFailure} for it have been returned via this callback.
- */
- public void onCaptureSequenceCompleted(CameraDevice camera,
- int sequenceId, long frameNumber);
-
- /**
- * This method is called independently of the others in CaptureCallback,
- * when a capture sequence aborts before any {@link CaptureResult}
- * or {@link CaptureFailure} for it have been returned via this callback.
- */
- public void onCaptureSequenceAborted(CameraDevice camera,
- int sequenceId);
-
- /**
- * This method is called independently of the others in CaptureCallback, if an output buffer
- * is dropped for a particular capture request.
- *
- * Loss of metadata is communicated via onCaptureFailed, independently of any buffer loss.
- */
- public void onCaptureBufferLost(CameraDevice camera,
- CaptureRequest request, Surface target, long frameNumber);
- }
-
- /**
* A callback for notifications about the state of a camera device, adding in the callbacks that
* were part of the earlier KK API design, but now only used internally.
*/
@@ -1426,478 +1423,6 @@ public class CameraDeviceImpl extends CameraDevice
}
}
- static class CaptureCallbackHolder {
-
- private final boolean mRepeating;
- private final CaptureCallback mCallback;
- private final List<CaptureRequest> mRequestList;
- private final Executor mExecutor;
- private final int mSessionId;
- /**
- * <p>Determine if the callback holder is for a constrained high speed request list that
- * expects batched capture results. Capture results will be batched if the request list
- * is interleaved with preview and video requests. Capture results won't be batched if the
- * request list only contains preview requests, or if the request doesn't belong to a
- * constrained high speed list.
- */
- private final boolean mHasBatchedOutputs;
-
- CaptureCallbackHolder(CaptureCallback callback, List<CaptureRequest> requestList,
- Executor executor, boolean repeating, int sessionId) {
- if (callback == null || executor == null) {
- throw new UnsupportedOperationException(
- "Must have a valid handler and a valid callback");
- }
- mRepeating = repeating;
- mExecutor = executor;
- mRequestList = new ArrayList<CaptureRequest>(requestList);
- mCallback = callback;
- mSessionId = sessionId;
-
- // Check whether this callback holder is for batched outputs.
- // The logic here should match createHighSpeedRequestList.
- boolean hasBatchedOutputs = true;
- for (int i = 0; i < requestList.size(); i++) {
- CaptureRequest request = requestList.get(i);
- if (!request.isPartOfCRequestList()) {
- hasBatchedOutputs = false;
- break;
- }
- if (i == 0) {
- Collection<Surface> targets = request.getTargets();
- if (targets.size() != 2) {
- hasBatchedOutputs = false;
- break;
- }
- }
- }
- mHasBatchedOutputs = hasBatchedOutputs;
- }
-
- public boolean isRepeating() {
- return mRepeating;
- }
-
- public CaptureCallback getCallback() {
- return mCallback;
- }
-
- public CaptureRequest getRequest(int subsequenceId) {
- if (subsequenceId >= mRequestList.size()) {
- throw new IllegalArgumentException(
- String.format(
- "Requested subsequenceId %d is larger than request list size %d.",
- subsequenceId, mRequestList.size()));
- } else {
- if (subsequenceId < 0) {
- throw new IllegalArgumentException(String.format(
- "Requested subsequenceId %d is negative", subsequenceId));
- } else {
- return mRequestList.get(subsequenceId);
- }
- }
- }
-
- public CaptureRequest getRequest() {
- return getRequest(0);
- }
-
- public Executor getExecutor() {
- return mExecutor;
- }
-
- public int getSessionId() {
- return mSessionId;
- }
-
- public int getRequestCount() {
- return mRequestList.size();
- }
-
- public boolean hasBatchedOutputs() {
- return mHasBatchedOutputs;
- }
- }
-
- /**
- * This class holds a capture ID and its expected last regular, zslStill, and reprocess
- * frame number.
- */
- static class RequestLastFrameNumbersHolder {
- // request ID
- private final int mRequestId;
- // The last regular frame number for this request ID. It's
- // CaptureCallback.NO_FRAMES_CAPTURED if the request ID has no regular request.
- private final long mLastRegularFrameNumber;
- // The last reprocess frame number for this request ID. It's
- // CaptureCallback.NO_FRAMES_CAPTURED if the request ID has no reprocess request.
- private final long mLastReprocessFrameNumber;
- // The last ZSL still capture frame number for this request ID. It's
- // CaptureCallback.NO_FRAMES_CAPTURED if the request ID has no zsl request.
- private final long mLastZslStillFrameNumber;
-
- /**
- * Create a request-last-frame-numbers holder with a list of requests, request ID, and
- * the last frame number returned by camera service.
- */
- public RequestLastFrameNumbersHolder(List<CaptureRequest> requestList, SubmitInfo requestInfo) {
- long lastRegularFrameNumber = CaptureCallback.NO_FRAMES_CAPTURED;
- long lastReprocessFrameNumber = CaptureCallback.NO_FRAMES_CAPTURED;
- long lastZslStillFrameNumber = CaptureCallback.NO_FRAMES_CAPTURED;
- long frameNumber = requestInfo.getLastFrameNumber();
-
- if (requestInfo.getLastFrameNumber() < requestList.size() - 1) {
- throw new IllegalArgumentException(
- "lastFrameNumber: " + requestInfo.getLastFrameNumber() +
- " should be at least " + (requestList.size() - 1) + " for the number of " +
- " requests in the list: " + requestList.size());
- }
-
- // find the last regular, zslStill, and reprocess frame number
- for (int i = requestList.size() - 1; i >= 0; i--) {
- CaptureRequest request = requestList.get(i);
- int requestType = request.getRequestType();
- if (requestType == CaptureRequest.REQUEST_TYPE_REPROCESS
- && lastReprocessFrameNumber == CaptureCallback.NO_FRAMES_CAPTURED) {
- lastReprocessFrameNumber = frameNumber;
- } else if (requestType == CaptureRequest.REQUEST_TYPE_ZSL_STILL
- && lastZslStillFrameNumber == CaptureCallback.NO_FRAMES_CAPTURED) {
- lastZslStillFrameNumber = frameNumber;
- } else if (requestType == CaptureRequest.REQUEST_TYPE_REGULAR
- && lastRegularFrameNumber == CaptureCallback.NO_FRAMES_CAPTURED) {
- lastRegularFrameNumber = frameNumber;
- }
-
- if (lastReprocessFrameNumber != CaptureCallback.NO_FRAMES_CAPTURED
- && lastZslStillFrameNumber != CaptureCallback.NO_FRAMES_CAPTURED
- && lastRegularFrameNumber != CaptureCallback.NO_FRAMES_CAPTURED) {
- break;
- }
-
- frameNumber--;
- }
-
- mLastRegularFrameNumber = lastRegularFrameNumber;
- mLastReprocessFrameNumber = lastReprocessFrameNumber;
- mLastZslStillFrameNumber = lastZslStillFrameNumber;
- mRequestId = requestInfo.getRequestId();
- }
-
- /**
- * Create a request-last-frame-numbers holder with a request ID and last regular/ZslStill
- * frame number.
- */
- RequestLastFrameNumbersHolder(int requestId, long lastFrameNumber,
- int[] repeatingRequestTypes) {
- long lastRegularFrameNumber = CaptureCallback.NO_FRAMES_CAPTURED;
- long lastZslStillFrameNumber = CaptureCallback.NO_FRAMES_CAPTURED;
-
- if (repeatingRequestTypes == null) {
- throw new IllegalArgumentException(
- "repeatingRequest list must not be null");
- }
- if (lastFrameNumber < repeatingRequestTypes.length - 1) {
- throw new IllegalArgumentException(
- "lastFrameNumber: " + lastFrameNumber + " should be at least "
- + (repeatingRequestTypes.length - 1)
- + " for the number of requests in the list: "
- + repeatingRequestTypes.length);
- }
-
- long frameNumber = lastFrameNumber;
- for (int i = repeatingRequestTypes.length - 1; i >= 0; i--) {
- if (repeatingRequestTypes[i] == CaptureRequest.REQUEST_TYPE_ZSL_STILL
- && lastZslStillFrameNumber == CaptureCallback.NO_FRAMES_CAPTURED) {
- lastZslStillFrameNumber = frameNumber;
- } else if (repeatingRequestTypes[i] == CaptureRequest.REQUEST_TYPE_REGULAR
- && lastRegularFrameNumber == CaptureCallback.NO_FRAMES_CAPTURED) {
- lastRegularFrameNumber = frameNumber;
- }
-
- if (lastZslStillFrameNumber != CaptureCallback.NO_FRAMES_CAPTURED
- && lastRegularFrameNumber != CaptureCallback.NO_FRAMES_CAPTURED) {
- break;
- }
-
- frameNumber--;
- }
-
- mLastRegularFrameNumber = lastRegularFrameNumber;
- mLastZslStillFrameNumber = lastZslStillFrameNumber;
- mLastReprocessFrameNumber = CaptureCallback.NO_FRAMES_CAPTURED;
- mRequestId = requestId;
- }
-
- /**
- * Return the last regular frame number. Return CaptureCallback.NO_FRAMES_CAPTURED if
- * it contains no regular request.
- */
- public long getLastRegularFrameNumber() {
- return mLastRegularFrameNumber;
- }
-
- /**
- * Return the last reprocess frame number. Return CaptureCallback.NO_FRAMES_CAPTURED if
- * it contains no reprocess request.
- */
- public long getLastReprocessFrameNumber() {
- return mLastReprocessFrameNumber;
- }
-
- /**
- * Return the last ZslStill frame number. Return CaptureCallback.NO_FRAMES_CAPTURED if
- * it contains no Zsl request.
- */
- public long getLastZslStillFrameNumber() {
- return mLastZslStillFrameNumber;
- }
-
- /**
- * Return the last frame number overall.
- */
- public long getLastFrameNumber() {
- return Math.max(mLastZslStillFrameNumber,
- Math.max(mLastRegularFrameNumber, mLastReprocessFrameNumber));
- }
-
- /**
- * Return the request ID.
- */
- public int getRequestId() {
- return mRequestId;
- }
- }
-
- /**
- * This class tracks the last frame number for submitted requests.
- */
- public class FrameNumberTracker {
-
- /** the completed frame number for each type of capture results */
- private long[] mCompletedFrameNumber = new long[CaptureRequest.REQUEST_TYPE_COUNT];
-
- /** the skipped frame numbers that don't belong to each type of capture results */
- private final LinkedList<Long>[] mSkippedOtherFrameNumbers =
- new LinkedList[CaptureRequest.REQUEST_TYPE_COUNT];
-
- /** the skipped frame numbers that belong to each type of capture results */
- private final LinkedList<Long>[] mSkippedFrameNumbers =
- new LinkedList[CaptureRequest.REQUEST_TYPE_COUNT];
-
- /** frame number -> request type */
- private final TreeMap<Long, Integer> mFutureErrorMap = new TreeMap<Long, Integer>();
- /** Map frame numbers to list of partial results */
- private final HashMap<Long, List<CaptureResult>> mPartialResults = new HashMap<>();
-
- public FrameNumberTracker() {
- for (int i = 0; i < CaptureRequest.REQUEST_TYPE_COUNT; i++) {
- mCompletedFrameNumber[i] = CaptureCallback.NO_FRAMES_CAPTURED;
- mSkippedOtherFrameNumbers[i] = new LinkedList<Long>();
- mSkippedFrameNumbers[i] = new LinkedList<Long>();
- }
- }
-
- private void update() {
- Iterator iter = mFutureErrorMap.entrySet().iterator();
- while (iter.hasNext()) {
- TreeMap.Entry pair = (TreeMap.Entry)iter.next();
- Long errorFrameNumber = (Long)pair.getKey();
- int requestType = (int) pair.getValue();
- Boolean removeError = false;
- if (errorFrameNumber == mCompletedFrameNumber[requestType] + 1) {
- mCompletedFrameNumber[requestType] = errorFrameNumber;
- removeError = true;
- } else {
- if (!mSkippedFrameNumbers[requestType].isEmpty()) {
- if (errorFrameNumber == mSkippedFrameNumbers[requestType].element()) {
- mCompletedFrameNumber[requestType] = errorFrameNumber;
- mSkippedFrameNumbers[requestType].remove();
- removeError = true;
- }
- } else {
- for (int i = 1; i < CaptureRequest.REQUEST_TYPE_COUNT; i++) {
- int otherType = (requestType + i) % CaptureRequest.REQUEST_TYPE_COUNT;
- if (!mSkippedOtherFrameNumbers[otherType].isEmpty() && errorFrameNumber
- == mSkippedOtherFrameNumbers[otherType].element()) {
- mCompletedFrameNumber[requestType] = errorFrameNumber;
- mSkippedOtherFrameNumbers[otherType].remove();
- removeError = true;
- break;
- }
- }
- }
- }
- if (removeError) {
- iter.remove();
- }
- }
- }
-
- /**
- * This function is called every time when a result or an error is received.
- * @param frameNumber the frame number corresponding to the result or error
- * @param isError true if it is an error, false if it is not an error
- * @param requestType the type of capture request: Reprocess, ZslStill, or Regular.
- */
- public void updateTracker(long frameNumber, boolean isError, int requestType) {
- if (isError) {
- mFutureErrorMap.put(frameNumber, requestType);
- } else {
- try {
- updateCompletedFrameNumber(frameNumber, requestType);
- } catch (IllegalArgumentException e) {
- Log.e(TAG, e.getMessage());
- }
- }
- update();
- }
-
- /**
- * This function is called every time a result has been completed.
- *
- * <p>It keeps a track of all the partial results already created for a particular
- * frame number.</p>
- *
- * @param frameNumber the frame number corresponding to the result
- * @param result the total or partial result
- * @param partial {@true} if the result is partial, {@code false} if total
- * @param requestType the type of capture request: Reprocess, ZslStill, or Regular.
- */
- public void updateTracker(long frameNumber, CaptureResult result, boolean partial,
- int requestType) {
- if (!partial) {
- // Update the total result's frame status as being successful
- updateTracker(frameNumber, /*isError*/false, requestType);
- // Don't keep a list of total results, we don't need to track them
- return;
- }
-
- if (result == null) {
- // Do not record blank results; this also means there will be no total result
- // so it doesn't matter that the partials were not recorded
- return;
- }
-
- // Partial results must be aggregated in-order for that frame number
- List<CaptureResult> partials = mPartialResults.get(frameNumber);
- if (partials == null) {
- partials = new ArrayList<>();
- mPartialResults.put(frameNumber, partials);
- }
-
- partials.add(result);
- }
-
- /**
- * Attempt to pop off all of the partial results seen so far for the {@code frameNumber}.
- *
- * <p>Once popped-off, the partial results are forgotten (unless {@code updateTracker}
- * is called again with new partials for that frame number).</p>
- *
- * @param frameNumber the frame number corresponding to the result
- * @return a list of partial results for that frame with at least 1 element,
- * or {@code null} if there were no partials recorded for that frame
- */
- public List<CaptureResult> popPartialResults(long frameNumber) {
- return mPartialResults.remove(frameNumber);
- }
-
- public long getCompletedFrameNumber() {
- return mCompletedFrameNumber[CaptureRequest.REQUEST_TYPE_REGULAR];
- }
-
- public long getCompletedReprocessFrameNumber() {
- return mCompletedFrameNumber[CaptureRequest.REQUEST_TYPE_REPROCESS];
- }
-
- public long getCompletedZslStillFrameNumber() {
- return mCompletedFrameNumber[CaptureRequest.REQUEST_TYPE_ZSL_STILL];
- }
-
- /**
- * Update the completed frame number for results of 3 categories
- * (Regular/Reprocess/ZslStill).
- *
- * It validates that all previous frames of the same category have arrived.
- *
- * If there is a gap since previous frame number of the same category, assume the frames in
- * the gap are other categories and store them in the skipped frame number queue to check
- * against when frames of those categories arrive.
- */
- private void updateCompletedFrameNumber(long frameNumber,
- int requestType) throws IllegalArgumentException {
- if (frameNumber <= mCompletedFrameNumber[requestType]) {
- throw new IllegalArgumentException("frame number " + frameNumber + " is a repeat");
- }
-
- // Assume there are only 3 different types of capture requests.
- int otherType1 = (requestType + 1) % CaptureRequest.REQUEST_TYPE_COUNT;
- int otherType2 = (requestType + 2) % CaptureRequest.REQUEST_TYPE_COUNT;
- long maxOtherFrameNumberSeen =
- Math.max(mCompletedFrameNumber[otherType1], mCompletedFrameNumber[otherType2]);
- if (frameNumber < maxOtherFrameNumberSeen) {
- // if frame number is smaller than completed frame numbers of other categories,
- // it must be:
- // - the head of mSkippedFrameNumbers for this category, or
- // - in one of other mSkippedOtherFrameNumbers
- if (!mSkippedFrameNumbers[requestType].isEmpty()) {
- // frame number must be head of current type of mSkippedFrameNumbers if
- // mSkippedFrameNumbers isn't empty.
- if (frameNumber < mSkippedFrameNumbers[requestType].element()) {
- throw new IllegalArgumentException("frame number " + frameNumber
- + " is a repeat");
- } else if (frameNumber > mSkippedFrameNumbers[requestType].element()) {
- throw new IllegalArgumentException("frame number " + frameNumber
- + " comes out of order. Expecting "
- + mSkippedFrameNumbers[requestType].element());
- }
- // frame number matches the head of the skipped frame number queue.
- mSkippedFrameNumbers[requestType].remove();
- } else {
- // frame number must be in one of the other mSkippedOtherFrameNumbers.
- int index1 = mSkippedOtherFrameNumbers[otherType1].indexOf(frameNumber);
- int index2 = mSkippedOtherFrameNumbers[otherType2].indexOf(frameNumber);
- boolean inSkippedOther1 = index1 != -1;
- boolean inSkippedOther2 = index2 != -1;
- if (!(inSkippedOther1 ^ inSkippedOther2)) {
- throw new IllegalArgumentException("frame number " + frameNumber
- + " is a repeat or invalid");
- }
-
- // We know the category of frame numbers in skippedOtherFrameNumbers leading up
- // to the current frame number. Move them into the correct skippedFrameNumbers.
- LinkedList<Long> srcList, dstList;
- int index;
- if (inSkippedOther1) {
- srcList = mSkippedOtherFrameNumbers[otherType1];
- dstList = mSkippedFrameNumbers[otherType2];
- index = index1;
- } else {
- srcList = mSkippedOtherFrameNumbers[otherType2];
- dstList = mSkippedFrameNumbers[otherType1];
- index = index2;
- }
- for (int i = 0; i < index; i++) {
- dstList.add(srcList.removeFirst());
- }
-
- // Remove current frame number from skippedOtherFrameNumbers
- srcList.remove();
- }
- } else {
- // there is a gap of unseen frame numbers which should belong to the other
- // 2 categories. Put all the skipped frame numbers in the queue.
- for (long i =
- Math.max(maxOtherFrameNumberSeen, mCompletedFrameNumber[requestType]) + 1;
- i < frameNumber; i++) {
- mSkippedOtherFrameNumbers[requestType].add(i);
- }
- }
-
- mCompletedFrameNumber[requestType] = frameNumber;
- }
- }
-
private void checkAndFireSequenceComplete() {
long completedFrameNumber = mFrameNumberTracker.getCompletedFrameNumber();
long completedReprocessFrameNumber = mFrameNumberTracker.getCompletedReprocessFrameNumber();
@@ -1979,69 +1504,211 @@ public class CameraDeviceImpl extends CameraDevice
}
}
- public class CameraDeviceCallbacks extends ICameraDeviceCallbacks.Stub {
-
- @Override
- public IBinder asBinder() {
- return this;
+ public void onDeviceError(final int errorCode, CaptureResultExtras resultExtras) {
+ if (DEBUG) {
+ Log.d(TAG, String.format(
+ "Device error received, code %d, frame number %d, request ID %d, subseq ID %d",
+ errorCode, resultExtras.getFrameNumber(), resultExtras.getRequestId(),
+ resultExtras.getSubsequenceId()));
}
- @Override
- public void onDeviceError(final int errorCode, CaptureResultExtras resultExtras) {
- if (DEBUG) {
- Log.d(TAG, String.format(
- "Device error received, code %d, frame number %d, request ID %d, subseq ID %d",
- errorCode, resultExtras.getFrameNumber(), resultExtras.getRequestId(),
- resultExtras.getSubsequenceId()));
+ synchronized(mInterfaceLock) {
+ if (mRemoteDevice == null) {
+ return; // Camera already closed
}
- synchronized(mInterfaceLock) {
- if (mRemoteDevice == null) {
- return; // Camera already closed
- }
+ // Redirect device callback to the offline session in case we are in the middle
+ // of an offline switch
+ if (mOfflineSessionImpl != null) {
+ mOfflineSessionImpl.getCallbacks().onDeviceError(errorCode, resultExtras);
+ return;
+ }
- switch (errorCode) {
- case ERROR_CAMERA_DISCONNECTED:
- final long ident = Binder.clearCallingIdentity();
- try {
- CameraDeviceImpl.this.mDeviceExecutor.execute(mCallOnDisconnected);
- } finally {
- Binder.restoreCallingIdentity(ident);
+ switch (errorCode) {
+ case CameraDeviceCallbacks.ERROR_CAMERA_DISCONNECTED:
+ final long ident = Binder.clearCallingIdentity();
+ try {
+ mDeviceExecutor.execute(mCallOnDisconnected);
+ } finally {
+ Binder.restoreCallingIdentity(ident);
+ }
+ break;
+ case CameraDeviceCallbacks.ERROR_CAMERA_REQUEST:
+ case CameraDeviceCallbacks.ERROR_CAMERA_RESULT:
+ case CameraDeviceCallbacks.ERROR_CAMERA_BUFFER:
+ onCaptureErrorLocked(errorCode, resultExtras);
+ break;
+ case CameraDeviceCallbacks.ERROR_CAMERA_DEVICE:
+ scheduleNotifyError(StateCallback.ERROR_CAMERA_DEVICE);
+ break;
+ case CameraDeviceCallbacks.ERROR_CAMERA_DISABLED:
+ scheduleNotifyError(StateCallback.ERROR_CAMERA_DISABLED);
+ break;
+ default:
+ Log.e(TAG, "Unknown error from camera device: " + errorCode);
+ scheduleNotifyError(StateCallback.ERROR_CAMERA_SERVICE);
+ }
+ }
+ }
+
+ private void scheduleNotifyError(int code) {
+ mInError = true;
+ final long ident = Binder.clearCallingIdentity();
+ try {
+ mDeviceExecutor.execute(obtainRunnable(
+ CameraDeviceImpl::notifyError, this, code).recycleOnUse());
+ } finally {
+ Binder.restoreCallingIdentity(ident);
+ }
+ }
+
+ private void notifyError(int code) {
+ if (!CameraDeviceImpl.this.isClosed()) {
+ mDeviceCallback.onError(CameraDeviceImpl.this, code);
+ }
+ }
+
+ /**
+ * Called by onDeviceError for handling single-capture failures.
+ */
+ private void onCaptureErrorLocked(int errorCode, CaptureResultExtras resultExtras) {
+
+ final int requestId = resultExtras.getRequestId();
+ final int subsequenceId = resultExtras.getSubsequenceId();
+ final long frameNumber = resultExtras.getFrameNumber();
+ final String errorPhysicalCameraId = resultExtras.getErrorPhysicalCameraId();
+ final CaptureCallbackHolder holder = mCaptureCallbackMap.get(requestId);
+
+ if (holder == null) {
+ Log.e(TAG, String.format("Receive capture error on unknown request ID %d",
+ requestId));
+ return;
+ }
+
+ final CaptureRequest request = holder.getRequest(subsequenceId);
+
+ Runnable failureDispatch = null;
+ if (errorCode == CameraDeviceCallbacks.ERROR_CAMERA_BUFFER) {
+ // Because 1 stream id could map to multiple surfaces, we need to specify both
+ // streamId and surfaceId.
+ OutputConfiguration config = mConfiguredOutputs.get(
+ resultExtras.getErrorStreamId());
+ if (config == null) {
+ Log.v(TAG, String.format(
+ "Stream %d has been removed. Skipping buffer lost callback",
+ resultExtras.getErrorStreamId()));
+ return;
+ }
+ for (Surface surface : config.getSurfaces()) {
+ if (!request.containsTarget(surface)) {
+ continue;
+ }
+ if (DEBUG) {
+ Log.v(TAG, String.format(
+ "Lost output buffer reported for frame %d, target %s",
+ frameNumber, surface));
+ }
+ failureDispatch = new Runnable() {
+ @Override
+ public void run() {
+ if (!isClosed()){
+ holder.getCallback().onCaptureBufferLost(CameraDeviceImpl.this, request,
+ surface, frameNumber);
}
- break;
- case ERROR_CAMERA_REQUEST:
- case ERROR_CAMERA_RESULT:
- case ERROR_CAMERA_BUFFER:
- onCaptureErrorLocked(errorCode, resultExtras);
- break;
- case ERROR_CAMERA_DEVICE:
- scheduleNotifyError(StateCallback.ERROR_CAMERA_DEVICE);
- break;
- case ERROR_CAMERA_DISABLED:
- scheduleNotifyError(StateCallback.ERROR_CAMERA_DISABLED);
- break;
- default:
- Log.e(TAG, "Unknown error from camera device: " + errorCode);
- scheduleNotifyError(StateCallback.ERROR_CAMERA_SERVICE);
+ }
+ };
+ // Dispatch the failure callback
+ final long ident = Binder.clearCallingIdentity();
+ try {
+ holder.getExecutor().execute(failureDispatch);
+ } finally {
+ Binder.restoreCallingIdentity(ident);
}
}
- }
+ } else {
+ boolean mayHaveBuffers = (errorCode == CameraDeviceCallbacks.ERROR_CAMERA_RESULT);
+
+ // This is only approximate - exact handling needs the camera service and HAL to
+ // disambiguate between request failures to due abort and due to real errors. For
+ // now, assume that if the session believes we're mid-abort, then the error is due
+ // to abort.
+ int reason = (mCurrentSession != null && mCurrentSession.isAborting()) ?
+ CaptureFailure.REASON_FLUSHED :
+ CaptureFailure.REASON_ERROR;
+
+ final CaptureFailure failure = new CaptureFailure(
+ request,
+ reason,
+ /*dropped*/ mayHaveBuffers,
+ requestId,
+ frameNumber,
+ errorPhysicalCameraId);
+
+ failureDispatch = new Runnable() {
+ @Override
+ public void run() {
+ if (!isClosed()){
+ holder.getCallback().onCaptureFailed(CameraDeviceImpl.this, request,
+ failure);
+ }
+ }
+ };
- private void scheduleNotifyError(int code) {
- mInError = true;
+ // Fire onCaptureSequenceCompleted if appropriate
+ if (DEBUG) {
+ Log.v(TAG, String.format("got error frame %d", frameNumber));
+ }
+ mFrameNumberTracker.updateTracker(frameNumber,
+ /*error*/true, request.getRequestType());
+ checkAndFireSequenceComplete();
+
+ // Dispatch the failure callback
final long ident = Binder.clearCallingIdentity();
try {
- CameraDeviceImpl.this.mDeviceExecutor.execute(obtainRunnable(
- CameraDeviceCallbacks::notifyError, this, code).recycleOnUse());
+ holder.getExecutor().execute(failureDispatch);
} finally {
Binder.restoreCallingIdentity(ident);
}
}
- private void notifyError(int code) {
- if (!CameraDeviceImpl.this.isClosed()) {
- mDeviceCallback.onError(CameraDeviceImpl.this, code);
+ }
+
+ public void onDeviceIdle() {
+ if (DEBUG) {
+ Log.d(TAG, "Camera now idle");
+ }
+ synchronized(mInterfaceLock) {
+ if (mRemoteDevice == null) return; // Camera already closed
+
+ // Redirect device callback to the offline session in case we are in the middle
+ // of an offline switch
+ if (mOfflineSessionImpl != null) {
+ mOfflineSessionImpl.getCallbacks().onDeviceIdle();
+ return;
+ }
+
+ if (!CameraDeviceImpl.this.mIdle) {
+ final long ident = Binder.clearCallingIdentity();
+ try {
+ mDeviceExecutor.execute(mCallOnIdle);
+ } finally {
+ Binder.restoreCallingIdentity(ident);
+ }
}
+ mIdle = true;
+ }
+ }
+
+ public class CameraDeviceCallbacks extends ICameraDeviceCallbacks.Stub {
+
+ @Override
+ public IBinder asBinder() {
+ return this;
+ }
+
+ @Override
+ public void onDeviceError(final int errorCode, CaptureResultExtras resultExtras) {
+ CameraDeviceImpl.this.onDeviceError(errorCode, resultExtras);
}
@Override
@@ -2057,6 +1724,14 @@ public class CameraDeviceImpl extends CameraDevice
return; // Camera already closed
}
+ // Redirect device callback to the offline session in case we are in the middle
+ // of an offline switch
+ if (mOfflineSessionImpl != null) {
+ mOfflineSessionImpl.getCallbacks().onRepeatingRequestError(
+ lastFrameNumber, repeatingRequestId);
+ return;
+ }
+
checkEarlyTriggerSequenceComplete(mRepeatingRequestId, lastFrameNumber,
mRepeatingRequestTypes);
// Check if there is already a new repeating request
@@ -2069,22 +1744,7 @@ public class CameraDeviceImpl extends CameraDevice
@Override
public void onDeviceIdle() {
- if (DEBUG) {
- Log.d(TAG, "Camera now idle");
- }
- synchronized(mInterfaceLock) {
- if (mRemoteDevice == null) return; // Camera already closed
-
- if (!CameraDeviceImpl.this.mIdle) {
- final long ident = Binder.clearCallingIdentity();
- try {
- CameraDeviceImpl.this.mDeviceExecutor.execute(mCallOnIdle);
- } finally {
- Binder.restoreCallingIdentity(ident);
- }
- }
- CameraDeviceImpl.this.mIdle = true;
- }
+ CameraDeviceImpl.this.onDeviceIdle();
}
@Override
@@ -2100,6 +1760,15 @@ public class CameraDeviceImpl extends CameraDevice
synchronized(mInterfaceLock) {
if (mRemoteDevice == null) return; // Camera already closed
+
+ // Redirect device callback to the offline session in case we are in the middle
+ // of an offline switch
+ if (mOfflineSessionImpl != null) {
+ mOfflineSessionImpl.getCallbacks().onCaptureStarted(resultExtras,
+ timestamp);
+ return;
+ }
+
// Get the callback for this frame ID, if there is one
holder = CameraDeviceImpl.this.mCaptureCallbackMap.get(requestId);
@@ -2164,6 +1833,15 @@ public class CameraDeviceImpl extends CameraDevice
synchronized(mInterfaceLock) {
if (mRemoteDevice == null) return; // Camera already closed
+
+ // Redirect device callback to the offline session in case we are in the middle
+ // of an offline switch
+ if (mOfflineSessionImpl != null) {
+ mOfflineSessionImpl.getCallbacks().onResultReceived(result, resultExtras,
+ physicalResults);
+ return;
+ }
+
// TODO: Handle CameraCharacteristics access from CaptureResult correctly.
result.set(CameraCharacteristics.LENS_INFO_SHADING_MAP_SIZE,
getCharacteristics().get(CameraCharacteristics.LENS_INFO_SHADING_MAP_SIZE));
@@ -2325,6 +2003,13 @@ public class CameraDeviceImpl extends CameraDevice
}
synchronized(mInterfaceLock) {
+ // Redirect device callback to the offline session in case we are in the middle
+ // of an offline switch
+ if (mOfflineSessionImpl != null) {
+ mOfflineSessionImpl.getCallbacks().onPrepared(streamId);
+ return;
+ }
+
output = mConfiguredOutputs.get(streamId);
sessionCallback = mSessionStateCallback;
}
@@ -2350,6 +2035,13 @@ public class CameraDeviceImpl extends CameraDevice
}
synchronized(mInterfaceLock) {
+ // Redirect device callback to the offline session in case we are in the middle
+ // of an offline switch
+ if (mOfflineSessionImpl != null) {
+ mOfflineSessionImpl.getCallbacks().onRequestQueueEmpty();
+ return;
+ }
+
sessionCallback = mSessionStateCallback;
}
@@ -2358,117 +2050,6 @@ public class CameraDeviceImpl extends CameraDevice
sessionCallback.onRequestQueueEmpty();
}
- /**
- * Called by onDeviceError for handling single-capture failures.
- */
- private void onCaptureErrorLocked(int errorCode, CaptureResultExtras resultExtras) {
-
- final int requestId = resultExtras.getRequestId();
- final int subsequenceId = resultExtras.getSubsequenceId();
- final long frameNumber = resultExtras.getFrameNumber();
- final String errorPhysicalCameraId = resultExtras.getErrorPhysicalCameraId();
- final CaptureCallbackHolder holder =
- CameraDeviceImpl.this.mCaptureCallbackMap.get(requestId);
-
- if (holder == null) {
- Log.e(TAG, String.format("Receive capture error on unknown request ID %d",
- requestId));
- return;
- }
-
- final CaptureRequest request = holder.getRequest(subsequenceId);
-
- Runnable failureDispatch = null;
- if (errorCode == ERROR_CAMERA_BUFFER) {
- // Because 1 stream id could map to multiple surfaces, we need to specify both
- // streamId and surfaceId.
- OutputConfiguration config = mConfiguredOutputs.get(
- resultExtras.getErrorStreamId());
- if (config == null) {
- Log.v(TAG, String.format(
- "Stream %d has been removed. Skipping buffer lost callback",
- resultExtras.getErrorStreamId()));
- return;
- }
- for (Surface surface : config.getSurfaces()) {
- if (!request.containsTarget(surface)) {
- continue;
- }
- if (DEBUG) {
- Log.v(TAG, String.format(
- "Lost output buffer reported for frame %d, target %s",
- frameNumber, surface));
- }
- failureDispatch = new Runnable() {
- @Override
- public void run() {
- if (!CameraDeviceImpl.this.isClosed()){
- holder.getCallback().onCaptureBufferLost(
- CameraDeviceImpl.this,
- request,
- surface,
- frameNumber);
- }
- }
- };
- // Dispatch the failure callback
- final long ident = Binder.clearCallingIdentity();
- try {
- holder.getExecutor().execute(failureDispatch);
- } finally {
- Binder.restoreCallingIdentity(ident);
- }
- }
- } else {
- boolean mayHaveBuffers = (errorCode == ERROR_CAMERA_RESULT);
-
- // This is only approximate - exact handling needs the camera service and HAL to
- // disambiguate between request failures to due abort and due to real errors. For
- // now, assume that if the session believes we're mid-abort, then the error is due
- // to abort.
- int reason = (mCurrentSession != null && mCurrentSession.isAborting()) ?
- CaptureFailure.REASON_FLUSHED :
- CaptureFailure.REASON_ERROR;
-
- final CaptureFailure failure = new CaptureFailure(
- request,
- reason,
- /*dropped*/ mayHaveBuffers,
- requestId,
- frameNumber,
- errorPhysicalCameraId);
-
- failureDispatch = new Runnable() {
- @Override
- public void run() {
- if (!CameraDeviceImpl.this.isClosed()){
- holder.getCallback().onCaptureFailed(
- CameraDeviceImpl.this,
- request,
- failure);
- }
- }
- };
-
- // Fire onCaptureSequenceCompleted if appropriate
- if (DEBUG) {
- Log.v(TAG, String.format("got error frame %d", frameNumber));
- }
- mFrameNumberTracker.updateTracker(frameNumber,
- /*error*/true, request.getRequestType());
- checkAndFireSequenceComplete();
-
- // Dispatch the failure callback
- final long ident = Binder.clearCallingIdentity();
- try {
- holder.getExecutor().execute(failureDispatch);
- } finally {
- Binder.restoreCallingIdentity(ident);
- }
- }
-
- }
-
} // public class CameraDeviceCallbacks
/**
diff --git a/core/java/android/hardware/camera2/impl/CameraOfflineSessionImpl.java b/core/java/android/hardware/camera2/impl/CameraOfflineSessionImpl.java
new file mode 100644
index 000000000000..1db377a61465
--- /dev/null
+++ b/core/java/android/hardware/camera2/impl/CameraOfflineSessionImpl.java
@@ -0,0 +1,840 @@
+/*
+ * Copyright (C) 2019 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 android.hardware.camera2.impl;
+
+import android.hardware.camera2.CameraAccessException;
+import android.hardware.camera2.CameraCaptureSession;
+import android.hardware.camera2.CameraCharacteristics;
+import android.hardware.camera2.CameraDevice;
+import android.hardware.camera2.CameraManager;
+import android.hardware.camera2.CameraOfflineSession;
+import android.hardware.camera2.CameraOfflineSession.CameraOfflineSessionCallback;
+import android.hardware.camera2.CaptureFailure;
+import android.hardware.camera2.CaptureRequest;
+import android.hardware.camera2.CaptureResult;
+import android.hardware.camera2.ICameraDeviceCallbacks;
+import android.hardware.camera2.ICameraOfflineSession;
+import android.hardware.camera2.TotalCaptureResult;
+import android.hardware.camera2.params.InputConfiguration;
+import android.hardware.camera2.params.OutputConfiguration;
+import android.os.Binder;
+import android.os.Handler;
+import android.os.IBinder;
+import android.os.RemoteException;
+import android.util.Log;
+import android.util.Range;
+import android.util.SparseArray;
+import android.view.Surface;
+
+import java.util.AbstractMap.SimpleEntry;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Iterator;
+import java.util.List;
+import java.util.concurrent.atomic.AtomicBoolean;
+import java.util.concurrent.Executor;
+
+import static com.android.internal.util.Preconditions.*;
+
+public class CameraOfflineSessionImpl extends CameraOfflineSession
+ implements IBinder.DeathRecipient {
+ private static final String TAG = "CameraOfflineSessionImpl";
+ private static final int REQUEST_ID_NONE = -1;
+ private static final long NANO_PER_SECOND = 1000000000; //ns
+ private final boolean DEBUG = false;
+
+ private ICameraOfflineSession mRemoteSession;
+ private final AtomicBoolean mClosing = new AtomicBoolean();
+
+ private SimpleEntry<Integer, InputConfiguration> mOfflineInput =
+ new SimpleEntry<>(REQUEST_ID_NONE, null);
+ private SparseArray<OutputConfiguration> mOfflineOutputs = new SparseArray<>();
+
+ final Object mInterfaceLock = new Object(); // access from this class and Session only!
+
+ private final String mCameraId;
+ private final CameraCharacteristics mCharacteristics;
+ private final int mTotalPartialCount;
+
+ private final Executor mOfflineExecutor;
+ private final CameraOfflineSessionCallback mOfflineCallback;
+
+ private final CameraDeviceCallbacks mCallbacks = new CameraDeviceCallbacks();
+
+ /**
+ * A list tracking request and its expected last regular/reprocess/zslStill frame
+ * number.
+ */
+ private List<RequestLastFrameNumbersHolder> mOfflineRequestLastFrameNumbersList =
+ new ArrayList<>();
+
+ /**
+ * An object tracking received frame numbers.
+ * Updated when receiving callbacks from ICameraDeviceCallbacks.
+ */
+ private FrameNumberTracker mFrameNumberTracker = new FrameNumberTracker();
+
+ /** map request IDs to callback/request data */
+ private SparseArray<CaptureCallbackHolder> mCaptureCallbackMap =
+ new SparseArray<CaptureCallbackHolder>();
+
+ public CameraOfflineSessionImpl(String cameraId, CameraCharacteristics characteristics,
+ Executor offlineExecutor, CameraOfflineSessionCallback offlineCallback,
+ SparseArray<OutputConfiguration> offlineOutputs,
+ SimpleEntry<Integer, InputConfiguration> offlineInput,
+ FrameNumberTracker frameNumberTracker, SparseArray<CaptureCallbackHolder> callbackMap,
+ List<RequestLastFrameNumbersHolder> frameNumberList) {
+ if ((cameraId == null) || (characteristics == null)) {
+ throw new IllegalArgumentException("Null argument given");
+ }
+
+ mCameraId = cameraId;
+ mCharacteristics = characteristics;
+
+ Integer partialCount =
+ mCharacteristics.get(CameraCharacteristics.REQUEST_PARTIAL_RESULT_COUNT);
+ if (partialCount == null) {
+ // 1 means partial result is not supported.
+ mTotalPartialCount = 1;
+ } else {
+ mTotalPartialCount = partialCount;
+ }
+
+ mOfflineRequestLastFrameNumbersList.addAll(frameNumberList);
+ mFrameNumberTracker = frameNumberTracker;
+ mCaptureCallbackMap = callbackMap;
+ mOfflineOutputs = offlineOutputs;
+ mOfflineInput = offlineInput;
+ mOfflineExecutor = checkNotNull(offlineExecutor, "offline executor must not be null");
+ mOfflineCallback = checkNotNull(offlineCallback, "offline callback must not be null");
+
+ }
+
+ public CameraDeviceCallbacks getCallbacks() {
+ return mCallbacks;
+ }
+
+ public class CameraDeviceCallbacks extends ICameraDeviceCallbacks.Stub {
+ @Override
+ public IBinder asBinder() {
+ return this;
+ }
+
+ @Override
+ public void onDeviceError(final int errorCode, CaptureResultExtras resultExtras) {
+ synchronized(mInterfaceLock) {
+ if (mRemoteSession == null) {
+ return; // Camera already closed
+ }
+
+ switch (errorCode) {
+ case CameraDeviceCallbacks.ERROR_CAMERA_REQUEST:
+ case CameraDeviceCallbacks.ERROR_CAMERA_RESULT:
+ case CameraDeviceCallbacks.ERROR_CAMERA_BUFFER:
+ onCaptureErrorLocked(errorCode, resultExtras);
+ break;
+ default:
+ Runnable errorDispatch = new Runnable() {
+ @Override
+ public void run() {
+ if (!isClosed()) {
+ mOfflineCallback.onError(CameraOfflineSessionImpl.this,
+ CameraOfflineSessionCallback.STATUS_INTERNAL_ERROR);
+ }
+ }
+ };
+
+ final long ident = Binder.clearCallingIdentity();
+ try {
+ mOfflineExecutor.execute(errorDispatch);
+ } finally {
+ Binder.restoreCallingIdentity(ident);
+ }
+ }
+ }
+ }
+
+ @Override
+ public void onRepeatingRequestError(long lastFrameNumber, int repeatingRequestId) {
+ Log.e(TAG, "Unexpected repeating request error received. Last frame number is " +
+ lastFrameNumber);
+ }
+
+ @Override
+ public void onDeviceIdle() {
+ synchronized(mInterfaceLock) {
+ Runnable idleDispatch = new Runnable() {
+ @Override
+ public void run() {
+ if (!isClosed()) {
+ mOfflineCallback.onIdle(CameraOfflineSessionImpl.this);
+ }
+ }
+ };
+
+ final long ident = Binder.clearCallingIdentity();
+ try {
+ mOfflineExecutor.execute(idleDispatch);
+ } finally {
+ Binder.restoreCallingIdentity(ident);
+ }
+ }
+ }
+
+ @Override
+ public void onCaptureStarted(final CaptureResultExtras resultExtras, final long timestamp) {
+ int requestId = resultExtras.getRequestId();
+ final long frameNumber = resultExtras.getFrameNumber();
+
+ final CaptureCallbackHolder holder;
+
+ synchronized(mInterfaceLock) {
+ if (mRemoteSession == null) return; // Camera already closed
+
+ // Get the callback for this frame ID, if there is one
+ holder = CameraOfflineSessionImpl.this.mCaptureCallbackMap.get(requestId);
+
+ if (holder == null) {
+ return;
+ }
+
+ final Executor executor = holder.getCallback().getExecutor();
+ if (isClosed() || (executor == null)) return;
+
+ // Dispatch capture start notice
+ final long ident = Binder.clearCallingIdentity();
+ try {
+ executor.execute(
+ new Runnable() {
+ @Override
+ public void run() {
+ final CameraCaptureSession.CaptureCallback callback =
+ holder.getCallback().getSessionCallback();
+ if (!CameraOfflineSessionImpl.this.isClosed() &&
+ (callback != null)) {
+ final int subsequenceId = resultExtras.getSubsequenceId();
+ final CaptureRequest request = holder.getRequest(subsequenceId);
+
+ if (holder.hasBatchedOutputs()) {
+ // Send derived onCaptureStarted for requests within the
+ // batch
+ final Range<Integer> fpsRange =
+ request.get(
+ CaptureRequest.CONTROL_AE_TARGET_FPS_RANGE);
+ for (int i = 0; i < holder.getRequestCount(); i++) {
+ final CaptureRequest cbRequest = holder.getRequest(i);
+ final long cbTimestamp =
+ timestamp - (subsequenceId - i) *
+ NANO_PER_SECOND/fpsRange.getUpper();
+ final long cbFrameNumber =
+ frameNumber - (subsequenceId - i);
+ callback.onCaptureStarted(CameraOfflineSessionImpl.this,
+ cbRequest, cbTimestamp, cbFrameNumber);
+ }
+ } else {
+ callback.onCaptureStarted(CameraOfflineSessionImpl.this,
+ holder.getRequest(
+ resultExtras.getSubsequenceId()),
+ timestamp, frameNumber);
+ }
+ }
+ }
+ });
+ } finally {
+ Binder.restoreCallingIdentity(ident);
+ }
+ }
+ }
+
+ @Override
+ public void onResultReceived(CameraMetadataNative result,
+ CaptureResultExtras resultExtras, PhysicalCaptureResultInfo physicalResults[])
+ throws RemoteException {
+
+ int requestId = resultExtras.getRequestId();
+ long frameNumber = resultExtras.getFrameNumber();
+
+ synchronized(mInterfaceLock) {
+ if (mRemoteSession == null) return; // Camera already closed
+
+ // TODO: Handle CameraCharacteristics access from CaptureResult correctly.
+ result.set(CameraCharacteristics.LENS_INFO_SHADING_MAP_SIZE,
+ mCharacteristics.get(CameraCharacteristics.LENS_INFO_SHADING_MAP_SIZE));
+
+ final CaptureCallbackHolder holder =
+ CameraOfflineSessionImpl.this.mCaptureCallbackMap.get(requestId);
+ final CaptureRequest request = holder.getRequest(resultExtras.getSubsequenceId());
+
+ boolean isPartialResult =
+ (resultExtras.getPartialResultCount() < mTotalPartialCount);
+ int requestType = request.getRequestType();
+
+ // Check if we have a callback for this
+ if (holder == null) {
+ mFrameNumberTracker.updateTracker(frameNumber, /*result*/null, isPartialResult,
+ requestType);
+
+ return;
+ }
+
+ if (isClosed()) {
+ mFrameNumberTracker.updateTracker(frameNumber, /*result*/null, isPartialResult,
+ requestType);
+ return;
+ }
+
+
+ Runnable resultDispatch = null;
+
+ CaptureResult finalResult;
+ // Make a copy of the native metadata before it gets moved to a CaptureResult
+ // object.
+ final CameraMetadataNative resultCopy;
+ if (holder.hasBatchedOutputs()) {
+ resultCopy = new CameraMetadataNative(result);
+ } else {
+ resultCopy = null;
+ }
+
+ final Executor executor = holder.getCallback().getExecutor();
+ // Either send a partial result or the final capture completed result
+ if (isPartialResult) {
+ final CaptureResult resultAsCapture =
+ new CaptureResult(result, request, resultExtras);
+ // Partial result
+ resultDispatch = new Runnable() {
+ @Override
+ public void run() {
+ final CameraCaptureSession.CaptureCallback callback =
+ holder.getCallback().getSessionCallback();
+ if (!CameraOfflineSessionImpl.this.isClosed() && (callback != null)) {
+ if (holder.hasBatchedOutputs()) {
+ // Send derived onCaptureProgressed for requests within
+ // the batch.
+ for (int i = 0; i < holder.getRequestCount(); i++) {
+ CameraMetadataNative resultLocal =
+ new CameraMetadataNative(resultCopy);
+ final CaptureResult resultInBatch = new CaptureResult(
+ resultLocal, holder.getRequest(i), resultExtras);
+
+ final CaptureRequest cbRequest = holder.getRequest(i);
+ callback.onCaptureProgressed(CameraOfflineSessionImpl.this,
+ cbRequest, resultInBatch);
+ }
+ } else {
+ callback.onCaptureProgressed(CameraOfflineSessionImpl.this,
+ request, resultAsCapture);
+ }
+ }
+ }
+ };
+ finalResult = resultAsCapture;
+ } else {
+ List<CaptureResult> partialResults =
+ mFrameNumberTracker.popPartialResults(frameNumber);
+
+ final long sensorTimestamp =
+ result.get(CaptureResult.SENSOR_TIMESTAMP);
+ final Range<Integer> fpsRange =
+ request.get(CaptureRequest.CONTROL_AE_TARGET_FPS_RANGE);
+ final int subsequenceId = resultExtras.getSubsequenceId();
+ final TotalCaptureResult resultAsCapture = new TotalCaptureResult(result,
+ request, resultExtras, partialResults, holder.getSessionId(),
+ physicalResults);
+ // Final capture result
+ resultDispatch = new Runnable() {
+ @Override
+ public void run() {
+ final CameraCaptureSession.CaptureCallback callback =
+ holder.getCallback().getSessionCallback();
+ if (!CameraOfflineSessionImpl.this.isClosed() && (callback != null)) {
+ if (holder.hasBatchedOutputs()) {
+ // Send derived onCaptureCompleted for requests within
+ // the batch.
+ for (int i = 0; i < holder.getRequestCount(); i++) {
+ resultCopy.set(CaptureResult.SENSOR_TIMESTAMP,
+ sensorTimestamp - (subsequenceId - i) *
+ NANO_PER_SECOND/fpsRange.getUpper());
+ CameraMetadataNative resultLocal =
+ new CameraMetadataNative(resultCopy);
+ // No logical multi-camera support for batched output mode.
+ TotalCaptureResult resultInBatch = new TotalCaptureResult(
+ resultLocal, holder.getRequest(i), resultExtras,
+ partialResults, holder.getSessionId(),
+ new PhysicalCaptureResultInfo[0]);
+
+ final CaptureRequest cbRequest = holder.getRequest(i);
+ callback.onCaptureCompleted(CameraOfflineSessionImpl.this,
+ cbRequest, resultInBatch);
+ }
+ } else {
+ callback.onCaptureCompleted(CameraOfflineSessionImpl.this,
+ request, resultAsCapture);
+ }
+ }
+ }
+ };
+ finalResult = resultAsCapture;
+ }
+
+ if (executor != null) {
+ final long ident = Binder.clearCallingIdentity();
+ try {
+ executor.execute(resultDispatch);
+ } finally {
+ Binder.restoreCallingIdentity(ident);
+ }
+ }
+
+ // Collect the partials for a total result; or mark the frame as totally completed
+ mFrameNumberTracker.updateTracker(frameNumber, finalResult, isPartialResult,
+ requestType);
+
+ // Fire onCaptureSequenceCompleted
+ if (!isPartialResult) {
+ checkAndFireSequenceComplete();
+ }
+ }
+ }
+
+ @Override
+ public void onPrepared(int streamId) {
+ Log.e(TAG, "Unexpected stream " + streamId + " is prepared");
+ }
+
+ @Override
+ public void onRequestQueueEmpty() {
+ // No-op during offline mode
+ Log.v(TAG, "onRequestQueueEmpty");
+ }
+
+ /**
+ * Called by onDeviceError for handling single-capture failures.
+ */
+ private void onCaptureErrorLocked(int errorCode, CaptureResultExtras resultExtras) {
+ final int requestId = resultExtras.getRequestId();
+ final int subsequenceId = resultExtras.getSubsequenceId();
+ final long frameNumber = resultExtras.getFrameNumber();
+ final String errorPhysicalCameraId = resultExtras.getErrorPhysicalCameraId();
+ final CaptureCallbackHolder holder =
+ CameraOfflineSessionImpl.this.mCaptureCallbackMap.get(requestId);
+
+ if (holder == null) {
+ Log.e(TAG, String.format("Receive capture error on unknown request ID %d",
+ requestId));
+ return;
+ }
+
+ final CaptureRequest request = holder.getRequest(subsequenceId);
+
+ Runnable failureDispatch = null;
+ if (errorCode == ERROR_CAMERA_BUFFER) {
+ // Because 1 stream id could map to multiple surfaces, we need to specify both
+ // streamId and surfaceId.
+ OutputConfiguration config = mOfflineOutputs.get(
+ resultExtras.getErrorStreamId());
+ if (config == null) {
+ Log.v(TAG, String.format(
+ "Stream %d has been removed. Skipping buffer lost callback",
+ resultExtras.getErrorStreamId()));
+ return;
+ }
+ for (Surface surface : config.getSurfaces()) {
+ if (!request.containsTarget(surface)) {
+ continue;
+ }
+ final Executor executor = holder.getCallback().getExecutor();
+ failureDispatch = new Runnable() {
+ @Override
+ public void run() {
+ final CameraCaptureSession.CaptureCallback callback =
+ holder.getCallback().getSessionCallback();
+ if (!CameraOfflineSessionImpl.this.isClosed() && (callback != null)) {
+ callback.onCaptureBufferLost( CameraOfflineSessionImpl.this,
+ request, surface, frameNumber);
+ }
+ }
+ };
+ if (executor != null) {
+ // Dispatch the failure callback
+ final long ident = Binder.clearCallingIdentity();
+ try {
+ executor.execute(failureDispatch);
+ } finally {
+ Binder.restoreCallingIdentity(ident);
+ }
+ }
+ }
+ } else {
+ boolean mayHaveBuffers = (errorCode == ERROR_CAMERA_RESULT);
+ int reason = CaptureFailure.REASON_ERROR;
+
+ final CaptureFailure failure = new CaptureFailure(
+ request,
+ reason,
+ /*dropped*/ mayHaveBuffers,
+ requestId,
+ frameNumber,
+ errorPhysicalCameraId);
+
+ final Executor executor = holder.getCallback().getExecutor();
+ failureDispatch = new Runnable() {
+ @Override
+ public void run() {
+ final CameraCaptureSession.CaptureCallback callback =
+ holder.getCallback().getSessionCallback();
+ if (!CameraOfflineSessionImpl.this.isClosed() && (callback != null)) {
+ callback.onCaptureFailed(CameraOfflineSessionImpl.this, request,
+ failure);
+ }
+ }
+ };
+
+ // Fire onCaptureSequenceCompleted if appropriate
+ mFrameNumberTracker.updateTracker(frameNumber,
+ /*error*/true, request.getRequestType());
+ checkAndFireSequenceComplete();
+
+ if (executor != null) {
+ // Dispatch the failure callback
+ final long ident = Binder.clearCallingIdentity();
+ try {
+ executor.execute(failureDispatch);
+ } finally {
+ Binder.restoreCallingIdentity(ident);
+ }
+ }
+ }
+
+ }
+
+ }
+
+ private void checkAndFireSequenceComplete() {
+ long completedFrameNumber = mFrameNumberTracker.getCompletedFrameNumber();
+ long completedReprocessFrameNumber = mFrameNumberTracker.getCompletedReprocessFrameNumber();
+ long completedZslStillFrameNumber = mFrameNumberTracker.getCompletedZslStillFrameNumber();
+ Iterator<RequestLastFrameNumbersHolder> iter =
+ mOfflineRequestLastFrameNumbersList.iterator();
+ while (iter.hasNext()) {
+ final RequestLastFrameNumbersHolder requestLastFrameNumbers = iter.next();
+ boolean sequenceCompleted = false;
+ final int requestId = requestLastFrameNumbers.getRequestId();
+ final CaptureCallbackHolder holder;
+ final Executor executor;
+ final CameraCaptureSession.CaptureCallback callback;
+ synchronized(mInterfaceLock) {
+ if (mRemoteSession == null) {
+ Log.w(TAG, "Camera closed while checking sequences");
+ return;
+ }
+
+ int index = mCaptureCallbackMap.indexOfKey(requestId);
+ holder = (index >= 0) ?
+ mCaptureCallbackMap.valueAt(index) : null;
+ if (holder != null) {
+ long lastRegularFrameNumber =
+ requestLastFrameNumbers.getLastRegularFrameNumber();
+ long lastReprocessFrameNumber =
+ requestLastFrameNumbers.getLastReprocessFrameNumber();
+ long lastZslStillFrameNumber =
+ requestLastFrameNumbers.getLastZslStillFrameNumber();
+ executor = holder.getCallback().getExecutor();
+ callback = holder.getCallback().getSessionCallback();
+ // check if it's okay to remove request from mCaptureCallbackMap
+ if (lastRegularFrameNumber <= completedFrameNumber
+ && lastReprocessFrameNumber <= completedReprocessFrameNumber
+ && lastZslStillFrameNumber <= completedZslStillFrameNumber) {
+ sequenceCompleted = true;
+ mCaptureCallbackMap.removeAt(index);
+ }
+ } else {
+ executor = null;
+ callback = null;
+ }
+ }
+
+ // If no callback is registered for this requestId or sequence completed, remove it
+ // from the frame number->request pair because it's not needed anymore.
+ if (holder == null || sequenceCompleted) {
+ iter.remove();
+ }
+
+ // Call onCaptureSequenceCompleted
+ if ((sequenceCompleted) && (callback != null) && (executor == null)) {
+ Runnable resultDispatch = new Runnable() {
+ @Override
+ public void run() {
+ if (!isClosed()) {
+ callback.onCaptureSequenceCompleted(CameraOfflineSessionImpl.this,
+ requestId, requestLastFrameNumbers.getLastFrameNumber());
+ }
+ }
+ };
+
+ final long ident = Binder.clearCallingIdentity();
+ try {
+ executor.execute(resultDispatch);
+ } finally {
+ Binder.restoreCallingIdentity(ident);
+ }
+ }
+ }
+ }
+
+ public void notifyFailedSwitch() {
+ synchronized(mInterfaceLock) {
+ Runnable switchFailDispatch = new Runnable() {
+ @Override
+ public void run() {
+ mOfflineCallback.onSwitchFailed(CameraOfflineSessionImpl.this);
+ }
+ };
+
+ final long ident = Binder.clearCallingIdentity();
+ try {
+ mOfflineExecutor.execute(switchFailDispatch);
+ } finally {
+ Binder.restoreCallingIdentity(ident);
+ }
+ }
+ }
+
+ /**
+ * Set remote session.
+ *
+ */
+ public void setRemoteSession(ICameraOfflineSession remoteSession) throws CameraAccessException {
+ synchronized(mInterfaceLock) {
+ if (remoteSession == null) {
+ notifyFailedSwitch();
+ return;
+ }
+
+ mRemoteSession = remoteSession;
+
+ IBinder remoteSessionBinder = remoteSession.asBinder();
+ if (remoteSessionBinder == null) {
+ throw new CameraAccessException(CameraAccessException.CAMERA_DISCONNECTED,
+ "The camera offline session has encountered a serious error");
+ }
+
+ try {
+ remoteSessionBinder.linkToDeath(this, /*flag*/ 0);
+ } catch (RemoteException e) {
+ throw new CameraAccessException(CameraAccessException.CAMERA_DISCONNECTED,
+ "The camera offline session has encountered a serious error");
+ }
+
+ Runnable readyDispatch = new Runnable() {
+ @Override
+ public void run() {
+ if (!isClosed()) {
+ mOfflineCallback.onReady(CameraOfflineSessionImpl.this);
+ }
+ }
+ };
+
+ final long ident = Binder.clearCallingIdentity();
+ try {
+ mOfflineExecutor.execute(readyDispatch);
+ } finally {
+ Binder.restoreCallingIdentity(ident);
+ }
+ }
+ }
+
+ /** Whether the offline session has started to close (may not yet have finished) */
+ private boolean isClosed() {
+ return mClosing.get();
+ }
+
+ private void disconnect() {
+ synchronized (mInterfaceLock) {
+ if (mClosing.getAndSet(true)) {
+ return;
+ }
+
+ if (mRemoteSession != null) {
+ mRemoteSession.asBinder().unlinkToDeath(this, /*flags*/0);
+
+ try {
+ mRemoteSession.disconnect();
+ } catch (RemoteException e) {
+ Log.e(TAG, "Exception while disconnecting from offline session: ", e);
+ }
+ } else {
+ throw new IllegalStateException("Offline session is not yet ready");
+ }
+
+ mRemoteSession = null;
+
+ Runnable closeDispatch = new Runnable() {
+ @Override
+ public void run() {
+ if (!isClosed()) {
+ mOfflineCallback.onClosed(CameraOfflineSessionImpl.this);
+ }
+ }
+ };
+
+ final long ident = Binder.clearCallingIdentity();
+ try {
+ mOfflineExecutor.execute(closeDispatch);
+ } finally {
+ Binder.restoreCallingIdentity(ident);
+ }
+ }
+ }
+
+ @Override
+ protected void finalize() throws Throwable {
+ try {
+ disconnect();
+ }
+ finally {
+ super.finalize();
+ }
+ }
+
+ /**
+ * Listener for binder death.
+ *
+ * <p> Handle binder death for ICameraOfflineSession.</p>
+ */
+ @Override
+ public void binderDied() {
+ Log.w(TAG, "CameraOfflineSession on device " + mCameraId + " died unexpectedly");
+ disconnect();
+ }
+
+ @Override
+ public CameraDevice getDevice() {
+ throw new UnsupportedOperationException("Operation not supported in offline mode");
+ }
+
+ @Override
+ public void prepare(Surface surface) throws CameraAccessException {
+ throw new UnsupportedOperationException("Operation not supported in offline mode");
+ }
+
+ @Override
+ public void prepare(int maxCount, Surface surface) throws CameraAccessException {
+ throw new UnsupportedOperationException("Operation not supported in offline mode");
+ }
+
+ @Override
+ public void tearDown(Surface surface) throws CameraAccessException {
+ throw new UnsupportedOperationException("Operation not supported in offline mode");
+ }
+
+ @Override
+ public void finalizeOutputConfigurations(
+ List<OutputConfiguration> outputConfigs) throws CameraAccessException {
+ throw new UnsupportedOperationException("Operation not supported in offline mode");
+ }
+
+ @Override
+ public int capture(CaptureRequest request, CaptureCallback callback,
+ Handler handler) throws CameraAccessException {
+ throw new UnsupportedOperationException("Operation not supported in offline mode");
+ }
+
+ @Override
+ public int captureSingleRequest(CaptureRequest request, Executor executor,
+ CaptureCallback callback) throws CameraAccessException {
+ throw new UnsupportedOperationException("Operation not supported in offline mode");
+ }
+
+ @Override
+ public int captureBurst(List<CaptureRequest> requests, CaptureCallback callback,
+ Handler handler) throws CameraAccessException {
+ throw new UnsupportedOperationException("Operation not supported in offline mode");
+ }
+
+ @Override
+ public int captureBurstRequests(List<CaptureRequest> requests, Executor executor,
+ CaptureCallback callback) throws CameraAccessException {
+ throw new UnsupportedOperationException("Operation not supported in offline mode");
+ }
+
+ @Override
+ public int setRepeatingRequest(CaptureRequest request, CaptureCallback callback,
+ Handler handler) throws CameraAccessException {
+ throw new UnsupportedOperationException("Operation not supported in offline mode");
+ }
+
+ @Override
+ public int setSingleRepeatingRequest(CaptureRequest request, Executor executor,
+ CaptureCallback callback) throws CameraAccessException {
+ throw new UnsupportedOperationException("Operation not supported in offline mode");
+ }
+
+ @Override
+ public int setRepeatingBurst(List<CaptureRequest> requests,
+ CaptureCallback callback, Handler handler) throws CameraAccessException {
+ throw new UnsupportedOperationException("Operation not supported in offline mode");
+ }
+
+ @Override
+ public int setRepeatingBurstRequests(List<CaptureRequest> requests, Executor executor,
+ CaptureCallback callback) throws CameraAccessException {
+ throw new UnsupportedOperationException("Operation not supported in offline mode");
+ }
+
+ @Override
+ public void stopRepeating() throws CameraAccessException {
+ throw new UnsupportedOperationException("Operation not supported in offline mode");
+ }
+
+ @Override
+ public void abortCaptures() throws CameraAccessException {
+ throw new UnsupportedOperationException("Operation not supported in offline mode");
+ }
+
+ @Override
+ public void updateOutputConfiguration(OutputConfiguration config)
+ throws CameraAccessException {
+ throw new UnsupportedOperationException("Operation not supported in offline mode");
+ }
+
+ @Override
+ public boolean isReprocessable() {
+ throw new UnsupportedOperationException("Operation not supported in offline mode");
+ }
+
+ @Override
+ public Surface getInputSurface() {
+ throw new UnsupportedOperationException("Operation not supported in offline mode");
+ }
+
+ @Override
+ public CameraOfflineSession switchToOffline(Collection<Surface> offlineOutputs,
+ Executor executor, CameraOfflineSessionCallback listener) throws CameraAccessException {
+ throw new UnsupportedOperationException("Operation not supported in offline mode");
+ }
+
+ @Override
+ public boolean supportsOfflineProcessing(Surface surface) {
+ throw new UnsupportedOperationException("Operation not supported in offline mode");
+ }
+
+ @Override
+ public void close() {
+ disconnect();
+ }
+}
diff --git a/core/java/android/hardware/camera2/impl/CaptureCallback.java b/core/java/android/hardware/camera2/impl/CaptureCallback.java
new file mode 100644
index 000000000000..6defe63b1766
--- /dev/null
+++ b/core/java/android/hardware/camera2/impl/CaptureCallback.java
@@ -0,0 +1,124 @@
+/*
+ * Copyright (C) 2019 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 android.hardware.camera2.impl;
+
+import android.hardware.camera2.CameraCaptureSession;
+import android.hardware.camera2.CameraDevice;
+import android.hardware.camera2.CaptureFailure;
+import android.hardware.camera2.CaptureRequest;
+import android.hardware.camera2.CaptureResult;
+import android.hardware.camera2.TotalCaptureResult;
+import android.view.Surface;
+
+import java.util.concurrent.Executor;
+
+/**
+ * <p>An internal callback for tracking the progress of a {@link CaptureRequest}
+ * submitted to the camera device.</p>
+ */
+public abstract class CaptureCallback {
+
+ private Executor mExecutor;
+ private CameraCaptureSession.CaptureCallback mCallback;
+
+ public CaptureCallback(Executor executor, CameraCaptureSession.CaptureCallback callback) {
+ mExecutor = executor;
+ mCallback = callback;
+ }
+
+ /**
+ * Retrieve callback executor
+ *
+ */
+ public Executor getExecutor() {
+ return mExecutor;
+ }
+
+ /**
+ * Retrieve capture callback
+ *
+ */
+ public CameraCaptureSession.CaptureCallback getSessionCallback() {
+ return mCallback;
+ }
+
+ /**
+ * This method is called when the camera device has started capturing
+ * the output image for the request, at the beginning of image exposure.
+ *
+ * @see android.media.MediaActionSound
+ */
+ public abstract void onCaptureStarted(CameraDevice camera,
+ CaptureRequest request, long timestamp, long frameNumber);
+
+ /**
+ * This method is called when some results from an image capture are
+ * available.
+ *
+ * @hide
+ */
+ public abstract void onCapturePartial(CameraDevice camera,
+ CaptureRequest request, CaptureResult result);
+
+ /**
+ * This method is called when an image capture makes partial forward progress; some
+ * (but not all) results from an image capture are available.
+ *
+ */
+ public abstract void onCaptureProgressed(CameraDevice camera,
+ CaptureRequest request, CaptureResult partialResult);
+
+ /**
+ * This method is called when an image capture has fully completed and all the
+ * result metadata is available.
+ */
+ public abstract void onCaptureCompleted(CameraDevice camera,
+ CaptureRequest request, TotalCaptureResult result);
+
+ /**
+ * This method is called instead of {@link #onCaptureCompleted} when the
+ * camera device failed to produce a {@link CaptureResult} for the
+ * request.
+ */
+ public abstract void onCaptureFailed(CameraDevice camera,
+ CaptureRequest request, CaptureFailure failure);
+
+ /**
+ * This method is called independently of the others in CaptureCallback,
+ * when a capture sequence finishes and all {@link CaptureResult}
+ * or {@link CaptureFailure} for it have been returned via this callback.
+ */
+ public abstract void onCaptureSequenceCompleted(CameraDevice camera,
+ int sequenceId, long frameNumber);
+
+ /**
+ * This method is called independently of the others in CaptureCallback,
+ * when a capture sequence aborts before any {@link CaptureResult}
+ * or {@link CaptureFailure} for it have been returned via this callback.
+ */
+ public abstract void onCaptureSequenceAborted(CameraDevice camera,
+ int sequenceId);
+
+ /**
+ * This method is called independently of the others in CaptureCallback, if an output buffer
+ * is dropped for a particular capture request.
+ *
+ * Loss of metadata is communicated via onCaptureFailed, independently of any buffer loss.
+ */
+ public abstract void onCaptureBufferLost(CameraDevice camera,
+ CaptureRequest request, Surface target, long frameNumber);
+}
diff --git a/core/java/android/hardware/camera2/impl/CaptureCallbackHolder.java b/core/java/android/hardware/camera2/impl/CaptureCallbackHolder.java
new file mode 100644
index 000000000000..01c38907b7e3
--- /dev/null
+++ b/core/java/android/hardware/camera2/impl/CaptureCallbackHolder.java
@@ -0,0 +1,119 @@
+/*
+ * Copyright (C) 2019 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 android.hardware.camera2.impl;
+
+import android.hardware.camera2.CaptureRequest;
+import android.view.Surface;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+import java.util.concurrent.Executor;
+
+public class CaptureCallbackHolder {
+
+ private final boolean mRepeating;
+ private final CaptureCallback mCallback;
+ private final List<CaptureRequest> mRequestList;
+ private final Executor mExecutor;
+ private final int mSessionId;
+ /**
+ * <p>Determine if the callback holder is for a constrained high speed request list that
+ * expects batched capture results. Capture results will be batched if the request list
+ * is interleaved with preview and video requests. Capture results won't be batched if the
+ * request list only contains preview requests, or if the request doesn't belong to a
+ * constrained high speed list.
+ */
+ private final boolean mHasBatchedOutputs;
+
+ CaptureCallbackHolder(CaptureCallback callback, List<CaptureRequest> requestList,
+ Executor executor, boolean repeating, int sessionId) {
+ if (callback == null || executor == null) {
+ throw new UnsupportedOperationException(
+ "Must have a valid handler and a valid callback");
+ }
+ mRepeating = repeating;
+ mExecutor = executor;
+ mRequestList = new ArrayList<CaptureRequest>(requestList);
+ mCallback = callback;
+ mSessionId = sessionId;
+
+ // Check whether this callback holder is for batched outputs.
+ // The logic here should match createHighSpeedRequestList.
+ boolean hasBatchedOutputs = true;
+ for (int i = 0; i < requestList.size(); i++) {
+ CaptureRequest request = requestList.get(i);
+ if (!request.isPartOfCRequestList()) {
+ hasBatchedOutputs = false;
+ break;
+ }
+ if (i == 0) {
+ Collection<Surface> targets = request.getTargets();
+ if (targets.size() != 2) {
+ hasBatchedOutputs = false;
+ break;
+ }
+ }
+ }
+ mHasBatchedOutputs = hasBatchedOutputs;
+ }
+
+ public boolean isRepeating() {
+ return mRepeating;
+ }
+
+ public CaptureCallback getCallback() {
+ return mCallback;
+ }
+
+ public CaptureRequest getRequest(int subsequenceId) {
+ if (subsequenceId >= mRequestList.size()) {
+ throw new IllegalArgumentException(
+ String.format(
+ "Requested subsequenceId %d is larger than request list size %d.",
+ subsequenceId, mRequestList.size()));
+ } else {
+ if (subsequenceId < 0) {
+ throw new IllegalArgumentException(String.format(
+ "Requested subsequenceId %d is negative", subsequenceId));
+ } else {
+ return mRequestList.get(subsequenceId);
+ }
+ }
+ }
+
+ public CaptureRequest getRequest() {
+ return getRequest(0);
+ }
+
+ public Executor getExecutor() {
+ return mExecutor;
+ }
+
+ public int getSessionId() {
+ return mSessionId;
+ }
+
+ public int getRequestCount() {
+ return mRequestList.size();
+ }
+
+ public boolean hasBatchedOutputs() {
+ return mHasBatchedOutputs;
+ }
+}
diff --git a/core/java/android/hardware/camera2/impl/FrameNumberTracker.java b/core/java/android/hardware/camera2/impl/FrameNumberTracker.java
new file mode 100644
index 000000000000..27f8a61b8999
--- /dev/null
+++ b/core/java/android/hardware/camera2/impl/FrameNumberTracker.java
@@ -0,0 +1,261 @@
+/*
+ * Copyright (C) 2019 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 android.hardware.camera2.impl;
+
+import android.hardware.camera2.CameraCaptureSession;
+import android.hardware.camera2.CaptureRequest;
+import android.hardware.camera2.CaptureResult;
+import android.util.Log;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.TreeMap;
+
+/**
+ * This class tracks the last frame number for submitted requests.
+ */
+public class FrameNumberTracker {
+ private static final String TAG = "FrameNumberTracker";
+
+ /** the completed frame number for each type of capture results */
+ private long[] mCompletedFrameNumber = new long[CaptureRequest.REQUEST_TYPE_COUNT];
+
+ /** the skipped frame numbers that don't belong to each type of capture results */
+ private final LinkedList<Long>[] mSkippedOtherFrameNumbers =
+ new LinkedList[CaptureRequest.REQUEST_TYPE_COUNT];
+
+ /** the skipped frame numbers that belong to each type of capture results */
+ private final LinkedList<Long>[] mSkippedFrameNumbers =
+ new LinkedList[CaptureRequest.REQUEST_TYPE_COUNT];
+
+ /** frame number -> request type */
+ private final TreeMap<Long, Integer> mFutureErrorMap = new TreeMap<Long, Integer>();
+ /** Map frame numbers to list of partial results */
+ private final HashMap<Long, List<CaptureResult>> mPartialResults = new HashMap<>();
+
+ public FrameNumberTracker() {
+ for (int i = 0; i < CaptureRequest.REQUEST_TYPE_COUNT; i++) {
+ mCompletedFrameNumber[i] = CameraCaptureSession.CaptureCallback.NO_FRAMES_CAPTURED;
+ mSkippedOtherFrameNumbers[i] = new LinkedList<Long>();
+ mSkippedFrameNumbers[i] = new LinkedList<Long>();
+ }
+ }
+
+ private void update() {
+ Iterator iter = mFutureErrorMap.entrySet().iterator();
+ while (iter.hasNext()) {
+ TreeMap.Entry pair = (TreeMap.Entry)iter.next();
+ Long errorFrameNumber = (Long)pair.getKey();
+ int requestType = (int) pair.getValue();
+ Boolean removeError = false;
+ if (errorFrameNumber == mCompletedFrameNumber[requestType] + 1) {
+ mCompletedFrameNumber[requestType] = errorFrameNumber;
+ removeError = true;
+ } else {
+ if (!mSkippedFrameNumbers[requestType].isEmpty()) {
+ if (errorFrameNumber == mSkippedFrameNumbers[requestType].element()) {
+ mCompletedFrameNumber[requestType] = errorFrameNumber;
+ mSkippedFrameNumbers[requestType].remove();
+ removeError = true;
+ }
+ } else {
+ for (int i = 1; i < CaptureRequest.REQUEST_TYPE_COUNT; i++) {
+ int otherType = (requestType + i) % CaptureRequest.REQUEST_TYPE_COUNT;
+ if (!mSkippedOtherFrameNumbers[otherType].isEmpty() && errorFrameNumber
+ == mSkippedOtherFrameNumbers[otherType].element()) {
+ mCompletedFrameNumber[requestType] = errorFrameNumber;
+ mSkippedOtherFrameNumbers[otherType].remove();
+ removeError = true;
+ break;
+ }
+ }
+ }
+ }
+ if (removeError) {
+ iter.remove();
+ }
+ }
+ }
+
+ /**
+ * This function is called every time when a result or an error is received.
+ * @param frameNumber the frame number corresponding to the result or error
+ * @param isError true if it is an error, false if it is not an error
+ * @param requestType the type of capture request: Reprocess, ZslStill, or Regular.
+ */
+ public void updateTracker(long frameNumber, boolean isError, int requestType) {
+ if (isError) {
+ mFutureErrorMap.put(frameNumber, requestType);
+ } else {
+ try {
+ updateCompletedFrameNumber(frameNumber, requestType);
+ } catch (IllegalArgumentException e) {
+ Log.e(TAG, e.getMessage());
+ }
+ }
+ update();
+ }
+
+ /**
+ * This function is called every time a result has been completed.
+ *
+ * <p>It keeps a track of all the partial results already created for a particular
+ * frame number.</p>
+ *
+ * @param frameNumber the frame number corresponding to the result
+ * @param result the total or partial result
+ * @param partial {@true} if the result is partial, {@code false} if total
+ * @param requestType the type of capture request: Reprocess, ZslStill, or Regular.
+ */
+ public void updateTracker(long frameNumber, CaptureResult result, boolean partial,
+ int requestType) {
+ if (!partial) {
+ // Update the total result's frame status as being successful
+ updateTracker(frameNumber, /*isError*/false, requestType);
+ // Don't keep a list of total results, we don't need to track them
+ return;
+ }
+
+ if (result == null) {
+ // Do not record blank results; this also means there will be no total result
+ // so it doesn't matter that the partials were not recorded
+ return;
+ }
+
+ // Partial results must be aggregated in-order for that frame number
+ List<CaptureResult> partials = mPartialResults.get(frameNumber);
+ if (partials == null) {
+ partials = new ArrayList<>();
+ mPartialResults.put(frameNumber, partials);
+ }
+
+ partials.add(result);
+ }
+
+ /**
+ * Attempt to pop off all of the partial results seen so far for the {@code frameNumber}.
+ *
+ * <p>Once popped-off, the partial results are forgotten (unless {@code updateTracker}
+ * is called again with new partials for that frame number).</p>
+ *
+ * @param frameNumber the frame number corresponding to the result
+ * @return a list of partial results for that frame with at least 1 element,
+ * or {@code null} if there were no partials recorded for that frame
+ */
+ public List<CaptureResult> popPartialResults(long frameNumber) {
+ return mPartialResults.remove(frameNumber);
+ }
+
+ public long getCompletedFrameNumber() {
+ return mCompletedFrameNumber[CaptureRequest.REQUEST_TYPE_REGULAR];
+ }
+
+ public long getCompletedReprocessFrameNumber() {
+ return mCompletedFrameNumber[CaptureRequest.REQUEST_TYPE_REPROCESS];
+ }
+
+ public long getCompletedZslStillFrameNumber() {
+ return mCompletedFrameNumber[CaptureRequest.REQUEST_TYPE_ZSL_STILL];
+ }
+
+ /**
+ * Update the completed frame number for results of 3 categories
+ * (Regular/Reprocess/ZslStill).
+ *
+ * It validates that all previous frames of the same category have arrived.
+ *
+ * If there is a gap since previous frame number of the same category, assume the frames in
+ * the gap are other categories and store them in the skipped frame number queue to check
+ * against when frames of those categories arrive.
+ */
+ private void updateCompletedFrameNumber(long frameNumber,
+ int requestType) throws IllegalArgumentException {
+ if (frameNumber <= mCompletedFrameNumber[requestType]) {
+ throw new IllegalArgumentException("frame number " + frameNumber + " is a repeat");
+ }
+
+ // Assume there are only 3 different types of capture requests.
+ int otherType1 = (requestType + 1) % CaptureRequest.REQUEST_TYPE_COUNT;
+ int otherType2 = (requestType + 2) % CaptureRequest.REQUEST_TYPE_COUNT;
+ long maxOtherFrameNumberSeen =
+ Math.max(mCompletedFrameNumber[otherType1], mCompletedFrameNumber[otherType2]);
+ if (frameNumber < maxOtherFrameNumberSeen) {
+ // if frame number is smaller than completed frame numbers of other categories,
+ // it must be:
+ // - the head of mSkippedFrameNumbers for this category, or
+ // - in one of other mSkippedOtherFrameNumbers
+ if (!mSkippedFrameNumbers[requestType].isEmpty()) {
+ // frame number must be head of current type of mSkippedFrameNumbers if
+ // mSkippedFrameNumbers isn't empty.
+ if (frameNumber < mSkippedFrameNumbers[requestType].element()) {
+ throw new IllegalArgumentException("frame number " + frameNumber
+ + " is a repeat");
+ } else if (frameNumber > mSkippedFrameNumbers[requestType].element()) {
+ throw new IllegalArgumentException("frame number " + frameNumber
+ + " comes out of order. Expecting "
+ + mSkippedFrameNumbers[requestType].element());
+ }
+ // frame number matches the head of the skipped frame number queue.
+ mSkippedFrameNumbers[requestType].remove();
+ } else {
+ // frame number must be in one of the other mSkippedOtherFrameNumbers.
+ int index1 = mSkippedOtherFrameNumbers[otherType1].indexOf(frameNumber);
+ int index2 = mSkippedOtherFrameNumbers[otherType2].indexOf(frameNumber);
+ boolean inSkippedOther1 = index1 != -1;
+ boolean inSkippedOther2 = index2 != -1;
+ if (!(inSkippedOther1 ^ inSkippedOther2)) {
+ throw new IllegalArgumentException("frame number " + frameNumber
+ + " is a repeat or invalid");
+ }
+
+ // We know the category of frame numbers in skippedOtherFrameNumbers leading up
+ // to the current frame number. Move them into the correct skippedFrameNumbers.
+ LinkedList<Long> srcList, dstList;
+ int index;
+ if (inSkippedOther1) {
+ srcList = mSkippedOtherFrameNumbers[otherType1];
+ dstList = mSkippedFrameNumbers[otherType2];
+ index = index1;
+ } else {
+ srcList = mSkippedOtherFrameNumbers[otherType2];
+ dstList = mSkippedFrameNumbers[otherType1];
+ index = index2;
+ }
+ for (int i = 0; i < index; i++) {
+ dstList.add(srcList.removeFirst());
+ }
+
+ // Remove current frame number from skippedOtherFrameNumbers
+ srcList.remove();
+ }
+ } else {
+ // there is a gap of unseen frame numbers which should belong to the other
+ // 2 categories. Put all the skipped frame numbers in the queue.
+ for (long i =
+ Math.max(maxOtherFrameNumberSeen, mCompletedFrameNumber[requestType]) + 1;
+ i < frameNumber; i++) {
+ mSkippedOtherFrameNumbers[requestType].add(i);
+ }
+ }
+
+ mCompletedFrameNumber[requestType] = frameNumber;
+ }
+}
+
diff --git a/core/java/android/hardware/camera2/impl/ICameraDeviceUserWrapper.java b/core/java/android/hardware/camera2/impl/ICameraDeviceUserWrapper.java
index 397417ba5b4f..fa7301bb72c3 100644
--- a/core/java/android/hardware/camera2/impl/ICameraDeviceUserWrapper.java
+++ b/core/java/android/hardware/camera2/impl/ICameraDeviceUserWrapper.java
@@ -110,10 +110,10 @@ public class ICameraDeviceUserWrapper {
}
}
- public void endConfigure(int operatingMode, CameraMetadataNative sessionParams)
+ public int[] endConfigure(int operatingMode, CameraMetadataNative sessionParams)
throws CameraAccessException {
try {
- mRemoteDevice.endConfigure(operatingMode, (sessionParams == null) ?
+ return mRemoteDevice.endConfigure(operatingMode, (sessionParams == null) ?
new CameraMetadataNative() : sessionParams);
} catch (Throwable t) {
CameraManager.throwAsPublicException(t);
@@ -251,10 +251,9 @@ public class ICameraDeviceUserWrapper {
}
public ICameraOfflineSession switchToOffline(ICameraDeviceCallbacks cbs,
- Surface[] offlineOutputs)
- throws CameraAccessException {
+ int[] offlineOutputIds) throws CameraAccessException {
try {
- return mRemoteDevice.switchToOffline(cbs, offlineOutputs);
+ return mRemoteDevice.switchToOffline(cbs, offlineOutputIds);
} catch (Throwable t) {
CameraManager.throwAsPublicException(t);
throw new UnsupportedOperationException("Unexpected exception", t);
diff --git a/core/java/android/hardware/camera2/impl/RequestLastFrameNumbersHolder.java b/core/java/android/hardware/camera2/impl/RequestLastFrameNumbersHolder.java
new file mode 100644
index 000000000000..bd1df9e1ac7d
--- /dev/null
+++ b/core/java/android/hardware/camera2/impl/RequestLastFrameNumbersHolder.java
@@ -0,0 +1,181 @@
+/*
+ * Copyright (C) 2019 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 android.hardware.camera2.impl;
+
+import android.hardware.camera2.CameraCaptureSession;
+import android.hardware.camera2.CaptureRequest;
+import android.hardware.camera2.utils.SubmitInfo;
+
+import java.util.List;
+
+/**
+ * This class holds a capture ID and its expected last regular, zslStill, and reprocess
+ * frame number.
+ */
+public class RequestLastFrameNumbersHolder {
+ // request ID
+ private final int mRequestId;
+ // The last regular frame number for this request ID. It's
+ // CaptureCallback.NO_FRAMES_CAPTURED if the request ID has no regular request.
+ private final long mLastRegularFrameNumber;
+ // The last reprocess frame number for this request ID. It's
+ // CaptureCallback.NO_FRAMES_CAPTURED if the request ID has no reprocess request.
+ private final long mLastReprocessFrameNumber;
+ // The last ZSL still capture frame number for this request ID. It's
+ // CaptureCallback.NO_FRAMES_CAPTURED if the request ID has no zsl request.
+ private final long mLastZslStillFrameNumber;
+
+ /**
+ * Create a request-last-frame-numbers holder with a list of requests, request ID, and
+ * the last frame number returned by camera service.
+ */
+ public RequestLastFrameNumbersHolder(List<CaptureRequest> requestList, SubmitInfo requestInfo) {
+ long lastRegularFrameNumber = CameraCaptureSession.CaptureCallback.NO_FRAMES_CAPTURED;
+ long lastReprocessFrameNumber = CameraCaptureSession.CaptureCallback.NO_FRAMES_CAPTURED;
+ long lastZslStillFrameNumber = CameraCaptureSession.CaptureCallback.NO_FRAMES_CAPTURED;
+ long frameNumber = requestInfo.getLastFrameNumber();
+
+ if (requestInfo.getLastFrameNumber() < requestList.size() - 1) {
+ throw new IllegalArgumentException(
+ "lastFrameNumber: " + requestInfo.getLastFrameNumber() +
+ " should be at least " + (requestList.size() - 1) + " for the number of " +
+ " requests in the list: " + requestList.size());
+ }
+
+ // find the last regular, zslStill, and reprocess frame number
+ for (int i = requestList.size() - 1; i >= 0; i--) {
+ CaptureRequest request = requestList.get(i);
+ int requestType = request.getRequestType();
+ if (requestType == CaptureRequest.REQUEST_TYPE_REPROCESS
+ && lastReprocessFrameNumber ==
+ CameraCaptureSession.CaptureCallback.NO_FRAMES_CAPTURED) {
+ lastReprocessFrameNumber = frameNumber;
+ } else if (requestType == CaptureRequest.REQUEST_TYPE_ZSL_STILL
+ && lastZslStillFrameNumber ==
+ CameraCaptureSession.CaptureCallback.NO_FRAMES_CAPTURED) {
+ lastZslStillFrameNumber = frameNumber;
+ } else if (requestType == CaptureRequest.REQUEST_TYPE_REGULAR
+ && lastRegularFrameNumber ==
+ CameraCaptureSession.CaptureCallback.NO_FRAMES_CAPTURED) {
+ lastRegularFrameNumber = frameNumber;
+ }
+
+ if (lastReprocessFrameNumber != CameraCaptureSession.CaptureCallback.NO_FRAMES_CAPTURED
+ && lastZslStillFrameNumber !=
+ CameraCaptureSession.CaptureCallback.NO_FRAMES_CAPTURED
+ && lastRegularFrameNumber !=
+ CameraCaptureSession.CaptureCallback.NO_FRAMES_CAPTURED) {
+ break;
+ }
+
+ frameNumber--;
+ }
+
+ mLastRegularFrameNumber = lastRegularFrameNumber;
+ mLastReprocessFrameNumber = lastReprocessFrameNumber;
+ mLastZslStillFrameNumber = lastZslStillFrameNumber;
+ mRequestId = requestInfo.getRequestId();
+ }
+
+ /**
+ * Create a request-last-frame-numbers holder with a request ID and last regular/ZslStill
+ * frame number.
+ */
+ RequestLastFrameNumbersHolder(int requestId, long lastFrameNumber,
+ int[] repeatingRequestTypes) {
+ long lastRegularFrameNumber = CameraCaptureSession.CaptureCallback.NO_FRAMES_CAPTURED;
+ long lastZslStillFrameNumber = CameraCaptureSession.CaptureCallback.NO_FRAMES_CAPTURED;
+
+ if (repeatingRequestTypes == null) {
+ throw new IllegalArgumentException(
+ "repeatingRequest list must not be null");
+ }
+ if (lastFrameNumber < repeatingRequestTypes.length - 1) {
+ throw new IllegalArgumentException(
+ "lastFrameNumber: " + lastFrameNumber + " should be at least "
+ + (repeatingRequestTypes.length - 1)
+ + " for the number of requests in the list: "
+ + repeatingRequestTypes.length);
+ }
+
+ long frameNumber = lastFrameNumber;
+ for (int i = repeatingRequestTypes.length - 1; i >= 0; i--) {
+ if (repeatingRequestTypes[i] == CaptureRequest.REQUEST_TYPE_ZSL_STILL
+ && lastZslStillFrameNumber ==
+ CameraCaptureSession.CaptureCallback.NO_FRAMES_CAPTURED) {
+ lastZslStillFrameNumber = frameNumber;
+ } else if (repeatingRequestTypes[i] == CaptureRequest.REQUEST_TYPE_REGULAR
+ && lastRegularFrameNumber ==
+ CameraCaptureSession.CaptureCallback.NO_FRAMES_CAPTURED) {
+ lastRegularFrameNumber = frameNumber;
+ }
+
+ if (lastZslStillFrameNumber != CameraCaptureSession.CaptureCallback.NO_FRAMES_CAPTURED
+ && lastRegularFrameNumber !=
+ CameraCaptureSession.CaptureCallback.NO_FRAMES_CAPTURED) {
+ break;
+ }
+
+ frameNumber--;
+ }
+
+ mLastRegularFrameNumber = lastRegularFrameNumber;
+ mLastZslStillFrameNumber = lastZslStillFrameNumber;
+ mLastReprocessFrameNumber = CameraCaptureSession.CaptureCallback.NO_FRAMES_CAPTURED;
+ mRequestId = requestId;
+ }
+
+ /**
+ * Return the last regular frame number. Return CaptureCallback.NO_FRAMES_CAPTURED if
+ * it contains no regular request.
+ */
+ public long getLastRegularFrameNumber() {
+ return mLastRegularFrameNumber;
+ }
+
+ /**
+ * Return the last reprocess frame number. Return CaptureCallback.NO_FRAMES_CAPTURED if
+ * it contains no reprocess request.
+ */
+ public long getLastReprocessFrameNumber() {
+ return mLastReprocessFrameNumber;
+ }
+
+ /**
+ * Return the last ZslStill frame number. Return CaptureCallback.NO_FRAMES_CAPTURED if
+ * it contains no Zsl request.
+ */
+ public long getLastZslStillFrameNumber() {
+ return mLastZslStillFrameNumber;
+ }
+
+ /**
+ * Return the last frame number overall.
+ */
+ public long getLastFrameNumber() {
+ return Math.max(mLastZslStillFrameNumber,
+ Math.max(mLastRegularFrameNumber, mLastReprocessFrameNumber));
+ }
+
+ /**
+ * Return the request ID.
+ */
+ public int getRequestId() {
+ return mRequestId;
+ }
+}
+
diff --git a/core/java/android/hardware/camera2/legacy/CameraDeviceUserShim.java b/core/java/android/hardware/camera2/legacy/CameraDeviceUserShim.java
index 6ab0c294f5e4..cf8cab2cbc44 100644
--- a/core/java/android/hardware/camera2/legacy/CameraDeviceUserShim.java
+++ b/core/java/android/hardware/camera2/legacy/CameraDeviceUserShim.java
@@ -541,7 +541,7 @@ public class CameraDeviceUserShim implements ICameraDeviceUser {
}
@Override
- public void endConfigure(int operatingMode, CameraMetadataNative sessionParams) {
+ public int[] endConfigure(int operatingMode, CameraMetadataNative sessionParams) {
if (DEBUG) {
Log.d(TAG, "endConfigure called.");
}
@@ -576,6 +576,8 @@ public class CameraDeviceUserShim implements ICameraDeviceUser {
mConfiguring = false;
}
mLegacyDevice.configureOutputs(surfaces);
+
+ return new int[0]; // Offline mode is not supported
}
@Override
@@ -791,8 +793,8 @@ public class CameraDeviceUserShim implements ICameraDeviceUser {
@Override
public ICameraOfflineSession switchToOffline(ICameraDeviceCallbacks cbs,
- Surface[] offlineOutputs) {
- throw new UnsupportedOperationException("Legacy device does not support switchToOffline");
+ int[] offlineOutputIds) {
+ throw new UnsupportedOperationException("Legacy device does not support offline mode");
}
@Override
diff --git a/core/java/android/inputmethodservice/IInputMethodWrapper.java b/core/java/android/inputmethodservice/IInputMethodWrapper.java
index 4d5fabbae961..2a441de067c6 100644
--- a/core/java/android/inputmethodservice/IInputMethodWrapper.java
+++ b/core/java/android/inputmethodservice/IInputMethodWrapper.java
@@ -221,7 +221,9 @@ class IInputMethodWrapper extends IInputMethod.Stub
inputMethod.revokeSession((InputMethodSession)msg.obj);
return;
case DO_SHOW_SOFT_INPUT:
- inputMethod.showSoftInput(msg.arg1, (ResultReceiver)msg.obj);
+ SomeArgs args = (SomeArgs)msg.obj;
+ inputMethod.showSoftInputWithToken(
+ msg.arg1, (ResultReceiver) args.arg2, (IBinder) args.arg1);
return;
case DO_HIDE_SOFT_INPUT:
inputMethod.hideSoftInput(msg.arg1, (ResultReceiver)msg.obj);
@@ -230,10 +232,11 @@ class IInputMethodWrapper extends IInputMethod.Stub
inputMethod.changeInputMethodSubtype((InputMethodSubtype)msg.obj);
return;
case DO_CREATE_INLINE_SUGGESTIONS_REQUEST:
- SomeArgs args = (SomeArgs) msg.obj;
+ args = (SomeArgs) msg.obj;
inputMethod.onCreateInlineSuggestionsRequest((ComponentName) args.arg1,
(AutofillId) args.arg2, (IInlineSuggestionsRequestCallback) args.arg3);
return;
+
}
Log.w(TAG, "Unhandled message code: " + msg.what);
}
@@ -371,9 +374,9 @@ class IInputMethodWrapper extends IInputMethod.Stub
@BinderThread
@Override
- public void showSoftInput(int flags, ResultReceiver resultReceiver) {
- mCaller.executeOrSendMessage(mCaller.obtainMessageIO(DO_SHOW_SOFT_INPUT,
- flags, resultReceiver));
+ public void showSoftInput(IBinder showInputToken, int flags, ResultReceiver resultReceiver) {
+ mCaller.executeOrSendMessage(mCaller.obtainMessageIOO(DO_SHOW_SOFT_INPUT,
+ flags, showInputToken, resultReceiver));
}
@BinderThread
diff --git a/core/java/android/inputmethodservice/InputMethodService.java b/core/java/android/inputmethodservice/InputMethodService.java
index 8e52ee944c1c..81a0d629380a 100644
--- a/core/java/android/inputmethodservice/InputMethodService.java
+++ b/core/java/android/inputmethodservice/InputMethodService.java
@@ -46,11 +46,13 @@ import android.database.ContentObserver;
import android.graphics.Rect;
import android.graphics.Region;
import android.net.Uri;
+import android.os.Binder;
import android.os.Build;
import android.os.Bundle;
import android.os.Handler;
import android.os.IBinder;
import android.os.Looper;
+import android.os.Process;
import android.os.RemoteException;
import android.os.ResultReceiver;
import android.os.SystemClock;
@@ -450,6 +452,16 @@ public class InputMethodService extends AbstractInputMethodService {
@Nullable
private InlineSuggestionsRequestInfo mInlineSuggestionsRequestInfo = null;
+ /**
+ * An opaque {@link Binder} token of window requesting {@link InputMethodImpl#showSoftInput}
+ * The original app window token is passed from client app window.
+ * {@link com.android.server.inputmethod.InputMethodManagerService} creates a unique dummy
+ * token to identify this window.
+ * This dummy token is only valid for a single call to {@link InputMethodImpl#showSoftInput},
+ * after which it is set null until next call.
+ */
+ private IBinder mCurShowInputToken;
+
private final Handler mHandler = new Handler(Looper.getMainLooper(), null, true);
final ViewTreeObserver.OnComputeInternalInsetsListener mInsetsComputer = info -> {
@@ -491,6 +503,9 @@ public class InputMethodService extends AbstractInputMethodService {
* all of the standard behavior for an input method.
*/
public class InputMethodImpl extends AbstractInputMethodImpl {
+
+ private boolean mSystemCallingShowSoftInput;
+
/**
* {@inheritDoc}
* @hide
@@ -659,11 +674,33 @@ public class InputMethodService extends AbstractInputMethodService {
/**
* {@inheritDoc}
+ * @hide
+ */
+ @MainThread
+ @Override
+ public void showSoftInputWithToken(int flags, ResultReceiver resultReceiver,
+ IBinder showInputToken) {
+ mSystemCallingShowSoftInput = true;
+ mCurShowInputToken = showInputToken;
+ showSoftInput(flags, resultReceiver);
+ mCurShowInputToken = null;
+ mSystemCallingShowSoftInput = false;
+ }
+
+ /**
+ * {@inheritDoc}
*/
@MainThread
@Override
public void showSoftInput(int flags, ResultReceiver resultReceiver) {
if (DEBUG) Log.v(TAG, "showSoftInput()");
+ // TODO(b/148086656): Disallow IME developers from calling InputMethodImpl methods.
+ if (getApplicationInfo().targetSdkVersion >= Build.VERSION_CODES.R
+ && !mSystemCallingShowSoftInput) {
+ Log.e(TAG," IME shouldn't call showSoftInput on itself."
+ + " Use requestShowSelf(int) itself");
+ return;
+ }
final boolean wasVisible = mIsPreRendered
? mDecorViewVisible && mWindowVisible : isInputViewShown();
if (dispatchOnShowInputRequested(flags, false)) {
@@ -698,6 +735,15 @@ public class InputMethodService extends AbstractInputMethodService {
public void changeInputMethodSubtype(InputMethodSubtype subtype) {
dispatchOnCurrentInputMethodSubtypeChanged(subtype);
}
+
+ /**
+ * {@inheritDoc}
+ * @hide
+ */
+ @Override
+ public void setCurrentShowInputToken(IBinder showInputToken) {
+ mCurShowInputToken = showInputToken;
+ }
}
// TODO(b/137800469): Add detailed docs explaining the inline suggestions process.
@@ -2181,7 +2227,7 @@ public class InputMethodService extends AbstractInputMethodService {
if (!isVisibilityAppliedUsingInsetsConsumer()) {
return;
}
- mPrivOps.applyImeVisibility(setVisible);
+ mPrivOps.applyImeVisibility(mCurShowInputToken, setVisible);
}
private boolean isVisibilityAppliedUsingInsetsConsumer() {
diff --git a/core/java/android/nfc/Tag.java b/core/java/android/nfc/Tag.java
index 8bb2df0bba58..b9e6ff4a5a9e 100644
--- a/core/java/android/nfc/Tag.java
+++ b/core/java/android/nfc/Tag.java
@@ -455,12 +455,12 @@ public final class Tag implements Parcelable {
*
* @hide
*/
- public synchronized void setConnectedTechnology(int technology) {
- if (mConnectedTechnology == -1) {
- mConnectedTechnology = technology;
- } else {
- throw new IllegalStateException("Close other technology first!");
+ public synchronized boolean setConnectedTechnology(int technology) {
+ if (mConnectedTechnology != -1) {
+ return false;
}
+ mConnectedTechnology = technology;
+ return true;
}
/**
diff --git a/core/java/android/nfc/tech/BasicTagTechnology.java b/core/java/android/nfc/tech/BasicTagTechnology.java
index b6b347ca0619..ae468fead7a2 100644
--- a/core/java/android/nfc/tech/BasicTagTechnology.java
+++ b/core/java/android/nfc/tech/BasicTagTechnology.java
@@ -75,7 +75,10 @@ abstract class BasicTagTechnology implements TagTechnology {
if (errorCode == ErrorCodes.SUCCESS) {
// Store this in the tag object
- mTag.setConnectedTechnology(mSelectedTechnology);
+ if (!mTag.setConnectedTechnology(mSelectedTechnology)) {
+ Log.e(TAG, "Close other technology first!");
+ throw new IOException("Only one TagTechnology can be connected at a time.");
+ }
mIsConnected = true;
} else if (errorCode == ErrorCodes.ERROR_NOT_SUPPORTED) {
throw new UnsupportedOperationException("Connecting to " +
diff --git a/core/java/android/os/IncidentManager.java b/core/java/android/os/IncidentManager.java
index f6563ebdbbf4..8dde117fd19a 100644
--- a/core/java/android/os/IncidentManager.java
+++ b/core/java/android/os/IncidentManager.java
@@ -36,6 +36,7 @@ import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.util.ArrayList;
import java.util.List;
+import java.util.Objects;
import java.util.concurrent.Executor;
/**
@@ -426,10 +427,9 @@ public class IncidentManager {
*
* @see #registerSection
* @see #unregisterSection
- *
- * @hide
*/
public static class DumpCallback {
+ private int mId;
private Executor mExecutor;
IIncidentDumpCallback.Stub mBinder = new IIncidentDumpCallback.Stub() {
@@ -437,20 +437,25 @@ public class IncidentManager {
public void onDumpSection(ParcelFileDescriptor pfd) {
if (mExecutor != null) {
mExecutor.execute(() -> {
- DumpCallback.this.onDumpSection(
+ DumpCallback.this.onDumpSection(mId,
new ParcelFileDescriptor.AutoCloseOutputStream(pfd));
});
} else {
- DumpCallback.this.onDumpSection(
+ DumpCallback.this.onDumpSection(mId,
new ParcelFileDescriptor.AutoCloseOutputStream(pfd));
}
}
};
/**
- * Called when incidentd requests to dump this section.
+ * Dump the registered section as a protobuf message to the given OutputStream. Called when
+ * incidentd requests to dump this section.
+ *
+ * @param id the id of the registered section. The same id used in calling
+ * {@link #registerSection(int, String, DumpCallback)} will be passed in here.
+ * @param out the OutputStream to write the protobuf message
*/
- public void onDumpSection(OutputStream out) {
+ public void onDumpSection(int id, @NonNull OutputStream out) {
}
}
@@ -563,12 +568,20 @@ public class IncidentManager {
/**
* Register a callback to dump an extended incident report section with the given id and name.
- * The callback function will be invoked when an incident report with all sections or sections
- * matching the given id is being taken.
*
- * @hide
+ * Calling <code>registerSection</code> with a duplicate id will override previous registration.
+ * However, the request must come from the same calling uid.
+ *
+ * @param id the ID of the extended section. It should be unique system-wide, and be
+ * different from IDs of all existing section in
+ * frameworks/base/core/proto/android/os/incident.proto.
+ * Also see incident.proto for other rules about the ID.
+ * @param name the name to display in logs and/or stderr when taking an incident report
+ * containing this section, mainly for debugging purpose
+ * @param callback the callback function to be invoked when an incident report with all sections
+ * or sections matching the given id is being taken
*/
- public void registerSection(int id, String name, @NonNull DumpCallback callback) {
+ public void registerSection(int id, @NonNull String name, @NonNull DumpCallback callback) {
registerSection(id, name, mContext.getMainExecutor(), callback);
}
@@ -576,16 +589,27 @@ public class IncidentManager {
* Register a callback to dump an extended incident report section with the given id and name,
* running on the supplied executor.
*
- * @hide
+ * @param id the ID of the extended section. It should be unique system-wide, and be
+ * different from IDs of all existing section in
+ * frameworks/base/core/proto/android/os/incident.proto.
+ * Also see incident.proto for other rules about the ID.
+ * @param name the name to display in logs and/or stderr when taking an incident report
+ * containing this section, mainly for debugging purpose
+ * @param executor the executor used to run the callback
+ * @param callback the callback function to be invoked when an incident report with all sections
+ * or sections matching the given id is being taken
*/
- public void registerSection(int id, String name, @NonNull @CallbackExecutor Executor executor,
- @NonNull DumpCallback callback) {
+ public void registerSection(int id, @NonNull String name,
+ @NonNull @CallbackExecutor Executor executor, @NonNull DumpCallback callback) {
+ Objects.requireNonNull(executor, "executor cannot be null");
+ Objects.requireNonNull(callback, "callback cannot be null");
try {
if (callback.mExecutor != null) {
throw new RuntimeException("Do not reuse DumpCallback objects when calling"
+ " registerSection");
}
callback.mExecutor = executor;
+ callback.mId = id;
final IIncidentManager service = getIIncidentManagerLocked();
if (service == null) {
Slog.e(TAG, "registerSection can't find incident binder service");
@@ -599,9 +623,7 @@ public class IncidentManager {
/**
* Unregister an extended section dump function. The section must be previously registered with
- * {@link #registerSection(int, String, DumpCallback)}
- *
- * @hide
+ * {@link #registerSection(int, String, DumpCallback)} by the same calling uid.
*/
public void unregisterSection(int id) {
try {
@@ -719,7 +741,7 @@ public class IncidentManager {
throw new RuntimeException("Invalid URI: No "
+ URI_PARAM_REPORT_ID + " parameter. " + uri);
}
-
+
try {
getCompanionServiceLocked().deleteIncidentReports(pkg, cls, id);
} catch (RemoteException ex) {
diff --git a/core/java/android/provider/DocumentsContract.java b/core/java/android/provider/DocumentsContract.java
index 1453608c1518..bb1c8ed165c9 100644
--- a/core/java/android/provider/DocumentsContract.java
+++ b/core/java/android/provider/DocumentsContract.java
@@ -16,6 +16,8 @@
package android.provider;
+import static android.annotation.SystemApi.Client.MODULE_APPS;
+
import static com.android.internal.util.Preconditions.checkCollectionElementsNotNull;
import static com.android.internal.util.Preconditions.checkCollectionNotEmpty;
@@ -24,6 +26,7 @@ import android.annotation.Nullable;
import android.annotation.SystemApi;
import android.compat.annotation.UnsupportedAppUsage;
import android.content.ContentInterface;
+import android.content.ContentProvider;
import android.content.ContentResolver;
import android.content.Context;
import android.content.Intent;
@@ -47,6 +50,7 @@ import android.os.ParcelFileDescriptor.OnCloseListener;
import android.os.Parcelable;
import android.os.ParcelableException;
import android.os.RemoteException;
+import android.os.UserHandle;
import android.util.Log;
import com.android.internal.util.Preconditions;
@@ -945,6 +949,20 @@ public final class DocumentsContract {
return getBaseDocumentUriBuilder(authority).appendPath(documentId).build();
}
+ /**
+ * Builds URI as described in {@link #buildDocumentUri(String, String)}, but such that it will
+ * be associated with the given user.
+ *
+ * @hide
+ */
+ @SystemApi(client = MODULE_APPS)
+ @NonNull
+ public static Uri buildDocumentUriAsUser(
+ @NonNull String authority, @NonNull String documentId, @NonNull UserHandle user) {
+ return ContentProvider.maybeAddUserId(
+ buildDocumentUri(authority, documentId), user.getIdentifier());
+ }
+
/** {@hide} */
public static Uri buildBaseDocumentUri(String authority) {
return getBaseDocumentUriBuilder(authority).build();
diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java
index 0742a20a9fd6..c7c3140f7365 100644
--- a/core/java/android/provider/Settings.java
+++ b/core/java/android/provider/Settings.java
@@ -1969,6 +1969,21 @@ public final class Settings {
"android.settings.REQUEST_SET_AUTOFILL_SERVICE";
/**
+ * Activity Action: Show screen for controlling the Quick Access Wallet.
+ * <p>
+ * In some cases, a matching Activity may not exist, so ensure you
+ * safeguard against this.
+ * <p>
+ * Input: The Intent's data URI specifies the application package name
+ * to be shown, with the "package" scheme. That is "package:com.my.app".
+ * <p>
+ * Output: Nothing.
+ */
+ @SdkConstant(SdkConstantType.ACTIVITY_INTENT_ACTION)
+ public static final String ACTION_QUICK_ACCESS_WALLET_SETTINGS =
+ "android.settings.QUICK_ACCESS_WALLET_SETTINGS";
+
+ /**
* Activity Action: Show screen for controlling which apps have access on volume directories.
* <p>
* Input: Nothing.
diff --git a/core/java/android/service/quickaccesswallet/GetWalletCardsCallback.java b/core/java/android/service/quickaccesswallet/GetWalletCardsCallback.java
new file mode 100644
index 000000000000..9d210cd82c23
--- /dev/null
+++ b/core/java/android/service/quickaccesswallet/GetWalletCardsCallback.java
@@ -0,0 +1,92 @@
+/*
+ * Copyright (C) 2020 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 android.service.quickaccesswallet;
+
+import android.annotation.NonNull;
+import android.os.Handler;
+import android.os.RemoteException;
+import android.util.Log;
+
+/**
+ * Handles response from the {@link QuickAccessWalletService} for {@link GetWalletCardsRequest}
+ */
+public final class GetWalletCardsCallback {
+
+ private static final String TAG = "QAWalletCallback";
+
+ private final IQuickAccessWalletServiceCallbacks mCallback;
+ private final Handler mHandler;
+ private boolean mCalled;
+
+ /**
+ * @hide
+ */
+ GetWalletCardsCallback(IQuickAccessWalletServiceCallbacks callback, Handler handler) {
+ mCallback = callback;
+ mHandler = handler;
+ }
+
+ /**
+ * Notifies the Android System that an {@link QuickAccessWalletService#onWalletCardsRequested}
+ * was successfully handled by the service.
+ *
+ * @param response The response contains the list of {@link WalletCard walletCards} to be shown
+ * to the user as well as the index of the card that should initially be
+ * presented as the selected card.
+ */
+ public void onSuccess(@NonNull GetWalletCardsResponse response) {
+ mHandler.post(() -> onSuccessInternal(response));
+ }
+
+ /**
+ * Notifies the Android System that an {@link QuickAccessWalletService#onWalletCardsRequested}
+ * could not be handled by the service.
+ *
+ * @param error The error message. <b>Note: </b> this message should <b>not</b> contain PII
+ * (Personally Identifiable Information, such as username or email address).
+ * @throws IllegalStateException if this method or {@link #onSuccess} was already called.
+ */
+ public void onFailure(@NonNull GetWalletCardsError error) {
+ mHandler.post(() -> onFailureInternal(error));
+ }
+
+ private void onSuccessInternal(GetWalletCardsResponse response) {
+ if (mCalled) {
+ Log.w(TAG, "already called");
+ return;
+ }
+ mCalled = true;
+ try {
+ mCallback.onGetWalletCardsSuccess(response);
+ } catch (RemoteException e) {
+ Log.e(TAG, "Error returning wallet cards", e);
+ }
+ }
+
+ private void onFailureInternal(GetWalletCardsError error) {
+ if (mCalled) {
+ Log.w(TAG, "already called");
+ return;
+ }
+ mCalled = true;
+ try {
+ mCallback.onGetWalletCardsFailure(error);
+ } catch (RemoteException e) {
+ Log.e(TAG, "Error returning failure message", e);
+ }
+ }
+}
diff --git a/core/java/android/service/quickaccesswallet/GetWalletCardsError.aidl b/core/java/android/service/quickaccesswallet/GetWalletCardsError.aidl
new file mode 100644
index 000000000000..847f5accbd8e
--- /dev/null
+++ b/core/java/android/service/quickaccesswallet/GetWalletCardsError.aidl
@@ -0,0 +1,19 @@
+/*
+ * Copyright 2020 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 android.service.quickaccesswallet;
+
+parcelable GetWalletCardsError; \ No newline at end of file
diff --git a/core/java/android/service/quickaccesswallet/GetWalletCardsError.java b/core/java/android/service/quickaccesswallet/GetWalletCardsError.java
new file mode 100644
index 000000000000..527d2b79b2de
--- /dev/null
+++ b/core/java/android/service/quickaccesswallet/GetWalletCardsError.java
@@ -0,0 +1,100 @@
+/*
+ * Copyright (C) 2020 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 android.service.quickaccesswallet;
+
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.graphics.drawable.Icon;
+import android.os.Parcel;
+import android.os.Parcelable;
+import android.text.TextUtils;
+
+/**
+ * Error response for an {@link GetWalletCardsRequest}.
+ */
+public final class GetWalletCardsError implements Parcelable {
+
+ private final Icon mIcon;
+ private final CharSequence mMessage;
+
+ /**
+ * Construct a new error response. If provided, the icon and message will be displayed to the
+ * user.
+ *
+ * @param icon an icon to be shown to the user next to the message. Optional.
+ * @param message message to be shown to the user. Optional.
+ */
+ public GetWalletCardsError(@Nullable Icon icon, @Nullable CharSequence message) {
+ mIcon = icon;
+ mMessage = message;
+ }
+
+ @Override
+ public int describeContents() {
+ return 0;
+ }
+
+ @Override
+ public void writeToParcel(@NonNull Parcel dest, int flags) {
+ if (mIcon == null) {
+ dest.writeByte((byte) 0);
+ } else {
+ dest.writeByte((byte) 1);
+ mIcon.writeToParcel(dest, flags);
+ }
+ TextUtils.writeToParcel(mMessage, dest, flags);
+ }
+
+ private static GetWalletCardsError readFromParcel(Parcel source) {
+ Icon icon = source.readByte() == 0 ? null : Icon.CREATOR.createFromParcel(source);
+ CharSequence message = TextUtils.CHAR_SEQUENCE_CREATOR.createFromParcel(source);
+ return new GetWalletCardsError(icon, message);
+ }
+
+ @NonNull
+ public static final Creator<GetWalletCardsError> CREATOR =
+ new Creator<GetWalletCardsError>() {
+ @Override
+ public GetWalletCardsError createFromParcel(Parcel source) {
+ return readFromParcel(source);
+ }
+
+ @Override
+ public GetWalletCardsError[] newArray(int size) {
+ return new GetWalletCardsError[size];
+ }
+ };
+
+ /**
+ * An icon that may be displayed with the message to provide a visual indication of why cards
+ * could not be provided in the Quick Access Wallet.
+ */
+ @Nullable
+ public Icon getIcon() {
+ return mIcon;
+ }
+
+ /**
+ * A localized message that may be shown to the user in the event that the wallet cards cannot
+ * be retrieved. <b>Note: </b> this message should <b>not</b> contain PII (Personally
+ * Identifiable Information, such as username or email address).
+ */
+ @Nullable
+ public CharSequence getMessage() {
+ return mMessage;
+ }
+}
diff --git a/core/java/android/service/quickaccesswallet/GetWalletCardsRequest.aidl b/core/java/android/service/quickaccesswallet/GetWalletCardsRequest.aidl
new file mode 100644
index 000000000000..e70a98258afb
--- /dev/null
+++ b/core/java/android/service/quickaccesswallet/GetWalletCardsRequest.aidl
@@ -0,0 +1,19 @@
+/*
+ * Copyright 2020 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 android.service.quickaccesswallet;
+
+parcelable GetWalletCardsRequest; \ No newline at end of file
diff --git a/core/java/android/service/quickaccesswallet/GetWalletCardsRequest.java b/core/java/android/service/quickaccesswallet/GetWalletCardsRequest.java
new file mode 100644
index 000000000000..2ba448fc03c4
--- /dev/null
+++ b/core/java/android/service/quickaccesswallet/GetWalletCardsRequest.java
@@ -0,0 +1,137 @@
+/*
+ * Copyright 2020 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 android.service.quickaccesswallet;
+
+import android.annotation.NonNull;
+import android.os.Parcel;
+import android.os.Parcelable;
+
+/**
+ * Represents a request to a {@link QuickAccessWalletService} for {@link WalletCard walletCards}.
+ * Wallet cards may represent anything that a user might carry in their wallet -- a credit card,
+ * library card, a transit pass, etc. This request contains the desired size of the card images and
+ * icons as well as the maximum number of cards that may be returned in the {@link
+ * GetWalletCardsResponse}.
+ *
+ * <p>Cards may be displayed with an optional icon and label. The icon and label should communicate
+ * the same idea. For example, if a card can be used at an NFC terminal, the icon could be an NFC
+ * icon and the label could inform the user how to interact with the NFC terminal.
+ *
+ * <p>The maximum number of cards that may be displayed in the wallet is provided in {@link
+ * #getMaxCards()}. The {@link QuickAccessWalletService} may provide up to this many cards in the
+ * {@link GetWalletCardsResponse#getWalletCards()}. If the list of cards provided exceeds this
+ * number, some of the cards may not be shown to the user.
+ */
+public final class GetWalletCardsRequest implements Parcelable {
+
+ private final int mCardWidthPx;
+ private final int mCardHeightPx;
+ private final int mIconSizePx;
+ private final int mMaxCards;
+
+ /**
+ * Creates a new GetWalletCardsRequest.
+ *
+ * @param cardWidthPx The width of the card image in pixels.
+ * @param cardHeightPx The height of the card image in pixels.
+ * @param iconSizePx The width and height of the optional card icon in pixels.
+ * @param maxCards The maximum number of cards that may be provided in the response.
+ */
+ public GetWalletCardsRequest(int cardWidthPx, int cardHeightPx, int iconSizePx, int maxCards) {
+ this.mCardWidthPx = cardWidthPx;
+ this.mCardHeightPx = cardHeightPx;
+ this.mIconSizePx = iconSizePx;
+ this.mMaxCards = maxCards;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public int describeContents() {
+ return 0;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public void writeToParcel(@NonNull Parcel dest, int flags) {
+ dest.writeInt(mCardWidthPx);
+ dest.writeInt(mCardHeightPx);
+ dest.writeInt(mIconSizePx);
+ dest.writeInt(mMaxCards);
+ }
+
+ @NonNull
+ public static final Creator<GetWalletCardsRequest> CREATOR =
+ new Creator<GetWalletCardsRequest>() {
+ @Override
+ public GetWalletCardsRequest createFromParcel(Parcel source) {
+ int cardWidthPx = source.readInt();
+ int cardHeightPx = source.readInt();
+ int iconSizePx = source.readInt();
+ int maxCards = source.readInt();
+ return new GetWalletCardsRequest(cardWidthPx,
+ cardHeightPx,
+ iconSizePx,
+ maxCards);
+ }
+
+ @Override
+ public GetWalletCardsRequest[] newArray(int size) {
+ return new GetWalletCardsRequest[size];
+ }
+ };
+
+ /**
+ * The desired width of the {@link WalletCard#getCardImage()}, in pixels. The dimensions of the
+ * card image are requested so that it may be rendered without scaling.
+ * <p>
+ * The {@code cardWidthPx} and {@code cardHeightPx} should be applied to the size of the {@link
+ * WalletCard#getCardImage()}. The size of the card image is specified so that it may be
+ * rendered accurately and without distortion caused by scaling.
+ */
+ public int getCardWidthPx() {
+ return mCardWidthPx;
+ }
+
+ /**
+ * The desired height of the {@link WalletCard#getCardImage()}, in pixels. The dimensions of the
+ * card image are requested so that it may be rendered without scaling.
+ */
+ public int getCardHeightPx() {
+ return mCardHeightPx;
+ }
+
+ /**
+ * Wallet cards may be displayed next to an icon. The icon can help to convey additional
+ * information about the state of the card. If the provided icon is a bitmap, its width and
+ * height should equal iconSizePx so that it is rendered without distortion caused by scaling.
+ */
+ public int getIconSizePx() {
+ return mIconSizePx;
+ }
+
+ /**
+ * The maximum size of the {@link GetWalletCardsResponse#getWalletCards()}. If the list of cards
+ * exceeds this number, not all cards may be displayed.
+ */
+ public int getMaxCards() {
+ return mMaxCards;
+ }
+}
diff --git a/core/java/android/service/quickaccesswallet/GetWalletCardsResponse.aidl b/core/java/android/service/quickaccesswallet/GetWalletCardsResponse.aidl
new file mode 100644
index 000000000000..b0f25b3c7d72
--- /dev/null
+++ b/core/java/android/service/quickaccesswallet/GetWalletCardsResponse.aidl
@@ -0,0 +1,19 @@
+/*
+ * Copyright 2020 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 android.service.quickaccesswallet;
+
+parcelable GetWalletCardsResponse; \ No newline at end of file
diff --git a/core/java/android/service/quickaccesswallet/GetWalletCardsResponse.java b/core/java/android/service/quickaccesswallet/GetWalletCardsResponse.java
new file mode 100644
index 000000000000..996622a3e5aa
--- /dev/null
+++ b/core/java/android/service/quickaccesswallet/GetWalletCardsResponse.java
@@ -0,0 +1,100 @@
+/*
+ * Copyright 2020 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 android.service.quickaccesswallet;
+
+import android.annotation.NonNull;
+import android.os.Parcel;
+import android.os.Parcelable;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * The response for an {@link GetWalletCardsRequest} contains a list of wallet cards and the index
+ * of the card that should initially be displayed in the 'selected' position.
+ */
+public final class GetWalletCardsResponse implements Parcelable {
+
+ private final List<WalletCard> mWalletCards;
+ private final int mSelectedIndex;
+
+ /**
+ * Construct a new response.
+ *
+ * @param walletCards The list of wallet cards.
+ * @param selectedIndex The index of the card that should be presented as the initially
+ * 'selected' card
+ */
+ public GetWalletCardsResponse(@NonNull List<WalletCard> walletCards, int selectedIndex) {
+ this.mWalletCards = walletCards;
+ this.mSelectedIndex = selectedIndex;
+ }
+
+ @Override
+ public int describeContents() {
+ return 0;
+ }
+
+ @Override
+ public void writeToParcel(@NonNull Parcel dest, int flags) {
+ dest.writeInt(mWalletCards.size());
+ dest.writeParcelableList(mWalletCards, flags);
+ dest.writeInt(mSelectedIndex);
+ }
+
+ private static GetWalletCardsResponse readFromParcel(Parcel source) {
+ int size = source.readInt();
+ List<WalletCard> walletCards =
+ source.readParcelableList(new ArrayList<>(size), WalletCard.class.getClassLoader());
+ int selectedIndex = source.readInt();
+ return new GetWalletCardsResponse(walletCards, selectedIndex);
+ }
+
+ @NonNull
+ public static final Creator<GetWalletCardsResponse> CREATOR =
+ new Creator<GetWalletCardsResponse>() {
+ @Override
+ public GetWalletCardsResponse createFromParcel(Parcel source) {
+ return readFromParcel(source);
+ }
+
+ @Override
+ public GetWalletCardsResponse[] newArray(int size) {
+ return new GetWalletCardsResponse[size];
+ }
+ };
+
+ /**
+ * The list of {@link WalletCard}s. The size of this list should not exceed {@link
+ * GetWalletCardsRequest#getMaxCards()}.
+ */
+ @NonNull
+ public List<WalletCard> getWalletCards() {
+ return mWalletCards;
+ }
+
+ /**
+ * The {@code selectedIndex} represents the index of the card that should be presented in the
+ * 'selected' position when the cards are initially displayed in the quick access wallet. The
+ * {@code selectedIndex} should be greater than or equal to zero and less than the size of the
+ * list of {@link WalletCard walletCards}, unless the list is empty in which case the {@code
+ * selectedIndex} can take any value. 0 is a nice round number for such cases.
+ */
+ public int getSelectedIndex() {
+ return mSelectedIndex;
+ }
+}
diff --git a/core/java/android/service/quickaccesswallet/IQuickAccessWalletService.aidl b/core/java/android/service/quickaccesswallet/IQuickAccessWalletService.aidl
new file mode 100644
index 000000000000..ee70be442d16
--- /dev/null
+++ b/core/java/android/service/quickaccesswallet/IQuickAccessWalletService.aidl
@@ -0,0 +1,44 @@
+/*
+ * Copyright 2020 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 android.service.quickaccesswallet;
+
+import android.service.quickaccesswallet.GetWalletCardsRequest;
+import android.service.quickaccesswallet.IQuickAccessWalletServiceCallbacks;
+import android.service.quickaccesswallet.SelectWalletCardRequest;
+import android.service.quickaccesswallet.WalletServiceEvent;
+import android.service.quickaccesswallet.WalletServiceEventListenerRequest;
+
+/**
+ * Implemented by QuickAccessWalletService in the payment application
+ *
+ * @hide
+ */
+interface IQuickAccessWalletService {
+ // Request to get cards, which should be provided using the callback.
+ oneway void onWalletCardsRequested(
+ in GetWalletCardsRequest request, in IQuickAccessWalletServiceCallbacks callback);
+ // Indicates that a card has been selected.
+ oneway void onWalletCardSelected(in SelectWalletCardRequest request);
+ // Sent when the wallet is dismissed or closed.
+ oneway void onWalletDismissed();
+ // Register an event listener
+ oneway void registerWalletServiceEventListener(
+ in WalletServiceEventListenerRequest request,
+ in IQuickAccessWalletServiceCallbacks callback);
+ // Unregister an event listener
+ oneway void unregisterWalletServiceEventListener(in WalletServiceEventListenerRequest request);
+} \ No newline at end of file
diff --git a/core/java/android/service/quickaccesswallet/IQuickAccessWalletServiceCallbacks.aidl b/core/java/android/service/quickaccesswallet/IQuickAccessWalletServiceCallbacks.aidl
new file mode 100644
index 000000000000..f37b930aabce
--- /dev/null
+++ b/core/java/android/service/quickaccesswallet/IQuickAccessWalletServiceCallbacks.aidl
@@ -0,0 +1,37 @@
+/*
+ * Copyright 2020 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 android.service.quickaccesswallet;
+
+import android.service.quickaccesswallet.GetWalletCardsError;
+import android.service.quickaccesswallet.GetWalletCardsResponse;
+import android.service.quickaccesswallet.WalletServiceEvent;
+
+/**
+ * Interface to receive the result of requests to the wallet application.
+ *
+ * @hide
+ */
+interface IQuickAccessWalletServiceCallbacks {
+ // Called in response to onWalletCardsRequested on success. May only be called once per request.
+ oneway void onGetWalletCardsSuccess(in GetWalletCardsResponse response);
+ // Called in response to onWalletCardsRequested when an error occurs. May only be called once
+ // per request.
+ oneway void onGetWalletCardsFailure(in GetWalletCardsError error);
+ // Called in response to registerWalletServiceEventListener. May be called multiple times as
+ // long as the event listener is registered.
+ oneway void onWalletServiceEvent(in WalletServiceEvent event);
+} \ No newline at end of file
diff --git a/core/java/android/service/quickaccesswallet/QuickAccessWalletClient.java b/core/java/android/service/quickaccesswallet/QuickAccessWalletClient.java
new file mode 100644
index 000000000000..cfc6d5777e82
--- /dev/null
+++ b/core/java/android/service/quickaccesswallet/QuickAccessWalletClient.java
@@ -0,0 +1,89 @@
+/*
+ * Copyright 2020 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 android.service.quickaccesswallet;
+
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.content.Context;
+import android.content.Intent;
+
+import java.util.function.Consumer;
+
+/**
+ * Facilitates accessing cards from the {@link QuickAccessWalletService}.
+ *
+ * @hide
+ */
+public interface QuickAccessWalletClient {
+
+ /**
+ * Create a client for accessing wallet cards from the {@link QuickAccessWalletService}. If the
+ * service is unavailable, {@link #isWalletServiceAvailable()} will return false.
+ */
+ @NonNull
+ static QuickAccessWalletClient create(@NonNull Context context) {
+ return new QuickAccessWalletClientImpl(context);
+ }
+
+ /**
+ * @return true if the {@link QuickAccessWalletService} is available.
+ */
+ boolean isWalletServiceAvailable();
+
+ /**
+ * Get wallet cards from the {@link QuickAccessWalletService}.
+ */
+ void getWalletCards(
+ @NonNull GetWalletCardsRequest request,
+ @NonNull Consumer<GetWalletCardsResponse> onSuccessListener,
+ @NonNull Consumer<GetWalletCardsError> onFailureListener);
+
+ /**
+ * Notify the {@link QuickAccessWalletService} service that a wallet card was selected.
+ */
+ void selectWalletCard(@NonNull SelectWalletCardRequest request);
+
+ /**
+ * Notify the {@link QuickAccessWalletService} service that the Wallet was dismissed.
+ */
+ void notifyWalletDismissed();
+
+ /**
+ * Unregister event listener.
+ */
+ void registerWalletServiceEventListener(Consumer<WalletServiceEvent> listener);
+
+ /**
+ * Unregister event listener
+ */
+ void unregisterWalletServiceEventListener(Consumer<WalletServiceEvent> listener);
+
+ /**
+ * The manifest entry for the QuickAccessWalletService may also publish information about the
+ * activity that hosts the Wallet view. This is typically the home screen of the Wallet
+ * application.
+ */
+ @Nullable
+ Intent getWalletActivity();
+
+ /**
+ * The manifest entry for the {@link QuickAccessWalletService} may publish the activity that
+ * hosts the settings
+ */
+ @Nullable
+ Intent getSettingsActivity();
+}
diff --git a/core/java/android/service/quickaccesswallet/QuickAccessWalletClientImpl.java b/core/java/android/service/quickaccesswallet/QuickAccessWalletClientImpl.java
new file mode 100644
index 000000000000..17c287fa8eeb
--- /dev/null
+++ b/core/java/android/service/quickaccesswallet/QuickAccessWalletClientImpl.java
@@ -0,0 +1,342 @@
+/*
+ * Copyright 2020 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 android.service.quickaccesswallet;
+
+import static android.service.quickaccesswallet.QuickAccessWalletService.SERVICE_INTERFACE;
+
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.Intent;
+import android.content.ServiceConnection;
+import android.os.Handler;
+import android.os.IBinder;
+import android.os.Looper;
+import android.os.Message;
+import android.os.RemoteException;
+import android.text.TextUtils;
+import android.util.Log;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.LinkedList;
+import java.util.Map;
+import java.util.Queue;
+import java.util.UUID;
+import java.util.function.Consumer;
+
+/**
+ * @hide
+ */
+@SuppressWarnings("AndroidJdkLibsChecker")
+class QuickAccessWalletClientImpl implements QuickAccessWalletClient, Handler.Callback,
+ ServiceConnection {
+
+ private static final String TAG = "QAWalletSClient";
+ private final Handler mHandler;
+ private final Context mContext;
+ private final Queue<ApiCaller> mRequestQueue;
+ private final Map<Consumer<WalletServiceEvent>, String> mEventListeners;
+ private boolean mIsConnected;
+ @Nullable
+ private IQuickAccessWalletService mService;
+
+
+ @Nullable
+ private final QuickAccessWalletServiceInfo mServiceInfo;
+
+ private static final int MSG_CONNECT = 1;
+ private static final int MSG_CONNECTED = 2;
+ private static final int MSG_EXECUTE = 3;
+ private static final int MSG_DISCONNECT = 4;
+
+ QuickAccessWalletClientImpl(@NonNull Context context) {
+ mContext = context.getApplicationContext();
+ mServiceInfo = QuickAccessWalletServiceInfo.tryCreate(context);
+ mHandler = new Handler(Looper.getMainLooper(), this);
+ mRequestQueue = new LinkedList<>();
+ mEventListeners = new HashMap<>(1);
+ }
+
+ @Override
+ public boolean handleMessage(Message msg) {
+ switch (msg.what) {
+ case MSG_CONNECT:
+ connectInternal();
+ break;
+ case MSG_CONNECTED:
+ onConnectedInternal((IQuickAccessWalletService) msg.obj);
+ break;
+ case MSG_EXECUTE:
+ executeInternal((ApiCaller) msg.obj);
+ break;
+ case MSG_DISCONNECT:
+ disconnectInternal();
+ break;
+ default:
+ Log.w(TAG, "Unknown what: " + msg.what);
+ return false;
+ }
+ return true;
+ }
+
+ private void connect() {
+ mHandler.sendMessage(mHandler.obtainMessage(MSG_CONNECT));
+ }
+
+ private void connectInternal() {
+ if (mServiceInfo == null) {
+ Log.w(TAG, "Wallet service unavailable");
+ return;
+ }
+ if (mIsConnected) {
+ Log.w(TAG, "already connected");
+ return;
+ }
+ mIsConnected = true;
+ Intent intent = new Intent(SERVICE_INTERFACE);
+ intent.setComponent(mServiceInfo.getComponentName());
+ int flags = Context.BIND_AUTO_CREATE | Context.BIND_WAIVE_PRIORITY;
+ mContext.bindService(intent, this, flags);
+ }
+
+ private void onConnectedInternal(IQuickAccessWalletService service) {
+ if (!mIsConnected) {
+ Log.w(TAG, "onConnectInternal but connection closed");
+ mService = null;
+ return;
+ }
+ mService = service;
+ for (ApiCaller apiCaller : new ArrayList<>(mRequestQueue)) {
+ try {
+ apiCaller.performApiCall(mService);
+ } catch (RemoteException e) {
+ Log.e(TAG, "onConnectedInternal error", e);
+ apiCaller.onApiError();
+ disconnect();
+ break;
+ }
+ mRequestQueue.remove(apiCaller);
+ }
+ }
+
+ private void disconnect() {
+ mHandler.sendMessage(mHandler.obtainMessage(MSG_DISCONNECT));
+ }
+
+ private void disconnectInternal() {
+ if (!mIsConnected) {
+ Log.w(TAG, "already disconnected");
+ return;
+ }
+ mIsConnected = false;
+ mContext.unbindService(/*conn=*/this);
+ mService = null;
+ mEventListeners.clear();
+ mRequestQueue.clear();
+ }
+
+ private void execute(ApiCaller apiCaller) {
+ mHandler.sendMessage(mHandler.obtainMessage(MSG_EXECUTE, apiCaller));
+ }
+
+ private void executeInternal(ApiCaller apiCall) {
+ if (mIsConnected && mService != null) {
+ try {
+ apiCall.performApiCall(mService);
+ } catch (RemoteException e) {
+ Log.w(TAG, "executeInternal error", e);
+ apiCall.onApiError();
+ disconnect();
+ }
+ } else {
+ mRequestQueue.add(apiCall);
+ connect();
+ }
+ }
+
+ public boolean isWalletServiceAvailable() {
+ return mServiceInfo != null;
+ }
+
+ private abstract static class ApiCaller {
+ abstract void performApiCall(IQuickAccessWalletService service) throws RemoteException;
+
+ void onApiError() {
+ Log.w(TAG, "api error");
+ }
+ }
+
+ public void getWalletCards(
+ @NonNull GetWalletCardsRequest request,
+ @NonNull Consumer<GetWalletCardsResponse> onSuccessListener,
+ @NonNull Consumer<GetWalletCardsError> onFailureListener) {
+
+ BaseCallbacks callback = new BaseCallbacks() {
+ @Override
+ public void onGetWalletCardsSuccess(GetWalletCardsResponse response) {
+ mHandler.post(() -> onSuccessListener.accept(response));
+ }
+
+ @Override
+ public void onGetWalletCardsFailure(GetWalletCardsError error) {
+ mHandler.post(() -> onFailureListener.accept(error));
+ }
+ };
+
+ execute(new ApiCaller() {
+ @Override
+ public void performApiCall(IQuickAccessWalletService service) throws RemoteException {
+ service.onWalletCardsRequested(request, callback);
+ }
+
+ @Override
+ public void onApiError() {
+ callback.onGetWalletCardsFailure(new GetWalletCardsError(null, null));
+ }
+ });
+ }
+
+ public void selectWalletCard(@NonNull SelectWalletCardRequest request) {
+ execute(new ApiCaller() {
+ @Override
+ public void performApiCall(IQuickAccessWalletService service) throws RemoteException {
+ service.onWalletCardSelected(request);
+ }
+ });
+ }
+
+ public void notifyWalletDismissed() {
+ execute(new ApiCaller() {
+ @Override
+ public void performApiCall(IQuickAccessWalletService service) throws RemoteException {
+ service.onWalletDismissed();
+ mHandler.sendMessage(mHandler.obtainMessage(MSG_DISCONNECT));
+ }
+ });
+ }
+
+ @Override
+ public void registerWalletServiceEventListener(Consumer<WalletServiceEvent> listener) {
+
+ BaseCallbacks callback = new BaseCallbacks() {
+ @Override
+ public void onWalletServiceEvent(WalletServiceEvent event) {
+ Log.i(TAG, "onWalletServiceEvent");
+ mHandler.post(() -> listener.accept(event));
+ }
+ };
+
+ execute(new ApiCaller() {
+ @Override
+ public void performApiCall(IQuickAccessWalletService service) throws RemoteException {
+ String listenerId = UUID.randomUUID().toString();
+ WalletServiceEventListenerRequest request =
+ new WalletServiceEventListenerRequest(listenerId);
+ mEventListeners.put(listener, listenerId);
+ service.registerWalletServiceEventListener(request, callback);
+ }
+ });
+ }
+
+ @Override
+ public void unregisterWalletServiceEventListener(Consumer<WalletServiceEvent> listener) {
+ execute(new ApiCaller() {
+ @Override
+ public void performApiCall(IQuickAccessWalletService service) throws RemoteException {
+ String listenerId = mEventListeners.get(listener);
+ if (listenerId == null) {
+ return;
+ }
+ WalletServiceEventListenerRequest request =
+ new WalletServiceEventListenerRequest(listenerId);
+ service.unregisterWalletServiceEventListener(request);
+ }
+ });
+ }
+
+ @Override
+ @Nullable
+ public Intent getWalletActivity() {
+ if (mServiceInfo == null || TextUtils.isEmpty(mServiceInfo.getWalletActivity())) {
+ return null;
+ }
+ return new Intent(QuickAccessWalletService.ACTION_VIEW_WALLET)
+ .setComponent(
+ new ComponentName(
+ mServiceInfo.getComponentName().getPackageName(),
+ mServiceInfo.getWalletActivity()));
+ }
+
+ @Override
+ @Nullable
+ public Intent getSettingsActivity() {
+ if (mServiceInfo == null || TextUtils.isEmpty(mServiceInfo.getSettingsActivity())) {
+ return null;
+ }
+ return new Intent(QuickAccessWalletService.ACTION_VIEW_WALLET_SETTINGS)
+ .setComponent(
+ new ComponentName(
+ mServiceInfo.getComponentName().getPackageName(),
+ mServiceInfo.getSettingsActivity()));
+ }
+
+ /**
+ * Connection to the {@link QuickAccessWalletService}
+ */
+
+
+ @Override
+ public void onServiceConnected(ComponentName name, IBinder binder) {
+ IQuickAccessWalletService service = IQuickAccessWalletService.Stub.asInterface(binder);
+ mHandler.sendMessage(mHandler.obtainMessage(MSG_CONNECTED, service));
+ }
+
+ @Override
+ public void onServiceDisconnected(ComponentName name) {
+ // Do not disconnect, as we may later be re-connected
+ Log.w(TAG, "onServiceDisconnected");
+ }
+
+ @Override
+ public void onBindingDied(ComponentName name) {
+ // This is a recoverable error but the client will need to reconnect.
+ Log.w(TAG, "onBindingDied");
+ disconnect();
+ }
+
+ @Override
+ public void onNullBinding(ComponentName name) {
+ Log.w(TAG, "onNullBinding");
+ disconnect();
+ }
+
+ private static class BaseCallbacks extends IQuickAccessWalletServiceCallbacks.Stub {
+ public void onGetWalletCardsSuccess(GetWalletCardsResponse response) {
+ throw new IllegalStateException();
+ }
+
+ public void onGetWalletCardsFailure(GetWalletCardsError error) {
+ throw new IllegalStateException();
+ }
+
+ public void onWalletServiceEvent(WalletServiceEvent event) {
+ throw new IllegalStateException();
+ }
+ }
+}
diff --git a/core/java/android/service/quickaccesswallet/QuickAccessWalletService.java b/core/java/android/service/quickaccesswallet/QuickAccessWalletService.java
new file mode 100644
index 000000000000..d968405002e3
--- /dev/null
+++ b/core/java/android/service/quickaccesswallet/QuickAccessWalletService.java
@@ -0,0 +1,337 @@
+/*
+ * Copyright 2020 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 android.service.quickaccesswallet;
+
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.annotation.SdkConstant;
+import android.app.Service;
+import android.content.Intent;
+import android.os.Build;
+import android.os.Handler;
+import android.os.IBinder;
+import android.os.Looper;
+import android.os.RemoteException;
+import android.provider.Settings;
+import android.util.Log;
+
+/**
+ * A {@code QuickAccessWalletService} provides a list of {@code WalletCard}s shown in the Quick
+ * Access Wallet. The Quick Access Wallet allows the user to change their selected payment method
+ * and access other important passes, such as tickets and transit passes, without leaving the
+ * context of their current app.
+ *
+ * <p>An {@code QuickAccessWalletService} is only bound to the Android System for the purposes of
+ * showing wallet cards if:
+ * <ol>
+ * <li>The application hosting the QuickAccessWalletService is also the default NFC payment
+ * application. This means that the same application must also have a
+ * {@link android.nfc.cardemulation.HostApduService} or
+ * {@link android.nfc.cardemulation.OffHostApduService} that requires the
+ * android.permission.BIND_NFC_SERVICE permission.
+ * <li>The user explicitly selected the application as the default payment application in
+ * the Tap &amp; pay settings screen.
+ * <li>The application requires the {@code android.permission.BIND_QUICK_ACCESS_WALLET_SERVICE}
+ * permission in its manifest.
+ * <li>The user explicitly enables it using Android Settings (the
+ * {@link Settings#ACTION_QUICK_ACCESS_WALLET_SETTINGS} intent can be used to launch it).
+ * </ol>
+ *
+ * <a name="BasicUsage"></a>
+ * <h3>Basic usage</h3>
+ *
+ * <p>The basic Quick Access Wallet process is defined by the workflow below:
+ * <ol>
+ * <li>User performs a gesture to bring up the Quick Access Wallet, which is displayed by the
+ * Android System.
+ * <li>The Android System creates a {@link GetWalletCardsRequest}, binds to the
+ * {@link QuickAccessWalletService}, and delivers the request.
+ * <li>The service receives the request through {@link #onWalletCardsRequested}
+ * <li>The service responds by calling {@link GetWalletCardsCallback#onSuccess} with a
+ * {@link GetWalletCardsResponse response} that contains between 1 and
+ * {@link GetWalletCardsRequest#getMaxCards() maxCards} cards.
+ * <li>The Android System displays the Quick Access Wallet containing the provided cards. The
+ * card at the {@link GetWalletCardsResponse#getSelectedIndex() selectedIndex} will initially
+ * be presented as the 'selected' card.
+ * <li>As soon as the cards are displayed, the Android System will notify the service that the
+ * card at the selected index has been selected through {@link #onWalletCardSelected}.
+ * <li>The user interacts with the wallet and may select one or more cards in sequence. Each time
+ * a new card is selected, the Android System will notify the service through
+ * {@link #onWalletCardSelected} and will provide the {@link WalletCard#getCardId() cardId} of the
+ * card that is now selected.
+ * <li>When the wallet is dismissed, the Android System will notify the service through
+ * {@link #onWalletDismissed}.
+ * </ol>
+ *
+ * <p>The workflow is designed to minimize the time that the Android System is bound to the
+ * service, but connections may be cached and reused to improve performance and conserve memory.
+ * All calls should be considered stateless: if the service needs to keep state between calls, it
+ * must do its own state management (keeping in mind that the service's process might be killed
+ * by the Android System when unbound; for example, if the device is running low in memory).
+ *
+ * <p>
+ * <a name="ErrorHandling"></a>
+ * <h3>Error handling</h3>
+ * <p>If the service encountered an error processing the request, it should call
+ * {@link GetWalletCardsCallback#onFailure}.
+ * For performance reasons, it's paramount that the service calls either
+ * {@link GetWalletCardsCallback#onSuccess} or
+ * {@link GetWalletCardsCallback#onFailure} for each
+ * {@link #onWalletCardsRequested} received - if it doesn't, the request will eventually time out
+ * and be discarded by the Android System.
+ *
+ * <p>
+ * <a name="ManifestEntry"></a>
+ * <h3>Manifest entry</h3>
+ *
+ * <p>QuickAccessWalletService must require the permission
+ * "android.permission.BIND_QUICK_ACCESS_WALLET_SERVICE".
+ *
+ * <pre class="prettyprint">
+ * {@literal
+ * <service
+ * android:name=".MyQuickAccessWalletService"
+ * android:label="@string/my_default_tile_label"
+ * android:icon="@drawable/my_default_icon_label"
+ * android:permission="android.permission.BIND_QUICK_ACCESS_WALLET_SERVICE">
+ * <intent-filter>
+ * <action android:name="android.service.quickaccesswallet.QuickAccessWalletService" />
+ * </intent-filter>
+ * <meta-data android:name="android.quickaccesswallet"
+ * android:resource="@xml/quickaccesswallet_configuration" />;
+ * </service>}
+ * </pre>
+ * <p>
+ * The {@literal <meta-data>} element includes an android:resource attribute that points to an
+ * XML resource with further details about the service. The {@code quickaccesswallet_configuration}
+ * in the example above specifies an activity that allows the users to view the entire wallet.
+ * The following example shows the quickaccesswallet_configuration XML resource:
+ * <p>
+ * <pre class="prettyprint">
+ * {@literal
+ * <quickaccesswallet-service
+ * xmlns:android="http://schemas.android.com/apk/res/android"
+ * android:settingsActivity="com.example.android.SettingsActivity"
+ * android:targetActivity="com.example.android.WalletActivity"/>
+ * }
+ * </pre>
+ *
+ * <p>The entry for {@code settingsActivity} should contain the fully qualified class name of an
+ * activity that allows the user to modify the settings for this service. The {@code targetActivity}
+ * entry should contain the fully qualified class name of an activity that allows the user to view
+ * their entire wallet. If specified, the wallet activity will be started with the Intent action
+ * {@link #ACTION_VIEW_WALLET} and the settings activity will be started with the Intent action
+ * {@link #ACTION_VIEW_WALLET_SETTINGS}.
+ */
+public abstract class QuickAccessWalletService extends Service {
+
+ private static final String TAG = "QAWalletService";
+
+ /**
+ * The {@link Intent} that must be declared as handled by the service. To be supported, the
+ * service must also require the
+ * {@link android.Manifest.permission#BIND_QUICK_ACCESS_WALLET_SERVICE}
+ * permission so that other applications can not abuse it.
+ */
+ @SdkConstant(SdkConstant.SdkConstantType.SERVICE_ACTION)
+ public static final String SERVICE_INTERFACE =
+ "android.service.quickaccesswallet.QuickAccessWalletService";
+
+ /**
+ * Intent action to launch an activity to display the wallet.
+ */
+ @SdkConstant(SdkConstant.SdkConstantType.ACTIVITY_INTENT_ACTION)
+ public static final String ACTION_VIEW_WALLET =
+ "android.service.quickaccesswallet.action.VIEW_WALLET";
+
+ /**
+ * Intent action to launch an activity to display quick access wallet settings.
+ */
+ @SdkConstant(SdkConstant.SdkConstantType.ACTIVITY_INTENT_ACTION)
+ public static final String ACTION_VIEW_WALLET_SETTINGS =
+ "android.service.quickaccesswallet.action.VIEW_WALLET_SETTINGS";
+
+ /**
+ * Broadcast Action: Sent by the wallet application to dismiss the Quick Access Wallet.
+ * <p>
+ * The Quick Access Wallet may be shown in a system window on top of other Activities. If the
+ * user selects a payment card from the Quick Access Wallet and then holds their phone to an NFC
+ * terminal, the wallet application will need to show a payment Activity. But if the Quick
+ * Access Wallet is still being shown, it may obscure the payment Activity. To avoid this, the
+ * wallet application can send a broadcast to the Android System with this action to request
+ * that the Quick Access Wallet be dismissed.
+ * <p>
+ * This broadcast must use the {@code android.permission.BIND_QUICK_ACCESS_WALLET_SERVICE}
+ * permission to ensure that it is only delivered to System UI. Furthermore, your application
+ * must require the {@code android.permission.DISMISS_QUICK_ACCESS_WALLET}
+ * <p>
+ * <pre class="prettyprint">
+ * context.sendBroadcast(
+ * new Intent(ACTION_DISMISS_WALLET), Manifest.permission.BIND_QUICK_ACCESS_WALLET_SERVICE);
+ * </pre>
+ */
+ @SdkConstant(SdkConstant.SdkConstantType.BROADCAST_INTENT_ACTION)
+ public static final String ACTION_DISMISS_WALLET =
+ "android.service.quickaccesswallet.action.DISMISS_WALLET";
+
+ /**
+ * Name under which a QuickAccessWalletService component publishes information about itself.
+ * This meta-data should reference an XML resource containing a
+ * <code>&lt;{@link
+ * android.R.styleable#QuickAccessWalletService quickaccesswallet-service}&gt;</code> tag. This
+ * is a a sample XML file configuring an QuickAccessWalletService:
+ * <pre> &lt;quickaccesswallet-service
+ * android:walletActivity="foo.bar.WalletActivity"
+ * . . .
+ * /&gt;</pre>
+ */
+ public static final String SERVICE_META_DATA = "android.quickaccesswallet";
+
+ private final Handler mHandler = new Handler(Looper.getMainLooper());
+ @Nullable
+ private String mEventListenerId;
+ @Nullable
+ private IQuickAccessWalletServiceCallbacks mEventListener;
+
+ private final IQuickAccessWalletService mInterface = new IQuickAccessWalletService.Stub() {
+ @Override
+ public void onWalletCardsRequested(
+ @NonNull GetWalletCardsRequest request,
+ @NonNull IQuickAccessWalletServiceCallbacks callback) {
+ mHandler.post(() -> onWalletCardsRequestedInternal(request, callback));
+ }
+
+ @Override
+ public void onWalletCardSelected(@NonNull SelectWalletCardRequest request) {
+ mHandler.post(() -> QuickAccessWalletService.this.onWalletCardSelected(request));
+ }
+
+ @Override
+ public void onWalletDismissed() {
+ mHandler.post(QuickAccessWalletService.this::onWalletDismissed);
+ }
+
+ public void registerWalletServiceEventListener(
+ @NonNull WalletServiceEventListenerRequest request,
+ @NonNull IQuickAccessWalletServiceCallbacks callback) {
+ mHandler.post(() -> registerDismissWalletListenerInternal(request, callback));
+ }
+
+ public void unregisterWalletServiceEventListener(
+ @NonNull WalletServiceEventListenerRequest request) {
+ mHandler.post(() -> unregisterDismissWalletListenerInternal(request));
+ }
+ };
+
+ private void onWalletCardsRequestedInternal(
+ GetWalletCardsRequest request,
+ IQuickAccessWalletServiceCallbacks callback) {
+ onWalletCardsRequested(request, new GetWalletCardsCallback(callback, mHandler));
+ }
+
+ @Override
+ @Nullable
+ public IBinder onBind(@NonNull Intent intent) {
+ if (Build.VERSION.SDK_INT < Build.VERSION_CODES.R) {
+ // Binding to the QuickAccessWalletService is protected by the
+ // android.permission.BIND_QUICK_ACCESS_WALLET_SERVICE permission, which is defined in
+ // R. Pre-R devices can have other side-loaded applications that claim this permission.
+ // This ensures that the service is only available when properly permission protected.
+ Log.w(TAG, "Warning: binding on pre-R device");
+ }
+ if (SERVICE_INTERFACE.equals(intent.getAction())) {
+ return mInterface.asBinder();
+ }
+ Log.w(TAG, "Tried to bind to wrong intent (should be " + SERVICE_INTERFACE + ": " + intent);
+ return null;
+ }
+
+ /**
+ * Called when the user requests the service to provide wallet cards.
+ *
+ * <p>This method will be called on the main thread, but the callback may be called from any
+ * thread. The callback should be called as quickly as possible. The service must always call
+ * either {@link GetWalletCardsCallback#onSuccess(GetWalletCardsResponse)} or {@link
+ * GetWalletCardsCallback#onFailure(GetWalletCardsError)}. Calling multiple times or calling
+ * both methods will cause an exception to be thrown.
+ */
+ public abstract void onWalletCardsRequested(
+ @NonNull GetWalletCardsRequest request,
+ @NonNull GetWalletCardsCallback callback);
+
+ /**
+ * A wallet card was selected. Sent when the user selects a wallet card from the list of cards.
+ * Selection may indicate that the card is now in the center of the screen, or highlighted in
+ * some other fashion. It does not mean that the user clicked on the card -- clicking on the
+ * card will cause the {@link WalletCard#getPendingIntent()} to be sent.
+ *
+ * <p>Card selection events are especially important to NFC payment applications because
+ * many NFC terminals can only accept one payment card at a time. If the user has several NFC
+ * cards in their wallet, selecting different cards can change which payment method is presented
+ * to the terminal.
+ */
+ public abstract void onWalletCardSelected(@NonNull SelectWalletCardRequest request);
+
+ /**
+ * Indicates that the wallet was dismissed. This is received when the Quick Access Wallet is no
+ * longer visible.
+ */
+ public abstract void onWalletDismissed();
+
+ /**
+ * Send a {@link WalletServiceEvent} to the Quick Access Wallet.
+ * <p>
+ * Background events may require that the Quick Access Wallet view be updated. For example, if
+ * the wallet application hosting this service starts to handle an NFC payment while the Quick
+ * Access Wallet is being shown, the Quick Access Wallet will need to be dismissed so that the
+ * Activity showing the payment can be displayed to the user.
+ */
+ public final void sendWalletServiceEvent(@NonNull WalletServiceEvent serviceEvent) {
+ mHandler.post(() -> sendWalletServiceEventInternal(serviceEvent));
+ }
+
+ private void sendWalletServiceEventInternal(WalletServiceEvent serviceEvent) {
+ if (mEventListener == null) {
+ Log.i(TAG, "No dismiss listener registered");
+ return;
+ }
+ try {
+ mEventListener.onWalletServiceEvent(serviceEvent);
+ } catch (RemoteException e) {
+ Log.w(TAG, "onWalletServiceEvent error", e);
+ mEventListenerId = null;
+ mEventListener = null;
+ }
+ }
+
+ private void registerDismissWalletListenerInternal(
+ @NonNull WalletServiceEventListenerRequest request,
+ @NonNull IQuickAccessWalletServiceCallbacks callback) {
+ mEventListenerId = request.getListenerId();
+ mEventListener = callback;
+ }
+
+ private void unregisterDismissWalletListenerInternal(
+ @NonNull WalletServiceEventListenerRequest request) {
+ if (mEventListenerId != null && mEventListenerId.equals(request.getListenerId())) {
+ mEventListenerId = null;
+ mEventListener = null;
+ } else {
+ Log.w(TAG, "dismiss listener missing or replaced");
+ }
+ }
+}
diff --git a/core/java/android/service/quickaccesswallet/QuickAccessWalletServiceInfo.java b/core/java/android/service/quickaccesswallet/QuickAccessWalletServiceInfo.java
new file mode 100644
index 000000000000..8793f28bc708
--- /dev/null
+++ b/core/java/android/service/quickaccesswallet/QuickAccessWalletServiceInfo.java
@@ -0,0 +1,187 @@
+/*
+ * Copyright (C) 2020 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 android.service.quickaccesswallet;
+
+import android.Manifest;
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.content.ComponentName;
+import android.content.ContentResolver;
+import android.content.Context;
+import android.content.Intent;
+import android.content.pm.PackageManager;
+import android.content.pm.ResolveInfo;
+import android.content.pm.ServiceInfo;
+import android.content.res.Resources;
+import android.content.res.TypedArray;
+import android.content.res.XmlResourceParser;
+import android.provider.Settings;
+import android.util.AttributeSet;
+import android.util.Log;
+import android.util.Xml;
+
+import com.android.internal.R;
+
+import org.xmlpull.v1.XmlPullParser;
+import org.xmlpull.v1.XmlPullParserException;
+
+import java.io.IOException;
+import java.util.List;
+
+/**
+ * {@link ServiceInfo} and meta-data about a {@link QuickAccessWalletService}.
+ *
+ * @hide
+ */
+class QuickAccessWalletServiceInfo {
+
+ private static final String TAG = "QAWalletSInfo";
+ private static final String TAG_WALLET_SERVICE = "quickaccesswallet-service";
+
+ private final ServiceInfo mServiceInfo;
+ private final ServiceMetadata mServiceMetadata;
+
+ private QuickAccessWalletServiceInfo(
+ @NonNull ServiceInfo serviceInfo,
+ @NonNull ServiceMetadata metadata) {
+ mServiceInfo = serviceInfo;
+ mServiceMetadata = metadata;
+ }
+
+ @Nullable
+ static QuickAccessWalletServiceInfo tryCreate(@NonNull Context context) {
+ ComponentName defaultPaymentApp = getDefaultPaymentApp(context);
+ if (defaultPaymentApp == null) {
+ Log.d(TAG, "create: default payment app not set");
+ return null;
+ }
+
+ ServiceInfo serviceInfo = getWalletServiceInfo(context, defaultPaymentApp.getPackageName());
+ if (serviceInfo == null) {
+ Log.d(TAG, "create: unable to resolve service intent");
+ return null;
+ }
+
+ if (!Manifest.permission.BIND_QUICK_ACCESS_WALLET_SERVICE.equals(serviceInfo.permission)) {
+ Log.w(TAG, String.format("QuickAccessWalletService from %s does not have permission %s",
+ serviceInfo.packageName, Manifest.permission.BIND_QUICK_ACCESS_WALLET_SERVICE));
+ return null;
+ }
+
+ ServiceMetadata metadata = parseServiceMetadata(context, serviceInfo);
+ return new QuickAccessWalletServiceInfo(serviceInfo, metadata);
+ }
+
+ private static ComponentName getDefaultPaymentApp(Context context) {
+ ContentResolver cr = context.getContentResolver();
+ String comp = Settings.Secure.getString(cr, Settings.Secure.NFC_PAYMENT_DEFAULT_COMPONENT);
+ return comp == null ? null : ComponentName.unflattenFromString(comp);
+ }
+
+ private static ServiceInfo getWalletServiceInfo(Context context, String packageName) {
+ Intent intent = new Intent(QuickAccessWalletService.SERVICE_INTERFACE);
+ intent.setPackage(packageName);
+ List<ResolveInfo> resolveInfos =
+ context.getPackageManager().queryIntentServices(intent,
+ PackageManager.MATCH_DEFAULT_ONLY);
+ return resolveInfos.isEmpty() ? null : resolveInfos.get(0).serviceInfo;
+ }
+
+ private static class ServiceMetadata {
+ @Nullable
+ private final String mSettingsActivity;
+ @Nullable
+ private final String mWalletActivity;
+
+ private ServiceMetadata(String settingsActivity, String walletActivity) {
+ this.mSettingsActivity = settingsActivity;
+ this.mWalletActivity = walletActivity;
+ }
+ }
+
+ private static ServiceMetadata parseServiceMetadata(Context context, ServiceInfo serviceInfo) {
+ PackageManager pm = context.getPackageManager();
+ final XmlResourceParser parser =
+ serviceInfo.loadXmlMetaData(pm, QuickAccessWalletService.SERVICE_META_DATA);
+
+ if (parser == null) {
+ return new ServiceMetadata(null, null);
+ }
+
+ try {
+ Resources resources = pm.getResourcesForApplication(serviceInfo.applicationInfo);
+ int type = 0;
+ while (type != XmlPullParser.END_DOCUMENT && type != XmlPullParser.START_TAG) {
+ type = parser.next();
+ }
+
+ if (TAG_WALLET_SERVICE.equals(parser.getName())) {
+ final AttributeSet allAttributes = Xml.asAttributeSet(parser);
+ TypedArray afsAttributes = null;
+ try {
+ afsAttributes = resources.obtainAttributes(allAttributes,
+ R.styleable.QuickAccessWalletService);
+ String settingsActivity = afsAttributes.getString(
+ R.styleable.QuickAccessWalletService_settingsActivity);
+ String walletActivity = afsAttributes.getString(
+ R.styleable.QuickAccessWalletService_targetActivity);
+ return new ServiceMetadata(settingsActivity, walletActivity);
+ } finally {
+ if (afsAttributes != null) {
+ afsAttributes.recycle();
+ }
+ }
+ } else {
+ Log.e(TAG, "Meta-data does not start with quickaccesswallet-service tag");
+ }
+
+ } catch (PackageManager.NameNotFoundException
+ | IOException
+ | XmlPullParserException e) {
+ Log.e(TAG, "Error parsing quickaccesswallet service meta-data", e);
+ }
+ return new ServiceMetadata(null, null);
+ }
+
+ /**
+ * @return the component name of the {@link QuickAccessWalletService}
+ */
+ @NonNull
+ ComponentName getComponentName() {
+ return mServiceInfo.getComponentName();
+ }
+
+ /**
+ * @return the fully qualified name of the activity that hosts the full wallet. If available,
+ * this intent should be started with the action
+ * {@link QuickAccessWalletService#ACTION_VIEW_WALLET}
+ */
+ @Nullable
+ String getWalletActivity() {
+ return mServiceMetadata.mWalletActivity;
+ }
+
+ /**
+ * @return the fully qualified name of the activity that allows the user to change quick access
+ * wallet settings. If available, this intent should be started with the action {@link
+ * QuickAccessWalletService#ACTION_VIEW_WALLET_SETTINGS}
+ */
+ @Nullable
+ String getSettingsActivity() {
+ return mServiceMetadata.mSettingsActivity;
+ }
+}
diff --git a/core/java/android/service/quickaccesswallet/SelectWalletCardRequest.aidl b/core/java/android/service/quickaccesswallet/SelectWalletCardRequest.aidl
new file mode 100644
index 000000000000..97a0d41ff635
--- /dev/null
+++ b/core/java/android/service/quickaccesswallet/SelectWalletCardRequest.aidl
@@ -0,0 +1,19 @@
+/*
+ * Copyright 2020 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 android.service.quickaccesswallet;
+
+parcelable SelectWalletCardRequest; \ No newline at end of file
diff --git a/core/java/android/service/quickaccesswallet/SelectWalletCardRequest.java b/core/java/android/service/quickaccesswallet/SelectWalletCardRequest.java
new file mode 100644
index 000000000000..cb69eee03427
--- /dev/null
+++ b/core/java/android/service/quickaccesswallet/SelectWalletCardRequest.java
@@ -0,0 +1,74 @@
+/*
+ * Copyright (C) 2020 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 android.service.quickaccesswallet;
+
+import android.annotation.NonNull;
+import android.os.Parcel;
+import android.os.Parcelable;
+
+/**
+ * Represents a request to a {@link QuickAccessWalletService} to select a particular {@link
+ * WalletCard walletCard}. Card selection events are transmitted to the WalletService so that the
+ * selected card may be used by the NFC payment service.
+ */
+public final class SelectWalletCardRequest implements Parcelable {
+
+ private final String mCardId;
+
+ /**
+ * Creates a new GetWalletCardsRequest.
+ *
+ * @param cardId The {@link WalletCard#getCardId() cardId} of the wallet card that is currently
+ * selected.
+ */
+ public SelectWalletCardRequest(@NonNull String cardId) {
+ this.mCardId = cardId;
+ }
+
+ @Override
+ public int describeContents() {
+ return 0;
+ }
+
+ @Override
+ public void writeToParcel(@NonNull Parcel dest, int flags) {
+ dest.writeString(mCardId);
+ }
+
+ @NonNull
+ public static final Creator<SelectWalletCardRequest> CREATOR =
+ new Creator<SelectWalletCardRequest>() {
+ @Override
+ public SelectWalletCardRequest createFromParcel(Parcel source) {
+ String cardId = source.readString();
+ return new SelectWalletCardRequest(cardId);
+ }
+
+ @Override
+ public SelectWalletCardRequest[] newArray(int size) {
+ return new SelectWalletCardRequest[size];
+ }
+ };
+
+ /**
+ * The {@link WalletCard#getCardId() cardId} of the wallet card that is currently selected.
+ */
+ @NonNull
+ public String getCardId() {
+ return mCardId;
+ }
+}
diff --git a/core/java/android/service/quickaccesswallet/WalletCard.aidl b/core/java/android/service/quickaccesswallet/WalletCard.aidl
new file mode 100644
index 000000000000..115213da2752
--- /dev/null
+++ b/core/java/android/service/quickaccesswallet/WalletCard.aidl
@@ -0,0 +1,19 @@
+/*
+ * Copyright 2020 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 android.service.quickaccesswallet;
+
+parcelable WalletCard; \ No newline at end of file
diff --git a/core/java/android/service/quickaccesswallet/WalletCard.java b/core/java/android/service/quickaccesswallet/WalletCard.java
new file mode 100644
index 000000000000..c3b1a4b0b85f
--- /dev/null
+++ b/core/java/android/service/quickaccesswallet/WalletCard.java
@@ -0,0 +1,245 @@
+/*
+ * Copyright 2020 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 android.service.quickaccesswallet;
+
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.app.PendingIntent;
+import android.graphics.drawable.Icon;
+import android.os.Parcel;
+import android.os.Parcelable;
+import android.text.TextUtils;
+
+/**
+ * A {@link WalletCard} can represent anything that a user might carry in their wallet -- a credit
+ * card, library card, transit pass, etc. Cards are identified by a String identifier and contain a
+ * card image, card image content description, and a {@link PendingIntent} to be used if the user
+ * clicks on the card. Cards may be displayed with an icon and label, though these are optional.
+ */
+public final class WalletCard implements Parcelable {
+
+ private final String mCardId;
+ private final Icon mCardImage;
+ private final CharSequence mContentDescription;
+ private final PendingIntent mPendingIntent;
+ private final Icon mCardIcon;
+ private final CharSequence mCardLabel;
+
+ private WalletCard(Builder builder) {
+ this.mCardId = builder.mCardId;
+ this.mCardImage = builder.mCardImage;
+ this.mContentDescription = builder.mContentDescription;
+ this.mPendingIntent = builder.mPendingIntent;
+ this.mCardIcon = builder.mCardIcon;
+ this.mCardLabel = builder.mCardLabel;
+ }
+
+ @Override
+ public int describeContents() {
+ return 0;
+ }
+
+ @Override
+ public void writeToParcel(@NonNull Parcel dest, int flags) {
+ dest.writeString(mCardId);
+ mCardImage.writeToParcel(dest, flags);
+ TextUtils.writeToParcel(mContentDescription, dest, flags);
+ PendingIntent.writePendingIntentOrNullToParcel(mPendingIntent, dest);
+ if (mCardIcon == null) {
+ dest.writeByte((byte) 0);
+ } else {
+ dest.writeByte((byte) 1);
+ mCardIcon.writeToParcel(dest, flags);
+ }
+ TextUtils.writeToParcel(mCardLabel, dest, flags);
+ }
+
+ private static WalletCard readFromParcel(Parcel source) {
+ String cardId = source.readString();
+ Icon cardImage = Icon.CREATOR.createFromParcel(source);
+ CharSequence contentDesc = TextUtils.CHAR_SEQUENCE_CREATOR.createFromParcel(source);
+ PendingIntent pendingIntent = PendingIntent.readPendingIntentOrNullFromParcel(source);
+ Icon cardIcon = source.readByte() == 0 ? null : Icon.CREATOR.createFromParcel(source);
+ CharSequence cardLabel = TextUtils.CHAR_SEQUENCE_CREATOR.createFromParcel(source);
+ return new Builder(cardId, cardImage, contentDesc, pendingIntent)
+ .setCardIcon(cardIcon)
+ .setCardLabel(cardLabel)
+ .build();
+ }
+
+ @NonNull
+ public static final Creator<WalletCard> CREATOR =
+ new Creator<WalletCard>() {
+ @Override
+ public WalletCard createFromParcel(Parcel source) {
+ return readFromParcel(source);
+ }
+
+ @Override
+ public WalletCard[] newArray(int size) {
+ return new WalletCard[size];
+ }
+ };
+
+ /**
+ * The card id must be unique within the list of cards returned.
+ */
+ @NonNull
+ public String getCardId() {
+ return mCardId;
+ }
+
+ /**
+ * The visual representation of the card. If the card image Icon is a bitmap, it should have a
+ * width of {@link GetWalletCardsRequest#getCardWidthPx()} and a height of {@link
+ * GetWalletCardsRequest#getCardHeightPx()}.
+ */
+ @NonNull
+ public Icon getCardImage() {
+ return mCardImage;
+ }
+
+ /**
+ * The content description of the card image.
+ */
+ @NonNull
+ public CharSequence getContentDescription() {
+ return mContentDescription;
+ }
+
+ /**
+ * If the user performs a click on the card, this PendingIntent will be sent. If the device is
+ * locked, the wallet will first request device unlock before sending the pending intent.
+ */
+ @NonNull
+ public PendingIntent getPendingIntent() {
+ return mPendingIntent;
+ }
+
+ /**
+ * An icon may be shown alongside the card image to convey information about how the card can be
+ * used, or if some other action must be taken before using the card. For example, an NFC logo
+ * could indicate that the card is NFC-enabled and will be provided to an NFC terminal if the
+ * phone is held in close proximity to the NFC reader.
+ *
+ * <p>If the supplied Icon is backed by a bitmap, it should have width and height
+ * {@link GetWalletCardsRequest#getIconSizePx()}.
+ */
+ @Nullable
+ public Icon getCardIcon() {
+ return mCardIcon;
+ }
+
+ /**
+ * A card label may be shown alongside the card image to convey information about how the card
+ * can be used, or if some other action must be taken before using the card. For example, an
+ * NFC-enabled card could be labeled "Hold near reader" to inform the user of how to use NFC
+ * cards when interacting with an NFC reader.
+ *
+ * <p>If the provided label is too long to fit on one line, it may be truncated and ellipsized.
+ */
+ @Nullable
+ public CharSequence getCardLabel() {
+ return mCardLabel;
+ }
+
+ /**
+ * Builder for {@link WalletCard} objects. You must to provide cardId, cardImage,
+ * contentDescription, and pendingIntent. If the card is opaque and should be shown with
+ * elevation, set hasShadow to true. cardIcon and cardLabel are optional.
+ */
+ public static final class Builder {
+ private String mCardId;
+ private Icon mCardImage;
+ private CharSequence mContentDescription;
+ private PendingIntent mPendingIntent;
+ private Icon mCardIcon;
+ private CharSequence mCardLabel;
+
+ /**
+ * @param cardId The card id must be non-null and unique within the list of
+ * cards returned. <b>Note:
+ * </b> this card ID should <b>not</b> contain PII (Personally
+ * Identifiable Information, * such as username or email
+ * address).
+ * @param cardImage The visual representation of the card. If the card image Icon
+ * is a bitmap, it should have a width of {@link
+ * GetWalletCardsRequest#getCardWidthPx()} and a height of {@link
+ * GetWalletCardsRequest#getCardHeightPx()}. If the card image
+ * does not have these dimensions, it may appear distorted when it
+ * is scaled to fit these dimensions on screen.
+ * @param contentDescription The content description of the card image. This field is
+ * required.
+ * <b>Note: </b> this message should <b>not</b> contain PII
+ * (Personally Identifiable Information, such as username or email
+ * address).
+ * @param pendingIntent If the user performs a click on the card, this PendingIntent
+ * will be sent. If the device is locked, the wallet will first
+ * request device unlock before sending the pending intent.
+ */
+ public Builder(@NonNull String cardId,
+ @NonNull Icon cardImage,
+ @NonNull CharSequence contentDescription,
+ @NonNull PendingIntent pendingIntent) {
+ mCardId = cardId;
+ mCardImage = cardImage;
+ mContentDescription = contentDescription;
+ mPendingIntent = pendingIntent;
+ }
+
+ /**
+ * An icon may be shown alongside the card image to convey information about how the card
+ * can be used, or if some other action must be taken before using the card. For example, an
+ * NFC logo could indicate that the card is NFC-enabled and will be provided to an NFC
+ * terminal if the phone is held in close proximity to the NFC reader. This field is
+ * optional.
+ *
+ * <p>If the supplied Icon is backed by a bitmap, it should have width and height
+ * {@link GetWalletCardsRequest#getIconSizePx()}.
+ */
+ @NonNull
+ public Builder setCardIcon(@Nullable Icon cardIcon) {
+ mCardIcon = cardIcon;
+ return this;
+ }
+
+ /**
+ * A card label may be shown alongside the card image to convey information about how the
+ * card can be used, or if some other action must be taken before using the card. For
+ * example, an NFC-enabled card could be labeled "Hold near reader" to inform the user of
+ * how to use NFC cards when interacting with an NFC reader. This field is optional.
+ * <b>Note: </b> this card label should <b>not</b> contain PII (Personally Identifiable
+ * Information, such as username or email address). If the provided label is too long to fit
+ * on one line, it may be truncated and ellipsized.
+ */
+ @NonNull
+ public Builder setCardLabel(@Nullable CharSequence cardLabel) {
+ mCardLabel = cardLabel;
+ return this;
+ }
+
+ /**
+ * Builds a new {@link WalletCard} instance.
+ *
+ * @return A built response.
+ */
+ @NonNull
+ public WalletCard build() {
+ return new WalletCard(this);
+ }
+ }
+}
diff --git a/core/java/android/service/quickaccesswallet/WalletServiceEvent.aidl b/core/java/android/service/quickaccesswallet/WalletServiceEvent.aidl
new file mode 100644
index 000000000000..891cf1d585bf
--- /dev/null
+++ b/core/java/android/service/quickaccesswallet/WalletServiceEvent.aidl
@@ -0,0 +1,19 @@
+/*
+ * Copyright 2020 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 android.service.quickaccesswallet;
+
+parcelable WalletServiceEvent; \ No newline at end of file
diff --git a/core/java/android/service/quickaccesswallet/WalletServiceEvent.java b/core/java/android/service/quickaccesswallet/WalletServiceEvent.java
new file mode 100644
index 000000000000..fb524be852fa
--- /dev/null
+++ b/core/java/android/service/quickaccesswallet/WalletServiceEvent.java
@@ -0,0 +1,92 @@
+/*
+ * Copyright (C) 2020 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 android.service.quickaccesswallet;
+
+import android.annotation.IntDef;
+import android.annotation.NonNull;
+import android.os.Parcel;
+import android.os.Parcelable;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+
+/**
+ * Represents a request from the {@link QuickAccessWalletService wallet app} to the Quick Access
+ * Wallet in System UI. Background events may necessitate that the Quick Access Wallet update its
+ * view. For example, if the wallet application handles an NFC payment while the Quick Access Wallet
+ * is being shown, it needs to tell the Quick Access Wallet so that the wallet can be dismissed and
+ * Activity showing the payment can be displayed to the user.
+ */
+public final class WalletServiceEvent implements Parcelable {
+
+ /**
+ * An NFC payment has started. If the Quick Access Wallet is in a system window, it will need to
+ * be dismissed so that an Activity showing the payment can be displayed.
+ */
+ public static final int TYPE_NFC_PAYMENT_STARTED = 1;
+
+ /**
+ * @hide
+ */
+ @Retention(RetentionPolicy.SOURCE)
+ @IntDef({TYPE_NFC_PAYMENT_STARTED})
+ public @interface EventType {
+ }
+
+ @EventType
+ private final int mEventType;
+
+ /**
+ * Creates a new DismissWalletRequest.
+ */
+ public WalletServiceEvent(@EventType int eventType) {
+ this.mEventType = eventType;
+ }
+
+ @Override
+ public int describeContents() {
+ return 0;
+ }
+
+ @Override
+ public void writeToParcel(@NonNull Parcel dest, int flags) {
+ dest.writeInt(mEventType);
+ }
+
+ @NonNull
+ public static final Creator<WalletServiceEvent> CREATOR =
+ new Creator<WalletServiceEvent>() {
+ @Override
+ public WalletServiceEvent createFromParcel(Parcel source) {
+ int eventType = source.readInt();
+ return new WalletServiceEvent(eventType);
+ }
+
+ @Override
+ public WalletServiceEvent[] newArray(int size) {
+ return new WalletServiceEvent[size];
+ }
+ };
+
+ /**
+ * @return the event type
+ */
+ @EventType
+ public int getEventType() {
+ return mEventType;
+ }
+}
diff --git a/core/java/android/service/quickaccesswallet/WalletServiceEventListenerRequest.aidl b/core/java/android/service/quickaccesswallet/WalletServiceEventListenerRequest.aidl
new file mode 100644
index 000000000000..155f92e8acc6
--- /dev/null
+++ b/core/java/android/service/quickaccesswallet/WalletServiceEventListenerRequest.aidl
@@ -0,0 +1,19 @@
+/*
+ * Copyright 2020 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 android.service.quickaccesswallet;
+
+parcelable WalletServiceEventListenerRequest; \ No newline at end of file
diff --git a/core/java/android/service/quickaccesswallet/WalletServiceEventListenerRequest.java b/core/java/android/service/quickaccesswallet/WalletServiceEventListenerRequest.java
new file mode 100644
index 000000000000..223110e45d01
--- /dev/null
+++ b/core/java/android/service/quickaccesswallet/WalletServiceEventListenerRequest.java
@@ -0,0 +1,78 @@
+/*
+ * Copyright (C) 2020 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 android.service.quickaccesswallet;
+
+import android.annotation.NonNull;
+import android.os.Parcel;
+import android.os.Parcelable;
+
+/**
+ * Register a dismiss request listener with the QuickAccessWalletService. This allows the service to
+ * dismiss the wallet if it needs to show a payment activity in response to an NFC event.
+ *
+ * @hide
+ */
+public final class WalletServiceEventListenerRequest implements Parcelable {
+
+ private final String mListenerId;
+
+ /**
+ * Construct a new {@code DismissWalletListenerRequest}.
+ *
+ * @param listenerKey A unique key that identifies the listener.
+ */
+ public WalletServiceEventListenerRequest(@NonNull String listenerKey) {
+ mListenerId = listenerKey;
+ }
+
+ @Override
+ public int describeContents() {
+ return 0;
+ }
+
+ @Override
+ public void writeToParcel(@NonNull Parcel dest, int flags) {
+ dest.writeString(mListenerId);
+ }
+
+ private static WalletServiceEventListenerRequest readFromParcel(Parcel source) {
+ String listenerId = source.readString();
+ return new WalletServiceEventListenerRequest(listenerId);
+ }
+
+ @NonNull
+ public static final Creator<WalletServiceEventListenerRequest> CREATOR =
+ new Creator<WalletServiceEventListenerRequest>() {
+ @Override
+ public WalletServiceEventListenerRequest createFromParcel(Parcel source) {
+ return readFromParcel(source);
+ }
+
+ @Override
+ public WalletServiceEventListenerRequest[] newArray(int size) {
+ return new WalletServiceEventListenerRequest[size];
+ }
+ };
+
+ /**
+ * Returns the unique key that identifies the wallet dismiss request listener.
+ */
+ @NonNull
+ public String getListenerId() {
+ return mListenerId;
+ }
+}
diff --git a/core/java/android/telephony/PhoneStateListener.java b/core/java/android/telephony/PhoneStateListener.java
index 4def80eb34a0..67cac0eb3b21 100644
--- a/core/java/android/telephony/PhoneStateListener.java
+++ b/core/java/android/telephony/PhoneStateListener.java
@@ -188,6 +188,10 @@ public class PhoneStateListener {
* Listen for {@link android.telephony.Annotation.PreciseCallStates} of ringing,
* background and foreground calls.
*
+ * <p>Requires permission {@link android.Manifest.permission#READ_PRECISE_PHONE_STATE}
+ * or the calling app has carrier privileges
+ * (see {@link TelephonyManager#hasCarrierPrivileges}).
+ *
* @hide
*/
@RequiresPermission((android.Manifest.permission.READ_PRECISE_PHONE_STATE))
@@ -197,13 +201,13 @@ public class PhoneStateListener {
/**
* Listen for {@link PreciseDataConnectionState} on the data connection (cellular).
*
- * <p>Requires permission {@link android.Manifest.permission#MODIFY_PHONE_STATE}
+ * <p>Requires permission {@link android.Manifest.permission#READ_PRECISE_PHONE_STATE}
* or the calling app has carrier privileges
* (see {@link TelephonyManager#hasCarrierPrivileges}).
*
* @see #onPreciseDataConnectionStateChanged
*/
- @RequiresPermission((android.Manifest.permission.MODIFY_PHONE_STATE))
+ @RequiresPermission((android.Manifest.permission.READ_PRECISE_PHONE_STATE))
public static final int LISTEN_PRECISE_DATA_CONNECTION_STATE = 0x00001000;
/**
@@ -328,26 +332,36 @@ public class PhoneStateListener {
* Listen for call disconnect causes which contains {@link DisconnectCause} and
* {@link PreciseDisconnectCause}.
*
+ * <p>Requires permission {@link android.Manifest.permission#READ_PRECISE_PHONE_STATE}
+ * or the calling app has carrier privileges
+ * (see {@link TelephonyManager#hasCarrierPrivileges}).
+ *
*/
@RequiresPermission((android.Manifest.permission.READ_PRECISE_PHONE_STATE))
public static final int LISTEN_CALL_DISCONNECT_CAUSES = 0x02000000;
/**
* Listen for changes to the call attributes of a currently active call.
- * {@more}
- * Requires Permission: {@link android.Manifest.permission#READ_PRECISE_PHONE_STATE
- * READ_PRECISE_PHONE_STATE}
+ *
+ * <p>Requires permission {@link android.Manifest.permission#READ_PRECISE_PHONE_STATE}
+ * or the calling app has carrier privileges
+ * (see {@link TelephonyManager#hasCarrierPrivileges}).
*
* @see #onCallAttributesChanged
* @hide
*/
@SystemApi
+ @RequiresPermission((android.Manifest.permission.READ_PRECISE_PHONE_STATE))
public static final int LISTEN_CALL_ATTRIBUTES_CHANGED = 0x04000000;
/**
* Listen for IMS call disconnect causes which contains
* {@link android.telephony.ims.ImsReasonInfo}
*
+ * <p>Requires permission {@link android.Manifest.permission#READ_PRECISE_PHONE_STATE}
+ * or the calling app has carrier privileges
+ * (see {@link TelephonyManager#hasCarrierPrivileges}).
+ *
* @see #onImsCallDisconnectCauseChanged(ImsReasonInfo)
*/
@RequiresPermission((android.Manifest.permission.READ_PRECISE_PHONE_STATE))
diff --git a/core/java/android/view/ImeFocusController.java b/core/java/android/view/ImeFocusController.java
index 5c494c17669a..271566acb74e 100644
--- a/core/java/android/view/ImeFocusController.java
+++ b/core/java/android/view/ImeFocusController.java
@@ -38,6 +38,7 @@ public final class ImeFocusController {
private boolean mHasImeFocus = false;
private View mServedView;
private View mNextServedView;
+ private InputMethodManagerDelegate mDelegate;
@UiThread
ImeFocusController(@NonNull ViewRootImpl viewRootImpl) {
@@ -45,7 +46,11 @@ public final class ImeFocusController {
}
private InputMethodManagerDelegate getImmDelegate() {
- return mViewRootImpl.mContext.getSystemService(InputMethodManager.class).getDelegate();
+ if (mDelegate == null) {
+ mDelegate = mViewRootImpl.mContext.getSystemService(
+ InputMethodManager.class).getDelegate();
+ }
+ return mDelegate;
}
@UiThread
diff --git a/core/java/android/view/inputmethod/InputMethod.java b/core/java/android/view/inputmethod/InputMethod.java
index cf494aec26f6..91e15c1949b6 100644
--- a/core/java/android/view/inputmethod/InputMethod.java
+++ b/core/java/android/view/inputmethod/InputMethod.java
@@ -27,6 +27,7 @@ import android.os.IBinder;
import android.os.RemoteException;
import android.os.ResultReceiver;
import android.util.Log;
+import android.view.View;
import android.view.autofill.AutofillId;
import com.android.internal.inputmethod.IInputMethodPrivilegedOperations;
@@ -298,7 +299,30 @@ public interface InputMethod {
* until deliberated dismissed by the user in its UI.
*/
public static final int SHOW_FORCED = 0x00002;
-
+
+ /**
+ * Request that any soft input part of the input method be shown to the user.
+ *
+ * @param flags Provides additional information about the show request.
+ * Currently may be 0 or have the bit {@link #SHOW_EXPLICIT} set.
+ * @param resultReceiver The client requesting the show may wish to
+ * be told the impact of their request, which should be supplied here.
+ * The result code should be
+ * {@link InputMethodManager#RESULT_UNCHANGED_SHOWN InputMethodManager.RESULT_UNCHANGED_SHOWN},
+ * {@link InputMethodManager#RESULT_UNCHANGED_HIDDEN InputMethodManager.RESULT_UNCHANGED_HIDDEN},
+ * {@link InputMethodManager#RESULT_SHOWN InputMethodManager.RESULT_SHOWN}, or
+ * {@link InputMethodManager#RESULT_HIDDEN InputMethodManager.RESULT_HIDDEN}.
+ * @param showInputToken an opaque {@link android.os.Binder} token to identify which API call
+ * of {@link InputMethodManager#showSoftInput(View, int)} is associated with
+ * this callback.
+ * @hide
+ */
+ @MainThread
+ default public void showSoftInputWithToken(int flags, ResultReceiver resultReceiver,
+ IBinder showInputToken) {
+ showSoftInput(flags, resultReceiver);
+ }
+
/**
* Request that any soft input part of the input method be shown to the user.
*
@@ -314,7 +338,7 @@ public interface InputMethod {
*/
@MainThread
public void showSoftInput(int flags, ResultReceiver resultReceiver);
-
+
/**
* Request that any soft input part of the input method be hidden from the user.
* @param flags Provides additional information about the show request.
@@ -336,4 +360,12 @@ public interface InputMethod {
*/
@MainThread
public void changeInputMethodSubtype(InputMethodSubtype subtype);
+
+ /**
+ * Update token of the client window requesting {@link #showSoftInput(int, ResultReceiver)}
+ * @param showInputToken dummy app window token for window requesting
+ * {@link InputMethodManager#showSoftInput(View, int)}
+ * @hide
+ */
+ public void setCurrentShowInputToken(IBinder showInputToken);
}
diff --git a/core/java/android/view/inputmethod/InputMethodManager.java b/core/java/android/view/inputmethod/InputMethodManager.java
index 904e736d214e..307abd2f5f65 100644
--- a/core/java/android/view/inputmethod/InputMethodManager.java
+++ b/core/java/android/view/inputmethod/InputMethodManager.java
@@ -59,12 +59,12 @@ import android.util.PrintWriterPrinter;
import android.util.Printer;
import android.util.SparseArray;
import android.view.Display;
+import android.view.ImeFocusController;
import android.view.ImeInsetsSourceConsumer;
import android.view.InputChannel;
import android.view.InputEvent;
import android.view.InputEventSender;
import android.view.KeyEvent;
-import android.view.ImeFocusController;
import android.view.View;
import android.view.ViewRootImpl;
import android.view.WindowManager.LayoutParams.SoftInputModeFlags;
@@ -562,14 +562,23 @@ public final class InputMethodManager {
public boolean startInput(@StartInputReason int startInputReason, View focusedView,
@StartInputFlags int startInputFlags, @SoftInputModeFlags int softInputMode,
int windowFlags) {
+ final View servedView;
synchronized (mH) {
mCurrentTextBoxAttribute = null;
mCompletions = null;
mServedConnecting = true;
- if (getServedViewLocked() != null && !getServedViewLocked().onCheckIsTextEditor()) {
- // servedView has changed and it's not editable.
- maybeCallServedViewChangedLocked(null);
- }
+ servedView = getServedViewLocked();
+ }
+ if (servedView != null && servedView.getHandler() != null) {
+ // Make sure View checks should be on the UI thread.
+ servedView.getHandler().post(() -> {
+ if (!servedView.onCheckIsTextEditor()) {
+ // servedView has changed and it's not editable.
+ synchronized (mH) {
+ maybeCallServedViewChangedLocked(null);
+ }
+ }
+ });
}
return startInputInner(startInputReason,
focusedView != null ? focusedView.getWindowToken() : null, startInputFlags,
@@ -607,21 +616,22 @@ public final class InputMethodManager {
mWindowFocusGainFuture.cancel(false /* mayInterruptIfRunning */);
}
mWindowFocusGainFuture = mStartInputWorker.submit(() -> {
- synchronized (mH) {
- if (mCurRootView == null) {
+ final ImeFocusController controller = getFocusController();
+ if (controller == null) {
+ return;
+ }
+ if (controller.checkFocus(forceNewFocus1, false)) {
+ // We need to restart input on the current focus view. This
+ // should be done in conjunction with telling the system service
+ // about the window gaining focus, to help make the transition
+ // smooth.
+ if (startInput(StartInputReason.WINDOW_FOCUS_GAIN,
+ focusedView, startInputFlags, softInputMode, windowFlags)) {
return;
}
- if (mCurRootView.getImeFocusController().checkFocus(forceNewFocus1, false)) {
- // We need to restart input on the current focus view. This
- // should be done in conjunction with telling the system service
- // about the window gaining focus, to help make the transition
- // smooth.
- if (startInput(StartInputReason.WINDOW_FOCUS_GAIN,
- focusedView, startInputFlags, softInputMode, windowFlags)) {
- return;
- }
- }
+ }
+ synchronized (mH) {
// For some reason we didn't do a startInput + windowFocusGain, so
// we'll just do a window focus gain and call it a day.
try {
@@ -716,6 +726,15 @@ public final class InputMethodManager {
}
}
+ private ImeFocusController getFocusController() {
+ synchronized (mH) {
+ if (mCurRootView != null) {
+ return mCurRootView.getImeFocusController();
+ }
+ return null;
+ }
+ }
+
/**
* Returns {@code true} when the given view has been served by Input Method.
*/
@@ -1617,7 +1636,8 @@ public final class InputMethodManager {
}
try {
- return mService.showSoftInput(mClient, flags, resultReceiver);
+ return mService.showSoftInput(
+ mClient, view.getWindowToken(), flags, resultReceiver);
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
@@ -1639,7 +1659,8 @@ public final class InputMethodManager {
Log.w(TAG, "showSoftInputUnchecked() is a hidden method, which will be removed "
+ "soon. If you are using android.support.v7.widget.SearchView, please update "
+ "to version 26.0 or newer version.");
- mService.showSoftInput(mClient, flags, resultReceiver);
+ mService.showSoftInput(
+ mClient, mCurRootView.getView().getWindowToken(), flags, resultReceiver);
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
@@ -1793,6 +1814,12 @@ public final class InputMethodManager {
startInputInner(StartInputReason.APP_CALLED_RESTART_INPUT_API, null, 0, 0, 0);
}
+ /**
+ * Called when {@link DelegateImpl#startInput}, {@link #restartInput(View)},
+ * {@link #MSG_BIND} or {@link #MSG_UNBIND}.
+ * Note that this method should *NOT* be called inside of {@code mH} lock to prevent start input
+ * background thread may blocked by other methods which already inside {@code mH} lock.
+ */
boolean startInputInner(@StartInputReason int startInputReason,
@Nullable IBinder windowGainingFocus, @StartInputFlags int startInputFlags,
@SoftInputModeFlags int softInputMode, int windowFlags) {
@@ -1976,15 +2003,16 @@ public final class InputMethodManager {
}
/**
+ * Check the next served view from {@link ImeFocusController} if needs to start input.
+ * Note that this method should *NOT* be called inside of {@code mH} lock to prevent start input
+ * background thread may blocked by other methods which already inside {@code mH} lock.
* @hide
*/
@UnsupportedAppUsage
public void checkFocus() {
- synchronized (mH) {
- if (mCurRootView != null) {
- mCurRootView.getImeFocusController().checkFocus(false /* forceNewFocus */,
- true /* startInput */);
- }
+ final ImeFocusController controller = getFocusController();
+ if (controller != null) {
+ controller.checkFocus(false /* forceNewFocus */, true /* startInput */);
}
}
diff --git a/core/java/android/widget/Editor.java b/core/java/android/widget/Editor.java
index 2732b2e0285a..b10631b7ef2f 100644
--- a/core/java/android/widget/Editor.java
+++ b/core/java/android/widget/Editor.java
@@ -220,7 +220,9 @@ public class Editor {
private final boolean mHapticTextHandleEnabled;
- private final MagnifierMotionAnimator mMagnifierAnimator;
+ @Nullable
+ private MagnifierMotionAnimator mMagnifierAnimator;
+
private final Runnable mUpdateMagnifierRunnable = new Runnable() {
@Override
public void run() {
@@ -397,12 +399,6 @@ public class Editor {
mHapticTextHandleEnabled = mTextView.getContext().getResources().getBoolean(
com.android.internal.R.bool.config_enableHapticTextHandle);
- if (FLAG_USE_MAGNIFIER) {
- final Magnifier magnifier =
- Magnifier.createBuilderWithOldMagnifierDefaults(mTextView).build();
- mMagnifierAnimator = new MagnifierMotionAnimator(magnifier);
- }
-
mCursorControlEnabled = AppGlobals.getIntCoreSetting(
WidgetFlags.KEY_ENABLE_CURSOR_CONTROL , 0) != 0;
if (TextView.DEBUG_CURSOR) {
@@ -421,6 +417,63 @@ public class Editor {
return mCursorControlEnabled;
}
+ // Lazy creates the magnifier animator.
+ private MagnifierMotionAnimator getMagnifierAnimator() {
+ if (FLAG_USE_MAGNIFIER && mMagnifierAnimator == null) {
+ // Lazy creates the magnifier instance because it requires the text height which cannot
+ // be measured at the time of Editor instance being created.
+ final Magnifier.Builder builder = shouldUseNewMagnifier()
+ ? createBuilderWithInlineMagnifierDefaults()
+ : Magnifier.createBuilderWithOldMagnifierDefaults(mTextView);
+ mMagnifierAnimator = new MagnifierMotionAnimator(builder.build());
+ }
+ return mMagnifierAnimator;
+ }
+
+ private boolean shouldUseNewMagnifier() {
+ // TODO: use a separate flag to enable new magnifier.
+ return mCursorControlEnabled;
+ }
+
+ private Magnifier.Builder createBuilderWithInlineMagnifierDefaults() {
+ final Magnifier.Builder params = new Magnifier.Builder(mTextView);
+
+ // TODO: supports changing the height/width dynamically because the text height can be
+ // dynamically changed.
+ final Paint.FontMetrics fontMetrics = mTextView.getPaint().getFontMetrics();
+ final float sourceHeight = fontMetrics.descent - fontMetrics.ascent;
+ final float zoom = 1.5f;
+ final float widthHeightRatio = 5.5f;
+ // Slightly increase the height to avoid tooLargeTextForMagnifier() returns true.
+ int height = (int)(sourceHeight * zoom) + 2;
+ int width = (int)(widthHeightRatio * height);
+
+
+ params.setFishEyeStyle()
+ .setSize(width, height)
+ .setSourceSize(width, Math.round(sourceHeight))
+ .setElevation(0)
+ .setInitialZoom(zoom)
+ .setClippingEnabled(false);
+
+ final Context context = mTextView.getContext();
+ final TypedArray a = context.obtainStyledAttributes(
+ null, com.android.internal.R.styleable.Magnifier,
+ com.android.internal.R.attr.magnifierStyle, 0);
+ params.setDefaultSourceToMagnifierOffset(
+ a.getDimensionPixelSize(
+ com.android.internal.R.styleable.Magnifier_magnifierHorizontalOffset, 0),
+ a.getDimensionPixelSize(
+ com.android.internal.R.styleable.Magnifier_magnifierVerticalOffset, 0));
+ a.recycle();
+
+ return params.setSourceBounds(
+ Magnifier.SOURCE_BOUND_MAX_VISIBLE,
+ Magnifier.SOURCE_BOUND_MAX_IN_SURFACE,
+ Magnifier.SOURCE_BOUND_MAX_VISIBLE,
+ Magnifier.SOURCE_BOUND_MAX_IN_SURFACE);
+ }
+
ParcelableParcel saveInstanceState() {
ParcelableParcel state = new ParcelableParcel(getClass().getClassLoader());
Parcel parcel = state.getParcel();
@@ -5022,7 +5075,7 @@ public class Editor {
}
protected final void updateMagnifier(@NonNull final MotionEvent event) {
- if (mMagnifierAnimator == null) {
+ if (getMagnifierAnimator() == null) {
return;
}
@@ -5036,6 +5089,16 @@ public class Editor {
mTextView.invalidateCursorPath();
suspendBlink();
+ if (shouldUseNewMagnifier()) {
+ // Calculates the line bounds as the content source bounds to the magnifier.
+ Layout layout = mTextView.getLayout();
+ int line = layout.getLineForOffset(getCurrentCursorOffset());
+ int lineLeft = (int) layout.getLineLeft(line);
+ lineLeft += mTextView.getTotalPaddingLeft() - mTextView.getScrollX();
+ int lineRight = (int) layout.getLineRight(line);
+ lineRight -= mTextView.getTotalPaddingRight() + mTextView.getScrollX();
+ mMagnifierAnimator.mMagnifier.setSourceHorizontalBounds(lineLeft, lineRight);
+ }
mMagnifierAnimator.show(showPosInView.x, showPosInView.y);
updateHandlesVisibility();
} else {
diff --git a/core/java/android/widget/Magnifier.java b/core/java/android/widget/Magnifier.java
index 2924dd9bf954..57b63a7a9f0d 100644
--- a/core/java/android/widget/Magnifier.java
+++ b/core/java/android/widget/Magnifier.java
@@ -140,6 +140,18 @@ public final class Magnifier {
// The lock used to synchronize the UI and render threads when a #dismiss is performed.
private final Object mDestroyLock = new Object();
+ // Members for new styled magnifier (Eloquent style).
+
+ // Whether the magnifier is in new style.
+ private boolean mIsFishEyeStyle;
+ // The width of the cut region on the left edge of the pixel copy source rect.
+ private int mLeftCutWidth = 0;
+ // The width of the cut region on the right edge of the pixel copy source rect.
+ private int mRightCutWidth = 0;
+ // The horizontal bounds of the content source in pixels, relative to the view.
+ private int mLeftBound = Integer.MIN_VALUE;
+ private int mRightBound = Integer.MAX_VALUE;
+
/**
* Initializes a magnifier.
*
@@ -198,8 +210,14 @@ public final class Magnifier {
mWindowWidth = params.mWidth;
mWindowHeight = params.mHeight;
mZoom = params.mZoom;
- mSourceWidth = Math.round(mWindowWidth / mZoom);
- mSourceHeight = Math.round(mWindowHeight / mZoom);
+ mIsFishEyeStyle = params.mIsFishEyeStyle;
+ if (params.mSourceWidth > 0 && params.mSourceHeight > 0) {
+ mSourceWidth = params.mSourceWidth;
+ mSourceHeight = params.mSourceHeight;
+ } else {
+ mSourceWidth = Math.round(mWindowWidth / mZoom);
+ mSourceHeight = Math.round(mWindowHeight / mZoom);
+ }
mWindowElevation = params.mElevation;
mWindowCornerRadius = params.mCornerRadius;
mOverlay = params.mOverlay;
@@ -221,6 +239,18 @@ public final class Magnifier {
}
/**
+ * Sets the horizontal bounds of the source when showing the magnifier.
+ * This is used for new style magnifier. e.g. limit the source bounds by the text line bounds.
+ *
+ * @param left the left of the bounds, relative to the view.
+ * @param right the right of the bounds, relative to the view.
+ */
+ void setSourceHorizontalBounds(int left, int right) {
+ mLeftBound = left;
+ mRightBound = right;
+ }
+
+ /**
* Shows the magnifier on the screen. The method takes the coordinates of the center
* of the content source going to be magnified and copied to the magnifier. The coordinates
* are relative to the top left corner of the magnified view. The magnifier will be
@@ -265,20 +295,37 @@ public final class Magnifier {
obtainSurfaces();
obtainContentCoordinates(sourceCenterX, sourceCenterY);
- obtainWindowCoordinates(magnifierCenterX, magnifierCenterY);
- final int startX = mClampedCenterZoomCoords.x - mSourceWidth / 2;
+ int startX = mClampedCenterZoomCoords.x - mSourceWidth / 2;
final int startY = mClampedCenterZoomCoords.y - mSourceHeight / 2;
+
+ if (mIsFishEyeStyle) {
+ // The magnifier center is the same as source center in new style.
+ magnifierCenterX = mClampedCenterZoomCoords.x - mViewCoordinatesInSurface[0];
+ magnifierCenterY = mClampedCenterZoomCoords.y - mViewCoordinatesInSurface[1];
+ // Gets the startX for new style, which should be bounded by the horizontal bounds.
+ // Also calculates the left/right cut width for pixel copy.
+ final int left = startX;
+ final int right = startX + mSourceWidth;
+ final int leftBound = mViewCoordinatesInSurface[0] + Math.max(0, mLeftBound);
+ final int rightBound =
+ mViewCoordinatesInSurface[0] + Math.min(mView.getWidth(), mRightBound);
+ startX = Math.max(left, leftBound);
+ mLeftCutWidth = Math.max(0, leftBound - left);
+ mRightCutWidth = Math.max(0, right - rightBound);
+ }
+ obtainWindowCoordinates(magnifierCenterX, magnifierCenterY);
+
if (sourceCenterX != mPrevShowSourceCoords.x || sourceCenterY != mPrevShowSourceCoords.y
|| mDirtyState) {
if (mWindow == null) {
synchronized (mLock) {
mWindow = new InternalPopupWindow(mView.getContext(), mView.getDisplay(),
- mParentSurface.mSurfaceControl, mWindowWidth, mWindowHeight,
+ mParentSurface.mSurfaceControl, mWindowWidth, mWindowHeight, mZoom,
mWindowElevation, mWindowCornerRadius,
mOverlay != null ? mOverlay : new ColorDrawable(Color.TRANSPARENT),
Handler.getMain() /* draw the magnifier on the UI thread */, mLock,
- mCallback);
+ mCallback, mIsFishEyeStyle);
}
}
performPixelCopy(startX, startY, true /* update window position */);
@@ -387,7 +434,7 @@ public final class Magnifier {
public void setZoom(@FloatRange(from = 0f) float zoom) {
Preconditions.checkArgumentPositive(zoom, "Zoom should be positive");
mZoom = zoom;
- mSourceWidth = Math.round(mWindowWidth / mZoom);
+ mSourceWidth = mIsFishEyeStyle ? mWindowWidth : Math.round(mWindowWidth / mZoom);
mSourceHeight = Math.round(mWindowHeight / mZoom);
mDirtyState = true;
}
@@ -634,8 +681,10 @@ public final class Magnifier {
resolvedBottom = Math.max(resolvedBottom, resolvedTop + mSourceHeight);
// Finally compute the coordinates of the source center.
- mClampedCenterZoomCoords.x = Math.max(resolvedLeft + mSourceWidth / 2, Math.min(
- zoomCenterX, resolvedRight - mSourceWidth / 2));
+ mClampedCenterZoomCoords.x = mIsFishEyeStyle
+ ? Math.max(resolvedLeft, Math.min(zoomCenterX, resolvedRight))
+ : Math.max(resolvedLeft + mSourceWidth / 2, Math.min(
+ zoomCenterX, resolvedRight - mSourceWidth / 2));
mClampedCenterZoomCoords.y = Math.max(resolvedTop + mSourceHeight / 2, Math.min(
zoomCenterY, resolvedBottom - mSourceHeight / 2));
}
@@ -678,11 +727,22 @@ public final class Magnifier {
// Perform the pixel copy.
mPixelCopyRequestRect.set(startXInSurface,
startYInSurface,
- startXInSurface + mSourceWidth,
+ startXInSurface + mSourceWidth - mLeftCutWidth - mRightCutWidth,
startYInSurface + mSourceHeight);
+ mPrevStartCoordsInSurface.x = startXInSurface;
+ mPrevStartCoordsInSurface.y = startYInSurface;
+ mDirtyState = false;
+
final InternalPopupWindow currentWindowInstance = mWindow;
+ if (mPixelCopyRequestRect.width() == 0) {
+ // If the copy rect is empty, updates an empty bitmap to the window.
+ mWindow.updateContent(
+ Bitmap.createBitmap(mSourceWidth, mSourceHeight, Bitmap.Config.ALPHA_8));
+ return;
+ }
final Bitmap bitmap =
- Bitmap.createBitmap(mSourceWidth, mSourceHeight, Bitmap.Config.ARGB_8888);
+ Bitmap.createBitmap(mSourceWidth - mLeftCutWidth - mRightCutWidth,
+ mSourceHeight, Bitmap.Config.ARGB_8888);
PixelCopy.request(mContentCopySurface.mSurface, mPixelCopyRequestRect, bitmap,
result -> {
if (result != PixelCopy.SUCCESS) {
@@ -696,15 +756,25 @@ public final class Magnifier {
}
if (updateWindowPosition) {
// TODO: pull the position update outside #performPixelCopy
- mWindow.setContentPositionForNextDraw(windowCoords.x, windowCoords.y);
+ mWindow.setContentPositionForNextDraw(windowCoords.x,
+ windowCoords.y);
+ }
+ if (bitmap.getWidth() < mSourceWidth) {
+ // When bitmap width has been cut, re-fills it with full width bitmap.
+ // This only happens in new styled magnifier.
+ final Bitmap newBitmap = Bitmap.createBitmap(
+ mSourceWidth, bitmap.getHeight(), bitmap.getConfig());
+ final Canvas can = new Canvas(newBitmap);
+ final Rect dstRect = new Rect(mLeftCutWidth, 0,
+ mSourceWidth - mRightCutWidth, bitmap.getHeight());
+ can.drawBitmap(bitmap, null, dstRect, null);
+ mWindow.updateContent(newBitmap);
+ } else {
+ mWindow.updateContent(bitmap);
}
- mWindow.updateContent(bitmap);
}
},
sPixelCopyHandlerThread.getThreadHandler());
- mPrevStartCoordsInSurface.x = startXInSurface;
- mPrevStartCoordsInSurface.y = startYInSurface;
- mDirtyState = false;
}
private void onPixelCopyFailed() {
@@ -790,9 +860,6 @@ public final class Magnifier {
// The size of the content of the magnifier.
private final int mContentWidth;
private final int mContentHeight;
- // The size of the allocated surface.
- private final int mSurfaceWidth;
- private final int mSurfaceHeight;
// The insets of the content inside the allocated surface.
private final int mOffsetX;
private final int mOffsetY;
@@ -815,9 +882,6 @@ public final class Magnifier {
private final Handler mHandler;
// The callback to be run after the next draw.
private Callback mCallback;
- // The position of the magnifier content when the last draw was requested.
- private int mLastDrawContentPositionX;
- private int mLastDrawContentPositionY;
// Members below describe the state of the magnifier. Reads/writes to them
// have to be synchronized between the UI thread and the thread that handles
@@ -838,10 +902,19 @@ public final class Magnifier {
// The current content of the magnifier. It is mBitmap + mOverlay, only used for testing.
private Bitmap mCurrentContent;
+ private final float mZoom;
+ // Whether is in the new magnifier style.
+ private boolean mIsFishEyeStyle;
+ // The mesh matrix for the fish-eye effect.
+ private float[] mMesh;
+ private int mMeshWidth;
+ private int mMeshHeight;
+
InternalPopupWindow(final Context context, final Display display,
final SurfaceControl parentSurfaceControl, final int width, final int height,
- final float elevation, final float cornerRadius, final Drawable overlay,
- final Handler handler, final Object lock, final Callback callback) {
+ final float zoom, final float elevation, final float cornerRadius,
+ final Drawable overlay, final Handler handler, final Object lock,
+ final Callback callback, final boolean isFishEyeStyle) {
mDisplay = display;
mOverlay = overlay;
mLock = lock;
@@ -849,15 +922,16 @@ public final class Magnifier {
mContentWidth = width;
mContentHeight = height;
+ mZoom = zoom;
mOffsetX = (int) (1.05f * elevation);
mOffsetY = (int) (1.05f * elevation);
// Setup the surface we will use for drawing the content and shadow.
- mSurfaceWidth = mContentWidth + 2 * mOffsetX;
- mSurfaceHeight = mContentHeight + 2 * mOffsetY;
+ final int surfaceWidth = mContentWidth + 2 * mOffsetX;
+ final int surfaceHeight = mContentHeight + 2 * mOffsetY;
mSurfaceSession = new SurfaceSession();
mSurfaceControl = new SurfaceControl.Builder(mSurfaceSession)
.setFormat(PixelFormat.TRANSLUCENT)
- .setBufferSize(mSurfaceWidth, mSurfaceHeight)
+ .setBufferSize(surfaceWidth, surfaceHeight)
.setName("magnifier surface")
.setFlags(SurfaceControl.HIDDEN)
.setParent(parentSurfaceControl)
@@ -904,6 +978,38 @@ public final class Magnifier {
mHandler = handler;
mMagnifierUpdater = this::doDraw;
mFrameDrawScheduled = false;
+ mIsFishEyeStyle = isFishEyeStyle;
+
+ if (mIsFishEyeStyle) {
+ createMeshMatrixForFishEyeEffect();
+ }
+ }
+
+ private void createMeshMatrixForFishEyeEffect() {
+ mMeshWidth = mZoom < 1.5f ? 5 : 4;
+ mMeshHeight = 6;
+ final float w = mContentWidth;
+ final float h = mContentHeight;
+ final float dx = (w - mZoom * w * (mMeshWidth - 2) / mMeshWidth) / 2;
+ mMesh = new float[2 * (mMeshWidth + 1) * (mMeshHeight + 1)];
+ for (int i = 0; i < 2 * (mMeshWidth + 1) * (mMeshHeight + 1); i += 2) {
+ // Calculates X value.
+ final int colIndex = i % (2 * (mMeshWidth + 1)) / 2;
+ if (colIndex == 0) {
+ mMesh[i] = 0;
+ } else if (colIndex == mMeshWidth) {
+ mMesh[i] = w;
+ } else {
+ mMesh[i] = (colIndex - 1) * (w - 2 * dx) / (mMeshWidth - 2) + dx;
+ }
+ // Calculates Y value.
+ final int rowIndex = i / 2 / (mMeshWidth + 1);
+ final float y0 = colIndex == 0 || colIndex == mMeshWidth
+ ? (h - h / mZoom) / 2 : 0;
+ final float dy = colIndex == 0 || colIndex == mMeshWidth
+ ? h / mZoom / mMeshHeight : h / mMeshHeight;
+ mMesh[i + 1] = y0 + rowIndex * dy;
+ }
}
private RenderNode createRenderNodeForBitmap(final String name,
@@ -1060,15 +1166,19 @@ public final class Magnifier {
final RecordingCanvas canvas =
mBitmapRenderNode.beginRecording(mContentWidth, mContentHeight);
try {
- final Rect srcRect = new Rect(0, 0, mBitmap.getWidth(), mBitmap.getHeight());
- final Rect dstRect = new Rect(0, 0, mContentWidth, mContentHeight);
- final Paint paint = new Paint();
- paint.setFilterBitmap(true);
- canvas.drawBitmap(mBitmap, srcRect, dstRect, paint);
+ if (mIsFishEyeStyle) {
+ canvas.drawBitmapMesh(
+ mBitmap, mMeshWidth, mMeshHeight, mMesh, 0, null, 0, null);
+ } else {
+ final Rect srcRect = new Rect(0, 0, mBitmap.getWidth(), mBitmap.getHeight());
+ final Rect dstRect = new Rect(0, 0, mContentWidth, mContentHeight);
+ final Paint paint = new Paint();
+ paint.setFilterBitmap(true);
+ canvas.drawBitmap(mBitmap, srcRect, dstRect, paint);
+ }
} finally {
mBitmapRenderNode.endRecording();
}
-
if (mPendingWindowPositionUpdate || mFirstDraw) {
// If the window has to be shown or moved, defer this until the next draw.
final boolean firstDraw = mFirstDraw;
@@ -1094,13 +1204,14 @@ public final class Magnifier {
}
mTransaction.apply();
};
- mRenderer.setLightCenter(mDisplay, pendingX, pendingY);
+ if (!mIsFishEyeStyle) {
+ // The new style magnifier doesn't need the light/shadow.
+ mRenderer.setLightCenter(mDisplay, pendingX, pendingY);
+ }
} else {
callback = null;
}
- mLastDrawContentPositionX = mWindowPositionX + mOffsetX;
- mLastDrawContentPositionY = mWindowPositionY + mOffsetY;
mFrameDrawScheduled = false;
}
@@ -1149,6 +1260,9 @@ public final class Magnifier {
private @SourceBound int mTopContentBound;
private @SourceBound int mRightContentBound;
private @SourceBound int mBottomContentBound;
+ private boolean mIsFishEyeStyle;
+ private int mSourceWidth;
+ private int mSourceHeight;
/**
* Construct a new builder for {@link Magnifier} objects.
@@ -1177,6 +1291,7 @@ public final class Magnifier {
mTopContentBound = SOURCE_BOUND_MAX_VISIBLE;
mRightContentBound = SOURCE_BOUND_MAX_VISIBLE;
mBottomContentBound = SOURCE_BOUND_MAX_VISIBLE;
+ mIsFishEyeStyle = false;
}
/**
@@ -1339,6 +1454,25 @@ public final class Magnifier {
}
/**
+ * Sets the source width/height.
+ */
+ @NonNull
+ Builder setSourceSize(int width, int height) {
+ mSourceWidth = width;
+ mSourceHeight = height;
+ return this;
+ }
+
+ /**
+ * Sets the magnifier as the new fish-eye style.
+ */
+ @NonNull
+ Builder setFishEyeStyle() {
+ mIsFishEyeStyle = true;
+ return this;
+ }
+
+ /**
* Builds a {@link Magnifier} instance based on the configuration of this {@link Builder}.
*/
public @NonNull Magnifier build() {
diff --git a/core/java/com/android/internal/inputmethod/IInputMethodPrivilegedOperations.aidl b/core/java/com/android/internal/inputmethod/IInputMethodPrivilegedOperations.aidl
index e27ff0076054..20cd7c21d512 100644
--- a/core/java/com/android/internal/inputmethod/IInputMethodPrivilegedOperations.aidl
+++ b/core/java/com/android/internal/inputmethod/IInputMethodPrivilegedOperations.aidl
@@ -41,5 +41,5 @@ interface IInputMethodPrivilegedOperations {
boolean shouldOfferSwitchingToNextInputMethod();
void notifyUserAction();
void reportPreRendered(in EditorInfo info);
- void applyImeVisibility(boolean setVisible);
+ void applyImeVisibility(IBinder showInputToken, boolean setVisible);
}
diff --git a/core/java/com/android/internal/inputmethod/InputMethodPrivilegedOperations.java b/core/java/com/android/internal/inputmethod/InputMethodPrivilegedOperations.java
index d42c607b98bf..9eeef963de7f 100644
--- a/core/java/com/android/internal/inputmethod/InputMethodPrivilegedOperations.java
+++ b/core/java/com/android/internal/inputmethod/InputMethodPrivilegedOperations.java
@@ -23,6 +23,7 @@ import android.net.Uri;
import android.os.IBinder;
import android.os.RemoteException;
import android.util.Log;
+import android.view.View;
import android.view.inputmethod.EditorInfo;
import android.view.inputmethod.InputMethodSubtype;
@@ -368,18 +369,20 @@ public final class InputMethodPrivilegedOperations {
}
/**
- * Calls {@link IInputMethodPrivilegedOperations#applyImeVisibility(boolean)}.
+ * Calls {@link IInputMethodPrivilegedOperations#applyImeVisibility(IBinder, boolean)}.
*
+ * @param showInputToken dummy token that maps to window requesting
+ * {@link android.view.inputmethod.InputMethodManager#showSoftInput(View, int)}
* @param setVisible {@code true} to set IME visible, else hidden.
*/
@AnyThread
- public void applyImeVisibility(boolean setVisible) {
+ public void applyImeVisibility(IBinder showInputToken, boolean setVisible) {
final IInputMethodPrivilegedOperations ops = mOps.getAndWarnIfNull();
if (ops == null) {
return;
}
try {
- ops.applyImeVisibility(setVisible);
+ ops.applyImeVisibility(showInputToken, setVisible);
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
diff --git a/core/java/com/android/internal/view/IInputMethod.aidl b/core/java/com/android/internal/view/IInputMethod.aidl
index 58aaa80b51be..475a3214096d 100644
--- a/core/java/com/android/internal/view/IInputMethod.aidl
+++ b/core/java/com/android/internal/view/IInputMethod.aidl
@@ -54,7 +54,7 @@ oneway interface IInputMethod {
void revokeSession(IInputMethodSession session);
- void showSoftInput(int flags, in ResultReceiver resultReceiver);
+ void showSoftInput(in IBinder showInputToken, int flags, in ResultReceiver resultReceiver);
void hideSoftInput(int flags, in ResultReceiver resultReceiver);
diff --git a/core/java/com/android/internal/view/IInputMethodManager.aidl b/core/java/com/android/internal/view/IInputMethodManager.aidl
index c29e823218eb..0337ddd1ab49 100644
--- a/core/java/com/android/internal/view/IInputMethodManager.aidl
+++ b/core/java/com/android/internal/view/IInputMethodManager.aidl
@@ -41,7 +41,7 @@ interface IInputMethodManager {
boolean allowsImplicitlySelectedSubtypes);
InputMethodSubtype getLastInputMethodSubtype();
- boolean showSoftInput(in IInputMethodClient client, int flags,
+ boolean showSoftInput(in IInputMethodClient client, IBinder windowToken, int flags,
in ResultReceiver resultReceiver);
boolean hideSoftInput(in IInputMethodClient client, int flags,
in ResultReceiver resultReceiver);
diff --git a/core/jni/android_media_AudioAttributes.cpp b/core/jni/android_media_AudioAttributes.cpp
index b87a34d6c7aa..b616ffc111a3 100644
--- a/core/jni/android_media_AudioAttributes.cpp
+++ b/core/jni/android_media_AudioAttributes.cpp
@@ -48,11 +48,14 @@ static struct {
jfieldID mFormattedTags; // AudioAttributes.mFormattedTags
} gAudioAttributesFields;
+static struct { jmethodID isSystemUsage; } gAudioAttributesClassMethods;
+
static jclass gAudioAttributesBuilderClass;
static jmethodID gAudioAttributesBuilderCstor;
static struct {
jmethodID build;
jmethodID setUsage;
+ jmethodID setSystemUsage;
jmethodID setInternalCapturePreset;
jmethodID setContentType;
jmethodID setFlags;
@@ -109,9 +112,17 @@ static jint nativeAudioAttributesToJavaAudioAttributes(
if (jAttributeBuilder.get() == nullptr) {
return (jint)AUDIO_JAVA_ERROR;
}
- env->CallObjectMethod(jAttributeBuilder.get(),
- gAudioAttributesBuilderMethods.setUsage,
- attributes.usage);
+
+ const bool isSystemUsage = env->CallStaticBooleanMethod(gAudioAttributesClass,
+ gAudioAttributesClassMethods.isSystemUsage,
+ attributes.usage);
+ if (isSystemUsage) {
+ env->CallObjectMethod(jAttributeBuilder.get(),
+ gAudioAttributesBuilderMethods.setSystemUsage, attributes.usage);
+ } else {
+ env->CallObjectMethod(jAttributeBuilder.get(), gAudioAttributesBuilderMethods.setUsage,
+ attributes.usage);
+ }
env->CallObjectMethod(jAttributeBuilder.get(),
gAudioAttributesBuilderMethods.setInternalCapturePreset,
attributes.source);
@@ -168,6 +179,9 @@ int register_android_media_AudioAttributes(JNIEnv *env)
{
jclass audioAttributesClass = FindClassOrDie(env, kClassPathName);
gAudioAttributesClass = MakeGlobalRefOrDie(env, audioAttributesClass);
+ gAudioAttributesClassMethods.isSystemUsage =
+ GetStaticMethodIDOrDie(env, gAudioAttributesClass, "isSystemUsage", "(I)Z");
+
gAudioAttributesFields.mUsage = GetFieldIDOrDie(env, audioAttributesClass, "mUsage", "I");
gAudioAttributesFields.mSource = GetFieldIDOrDie(env, audioAttributesClass, "mSource", "I");
gAudioAttributesFields.mContentType =
@@ -186,6 +200,9 @@ int register_android_media_AudioAttributes(JNIEnv *env)
gAudioAttributesBuilderMethods.setUsage = GetMethodIDOrDie(
env, audioAttributesBuilderClass, "setUsage",
"(I)Landroid/media/AudioAttributes$Builder;");
+ gAudioAttributesBuilderMethods.setSystemUsage =
+ GetMethodIDOrDie(env, audioAttributesBuilderClass, "setSystemUsage",
+ "(I)Landroid/media/AudioAttributes$Builder;");
gAudioAttributesBuilderMethods.setInternalCapturePreset = GetMethodIDOrDie(
env, audioAttributesBuilderClass, "setInternalCapturePreset",
"(I)Landroid/media/AudioAttributes$Builder;");
diff --git a/core/jni/android_media_AudioSystem.cpp b/core/jni/android_media_AudioSystem.cpp
index c4ee19519951..e266fe623947 100644
--- a/core/jni/android_media_AudioSystem.cpp
+++ b/core/jni/android_media_AudioSystem.cpp
@@ -2239,6 +2239,31 @@ android_media_AudioSystem_isHapticPlaybackSupported(JNIEnv *env, jobject thiz)
return AudioSystem::isHapticPlaybackSupported();
}
+static jint android_media_AudioSystem_setSupportedSystemUsages(JNIEnv *env, jobject thiz,
+ jintArray systemUsages) {
+ std::vector<audio_usage_t> nativeSystemUsagesVector;
+
+ if (systemUsages == nullptr) {
+ return (jint) AUDIO_JAVA_BAD_VALUE;
+ }
+
+ int *nativeSystemUsages = nullptr;
+ nativeSystemUsages = env->GetIntArrayElements(systemUsages, 0);
+
+ if (nativeSystemUsages != nullptr) {
+ jsize len = env->GetArrayLength(systemUsages);
+ for (size_t i = 0; i < len; i++) {
+ audio_usage_t nativeAudioUsage =
+ static_cast<audio_usage_t>(nativeSystemUsages[i]);
+ nativeSystemUsagesVector.push_back(nativeAudioUsage);
+ }
+ env->ReleaseIntArrayElements(systemUsages, nativeSystemUsages, 0);
+ }
+
+ status_t status = AudioSystem::setSupportedSystemUsages(nativeSystemUsagesVector);
+ return (jint)nativeToJavaStatus(status);
+}
+
static jint
android_media_AudioSystem_setAllowedCapturePolicy(JNIEnv *env, jobject thiz, jint uid, jint flags) {
return AudioSystem::setAllowedCapturePolicy(uid, flags);
@@ -2430,6 +2455,7 @@ static const JNINativeMethod gMethods[] = {
{"isHapticPlaybackSupported", "()Z", (void *)android_media_AudioSystem_isHapticPlaybackSupported},
{"getHwOffloadEncodingFormatsSupportedForA2DP", "(Ljava/util/ArrayList;)I",
(void*)android_media_AudioSystem_getHwOffloadEncodingFormatsSupportedForA2DP},
+ {"setSupportedSystemUsages", "([I)I", (void *)android_media_AudioSystem_setSupportedSystemUsages},
{"setAllowedCapturePolicy", "(II)I", (void *)android_media_AudioSystem_setAllowedCapturePolicy},
{"setRttEnabled", "(Z)I", (void *)android_media_AudioSystem_setRttEnabled},
{"setAudioHalPids", "([I)I", (void *)android_media_AudioSystem_setAudioHalPids},
diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml
index 194e262f9f90..8cb62f033f0f 100644
--- a/core/res/AndroidManifest.xml
+++ b/core/res/AndroidManifest.xml
@@ -3239,6 +3239,13 @@
<permission android:name="android.permission.BIND_NFC_SERVICE"
android:protectionLevel="signature" />
+ <!-- Must be required by a {@link android.service.quickaccesswallet.QuickAccessWalletService}
+ to ensure that only the system can bind to it.
+ <p>Protection level: signature
+ -->
+ <permission android:name="android.permission.BIND_QUICK_ACCESS_WALLET_SERVICE"
+ android:protectionLevel="signature" />
+
<!-- Must be required by the PrintSpooler to ensure that only the system can bind to it.
@hide -->
<permission android:name="android.permission.BIND_PRINT_SPOOLER_SERVICE"
diff --git a/core/res/res/values/attrs.xml b/core/res/res/values/attrs.xml
index e0d849223552..940e9f1ef88b 100644
--- a/core/res/res/values/attrs.xml
+++ b/core/res/res/values/attrs.xml
@@ -8329,6 +8329,26 @@
<attr name="successColor" format="color|reference"/>
</declare-styleable>
+ <!-- =============================== -->
+ <!-- QuickAccessWallet attributes -->
+ <!-- =============================== -->
+ <eat-comment />
+
+ <!-- Use <code>quickaccesswallet-service</code> as the root tag of the XML resource
+ that describes a {@link android.service.quickaccesswallet.QuickAccessWalletService},
+ which is referenced from its
+ {@link android.service.quickaccesswallet.QuickAccessWalletService#SERVICE_META_DATA}
+ meta-data entry.
+ -->
+ <declare-styleable name="QuickAccessWalletService">
+ <!-- Fully qualified class name of an activity that allows the user to modify
+ the settings for this service. -->
+ <attr name="settingsActivity"/>
+ <!-- Fully qualified class name of an activity that allows the user to view
+ their entire wallet -->
+ <attr name="targetActivity"/>
+ </declare-styleable>
+
<!-- Use <code>recognition-service</code> as the root tag of the XML resource that
describes a {@link android.speech.RecognitionService}, which is referenced from
its {@link android.speech.RecognitionService#SERVICE_META_DATA} meta-data entry.
diff --git a/core/res/res/values/strings.xml b/core/res/res/values/strings.xml
index f25f97c39f7e..6a00ecbe91bc 100644
--- a/core/res/res/values/strings.xml
+++ b/core/res/res/values/strings.xml
@@ -5271,6 +5271,10 @@
<!-- Description of media type: presentation file, such as PPT. The 'extension' variable is the file name extension. [CHAR LIMIT=32] -->
<string name="mime_type_presentation_ext"><xliff:g id="extension" example="PDF">%1$s</xliff:g> presentation</string>
+ <!-- Strings for Bluetooth service -->
+ <!-- toast message informing user that Bluetooth stays on after airplane mode is turned on. [CHAR LIMIT=NONE] -->
+ <string name="bluetooth_airplane_mode_toast">Bluetooth will stay on during airplane mode</string>
+
<!-- Strings for car -->
<!-- String displayed when loading a user in the car [CHAR LIMIT=30] -->
<string name="car_loading_profile">Loading</string>
diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml
index 527798d45b96..7e6eb5de25a2 100644
--- a/core/res/res/values/symbols.xml
+++ b/core/res/res/values/symbols.xml
@@ -3723,6 +3723,9 @@
<java-symbol type="string" name="mime_type_presentation" />
<java-symbol type="string" name="mime_type_presentation_ext" />
+ <!-- For Bluetooth service -->
+ <java-symbol type="string" name="bluetooth_airplane_mode_toast" />
+
<!-- For high refresh rate displays -->
<java-symbol type="integer" name="config_defaultPeakRefreshRate" />
<java-symbol type="integer" name="config_defaultRefreshRateInZone" />
diff --git a/graphics/java/android/graphics/drawable/AdaptiveIconDrawable.java b/graphics/java/android/graphics/drawable/AdaptiveIconDrawable.java
index fab96a1e9fbd..928e607abbbe 100644
--- a/graphics/java/android/graphics/drawable/AdaptiveIconDrawable.java
+++ b/graphics/java/android/graphics/drawable/AdaptiveIconDrawable.java
@@ -16,6 +16,7 @@
package android.graphics.drawable;
+import android.annotation.DrawableRes;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.TestApi;
@@ -223,6 +224,7 @@ public class AdaptiveIconDrawable extends Drawable implements Drawable.Callback
final int deviceDensity = Drawable.resolveDensity(r, 0);
state.setDensity(deviceDensity);
state.mSrcDensityOverride = mSrcDensityOverride;
+ state.mSourceDrawableId = Resources.getAttributeSetSourceResId(attrs);
final ChildDrawable[] array = state.mChildren;
for (int i = 0; i < state.mChildren.length; i++) {
@@ -446,6 +448,17 @@ public class AdaptiveIconDrawable extends Drawable implements Drawable.Callback
}
/**
+ * If the drawable was inflated from XML, this returns the resource ID for the drawable
+ *
+ * @hide
+ */
+ @DrawableRes
+ public int getSourceDrawableResId() {
+ final LayerState state = mLayerState;
+ return state == null ? Resources.ID_NULL : state.mSourceDrawableId;
+ }
+
+ /**
* Inflates child layers using the specified parser.
*/
private void inflateLayers(@NonNull Resources r, @NonNull XmlPullParser parser,
@@ -944,6 +957,8 @@ public class AdaptiveIconDrawable extends Drawable implements Drawable.Callback
@Config int mChangingConfigurations;
@Config int mChildrenChangingConfigurations;
+ @DrawableRes int mSourceDrawableId = Resources.ID_NULL;
+
private boolean mCheckedOpacity;
private int mOpacity;
diff --git a/identity/java/android/security/identity/WritableIdentityCredential.java b/identity/java/android/security/identity/WritableIdentityCredential.java
index 5f575b9d56f3..e2a389bfd4da 100644
--- a/identity/java/android/security/identity/WritableIdentityCredential.java
+++ b/identity/java/android/security/identity/WritableIdentityCredential.java
@@ -31,6 +31,11 @@ import java.util.Collection;
*/
public abstract class WritableIdentityCredential {
/**
+ * @hide
+ */
+ protected WritableIdentityCredential() {}
+
+ /**
* Generates and returns an X.509 certificate chain for the CredentialKey which identifies this
* credential to the issuing authority. The certificate contains an
* <a href="https://source.android.com/security/keystore/attestation">Android Keystore</a>
diff --git a/media/java/android/media/AudioAttributes.java b/media/java/android/media/AudioAttributes.java
index 8cd3c6e64b78..114c0f1f6bf3 100644
--- a/media/java/android/media/AudioAttributes.java
+++ b/media/java/android/media/AudioAttributes.java
@@ -99,6 +99,10 @@ public final class AudioAttributes implements Parcelable {
public final static int CONTENT_TYPE_SONIFICATION = 4;
/**
+ * Invalid value, only ever used for an uninitialized usage value
+ */
+ private static final int USAGE_INVALID = -1;
+ /**
* Usage value to use when the usage is unknown.
*/
public final static int USAGE_UNKNOWN = 0;
@@ -184,9 +188,43 @@ public final class AudioAttributes implements Parcelable {
* Usage value to use for assistant voice interaction with remote caller on Cell and VoIP calls.
*/
@SystemApi
- @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE)
+ @RequiresPermission(allOf = {
+ android.Manifest.permission.MODIFY_PHONE_STATE,
+ android.Manifest.permission.MODIFY_AUDIO_ROUTING
+ })
public static final int USAGE_CALL_ASSISTANT = 17;
+ private static final int SYSTEM_USAGE_OFFSET = 1000;
+
+ /**
+ * @hide
+ * Usage value to use when the usage is an emergency.
+ */
+ @SystemApi
+ @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING)
+ public static final int USAGE_EMERGENCY = SYSTEM_USAGE_OFFSET;
+ /**
+ * @hide
+ * Usage value to use when the usage is a safety sound.
+ */
+ @SystemApi
+ @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING)
+ public static final int USAGE_SAFETY = SYSTEM_USAGE_OFFSET + 1;
+ /**
+ * @hide
+ * Usage value to use when the usage is a vehicle status.
+ */
+ @SystemApi
+ @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING)
+ public static final int USAGE_VEHICLE_STATUS = SYSTEM_USAGE_OFFSET + 2;
+ /**
+ * @hide
+ * Usage value to use when the usage is an announcement.
+ */
+ @SystemApi
+ @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING)
+ public static final int USAGE_ANNOUNCEMENT = SYSTEM_USAGE_OFFSET + 3;
+
/**
* IMPORTANT: when adding new usage types, add them to SDK_USAGES and update SUPPRESSIBLE_USAGES
* if applicable, as well as audioattributes.proto.
@@ -489,6 +527,20 @@ public final class AudioAttributes implements Parcelable {
* @return one of the values that can be set in {@link Builder#setUsage(int)}
*/
public int getUsage() {
+ if (isSystemUsage(mUsage)) {
+ return USAGE_UNKNOWN;
+ }
+ return mUsage;
+ }
+
+ /**
+ * @hide
+ * Return the system usage.
+ * @return one of the values that can be set in {@link Builder#setUsage(int)} or
+ * {@link Builder#setSystemUsage(int)}
+ */
+ @SystemApi
+ public int getSystemUsage() {
return mUsage;
}
@@ -591,7 +643,8 @@ public final class AudioAttributes implements Parcelable {
* {@link MediaPlayer} will use a default usage of {@link AudioAttributes#USAGE_MEDIA}.
*/
public static class Builder {
- private int mUsage = USAGE_UNKNOWN;
+ private int mUsage = USAGE_INVALID;
+ private int mSystemUsage = USAGE_INVALID;
private int mContentType = CONTENT_TYPE_UNKNOWN;
private int mSource = MediaRecorder.AudioSource.AUDIO_SOURCE_INVALID;
private int mFlags = 0x0;
@@ -637,7 +690,22 @@ public final class AudioAttributes implements Parcelable {
public AudioAttributes build() {
AudioAttributes aa = new AudioAttributes();
aa.mContentType = mContentType;
- aa.mUsage = mUsage;
+
+ if (mUsage == USAGE_INVALID) {
+ if (mSystemUsage == USAGE_INVALID) {
+ aa.mUsage = USAGE_UNKNOWN;
+ } else {
+ aa.mUsage = mSystemUsage;
+ }
+ } else {
+ if (mSystemUsage == USAGE_INVALID) {
+ aa.mUsage = mUsage;
+ } else {
+ throw new IllegalArgumentException(
+ "Cannot set both usage and system usage on same builder");
+ }
+ }
+
aa.mSource = mSource;
aa.mFlags = mFlags;
if (mMuteHapticChannels) {
@@ -667,26 +735,26 @@ public final class AudioAttributes implements Parcelable {
}
/**
- * Sets the attribute describing what is the intended use of the the audio signal,
+ * Sets the attribute describing what is the intended use of the audio signal,
* such as alarm or ringtone.
- * @param usage one of {@link AudioAttributes#USAGE_UNKNOWN},
- * {@link AudioAttributes#USAGE_MEDIA},
- * {@link AudioAttributes#USAGE_VOICE_COMMUNICATION},
- * {@link AudioAttributes#USAGE_VOICE_COMMUNICATION_SIGNALLING},
- * {@link AudioAttributes#USAGE_ALARM}, {@link AudioAttributes#USAGE_NOTIFICATION},
- * {@link AudioAttributes#USAGE_NOTIFICATION_RINGTONE},
- * {@link AudioAttributes#USAGE_NOTIFICATION_COMMUNICATION_REQUEST},
- * {@link AudioAttributes#USAGE_NOTIFICATION_COMMUNICATION_INSTANT},
- * {@link AudioAttributes#USAGE_NOTIFICATION_COMMUNICATION_DELAYED},
- * {@link AudioAttributes#USAGE_NOTIFICATION_EVENT},
- * {@link AudioAttributes#USAGE_ASSISTANT},
- * {@link AudioAttributes#USAGE_ASSISTANCE_ACCESSIBILITY},
- * {@link AudioAttributes#USAGE_ASSISTANCE_NAVIGATION_GUIDANCE},
- * {@link AudioAttributes#USAGE_ASSISTANCE_SONIFICATION},
- * {@link AudioAttributes#USAGE_GAME}.
+ * @param usage one of {@link AttributeSdkUsage#USAGE_UNKNOWN},
+ * {@link AttributeSdkUsage#USAGE_MEDIA},
+ * {@link AttributeSdkUsage#USAGE_VOICE_COMMUNICATION},
+ * {@link AttributeSdkUsage#USAGE_VOICE_COMMUNICATION_SIGNALLING},
+ * {@link AttributeSdkUsage#USAGE_ALARM}, {@link AudioAttributes#USAGE_NOTIFICATION},
+ * {@link AttributeSdkUsage#USAGE_NOTIFICATION_RINGTONE},
+ * {@link AttributeSdkUsage#USAGE_NOTIFICATION_COMMUNICATION_REQUEST},
+ * {@link AttributeSdkUsage#USAGE_NOTIFICATION_COMMUNICATION_INSTANT},
+ * {@link AttributeSdkUsage#USAGE_NOTIFICATION_COMMUNICATION_DELAYED},
+ * {@link AttributeSdkUsage#USAGE_NOTIFICATION_EVENT},
+ * {@link AttributeSdkUsage#USAGE_ASSISTANT},
+ * {@link AttributeSdkUsage#USAGE_ASSISTANCE_ACCESSIBILITY},
+ * {@link AttributeSdkUsage#USAGE_ASSISTANCE_NAVIGATION_GUIDANCE},
+ * {@link AttributeSdkUsage#USAGE_ASSISTANCE_SONIFICATION},
+ * {@link AttributeSdkUsage#USAGE_GAME}.
* @return the same Builder instance.
*/
- public Builder setUsage(@AttributeUsage int usage) {
+ public Builder setUsage(@AttributeSdkUsage int usage) {
switch (usage) {
case USAGE_UNKNOWN:
case USAGE_MEDIA:
@@ -705,7 +773,6 @@ public final class AudioAttributes implements Parcelable {
case USAGE_GAME:
case USAGE_VIRTUAL_SOURCE:
case USAGE_ASSISTANT:
- case USAGE_CALL_ASSISTANT:
mUsage = usage;
break;
default:
@@ -715,6 +782,28 @@ public final class AudioAttributes implements Parcelable {
}
/**
+ * @hide
+ * Sets the attribute describing what is the intended use of the audio signal for categories
+ * of sounds restricted to the system, such as vehicle status or emergency.
+ *
+ * <p>Note that the AudioAttributes have a single usage value, therefore it is illegal to
+ * call both this method and {@link #setUsage(int)}.
+ * @param systemUsage the system-restricted usage.
+ * @return the same Builder instance.
+ */
+ @SystemApi
+ @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING)
+ public @NonNull Builder setSystemUsage(@AttributeSystemUsage int systemUsage) {
+ if (isSystemUsage(systemUsage)) {
+ mSystemUsage = systemUsage;
+ } else {
+ throw new IllegalArgumentException("Invalid system usage " + systemUsage);
+ }
+
+ return this;
+ }
+
+ /**
* Sets the attribute describing the content type of the audio signal, such as speech,
* or music.
* @param contentType the content type values, one of
@@ -1175,6 +1264,14 @@ public final class AudioAttributes implements Parcelable {
return new String("USAGE_ASSISTANT");
case USAGE_CALL_ASSISTANT:
return new String("USAGE_CALL_ASSISTANT");
+ case USAGE_EMERGENCY:
+ return new String("USAGE_EMERGENCY");
+ case USAGE_SAFETY:
+ return new String("USAGE_SAFETY");
+ case USAGE_VEHICLE_STATUS:
+ return new String("USAGE_VEHICLE_STATUS");
+ case USAGE_ANNOUNCEMENT:
+ return new String("USAGE_ANNOUNCEMENT");
default:
return new String("unknown usage " + usage);
}
@@ -1221,6 +1318,25 @@ public final class AudioAttributes implements Parcelable {
}
/**
+ * @param usage one of {@link AttributeSystemUsage},
+ * {@link AttributeSystemUsage#USAGE_CALL_ASSISTANT},
+ * {@link AttributeSystemUsage#USAGE_EMERGENCY},
+ * {@link AttributeSystemUsage#USAGE_SAFETY},
+ * {@link AttributeSystemUsage#USAGE_VEHICLE_STATUS},
+ * {@link AttributeSystemUsage#USAGE_ANNOUNCEMENT}
+ * @return boolean indicating if the usage is a system usage or not
+ * @hide
+ */
+ @SystemApi
+ public static boolean isSystemUsage(@AttributeSystemUsage int usage) {
+ return (usage == USAGE_CALL_ASSISTANT
+ || usage == USAGE_EMERGENCY
+ || usage == USAGE_SAFETY
+ || usage == USAGE_VEHICLE_STATUS
+ || usage == USAGE_ANNOUNCEMENT);
+ }
+
+ /**
* Returns the stream type matching this {@code AudioAttributes} instance for volume control.
* Use this method to derive the stream type needed to configure the volume
* control slider in an {@link android.app.Activity} with
@@ -1295,6 +1411,10 @@ public final class AudioAttributes implements Parcelable {
return AudioSystem.STREAM_NOTIFICATION;
case USAGE_ASSISTANCE_ACCESSIBILITY:
return AudioSystem.STREAM_ACCESSIBILITY;
+ case USAGE_EMERGENCY:
+ case USAGE_SAFETY:
+ case USAGE_VEHICLE_STATUS:
+ case USAGE_ANNOUNCEMENT:
case USAGE_UNKNOWN:
return AudioSystem.STREAM_MUSIC;
default:
@@ -1327,6 +1447,39 @@ public final class AudioAttributes implements Parcelable {
/** @hide */
@IntDef({
+ USAGE_CALL_ASSISTANT,
+ USAGE_EMERGENCY,
+ USAGE_SAFETY,
+ USAGE_VEHICLE_STATUS,
+ USAGE_ANNOUNCEMENT
+ })
+ @Retention(RetentionPolicy.SOURCE)
+ public @interface AttributeSystemUsage {}
+
+ /** @hide */
+ @IntDef({
+ USAGE_UNKNOWN,
+ USAGE_MEDIA,
+ USAGE_VOICE_COMMUNICATION,
+ USAGE_VOICE_COMMUNICATION_SIGNALLING,
+ USAGE_ALARM,
+ USAGE_NOTIFICATION,
+ USAGE_NOTIFICATION_RINGTONE,
+ USAGE_NOTIFICATION_COMMUNICATION_REQUEST,
+ USAGE_NOTIFICATION_COMMUNICATION_INSTANT,
+ USAGE_NOTIFICATION_COMMUNICATION_DELAYED,
+ USAGE_NOTIFICATION_EVENT,
+ USAGE_ASSISTANCE_ACCESSIBILITY,
+ USAGE_ASSISTANCE_NAVIGATION_GUIDANCE,
+ USAGE_ASSISTANCE_SONIFICATION,
+ USAGE_GAME,
+ USAGE_ASSISTANT,
+ })
+ @Retention(RetentionPolicy.SOURCE)
+ public @interface AttributeSdkUsage {}
+
+ /** @hide */
+ @IntDef({
USAGE_UNKNOWN,
USAGE_MEDIA,
USAGE_VOICE_COMMUNICATION,
@@ -1344,6 +1497,10 @@ public final class AudioAttributes implements Parcelable {
USAGE_GAME,
USAGE_ASSISTANT,
USAGE_CALL_ASSISTANT,
+ USAGE_EMERGENCY,
+ USAGE_SAFETY,
+ USAGE_VEHICLE_STATUS,
+ USAGE_ANNOUNCEMENT,
})
@Retention(RetentionPolicy.SOURCE)
public @interface AttributeUsage {}
diff --git a/media/java/android/media/AudioManager.java b/media/java/android/media/AudioManager.java
index 1b870e8e94ef..8ad5c04a1f85 100644
--- a/media/java/android/media/AudioManager.java
+++ b/media/java/android/media/AudioManager.java
@@ -37,6 +37,7 @@ import android.compat.annotation.UnsupportedAppUsage;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
+import android.media.AudioAttributes.AttributeSystemUsage;
import android.media.audiopolicy.AudioPolicy;
import android.media.audiopolicy.AudioPolicy.AudioPolicyFocusListener;
import android.media.audiopolicy.AudioProductStrategy;
@@ -1268,6 +1269,39 @@ public class AudioManager {
}
/**
+ * Set the system usages to be supported on this device.
+ * @param systemUsages array of system usages to support {@link AttributeSystemUsage}
+ * @hide
+ */
+ @SystemApi
+ @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING)
+ public void setSupportedSystemUsages(@NonNull @AttributeSystemUsage int[] systemUsages) {
+ Objects.requireNonNull(systemUsages, "systemUsages must not be null");
+ final IAudioService service = getService();
+ try {
+ service.setSupportedSystemUsages(systemUsages);
+ } catch (RemoteException e) {
+ throw e.rethrowFromSystemServer();
+ }
+ }
+
+ /**
+ * Get the system usages supported on this device.
+ * @return array of supported system usages {@link AttributeSystemUsage}
+ * @hide
+ */
+ @SystemApi
+ @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING)
+ public @NonNull @AttributeSystemUsage int[] getSupportedSystemUsages() {
+ final IAudioService service = getService();
+ try {
+ return service.getSupportedSystemUsages();
+ } catch (RemoteException e) {
+ throw e.rethrowFromSystemServer();
+ }
+ }
+
+ /**
* Solo or unsolo a particular stream.
* <p>
* Do not use. This method has been deprecated and is now a no-op.
diff --git a/media/java/android/media/AudioMetadata.java b/media/java/android/media/AudioMetadata.java
new file mode 100644
index 000000000000..7245aab41eec
--- /dev/null
+++ b/media/java/android/media/AudioMetadata.java
@@ -0,0 +1,406 @@
+/*
+ * Copyright (C) 2020 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 android.media;
+
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.util.Pair;
+
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Objects;
+import java.util.Set;
+
+/**
+ * AudioMetadata class is used to manage typed key-value pairs for
+ * configuration and capability requests within the Audio Framework.
+ */
+public final class AudioMetadata {
+ /**
+ * Key interface for the map.
+ *
+ * The presence of this {@code Key} interface on an object allows
+ * it to be used to reference metadata in the Audio Framework.
+ *
+ * @param <T> type of value associated with {@code Key}.
+ */
+ // Conceivably metadata keys exposing multiple interfaces
+ // could be eligible to work in multiple framework domains.
+ public interface Key<T> {
+ /**
+ * Returns the internal name of the key.
+ */
+ @NonNull
+ String getName();
+
+ /**
+ * Returns the class type of the associated value.
+ */
+ @NonNull
+ Class<T> getValueClass();
+
+ // TODO: consider adding bool isValid(@NonNull T value)
+
+ /**
+ * Do not allow non-framework apps to create their own keys
+ * by implementing this interface; keep a method hidden.
+ *
+ * @hide
+ */
+ boolean isFromFramework();
+ }
+
+ /**
+ * A read only {@code Map} interface of {@link Key} value pairs.
+ *
+ * Using a {@link Key} interface, look up the corresponding value.
+ */
+ public interface ReadMap {
+ /**
+ * Returns true if the key exists in the map.
+ *
+ * @param key interface for requesting the value.
+ * @param <T> type of value.
+ * @return true if key exists in the Map.
+ */
+ <T> boolean containsKey(@NonNull Key<T> key);
+
+ /**
+ * Returns a copy of the map.
+ *
+ * This is intended for safe conversion between a {@link ReadMap}
+ * interface and a {@link Map} interface.
+ * Currently only simple objects are used for key values which
+ * means a shallow copy is sufficient.
+ *
+ * @return a Map copied from the existing map.
+ */
+ @NonNull
+ Map dup(); // lint checker doesn't like clone().
+
+ /**
+ * Returns the value associated with the key.
+ *
+ * @param key interface for requesting the value.
+ * @param <T> type of value.
+ * @return returns the value of associated with key or null if it doesn't exist.
+ */
+ @Nullable
+ <T> T get(@NonNull Key<T> key);
+
+ /**
+ * Returns a {@code Set} of keys associated with the map.
+ * @hide
+ */
+ @NonNull
+ Set<Key<?>> keySet();
+
+ /**
+ * Returns the number of elements in the map.
+ */
+ int size();
+ }
+
+ /**
+ * A writeable {@link Map} interface of {@link Key} value pairs.
+ * This interface is not guaranteed to be thread-safe
+ * unless the supplier for the {@code Map} states it as thread safe.
+ */
+ // TODO: Create a wrapper like java.util.Collections.synchronizedMap?
+ public interface Map extends ReadMap {
+ /**
+ * Removes the value associated with the key.
+ * @param key interface for storing the value.
+ * @param <T> type of value.
+ * @return the value of the key, null if it doesn't exist.
+ */
+ @Nullable
+ <T> T remove(@NonNull Key<T> key);
+
+ /**
+ * Sets a value for the key.
+ *
+ * @param key interface for storing the value.
+ * @param <T> type of value.
+ * @param value a non-null value of type T.
+ * @return the previous value associated with key or null if it doesn't exist.
+ */
+ // See automatic Kotlin overloading for Java interoperability.
+ // https://kotlinlang.org/docs/reference/java-interop.html#operators
+ // See also Kotlin set for overloaded operator indexing.
+ // https://kotlinlang.org/docs/reference/operator-overloading.html#indexed
+ // Also the Kotlin mutable-list set.
+ // https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.collections/-mutable-list/set.html
+ @Nullable
+ <T> T set(@NonNull Key<T> key, @NonNull T value);
+ }
+
+ /**
+ * Creates a {@link Map} suitable for adding keys.
+ * @return an empty {@link Map} instance.
+ */
+ @NonNull
+ public static Map createMap() {
+ return new BaseMap();
+ }
+
+ /**
+ * A container class for AudioMetadata Format keys.
+ *
+ * @see AudioTrack.OnCodecFormatChangedListener
+ */
+ public static class Format {
+ // The key name strings used here must match that of the native framework, but are
+ // allowed to change between API releases. This due to the Java specification
+ // on what is a compile time constant.
+ //
+ // Key<?> are final variables but not constant variables (per Java spec 4.12.4) because
+ // the keys are not a primitive type nor a String initialized by a constant expression.
+ // Hence (per Java spec 13.1.3), they are not resolved at compile time,
+ // rather are picked up by applications at run time.
+ //
+ // So the contractual API behavior of AudioMetadata.Key<> are different than Strings
+ // initialized by a constant expression (for example MediaFormat.KEY_*).
+
+ // See MediaFormat
+ /**
+ * A key representing the bitrate of the encoded stream used in
+ *
+ * If the stream is variable bitrate, this is the average bitrate of the stream.
+ * The unit is bits per second.
+ *
+ * An Integer value.
+ *
+ * @see MediaFormat#KEY_BIT_RATE
+ */
+ @NonNull public static final Key<Integer> KEY_BIT_RATE =
+ createKey("bitrate", Integer.class);
+
+ /**
+ * A key representing the audio channel mask of the stream.
+ *
+ * An Integer value.
+ *
+ * @see AudioTrack#getChannelConfiguration()
+ * @see MediaFormat#KEY_CHANNEL_MASK
+ */
+ @NonNull public static final Key<Integer> KEY_CHANNEL_MASK =
+ createKey("channel-mask", Integer.class);
+
+
+ /**
+ * A key representing the codec mime string.
+ *
+ * A String value.
+ *
+ * @see MediaFormat#KEY_MIME
+ */
+ @NonNull public static final Key<String> KEY_MIME = createKey("mime", String.class);
+
+ /**
+ * A key representing the audio sample rate in Hz of the stream.
+ *
+ * An Integer value.
+ *
+ * @see AudioFormat#getSampleRate()
+ * @see MediaFormat#KEY_SAMPLE_RATE
+ */
+ @NonNull public static final Key<Integer> KEY_SAMPLE_RATE =
+ createKey("sample-rate", Integer.class);
+
+ // Unique to Audio
+
+ /**
+ * A key representing the bit width of an element of decoded data.
+ *
+ * An Integer value.
+ */
+ @NonNull public static final Key<Integer> KEY_BIT_WIDTH =
+ createKey("bit-width", Integer.class);
+
+ /**
+ * A key representing the presence of Atmos in an E-AC3 stream.
+ *
+ * A Boolean value which is true if Atmos is present in an E-AC3 stream.
+ */
+ @NonNull public static final Key<Boolean> KEY_ATMOS_PRESENT =
+ createKey("atmos-present", Boolean.class);
+
+ /**
+ * A key representing the audio encoding used for the stream.
+ * This is the same encoding used in {@link AudioFormat#getEncoding()}.
+ *
+ * An Integer value.
+ *
+ * @see AudioFormat#getEncoding()
+ */
+ @NonNull public static final Key<Integer> KEY_AUDIO_ENCODING =
+ createKey("audio-encoding", Integer.class);
+
+ private Format() {} // delete constructor
+ }
+
+ /////////////////////////////////////////////////////////////////////////
+ // Hidden methods and functions.
+
+ /**
+ * Returns a Key object with the correct interface for the AudioMetadata.
+ *
+ * An interface with the same name and type will be treated as
+ * identical for the purposes of value storage, even though
+ * other methods or hidden parameters may return different values.
+ *
+ * @param name The name of the key.
+ * @param type The class type of the value represented by the key.
+ * @param <T> The type of value.
+ * @return a new key interface.
+ *
+ * Creating keys is currently only allowed by the Framework.
+ * @hide
+ */
+ @NonNull
+ public static <T> Key<T> createKey(String name, Class<T> type) {
+ // Implementation specific.
+ return new Key<T>() {
+ private final String mName = name;
+ private final Class<T> mType = type;
+
+ @Override
+ @NonNull
+ public String getName() {
+ return mName;
+ }
+
+ @Override
+ @NonNull
+ public Class<T> getValueClass() {
+ return mType;
+ }
+
+ // hidden interface method to prevent user class implements the of Key interface.
+ @Override
+ public boolean isFromFramework() {
+ return true;
+ }
+ };
+ }
+
+ /**
+ * @hide
+ *
+ * AudioMetadata is based on interfaces in order to allow multiple inheritance
+ * and maximum flexibility in implementation.
+ *
+ * Here, we provide a simple implementation of {@link Map} interface;
+ * Note that the Keys are not specific to this Map implementation.
+ *
+ * It is possible to require the keys to be of a certain class
+ * before allowing a set or get operation.
+ */
+ public static class BaseMap implements Map {
+ @Override
+ public <T> boolean containsKey(@NonNull Key<T> key) {
+ Pair<Key<?>, Object> valuePair = mHashMap.get(pairFromKey(key));
+ return valuePair != null;
+ }
+
+ @Override
+ @NonNull
+ public Map dup() {
+ BaseMap map = new BaseMap();
+ map.mHashMap.putAll(this.mHashMap);
+ return map;
+ }
+
+ @Override
+ @Nullable
+ public <T> T get(@NonNull Key<T> key) {
+ Pair<Key<?>, Object> valuePair = mHashMap.get(pairFromKey(key));
+ return (T) getValueFromValuePair(valuePair);
+ }
+
+ @Override
+ @NonNull
+ public Set<Key<?>> keySet() {
+ HashSet<Key<?>> set = new HashSet();
+ for (Pair<Key<?>, Object> pair : mHashMap.values()) {
+ set.add(pair.first);
+ }
+ return set;
+ }
+
+ @Override
+ @Nullable
+ public <T> T remove(@NonNull Key<T> key) {
+ Pair<Key<?>, Object> valuePair = mHashMap.remove(pairFromKey(key));
+ return (T) getValueFromValuePair(valuePair);
+ }
+
+ @Override
+ @Nullable
+ public <T> T set(@NonNull Key<T> key, @NonNull T value) {
+ Objects.requireNonNull(value);
+ Pair<Key<?>, Object> valuePair = mHashMap
+ .put(pairFromKey(key), new Pair<Key<?>, Object>(key, value));
+ return (T) getValueFromValuePair(valuePair);
+ }
+
+ @Override
+ public int size() {
+ return mHashMap.size();
+ }
+
+ /*
+ * Implementation specific.
+ *
+ * To store the value in the HashMap we need to convert the Key interface
+ * to a hashcode() / equals() compliant Pair.
+ */
+ @NonNull
+ private static <T> Pair<String, Class<?>> pairFromKey(@NonNull Key<T> key) {
+ Objects.requireNonNull(key);
+ return new Pair<String, Class<?>>(key.getName(), key.getValueClass());
+ }
+
+ /*
+ * Implementation specific.
+ *
+ * We store in a Pair (valuePair) the key along with the Object value.
+ * This helper returns the Object value from the value pair.
+ */
+ @Nullable
+ private static Object getValueFromValuePair(@Nullable Pair<Key<?>, Object> valuePair) {
+ if (valuePair == null) {
+ return null;
+ }
+ return valuePair.second;
+ }
+
+ /*
+ * Implementation specific.
+ *
+ * We use a HashMap to back the AudioMetadata BaseMap object.
+ * This is not locked, so concurrent reads are permitted if all threads
+ * have a ReadMap; this is risky with a Map.
+ */
+ private final HashMap<Pair<String, Class<?>>, Pair<Key<?>, Object>> mHashMap =
+ new HashMap();
+ }
+
+ // Delete the constructor as there is nothing to implement here.
+ private AudioMetadata() {}
+}
diff --git a/media/java/android/media/AudioSystem.java b/media/java/android/media/AudioSystem.java
index fe57e71cca8c..48d27faa0855 100644
--- a/media/java/android/media/AudioSystem.java
+++ b/media/java/android/media/AudioSystem.java
@@ -1174,6 +1174,11 @@ public class AudioSystem
public static native float getStreamVolumeDB(int stream, int index, int device);
/**
+ * Communicate supported system usages to audio policy service.
+ */
+ public static native int setSupportedSystemUsages(int[] systemUsages);
+
+ /**
* @see AudioManager#setAllowedCapturePolicy()
*/
public static native int setAllowedCapturePolicy(int uid, int flags);
diff --git a/media/java/android/media/AudioTrack.java b/media/java/android/media/AudioTrack.java
index 4dbc79b54199..f566f646f1e0 100644
--- a/media/java/android/media/AudioTrack.java
+++ b/media/java/android/media/AudioTrack.java
@@ -188,6 +188,10 @@ public class AudioTrack extends PlayerBase
// Events:
// to keep in sync with frameworks/av/include/media/AudioTrack.h
+ // Note: To avoid collisions with other event constants,
+ // do not define an event here that is the same value as
+ // AudioSystem.NATIVE_EVENT_ROUTING_CHANGE.
+
/**
* Event id denotes when playback head has reached a previously set marker.
*/
@@ -210,6 +214,14 @@ public class AudioTrack extends PlayerBase
* back (after stop is called) for an offloaded track.
*/
private static final int NATIVE_EVENT_STREAM_END = 7;
+ /**
+ * Event id denotes when the codec format changes.
+ *
+ * Note: Similar to a device routing change (AudioSystem.NATIVE_EVENT_ROUTING_CHANGE),
+ * this event comes from the AudioFlinger Thread / Output Stream management
+ * (not from buffer indications as above).
+ */
+ private static final int NATIVE_EVENT_CODEC_FORMAT_CHANGE = 100;
private final static String TAG = "android.media.AudioTrack";
@@ -3409,6 +3421,67 @@ public class AudioTrack extends PlayerBase
}
}
+ //--------------------------------------------------------------------------
+ // Codec notifications
+ //--------------------
+
+ // OnCodecFormatChangedListener notifications uses an instance
+ // of ListenerList to manage its listeners.
+
+ private final Utils.ListenerList<AudioMetadata.ReadMap> mCodecFormatChangedListeners =
+ new Utils.ListenerList();
+
+ /**
+ * Interface definition for a listener for codec format changes.
+ */
+ public interface OnCodecFormatChangedListener {
+ /**
+ * Called when the compressed codec format changes.
+ *
+ * @param audioTrack is the {@code AudioTrack} instance associated with the codec.
+ * @param info is a {@link AudioMetadata.ReadMap} of values which contains decoded format
+ * changes reported by the codec. Not all hardware
+ * codecs indicate codec format changes. Acceptable keys are taken from
+ * {@code AudioMetadata.Format.KEY_*} range, with the associated value type.
+ */
+ void onCodecFormatChanged(
+ @NonNull AudioTrack audioTrack, @Nullable AudioMetadata.ReadMap info);
+ }
+
+ /**
+ * Adds an {@link OnCodecFormatChangedListener} to receive notifications of
+ * codec format change events on this {@code AudioTrack}.
+ *
+ * @param executor Specifies the {@link Executor} object to control execution.
+ *
+ * @param listener The {@link OnCodecFormatChangedListener} interface to receive
+ * notifications of codec events.
+ */
+ public void addOnCodecFormatChangedListener(
+ @NonNull @CallbackExecutor Executor executor,
+ @NonNull OnCodecFormatChangedListener listener) { // NPE checks done by ListenerList.
+ mCodecFormatChangedListeners.add(
+ listener, /* key for removal */
+ executor,
+ (int eventCode, AudioMetadata.ReadMap readMap) -> {
+ // eventCode is unused by this implementation.
+ listener.onCodecFormatChanged(this, readMap);
+ }
+ );
+ }
+
+ /**
+ * Removes an {@link OnCodecFormatChangedListener} which has been previously added
+ * to receive codec format change events.
+ *
+ * @param listener The previously added {@link OnCodecFormatChangedListener} interface
+ * to remove.
+ */
+ public void removeOnCodecFormatChangedListener(
+ @NonNull OnCodecFormatChangedListener listener) {
+ mCodecFormatChangedListeners.remove(listener); // NPE checks done by ListenerList.
+ }
+
//---------------------------------------------------------
// Interface definitions
//--------------------
@@ -3745,6 +3818,12 @@ public class AudioTrack extends PlayerBase
return;
}
+ if (what == NATIVE_EVENT_CODEC_FORMAT_CHANGE) {
+ track.mCodecFormatChangedListeners.notify(
+ 0 /* eventCode, unused */, (AudioMetadata.ReadMap) obj);
+ return;
+ }
+
if (what == NATIVE_EVENT_CAN_WRITE_MORE_DATA
|| what == NATIVE_EVENT_NEW_IAUDIOTRACK
|| what == NATIVE_EVENT_STREAM_END) {
diff --git a/media/java/android/media/IAudioService.aidl b/media/java/android/media/IAudioService.aidl
index 8e8385d382fb..7f1c69218f45 100644
--- a/media/java/android/media/IAudioService.aidl
+++ b/media/java/android/media/IAudioService.aidl
@@ -105,6 +105,10 @@ interface IAudioService {
int getLastAudibleStreamVolume(int streamType);
+ void setSupportedSystemUsages(in int[] systemUsages);
+
+ int[] getSupportedSystemUsages();
+
List<AudioProductStrategy> getAudioProductStrategies();
boolean isMicrophoneMuted();
diff --git a/media/java/android/media/MediaFile.java b/media/java/android/media/MediaFile.java
index 9908e042c6a4..668908079c4d 100644
--- a/media/java/android/media/MediaFile.java
+++ b/media/java/android/media/MediaFile.java
@@ -200,6 +200,84 @@ public class MediaFile {
return null;
}
+ /**
+ * Check whether the mime type is document or not.
+ * @param mimeType the mime type to check
+ * @return true, if the mimeType is matched. Otherwise, false.
+ */
+ public static boolean isDocumentMimeType(@Nullable String mimeType) {
+ if (mimeType == null) {
+ return false;
+ }
+
+ final String normalizedMimeType = normalizeMimeType(mimeType);
+ if (normalizedMimeType.startsWith("text/")) {
+ return true;
+ }
+
+ switch (normalizedMimeType) {
+ case "application/epub+zip":
+ case "application/msword":
+ case "application/pdf":
+ case "application/rtf":
+ case "application/vnd.ms-excel":
+ case "application/vnd.ms-excel.addin.macroEnabled.12":
+ case "application/vnd.ms-excel.sheet.binary.macroEnabled.12":
+ case "application/vnd.ms-excel.sheet.macroEnabled.12":
+ case "application/vnd.ms-excel.template.macroEnabled.12":
+ case "application/vnd.ms-powerpoint":
+ case "application/vnd.ms-powerpoint.addin.macroEnabled.12":
+ case "application/vnd.ms-powerpoint.presentation.macroEnabled.12":
+ case "application/vnd.ms-powerpoint.slideshow.macroEnabled.12":
+ case "application/vnd.ms-powerpoint.template.macroEnabled.12":
+ case "application/vnd.ms-word.document.macroEnabled.12":
+ case "application/vnd.ms-word.template.macroEnabled.12":
+ case "application/vnd.oasis.opendocument.chart":
+ case "application/vnd.oasis.opendocument.database":
+ case "application/vnd.oasis.opendocument.formula":
+ case "application/vnd.oasis.opendocument.graphics":
+ case "application/vnd.oasis.opendocument.graphics-template":
+ case "application/vnd.oasis.opendocument.presentation":
+ case "application/vnd.oasis.opendocument.presentation-template":
+ case "application/vnd.oasis.opendocument.spreadsheet":
+ case "application/vnd.oasis.opendocument.spreadsheet-template":
+ case "application/vnd.oasis.opendocument.text":
+ case "application/vnd.oasis.opendocument.text-master":
+ case "application/vnd.oasis.opendocument.text-template":
+ case "application/vnd.oasis.opendocument.text-web":
+ case "application/vnd.openxmlformats-officedocument.presentationml.presentation":
+ case "application/vnd.openxmlformats-officedocument.presentationml.slideshow":
+ case "application/vnd.openxmlformats-officedocument.presentationml.template":
+ case "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet":
+ case "application/vnd.openxmlformats-officedocument.spreadsheetml.template":
+ case "application/vnd.openxmlformats-officedocument.wordprocessingml.document":
+ case "application/vnd.openxmlformats-officedocument.wordprocessingml.template":
+ case "application/vnd.stardivision.calc":
+ case "application/vnd.stardivision.chart":
+ case "application/vnd.stardivision.draw":
+ case "application/vnd.stardivision.impress":
+ case "application/vnd.stardivision.impress-packed":
+ case "application/vnd.stardivision.mail":
+ case "application/vnd.stardivision.math":
+ case "application/vnd.stardivision.writer":
+ case "application/vnd.stardivision.writer-global":
+ case "application/vnd.sun.xml.calc":
+ case "application/vnd.sun.xml.calc.template":
+ case "application/vnd.sun.xml.draw":
+ case "application/vnd.sun.xml.draw.template":
+ case "application/vnd.sun.xml.impress":
+ case "application/vnd.sun.xml.impress.template":
+ case "application/vnd.sun.xml.math":
+ case "application/vnd.sun.xml.writer":
+ case "application/vnd.sun.xml.writer.global":
+ case "application/vnd.sun.xml.writer.template":
+ case "application/x-mspublisher":
+ return true;
+ default:
+ return false;
+ }
+ }
+
public static boolean isExifMimeType(@Nullable String mimeType) {
// For simplicity, assume that all image files might have EXIF data
return isImageMimeType(mimeType);
diff --git a/media/java/android/media/MediaPlayer.java b/media/java/android/media/MediaPlayer.java
index 71c97534c216..2d820e7c3c98 100644
--- a/media/java/android/media/MediaPlayer.java
+++ b/media/java/android/media/MediaPlayer.java
@@ -632,7 +632,6 @@ public class MediaPlayer extends PlayerBase
private boolean mScreenOnWhilePlaying;
private boolean mStayAwake;
private int mStreamType = AudioManager.USE_DEFAULT_STREAM_TYPE;
- private int mUsage = -1;
// Modular DRM
private UUID mDrmUUID;
@@ -2220,7 +2219,6 @@ public class MediaPlayer extends PlayerBase
throw new IllegalArgumentException(msg);
}
baseUpdateAudioAttributes(attributes);
- mUsage = attributes.getUsage();
Parcel pattributes = Parcel.obtain();
attributes.writeToParcel(pattributes, AudioAttributes.FLATTEN_TAGS);
setParameter(KEY_PARAMETER_AUDIO_ATTRIBUTES, pattributes);
diff --git a/media/java/android/media/Utils.java b/media/java/android/media/Utils.java
index d942bb653127..7a4e7b897de1 100644
--- a/media/java/android/media/Utils.java
+++ b/media/java/android/media/Utils.java
@@ -16,12 +16,17 @@
package android.media;
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.annotation.TestApi;
import android.content.ContentResolver;
import android.content.Context;
import android.database.Cursor;
import android.net.Uri;
+import android.os.Binder;
import android.os.Environment;
import android.os.FileUtils;
+import android.os.Handler;
import android.provider.OpenableColumns;
import android.util.Log;
import android.util.Pair;
@@ -29,14 +34,26 @@ import android.util.Range;
import android.util.Rational;
import android.util.Size;
+import com.android.internal.annotations.GuardedBy;
+
import java.io.File;
import java.io.FileNotFoundException;
import java.util.Arrays;
import java.util.Comparator;
+import java.util.HashMap;
+import java.util.Objects;
import java.util.Vector;
+import java.util.concurrent.Executor;
-// package private
-class Utils {
+/**
+ * Media Utilities
+ *
+ * This class is hidden but public to allow CTS testing and verification
+ * of the static methods and classes.
+ *
+ * @hide
+ */
+public class Utils {
private static final String TAG = "Utils";
/**
@@ -381,4 +398,265 @@ class Utils {
// it already represents the file's name.
return uri.toString();
}
+
+ /**
+ * {@code ListenerList} is a helper class that delivers events to listeners.
+ *
+ * It is written to isolate the <strong>mechanics</strong> of event delivery from the
+ * <strong>details</strong> of those events.
+ *
+ * The {@code ListenerList} is parameterized on the generic type {@code V}
+ * of the object delivered by {@code notify()}.
+ * This gives compile time type safety over run-time casting of a general {@code Object},
+ * much like {@code HashMap&lt;String, Object&gt;} does not give type safety of the
+ * stored {@code Object} value and may allow
+ * permissive storage of {@code Object}s that are not expected by users of the
+ * {@code HashMap}, later resulting in run-time cast exceptions that
+ * could have been caught by replacing
+ * {@code Object} with a more precise type to enforce a compile time contract.
+ *
+ * The {@code ListenerList} is implemented as a single method callback
+ * - or a "listener" according to Android style guidelines.
+ *
+ * The {@code ListenerList} can be trivially extended by a suitable lambda to implement
+ * a <strong> multiple method abstract class</strong> "callback",
+ * in which the generic type {@code V} could be an {@code Object}
+ * to encapsulate the details of the parameters of each callback method, and
+ * {@code instanceof} could be used to disambiguate which callback method to use.
+ * A {@link Bundle} could alternatively encapsulate those generic parameters,
+ * perhaps more conveniently.
+ * Again, this is a detail of the event, not the mechanics of the event delivery,
+ * which this class is concerned with.
+ *
+ * For details on how to use this class to implement a <strong>single listener</strong>
+ * {@code ListenerList}, see notes on {@link #add}.
+ *
+ * For details on how to optimize this class to implement
+ * a listener based on {@link Handler}s
+ * instead of {@link Executor}s, see{@link #ListenerList(boolean, boolean, boolean)}.
+ *
+ * This is a TestApi for CTS Unit Testing, not exposed for general Application use.
+ * @hide
+ *
+ * @param <V> The class of the object returned to the listener.
+ */
+ @TestApi
+ public static class ListenerList<V> {
+ /**
+ * The Listener interface for callback.
+ *
+ * @param <V> The class of the object returned to the listener
+ */
+ public interface Listener<V> {
+ /**
+ * General event listener interface which is managed by the {@code ListenerList}.
+ *
+ * @param eventCode is an integer representing the event type. This is an
+ * implementation defined parameter.
+ * @param info is the object returned to the listener. It is expected
+ * that the listener makes a private copy of the {@code info} object before
+ * modification, as it is the same instance passed to all listeners.
+ * This is an implementation defined parameter that may be null.
+ */
+ void onEvent(int eventCode, @Nullable V info);
+ }
+
+ private interface ListenerWithCancellation<V> extends Listener<V> {
+ void cancel();
+ }
+
+ /**
+ * Default {@code ListenerList} constructor for {@link Executor} based implementation.
+ *
+ * TODO: consider adding a "name" for debugging if this is used for
+ * multiple listener implementations.
+ */
+ public ListenerList() {
+ this(true /* restrictSingleCallerOnEvent */,
+ true /* clearCallingIdentity */,
+ false /* forceRemoveConsistency*/);
+ }
+
+ /**
+ * Specific {@code ListenerList} constructor for customization.
+ *
+ * See the internal notes for the corresponding private variables on the behavior of
+ * the boolean configuration parameters.
+ *
+ * {@code ListenerList(true, true, false)} is the default and used for
+ * {@link Executor} based notification implementation.
+ *
+ * {@code ListenerList(false, false, false)} may be used for as an optimization
+ * where the {@link Executor} is actually a {@link Handler} post.
+ *
+ * @param restrictSingleCallerOnEvent whether the listener will only be called by
+ * a single thread at a time.
+ * @param clearCallingIdentity whether the binder calling identity on
+ * {@link #notify} is cleared.
+ * @param forceRemoveConsistency whether remove() guarantees no more callbacks to
+ * the listener immediately after the call.
+ */
+ public ListenerList(boolean restrictSingleCallerOnEvent,
+ boolean clearCallingIdentity,
+ boolean forceRemoveConsistency) {
+ mRestrictSingleCallerOnEvent = restrictSingleCallerOnEvent;
+ mClearCallingIdentity = clearCallingIdentity;
+ mForceRemoveConsistency = forceRemoveConsistency;
+ }
+
+ /**
+ * Adds a listener to the {@code ListenerList}.
+ *
+ * The {@code ListenerList} is most often used to hold {@code multiple} listeners.
+ *
+ * Per Android style, for a single method Listener interface, the add and remove
+ * would be wrapped in "addSomeListener" or "removeSomeListener";
+ * or a lambda implemented abstract class callback, wrapped in
+ * "registerSomeCallback" or "unregisterSomeCallback".
+ *
+ * We allow a general {@code key} to be attached to add and remove that specific
+ * listener. It could be the {@code listener} object itself.
+ *
+ * For some implementations, there may be only a {@code single} listener permitted.
+ *
+ * Per Android style, for a single listener {@code ListenerList},
+ * the naming of the wrapping call to {@link #add} would be
+ * "setSomeListener" with a nullable listener, which would be null
+ * to call {@link #remove}.
+ *
+ * In that case, the caller may use this {@link #add} with a single constant object for
+ * the {@code key} to enforce only one Listener in the {@code ListenerList}.
+ * Likewise on remove it would use that
+ * same single constant object to remove the listener.
+ * That {@code key} object could be the {@code ListenerList} itself for convenience.
+ *
+ * @param key is a unique object that is used to identify the listener
+ * when {@code remove()} is called. It can be the listener itself.
+ * @param executor is used to execute the callback.
+ * @param listener is the {@link AudioTrack.ListenerList.Listener}
+ * interface to be called upon {@link notify}.
+ */
+ public void add(
+ @NonNull Object key, @NonNull Executor executor, @NonNull Listener<V> listener) {
+ Objects.requireNonNull(key);
+ Objects.requireNonNull(executor);
+ Objects.requireNonNull(listener);
+
+ // construct wrapper outside of lock.
+ ListenerWithCancellation<V> listenerWithCancellation =
+ new ListenerWithCancellation<V>() {
+ private final Object mLock = new Object(); // our lock is per Listener.
+ private volatile boolean mCancelled = false; // atomic rmw not needed.
+
+ @Override
+ public void onEvent(int eventCode, V info) {
+ executor.execute(() -> {
+ // Note deep execution of locking and cancellation
+ // so this works after posting on different threads.
+ if (mRestrictSingleCallerOnEvent || mForceRemoveConsistency) {
+ synchronized (mLock) {
+ if (mCancelled) return;
+ listener.onEvent(eventCode, info);
+ }
+ } else {
+ if (mCancelled) return;
+ listener.onEvent(eventCode, info);
+ }
+ });
+ }
+
+ @Override
+ public void cancel() {
+ if (mForceRemoveConsistency) {
+ synchronized (mLock) {
+ mCancelled = true;
+ }
+ } else {
+ mCancelled = true;
+ }
+ }
+ };
+
+ synchronized (mListeners) {
+ // TODO: consider an option to check the existence of the key
+ // and throw an ISE if it exists.
+ mListeners.put(key, listenerWithCancellation); // replaces old value
+ }
+ }
+
+ /**
+ * Removes a listener from the {@code ListenerList}.
+ *
+ * @param key the unique object associated with the listener during {@link #add}.
+ */
+ public void remove(@NonNull Object key) {
+ Objects.requireNonNull(key);
+
+ ListenerWithCancellation<V> listener;
+ synchronized (mListeners) {
+ listener = mListeners.get(key);
+ if (listener == null) { // TODO: consider an option to throw ISE Here.
+ return;
+ }
+ mListeners.remove(key); // removes if exist
+ }
+
+ // cancel outside of lock
+ listener.cancel();
+ }
+
+ /**
+ * Notifies all listeners on the List.
+ *
+ * @param eventCode to pass to all listeners.
+ * @param info to pass to all listeners. This is an implemention defined parameter
+ * which may be {@code null}.
+ */
+ public void notify(int eventCode, @Nullable V info) {
+ Object[] listeners; // note we can't cast an object array to a listener array
+ synchronized (mListeners) {
+ if (mListeners.size() == 0) {
+ return;
+ }
+ listeners = mListeners.values().toArray(); // guarantees a copy.
+ }
+
+ // notify outside of lock.
+ final Long identity = mClearCallingIdentity ? Binder.clearCallingIdentity() : null;
+ try {
+ for (Object object : listeners) {
+ final ListenerWithCancellation<V> listener =
+ (ListenerWithCancellation<V>) object;
+ listener.onEvent(eventCode, info);
+ }
+ } finally {
+ if (identity != null) {
+ Binder.restoreCallingIdentity(identity);
+ }
+ }
+ }
+
+ @GuardedBy("mListeners")
+ private HashMap<Object, ListenerWithCancellation<V>> mListeners = new HashMap<>();
+
+ // An Executor may run in multiple threads, whereas a Handler runs on a single Looper.
+ // Should be true for an Executor to avoid concurrent calling into the same listener,
+ // can be false for a Handler as a Handler forces single thread caller for each listener.
+ private final boolean mRestrictSingleCallerOnEvent; // default true
+
+ // An Executor may run in the calling thread, whereas a handler will post to the Looper.
+ // Should be true for an Executor to prevent privilege escalation,
+ // can be false for a Handler as its thread is not the calling binder thread.
+ private final boolean mClearCallingIdentity; // default true
+
+ // Guaranteeing no listener callbacks after removal requires taking the same lock for the
+ // remove as the callback; this is a reversal in calling layers,
+ // hence the risk of lock order inversion is great.
+ //
+ // Set to true only if you can control the caller's listen and remove methods and/or
+ // the threading of the Executor used for each listener.
+ // When set to false, we do not lock, but still do a best effort to cancel messages
+ // on the fly.
+ private final boolean mForceRemoveConsistency; // default false
+ }
}
diff --git a/media/java/android/media/tv/ITvInputManager.aidl b/media/java/android/media/tv/ITvInputManager.aidl
index b5e9d1b2939f..c199c6f8b761 100644
--- a/media/java/android/media/tv/ITvInputManager.aidl
+++ b/media/java/android/media/tv/ITvInputManager.aidl
@@ -95,7 +95,7 @@ interface ITvInputManager {
// For TV input hardware binding
List<TvInputHardwareInfo> getHardwareList();
ITvInputHardware acquireTvInputHardware(int deviceId, in ITvInputHardwareCallback callback,
- in TvInputInfo info, int userId);
+ in TvInputInfo info, int userId, String tvInputSessionId, int priorityHint);
void releaseTvInputHardware(int deviceId, in ITvInputHardware hardware, int userId);
// For TV input capturing
diff --git a/media/java/android/media/tv/TvInputManager.java b/media/java/android/media/tv/TvInputManager.java
index fc5d67d50ee5..9cdfa2aa0807 100644
--- a/media/java/android/media/tv/TvInputManager.java
+++ b/media/java/android/media/tv/TvInputManager.java
@@ -1735,8 +1735,14 @@ public final class TvInputManager {
/**
* Acquires {@link Hardware} object for the given device ID.
*
- * <p>A subsequent call to this method on the same {@code deviceId} will release the currently
- * acquired Hardware.
+ * <p>A subsequent call to this method on the same {@code deviceId} could release the currently
+ * acquired Hardware if TunerResourceManager(TRM) detects higher priority from the current
+ * request.
+ *
+ * <p>If the client would like to provide information for the TRM to compare, use
+ * {@link #acquireTvInputHardware(int, TvInputInfo, HardwareCallback, String, int)} instead.
+ *
+ * <p>Otherwise default priority will be applied.
*
* @param deviceId The device ID to acquire Hardware for.
* @param callback A callback to receive updates on Hardware.
@@ -1747,8 +1753,49 @@ public final class TvInputManager {
*/
@SystemApi
@RequiresPermission(android.Manifest.permission.TV_INPUT_HARDWARE)
- public Hardware acquireTvInputHardware(int deviceId, TvInputInfo info,
- final HardwareCallback callback) {
+ public Hardware acquireTvInputHardware(int deviceId, @NonNull TvInputInfo info,
+ @NonNull final HardwareCallback callback) {
+ Preconditions.checkNotNull(info);
+ Preconditions.checkNotNull(callback);
+ return acquireTvInputHardwareInternal(deviceId, info, callback, null,
+ TvInputService.PRIORITY_HINT_USE_CASE_TYPE_LIVE);
+ }
+
+ /**
+ * Acquires {@link Hardware} object for the given device ID.
+ *
+ * <p>A subsequent call to this method on the same {@code deviceId} could release the currently
+ * acquired Hardware if TunerResourceManager(TRM) detects higher priority from the current
+ * request.
+ *
+ * @param deviceId The device ID to acquire Hardware for.
+ * @param callback A callback to receive updates on Hardware.
+ * @param info The TV input which will use the acquired Hardware.
+ * @param tvInputSessionId a String returned to TIS when the session was created.
+ * {@see TvInputService#onCreateSession(String, String)}. If null, the client will be
+ * treated as a background app.
+ * @param priorityHint The use case of the client. {@see TvInputService#PriorityHintUseCaseType}
+ * @return Hardware on success, {@code null} otherwise. When the TRM decides to not grant
+ * resource, null is returned and the {@link IllegalStateException} is thrown with
+ * "No enough resources".
+ *
+ * @hide
+ */
+ @SystemApi
+ @Nullable
+ @RequiresPermission(android.Manifest.permission.TV_INPUT_HARDWARE)
+ public Hardware acquireTvInputHardware(int deviceId, @NonNull TvInputInfo info,
+ @NonNull final HardwareCallback callback,
+ @Nullable String tvInputSessionId,
+ @TvInputService.PriorityHintUseCaseType int priorityHint) {
+ Preconditions.checkNotNull(info);
+ Preconditions.checkNotNull(callback);
+ return acquireTvInputHardwareInternal(deviceId, info, callback,
+ tvInputSessionId, priorityHint);
+ }
+
+ private Hardware acquireTvInputHardwareInternal(int deviceId, TvInputInfo info,
+ final HardwareCallback callback, String tvInputSessionId, int priorityHint) {
try {
return new Hardware(
mService.acquireTvInputHardware(deviceId, new ITvInputHardwareCallback.Stub() {
@@ -1761,7 +1808,7 @@ public final class TvInputManager {
public void onStreamConfigChanged(TvStreamConfig[] configs) {
callback.onStreamConfigChanged(configs);
}
- }, info, mUserId));
+ }, info, mUserId, tvInputSessionId, priorityHint));
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
diff --git a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/MediaFileTest.java b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/MediaFileTest.java
index 481f4796951d..507dd4ae93e9 100644
--- a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/MediaFileTest.java
+++ b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/MediaFileTest.java
@@ -19,6 +19,7 @@ package com.android.mediaframeworktest.unit;
import static android.media.MediaFile.getFormatCode;
import static android.media.MediaFile.getMimeType;
import static android.media.MediaFile.isAudioMimeType;
+import static android.media.MediaFile.isDocumentMimeType;
import static android.media.MediaFile.isImageMimeType;
import static android.media.MediaFile.isPlayListMimeType;
import static android.media.MediaFile.isVideoMimeType;
@@ -88,7 +89,15 @@ public class MediaFileTest {
assertTrue(isPlayListMimeType(mimeMap.guessMimeTypeFromExtension("wpl")));
assertTrue(isPlayListMimeType(mimeMap.guessMimeTypeFromExtension("m3u")));
assertTrue(isPlayListMimeType(mimeMap.guessMimeTypeFromExtension("m3u8")));
- assertTrue(isPlayListMimeType(mimeMap.guessMimeTypeFromExtension("asf")));
+ }
+
+ @Test
+ public void testDocument() throws Exception {
+ assertTrue(isDocumentMimeType("text/csv"));
+ assertTrue(isDocumentMimeType("text/plain"));
+ assertTrue(isDocumentMimeType("application/pdf"));
+ assertTrue(isDocumentMimeType("application/msword"));
+ assertFalse(isDocumentMimeType("audio/mpeg"));
}
@Test
diff --git a/media/tests/MediaRouter/src/com/android/mediaroutertest/MediaRouter2Test.java b/media/tests/MediaRouter/src/com/android/mediaroutertest/MediaRouter2Test.java
index daaa8688e203..e0b454559456 100644
--- a/media/tests/MediaRouter/src/com/android/mediaroutertest/MediaRouter2Test.java
+++ b/media/tests/MediaRouter/src/com/android/mediaroutertest/MediaRouter2Test.java
@@ -36,6 +36,7 @@ import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotEquals;
import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertSame;
import static org.junit.Assert.assertTrue;
import static org.testng.Assert.assertThrows;
@@ -693,6 +694,14 @@ public class MediaRouter2Test {
assertFalse(systemController.isReleased());
}
+ @Test
+ public void testControllers() {
+ List<RoutingController> controllers = mRouter2.getControllers();
+ assertNotNull(controllers);
+ assertFalse(controllers.isEmpty());
+ assertSame(mRouter2.getSystemController(), controllers.get(0));
+ }
+
// Helper for getting routes easily
static Map<String, MediaRoute2Info> createRouteMap(List<MediaRoute2Info> routes) {
Map<String, MediaRoute2Info> routeMap = new HashMap<>();
diff --git a/packages/SettingsLib/SearchWidget/res/values-pt-rPT/strings.xml b/packages/SettingsLib/SearchWidget/res/values-pt-rPT/strings.xml
index ddf838ea8fe4..85a8d7342827 100644
--- a/packages/SettingsLib/SearchWidget/res/values-pt-rPT/strings.xml
+++ b/packages/SettingsLib/SearchWidget/res/values-pt-rPT/strings.xml
@@ -17,5 +17,5 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="search_menu" msgid="1914043873178389845">"Pesquisar definições"</string>
+ <string name="search_menu" msgid="1914043873178389845">"Pesquisa de definições"</string>
</resources>
diff --git a/packages/SettingsLib/res/values-af/arrays.xml b/packages/SettingsLib/res/values-af/arrays.xml
index d9aaf7dacafc..8a02c776751e 100644
--- a/packages/SettingsLib/res/values-af/arrays.xml
+++ b/packages/SettingsLib/res/values-af/arrays.xml
@@ -75,6 +75,16 @@
<item msgid="4398977131424970917">"avrcp15"</item>
<item msgid="1963366694959681026">"avrcp16"</item>
</string-array>
+ <string-array name="bluetooth_map_versions">
+ <item msgid="8786402640610987099">"MAP 1.2 (verstek)"</item>
+ <item msgid="6817922176194686449">"MAP 1.3"</item>
+ <item msgid="3423518690032737851">"MAP 1.4"</item>
+ </string-array>
+ <string-array name="bluetooth_map_version_values">
+ <item msgid="1164651830068248391">"map12"</item>
+ <item msgid="7073042887003102964">"map13"</item>
+ <item msgid="8147982633566548515">"map14"</item>
+ </string-array>
<string-array name="bluetooth_a2dp_codec_titles">
<item msgid="2494959071796102843">"Gebruik stelselkeuse (verstek)"</item>
<item msgid="4055460186095649420">"SBC"</item>
diff --git a/packages/SettingsLib/res/values-af/strings.xml b/packages/SettingsLib/res/values-af/strings.xml
index 25903388c6ca..2b143e425589 100644
--- a/packages/SettingsLib/res/values-af/strings.xml
+++ b/packages/SettingsLib/res/values-af/strings.xml
@@ -230,6 +230,8 @@
<string name="bluetooth_enable_gabeldorsche" msgid="9131730396242883416">"Aktiveer Gabeldorsche"</string>
<string name="bluetooth_select_avrcp_version_string" msgid="1710571610177659127">"Bluetooth AVRCP-weergawe"</string>
<string name="bluetooth_select_avrcp_version_dialog_title" msgid="7846922290083709633">"Kies Bluetooth AVRCP-weergawe"</string>
+ <string name="bluetooth_select_map_version_string" msgid="526308145174175327">"Bluetooth MAP-weergawe"</string>
+ <string name="bluetooth_select_map_version_dialog_title" msgid="7085934373987428460">"Kies Bluetooth MAP-weergawe"</string>
<string name="bluetooth_select_a2dp_codec_type" msgid="952001408455456494">"Bluetooth-oudiokodek"</string>
<string name="bluetooth_select_a2dp_codec_type_dialog_title" msgid="7510542404227225545">"Gebruik Bluetooth-oudiokodek\nKeuse"</string>
<string name="bluetooth_select_a2dp_codec_sample_rate" msgid="1638623076480928191">"Bluetooth-oudiovoorbeeldkoers"</string>
@@ -276,7 +278,7 @@
<string name="verify_apps_over_usb_summary" msgid="1317933737581167839">"Kontroleer programme wat via ADB/ADT geïnstalleer is vir skadelike gedrag."</string>
<string name="bluetooth_show_devices_without_names_summary" msgid="780964354377854507">"Bluetooth-toestelle sonder name (net MAC-adresse) sal gewys word"</string>
<string name="bluetooth_disable_absolute_volume_summary" msgid="2006309932135547681">"Deaktiveer die Bluetooth-kenmerk vir absolute volume indien daar volumeprobleme met afgeleë toestelle is, soos onaanvaarbare harde klank of geen beheer nie."</string>
- <string name="bluetooth_enable_gabeldorsche_summary" msgid="8472344901097607030">"Aktiveer die Bluetooth Gabeldorsche-kenmerkstapel."</string>
+ <string name="bluetooth_enable_gabeldorsche_summary" msgid="2054730331770712629">"Aktiveer die Bluetooth Gabeldorsche-kenmerkstapel."</string>
<string name="enable_terminal_title" msgid="3834790541986303654">"Plaaslike terminaal"</string>
<string name="enable_terminal_summary" msgid="2481074834856064500">"Aktiveer terminaalprogram wat plaaslike skermtoegang bied"</string>
<string name="hdcp_checking_title" msgid="3155692785074095986">"HDCP-kontrolering"</string>
diff --git a/packages/SettingsLib/res/values-am/arrays.xml b/packages/SettingsLib/res/values-am/arrays.xml
index fff7cae377d4..6a9334e3b65f 100644
--- a/packages/SettingsLib/res/values-am/arrays.xml
+++ b/packages/SettingsLib/res/values-am/arrays.xml
@@ -75,6 +75,16 @@
<item msgid="4398977131424970917">"avrcp15"</item>
<item msgid="1963366694959681026">"avrcp16"</item>
</string-array>
+ <string-array name="bluetooth_map_versions">
+ <item msgid="8786402640610987099">"MAP 1.2 (ነባሪ)"</item>
+ <item msgid="6817922176194686449">"MAP 1.3"</item>
+ <item msgid="3423518690032737851">"MAP 1.4"</item>
+ </string-array>
+ <string-array name="bluetooth_map_version_values">
+ <item msgid="1164651830068248391">"map12"</item>
+ <item msgid="7073042887003102964">"map13"</item>
+ <item msgid="8147982633566548515">"map14"</item>
+ </string-array>
<string-array name="bluetooth_a2dp_codec_titles">
<item msgid="2494959071796102843">"የስርዓቱን ምርጫ (ነባሪ) ተጠቀም"</item>
<item msgid="4055460186095649420">"SBC"</item>
diff --git a/packages/SettingsLib/res/values-am/strings.xml b/packages/SettingsLib/res/values-am/strings.xml
index 8277711a9870..2a93e01765bb 100644
--- a/packages/SettingsLib/res/values-am/strings.xml
+++ b/packages/SettingsLib/res/values-am/strings.xml
@@ -230,6 +230,8 @@
<string name="bluetooth_enable_gabeldorsche" msgid="9131730396242883416">"Gabeldorscheን አንቃ"</string>
<string name="bluetooth_select_avrcp_version_string" msgid="1710571610177659127">"የብሉቱዝ AVRCP ስሪት"</string>
<string name="bluetooth_select_avrcp_version_dialog_title" msgid="7846922290083709633">"የብሉቱዝ AVRCP ስሪት ይምረጡ"</string>
+ <string name="bluetooth_select_map_version_string" msgid="526308145174175327">"የብሉቱዝ MAP ስሪት"</string>
+ <string name="bluetooth_select_map_version_dialog_title" msgid="7085934373987428460">"የብሉቱዝ MAP ስሪቱን ይምረጡ"</string>
<string name="bluetooth_select_a2dp_codec_type" msgid="952001408455456494">"የብሉቱዝ ኦዲዮ ኮዴክ"</string>
<string name="bluetooth_select_a2dp_codec_type_dialog_title" msgid="7510542404227225545">"የብሉቱዝ ኦዲዮ ኮዴክ አስጀምር\nምርጫ"</string>
<string name="bluetooth_select_a2dp_codec_sample_rate" msgid="1638623076480928191">"የብሉቱዝ ኦዲዮ ናሙና ፍጥነት"</string>
@@ -276,7 +278,7 @@
<string name="verify_apps_over_usb_summary" msgid="1317933737581167839">"በADB/ADT በኩል የተጫኑ መተግበሪያዎች ጎጂ ባህሪ ካላቸው ያረጋግጡ።"</string>
<string name="bluetooth_show_devices_without_names_summary" msgid="780964354377854507">"የብሉቱዝ መሣሪያዎች ያለ ስሞች (MAC አድራሻዎች ብቻ) ይታያሉ"</string>
<string name="bluetooth_disable_absolute_volume_summary" msgid="2006309932135547681">"እንደ ተቀባይነት በሌለው ደረጃ ድምፁ ከፍ ማለት ወይም መቆጣጠር አለመቻል ያሉ ከሩቅ መሣሪያዎች ጋር የድምፅ ችግር በሚኖርበት ጊዜ የብሉቱዝ ፍጹማዊ ድምፅን ባሕሪ ያሰናክላል።"</string>
- <string name="bluetooth_enable_gabeldorsche_summary" msgid="8472344901097607030">"የብሉቱዝ Gabeldorche ባህሪ ቁልልን ያነቃል።"</string>
+ <string name="bluetooth_enable_gabeldorsche_summary" msgid="2054730331770712629">"የብሉቱዝ Gabeldorsche ባህሪ ቁልሉን ያነቃል።"</string>
<string name="enable_terminal_title" msgid="3834790541986303654">"አካባቢያዊ ተርሚናል"</string>
<string name="enable_terminal_summary" msgid="2481074834856064500">"የአካባቢያዊ ሼል መዳረሻ የሚያቀርብ የተርሚናል መተግበሪያ አንቃ"</string>
<string name="hdcp_checking_title" msgid="3155692785074095986">"የHDCP ምልከታ"</string>
diff --git a/packages/SettingsLib/res/values-ar/arrays.xml b/packages/SettingsLib/res/values-ar/arrays.xml
index b4f5253870c1..851a3d8f136a 100644
--- a/packages/SettingsLib/res/values-ar/arrays.xml
+++ b/packages/SettingsLib/res/values-ar/arrays.xml
@@ -75,6 +75,16 @@
<item msgid="4398977131424970917">"avrcp15"</item>
<item msgid="1963366694959681026">"avrcp16"</item>
</string-array>
+ <string-array name="bluetooth_map_versions">
+ <item msgid="8786402640610987099">"‏MAP 1.2 (الإعداد الافتراضي)"</item>
+ <item msgid="6817922176194686449">"MAP 1.3"</item>
+ <item msgid="3423518690032737851">"MAP 1.4"</item>
+ </string-array>
+ <string-array name="bluetooth_map_version_values">
+ <item msgid="1164651830068248391">"map12"</item>
+ <item msgid="7073042887003102964">"map13"</item>
+ <item msgid="8147982633566548515">"map14"</item>
+ </string-array>
<string-array name="bluetooth_a2dp_codec_titles">
<item msgid="2494959071796102843">"استخدام اختيار النظام (تلقائي)"</item>
<item msgid="4055460186095649420">"SBC"</item>
diff --git a/packages/SettingsLib/res/values-ar/strings.xml b/packages/SettingsLib/res/values-ar/strings.xml
index 43d2eceab51d..54856566e021 100644
--- a/packages/SettingsLib/res/values-ar/strings.xml
+++ b/packages/SettingsLib/res/values-ar/strings.xml
@@ -230,6 +230,8 @@
<string name="bluetooth_enable_gabeldorsche" msgid="9131730396242883416">"‏تفعيل Gabeldorsche"</string>
<string name="bluetooth_select_avrcp_version_string" msgid="1710571610177659127">"‏إصدار Bluetooth AVRCP"</string>
<string name="bluetooth_select_avrcp_version_dialog_title" msgid="7846922290083709633">"‏اختيار إصدار Bluetooth AVRCP"</string>
+ <string name="bluetooth_select_map_version_string" msgid="526308145174175327">"‏إصدار Bluetooth MAP"</string>
+ <string name="bluetooth_select_map_version_dialog_title" msgid="7085934373987428460">"‏اختيار إصدار Bluetooth MAP"</string>
<string name="bluetooth_select_a2dp_codec_type" msgid="952001408455456494">"برنامج ترميز صوت بلوتوث"</string>
<string name="bluetooth_select_a2dp_codec_type_dialog_title" msgid="7510542404227225545">"اختيار برنامج ترميز الصوت لمشغّل\nالبلوتوث"</string>
<string name="bluetooth_select_a2dp_codec_sample_rate" msgid="1638623076480928191">"معدّل عيّنة صوت بلوتوث"</string>
@@ -276,7 +278,7 @@
<string name="verify_apps_over_usb_summary" msgid="1317933737581167839">"‏التحقق من التطبيقات المثبتة عبر ADB/ADT لكشف السلوك الضار"</string>
<string name="bluetooth_show_devices_without_names_summary" msgid="780964354377854507">"‏سيتم عرض أجهزة البلوتوث بدون أسماء (عناوين MAC فقط)"</string>
<string name="bluetooth_disable_absolute_volume_summary" msgid="2006309932135547681">"لإيقاف ميزة مستوى الصوت المطلق للبلوتوث في حال حدوث مشاكل متعلقة بمستوى الصوت في الأجهزة البعيدة، مثل مستوى صوت عالٍ بشكل غير مقبول أو عدم إمكانية التحكّم في الصوت"</string>
- <string name="bluetooth_enable_gabeldorsche_summary" msgid="8472344901097607030">"‏تفعيل حِزم ميزة Bluetooth Gabeldorche"</string>
+ <string name="bluetooth_enable_gabeldorsche_summary" msgid="2054730331770712629">"‏تفعيل حِزم ميزة Bluetooth Gabeldorsche"</string>
<string name="enable_terminal_title" msgid="3834790541986303654">"تطبيق طرفي محلي"</string>
<string name="enable_terminal_summary" msgid="2481074834856064500">"تفعيل تطبيق طرفي يوفر إمكانية الدخول إلى واجهة النظام المحلية"</string>
<string name="hdcp_checking_title" msgid="3155692785074095986">"‏التحقق من HDCP"</string>
@@ -435,7 +437,7 @@
<string name="screen_zoom_summary_extremely_large" msgid="1438045624562358554">"أكبر مستوى"</string>
<string name="screen_zoom_summary_custom" msgid="3468154096832912210">"مخصص (<xliff:g id="DENSITYDPI">%d</xliff:g>)"</string>
<string name="content_description_menu_button" msgid="6254844309171779931">"القائمة"</string>
- <string name="retail_demo_reset_message" msgid="5392824901108195463">"إدخال كلمة المرور لإعادة الضبط بحسب بيانات المصنع في الوضع التجريبي"</string>
+ <string name="retail_demo_reset_message" msgid="5392824901108195463">"إدخال كلمة المرور لإعادة الضبط على الإعدادات الأصلية في الوضع التجريبي"</string>
<string name="retail_demo_reset_next" msgid="3688129033843885362">"التالي"</string>
<string name="retail_demo_reset_title" msgid="1866911701095959800">"يلزم توفر كلمة مرور"</string>
<string name="active_input_method_subtypes" msgid="4232680535471633046">"طرق الإدخال النشطة"</string>
diff --git a/packages/SettingsLib/res/values-as/arrays.xml b/packages/SettingsLib/res/values-as/arrays.xml
index 1a044f5ade70..503c13edebba 100644
--- a/packages/SettingsLib/res/values-as/arrays.xml
+++ b/packages/SettingsLib/res/values-as/arrays.xml
@@ -75,6 +75,16 @@
<item msgid="4398977131424970917">"avrcp১৫"</item>
<item msgid="1963366694959681026">"avrcp১৬"</item>
</string-array>
+ <string-array name="bluetooth_map_versions">
+ <item msgid="8786402640610987099">"MAP 1.2 (ডিফ’ল্ট)"</item>
+ <item msgid="6817922176194686449">"MAP 1.3"</item>
+ <item msgid="3423518690032737851">"MAP 1.4"</item>
+ </string-array>
+ <string-array name="bluetooth_map_version_values">
+ <item msgid="1164651830068248391">"map12"</item>
+ <item msgid="7073042887003102964">"map13"</item>
+ <item msgid="8147982633566548515">"map14"</item>
+ </string-array>
<string-array name="bluetooth_a2dp_codec_titles">
<item msgid="2494959071796102843">"ছিষ্টেমৰ বাছনি ব্যৱহাৰ কৰক (ডিফ\'ল্ট)"</item>
<item msgid="4055460186095649420">"এছবিচি"</item>
diff --git a/packages/SettingsLib/res/values-as/strings.xml b/packages/SettingsLib/res/values-as/strings.xml
index 3f85fe3dad37..fa26b9b93ef6 100644
--- a/packages/SettingsLib/res/values-as/strings.xml
+++ b/packages/SettingsLib/res/values-as/strings.xml
@@ -230,6 +230,8 @@
<string name="bluetooth_enable_gabeldorsche" msgid="9131730396242883416">"Gabeldorsche সক্ষম কৰক"</string>
<string name="bluetooth_select_avrcp_version_string" msgid="1710571610177659127">"ব্লুটুথ AVRCP সংস্কৰণ"</string>
<string name="bluetooth_select_avrcp_version_dialog_title" msgid="7846922290083709633">"ব্লুটুথ AVRCP সংস্কৰণ বাছনি কৰক"</string>
+ <string name="bluetooth_select_map_version_string" msgid="526308145174175327">"ব্লুটুথ MAP সংস্কৰণ"</string>
+ <string name="bluetooth_select_map_version_dialog_title" msgid="7085934373987428460">"ব্লুটুথ MAP সংস্কৰণ বাছনি কৰক"</string>
<string name="bluetooth_select_a2dp_codec_type" msgid="952001408455456494">"ব্লুটুথ অডিঅ’ ক’ডেক"</string>
<string name="bluetooth_select_a2dp_codec_type_dialog_title" msgid="7510542404227225545">"ব্লুটুথ অডিঅ\' ক\'ডেকৰ বাছনি\nআৰম্ভ কৰক"</string>
<string name="bluetooth_select_a2dp_codec_sample_rate" msgid="1638623076480928191">"ব্লুটুথ অডিঅ\' ছেম্পল ৰেইট"</string>
@@ -276,7 +278,7 @@
<string name="verify_apps_over_usb_summary" msgid="1317933737581167839">"ADB/ADTৰ যোগেৰে ইনষ্টল কৰা এপসমূহে কিবা ক্ষতিকাৰক আচৰণ কৰিছে নেকি পৰীক্ষা কৰক।"</string>
<string name="bluetooth_show_devices_without_names_summary" msgid="780964354377854507">"নামহীন ব্লুটুথ ডিভাইচসমূহ (মাত্ৰ MAC ঠিকনাযুক্ত) দেখুওৱা হ\'ব"</string>
<string name="bluetooth_disable_absolute_volume_summary" msgid="2006309932135547681">"ৰিম\'ট ডিভাইচবিলাকৰ সৈতে ভলিউম সম্পৰ্কীয় সমস্যা, যেনেকৈ অতি উচ্চ ভলিউম বা নিয়ন্ত্ৰণ কৰিবই নোৱাৰা অৱস্থাত ব্লুটুথৰ পূৰ্ণ ভলিউম সুবিধা অক্ষম কৰে।"</string>
- <string name="bluetooth_enable_gabeldorsche_summary" msgid="8472344901097607030">"ব্লুটুথ Gabeldorche সুবিধাৰ সমষ্টিটো সক্ষম কৰে।"</string>
+ <string name="bluetooth_enable_gabeldorsche_summary" msgid="2054730331770712629">"ব্লুটুথ Gabeldorche সুবিধাৰ সমষ্টিটো সক্ষম কৰে।"</string>
<string name="enable_terminal_title" msgid="3834790541986303654">"স্থানীয় টাৰ্মিনেল"</string>
<string name="enable_terminal_summary" msgid="2481074834856064500">"স্থানীয় শ্বেল প্ৰৱেশাধিকাৰ দিয়া টাৰ্মিনেল এপ্ সক্ষম কৰক"</string>
<string name="hdcp_checking_title" msgid="3155692785074095986">"HDCP পৰীক্ষণ"</string>
diff --git a/packages/SettingsLib/res/values-az/arrays.xml b/packages/SettingsLib/res/values-az/arrays.xml
index eb81381a4439..005bdf7e6fc0 100644
--- a/packages/SettingsLib/res/values-az/arrays.xml
+++ b/packages/SettingsLib/res/values-az/arrays.xml
@@ -75,6 +75,16 @@
<item msgid="4398977131424970917">"avrcp15"</item>
<item msgid="1963366694959681026">"avrcp16"</item>
</string-array>
+ <string-array name="bluetooth_map_versions">
+ <item msgid="8786402640610987099">"MAP 1.2 (Defolt)"</item>
+ <item msgid="6817922176194686449">"MAP 1.3"</item>
+ <item msgid="3423518690032737851">"MAP 1.4"</item>
+ </string-array>
+ <string-array name="bluetooth_map_version_values">
+ <item msgid="1164651830068248391">"map12"</item>
+ <item msgid="7073042887003102964">"map13"</item>
+ <item msgid="8147982633566548515">"map14"</item>
+ </string-array>
<string-array name="bluetooth_a2dp_codec_titles">
<item msgid="2494959071796102843">"Sistem Seçimini istifadə edin (Defolt)"</item>
<item msgid="4055460186095649420">"SBC"</item>
diff --git a/packages/SettingsLib/res/values-az/strings.xml b/packages/SettingsLib/res/values-az/strings.xml
index 3a1a54341aaf..2e80fdcb8972 100644
--- a/packages/SettingsLib/res/values-az/strings.xml
+++ b/packages/SettingsLib/res/values-az/strings.xml
@@ -230,6 +230,8 @@
<string name="bluetooth_enable_gabeldorsche" msgid="9131730396242883416">"Gabeldorsche\'ni aktiv edin"</string>
<string name="bluetooth_select_avrcp_version_string" msgid="1710571610177659127">"Bluetooth AVRCP Versiya"</string>
<string name="bluetooth_select_avrcp_version_dialog_title" msgid="7846922290083709633">"Bluetooth AVRCP Versiyasını seçin"</string>
+ <string name="bluetooth_select_map_version_string" msgid="526308145174175327">"Bluetooth MAP Versiyası"</string>
+ <string name="bluetooth_select_map_version_dialog_title" msgid="7085934373987428460">"Bluetooth MAP Versiyasını seçin"</string>
<string name="bluetooth_select_a2dp_codec_type" msgid="952001408455456494">"Bluetooth Audio Kodek"</string>
<string name="bluetooth_select_a2dp_codec_type_dialog_title" msgid="7510542404227225545">"Bluetooth Audio KodeK\nSeçimini aktiv edin"</string>
<string name="bluetooth_select_a2dp_codec_sample_rate" msgid="1638623076480928191">"Bluetooth Audio Nümunə Göstəricisi"</string>
@@ -276,7 +278,7 @@
<string name="verify_apps_over_usb_summary" msgid="1317933737581167839">"ADB/ADT vasitəsi ilə quraşdırılmış tətbiqləri zərərli davranış üzrə yoxlayın."</string>
<string name="bluetooth_show_devices_without_names_summary" msgid="780964354377854507">"Adsız Bluetooth cihazları (yalnız MAC ünvanları) göstəriləcək"</string>
<string name="bluetooth_disable_absolute_volume_summary" msgid="2006309932135547681">"Uzaqdan idarə olunan cihazlarda dözülməz yüksək səs həcmi və ya nəzarət çatışmazlığı kimi səs problemləri olduqda Bluetooth mütləq səs həcmi xüsusiyyətini deaktiv edir."</string>
- <string name="bluetooth_enable_gabeldorsche_summary" msgid="8472344901097607030">"Bluetooth Gabeldorche xüsusiyyətini aktiv edir."</string>
+ <string name="bluetooth_enable_gabeldorsche_summary" msgid="2054730331770712629">"Bluetooth Gabeldorsche funksiyasını aktiv edir."</string>
<string name="enable_terminal_title" msgid="3834790541986303654">"Yerli terminal"</string>
<string name="enable_terminal_summary" msgid="2481074834856064500">"Yerli örtük girişini təklif edən terminal tətbiqi aktiv edin"</string>
<string name="hdcp_checking_title" msgid="3155692785074095986">"HDCP yoxlanılır"</string>
diff --git a/packages/SettingsLib/res/values-b+sr+Latn/arrays.xml b/packages/SettingsLib/res/values-b+sr+Latn/arrays.xml
index c7b63b3f7f3e..10c0d6c62262 100644
--- a/packages/SettingsLib/res/values-b+sr+Latn/arrays.xml
+++ b/packages/SettingsLib/res/values-b+sr+Latn/arrays.xml
@@ -75,6 +75,16 @@
<item msgid="4398977131424970917">"avrcp15"</item>
<item msgid="1963366694959681026">"avrcp16"</item>
</string-array>
+ <string-array name="bluetooth_map_versions">
+ <item msgid="8786402640610987099">"MAP 1.2 (podrazumevano)"</item>
+ <item msgid="6817922176194686449">"MAP 1.3"</item>
+ <item msgid="3423518690032737851">"MAP 1.4"</item>
+ </string-array>
+ <string-array name="bluetooth_map_version_values">
+ <item msgid="1164651830068248391">"map12"</item>
+ <item msgid="7073042887003102964">"map13"</item>
+ <item msgid="8147982633566548515">"map14"</item>
+ </string-array>
<string-array name="bluetooth_a2dp_codec_titles">
<item msgid="2494959071796102843">"Koristi izbor sistema (podrazumevano)"</item>
<item msgid="4055460186095649420">"SBC"</item>
diff --git a/packages/SettingsLib/res/values-b+sr+Latn/strings.xml b/packages/SettingsLib/res/values-b+sr+Latn/strings.xml
index 02e5e3b5c435..ae5c93670644 100644
--- a/packages/SettingsLib/res/values-b+sr+Latn/strings.xml
+++ b/packages/SettingsLib/res/values-b+sr+Latn/strings.xml
@@ -230,6 +230,8 @@
<string name="bluetooth_enable_gabeldorsche" msgid="9131730396242883416">"Omogući Gabeldorsche"</string>
<string name="bluetooth_select_avrcp_version_string" msgid="1710571610177659127">"Verzija Bluetooth AVRCP-a"</string>
<string name="bluetooth_select_avrcp_version_dialog_title" msgid="7846922290083709633">"Izaberite verziju Bluetooth AVRCP-a"</string>
+ <string name="bluetooth_select_map_version_string" msgid="526308145174175327">"Verzija Bluetooth MAP-a"</string>
+ <string name="bluetooth_select_map_version_dialog_title" msgid="7085934373987428460">"Izaberite verziju Bluetooth MAP-a"</string>
<string name="bluetooth_select_a2dp_codec_type" msgid="952001408455456494">"Bluetooth audio kodek"</string>
<string name="bluetooth_select_a2dp_codec_type_dialog_title" msgid="7510542404227225545">"Izaberite Bluetooth audio kodek\n"</string>
<string name="bluetooth_select_a2dp_codec_sample_rate" msgid="1638623076480928191">"Brzina uzorkovanja za Bluetooth audio"</string>
@@ -276,7 +278,7 @@
<string name="verify_apps_over_usb_summary" msgid="1317933737581167839">"Proverava da li su aplikacije instalirane preko ADB-a/ADT-a štetne."</string>
<string name="bluetooth_show_devices_without_names_summary" msgid="780964354377854507">"Biće prikazani Bluetooth uređaji bez naziva (samo sa MAC adresama)"</string>
<string name="bluetooth_disable_absolute_volume_summary" msgid="2006309932135547681">"Onemogućava glavno podešavanje jačine zvuka na Bluetooth uređaju u slučaju problema sa jačinom zvuka na daljinskim uređajima, kao što su izuzetno velika jačina zvuka ili nedostatak kontrole."</string>
- <string name="bluetooth_enable_gabeldorsche_summary" msgid="8472344901097607030">"Omogućava grupu Bluetooth Gabeldorche funkcija."</string>
+ <string name="bluetooth_enable_gabeldorsche_summary" msgid="2054730331770712629">"Omogućava grupu Bluetooth Gabeldorsche funkcija."</string>
<string name="enable_terminal_title" msgid="3834790541986303654">"Lokalni terminal"</string>
<string name="enable_terminal_summary" msgid="2481074834856064500">"Omogući apl. terminala za pristup lokalnom komandnom okruženju"</string>
<string name="hdcp_checking_title" msgid="3155692785074095986">"HDCP provera"</string>
diff --git a/packages/SettingsLib/res/values-be/arrays.xml b/packages/SettingsLib/res/values-be/arrays.xml
index 9eaab6a6829a..e05fd602e303 100644
--- a/packages/SettingsLib/res/values-be/arrays.xml
+++ b/packages/SettingsLib/res/values-be/arrays.xml
@@ -75,6 +75,16 @@
<item msgid="4398977131424970917">"avrcp15"</item>
<item msgid="1963366694959681026">"avrcp16"</item>
</string-array>
+ <string-array name="bluetooth_map_versions">
+ <item msgid="8786402640610987099">"MAP 1.2 (стандартна)"</item>
+ <item msgid="6817922176194686449">"MAP 1.3"</item>
+ <item msgid="3423518690032737851">"MAP 1.4"</item>
+ </string-array>
+ <string-array name="bluetooth_map_version_values">
+ <item msgid="1164651830068248391">"map12"</item>
+ <item msgid="7073042887003102964">"map13"</item>
+ <item msgid="8147982633566548515">"map14"</item>
+ </string-array>
<string-array name="bluetooth_a2dp_codec_titles">
<item msgid="2494959071796102843">"Выбар сістэмы (стандартны)"</item>
<item msgid="4055460186095649420">"SBC"</item>
diff --git a/packages/SettingsLib/res/values-be/strings.xml b/packages/SettingsLib/res/values-be/strings.xml
index 481dfb0fd697..ad201d081fce 100644
--- a/packages/SettingsLib/res/values-be/strings.xml
+++ b/packages/SettingsLib/res/values-be/strings.xml
@@ -230,6 +230,8 @@
<string name="bluetooth_enable_gabeldorsche" msgid="9131730396242883416">"Уключыць Gabeldorsche"</string>
<string name="bluetooth_select_avrcp_version_string" msgid="1710571610177659127">"Версія Bluetooth AVRCP"</string>
<string name="bluetooth_select_avrcp_version_dialog_title" msgid="7846922290083709633">"Выбраць версію Bluetooth AVRCP"</string>
+ <string name="bluetooth_select_map_version_string" msgid="526308145174175327">"Версія Bluetooth MAP"</string>
+ <string name="bluetooth_select_map_version_dialog_title" msgid="7085934373987428460">"Выбраць версію Bluetooth MAP"</string>
<string name="bluetooth_select_a2dp_codec_type" msgid="952001408455456494">"Кодэк Bluetooth Audio"</string>
<string name="bluetooth_select_a2dp_codec_type_dialog_title" msgid="7510542404227225545">"Уключыць кодэк Bluetooth Audio\nВыбар"</string>
<string name="bluetooth_select_a2dp_codec_sample_rate" msgid="1638623076480928191">"Частата дыскрэтызацыі Bluetooth Audio"</string>
@@ -276,7 +278,7 @@
<string name="verify_apps_over_usb_summary" msgid="1317933737581167839">"Праверка бяспекі праграм, усталяваных з дапамогай ADB/ADT."</string>
<string name="bluetooth_show_devices_without_names_summary" msgid="780964354377854507">"Прылады Bluetooth будуць паказаны без назваў (толькі MAC-адрасы)"</string>
<string name="bluetooth_disable_absolute_volume_summary" msgid="2006309932135547681">"Адключыць функцыю абсалютнага гуку Bluetooth у выпадку праблем з гукам на аддаленых прыладах, напрыклад, пры непрымальна высокай гучнасці або адсутнасці кіравання."</string>
- <string name="bluetooth_enable_gabeldorsche_summary" msgid="8472344901097607030">"Уключае стос функцый Bluetooth Gabeldorche."</string>
+ <string name="bluetooth_enable_gabeldorsche_summary" msgid="2054730331770712629">"Уключае стос функцый Bluetooth Gabeldorsche."</string>
<string name="enable_terminal_title" msgid="3834790541986303654">"Лакальны тэрмінал"</string>
<string name="enable_terminal_summary" msgid="2481074834856064500">"Уключэнне прыкладання тэрмінала, якое прапануе доступ да лакальнай абалонкі"</string>
<string name="hdcp_checking_title" msgid="3155692785074095986">"Праверка HDCP"</string>
diff --git a/packages/SettingsLib/res/values-bg/arrays.xml b/packages/SettingsLib/res/values-bg/arrays.xml
index e7976fcc7bd5..a071baf97f14 100644
--- a/packages/SettingsLib/res/values-bg/arrays.xml
+++ b/packages/SettingsLib/res/values-bg/arrays.xml
@@ -75,6 +75,16 @@
<item msgid="4398977131424970917">"avrcp15"</item>
<item msgid="1963366694959681026">"avrcp16"</item>
</string-array>
+ <string-array name="bluetooth_map_versions">
+ <item msgid="8786402640610987099">"MAP 1.2 (по подразбиране)"</item>
+ <item msgid="6817922176194686449">"MAP 1.3"</item>
+ <item msgid="3423518690032737851">"MAP 1.4"</item>
+ </string-array>
+ <string-array name="bluetooth_map_version_values">
+ <item msgid="1164651830068248391">"map12"</item>
+ <item msgid="7073042887003102964">"map13"</item>
+ <item msgid="8147982633566548515">"map14"</item>
+ </string-array>
<string-array name="bluetooth_a2dp_codec_titles">
<item msgid="2494959071796102843">"Използване на сист. избор (стандартно)"</item>
<item msgid="4055460186095649420">"SBC"</item>
diff --git a/packages/SettingsLib/res/values-bg/strings.xml b/packages/SettingsLib/res/values-bg/strings.xml
index 2a0264039a78..94f78ad30a67 100644
--- a/packages/SettingsLib/res/values-bg/strings.xml
+++ b/packages/SettingsLib/res/values-bg/strings.xml
@@ -230,6 +230,8 @@
<string name="bluetooth_enable_gabeldorsche" msgid="9131730396242883416">"Активиране на Gabeldorsche"</string>
<string name="bluetooth_select_avrcp_version_string" msgid="1710571610177659127">"Версия на AVRCP за Bluetooth"</string>
<string name="bluetooth_select_avrcp_version_dialog_title" msgid="7846922290083709633">"Избиране на версия на AVRCP за Bluetooth"</string>
+ <string name="bluetooth_select_map_version_string" msgid="526308145174175327">"MAP версия за Bluetooth"</string>
+ <string name="bluetooth_select_map_version_dialog_title" msgid="7085934373987428460">"Изберете MAP версия за Bluetooth"</string>
<string name="bluetooth_select_a2dp_codec_type" msgid="952001408455456494">"Аудиокодек за Bluetooth"</string>
<string name="bluetooth_select_a2dp_codec_type_dialog_title" msgid="7510542404227225545">"Задействане на аудиокодек за Bluetooth\nИзбор"</string>
<string name="bluetooth_select_a2dp_codec_sample_rate" msgid="1638623076480928191">"Честота на дискретизация за звука през Bluetooth"</string>
@@ -276,7 +278,7 @@
<string name="verify_apps_over_usb_summary" msgid="1317933737581167839">"Проверка на инсталираните чрез ADB/ADT приложения за опасно поведение."</string>
<string name="bluetooth_show_devices_without_names_summary" msgid="780964354377854507">"Ще бъдат показани устройствата с Bluetooth без имена (само MAC адресите)"</string>
<string name="bluetooth_disable_absolute_volume_summary" msgid="2006309932135547681">"Деактивира функцията на Bluetooth за пълна сила на звука в случай на проблеми със звука на отдалечени устройства, като например неприемливо висока сила на звука или липса на управление."</string>
- <string name="bluetooth_enable_gabeldorsche_summary" msgid="8472344901097607030">"Активира стека на функциите на Bluetooth Gabeldorsche."</string>
+ <string name="bluetooth_enable_gabeldorsche_summary" msgid="2054730331770712629">"Активира стека на функциите на Bluetooth Gabeldorsche."</string>
<string name="enable_terminal_title" msgid="3834790541986303654">"Локален терминал"</string>
<string name="enable_terminal_summary" msgid="2481074834856064500">"Актив. на прил. за терминал с достъп до локалния команден ред"</string>
<string name="hdcp_checking_title" msgid="3155692785074095986">"Проверка с HDCP"</string>
diff --git a/packages/SettingsLib/res/values-bn/arrays.xml b/packages/SettingsLib/res/values-bn/arrays.xml
index a67b9eb493c4..a131a3b1ad91 100644
--- a/packages/SettingsLib/res/values-bn/arrays.xml
+++ b/packages/SettingsLib/res/values-bn/arrays.xml
@@ -75,6 +75,16 @@
<item msgid="4398977131424970917">"avrcp15"</item>
<item msgid="1963366694959681026">"avrcp16"</item>
</string-array>
+ <string-array name="bluetooth_map_versions">
+ <item msgid="8786402640610987099">"MAP 1.2 (ডিফল্ট)"</item>
+ <item msgid="6817922176194686449">"MAP 1.3"</item>
+ <item msgid="3423518690032737851">"MAP 1.4"</item>
+ </string-array>
+ <string-array name="bluetooth_map_version_values">
+ <item msgid="1164651830068248391">"map12"</item>
+ <item msgid="7073042887003102964">"map13"</item>
+ <item msgid="8147982633566548515">"map14"</item>
+ </string-array>
<string-array name="bluetooth_a2dp_codec_titles">
<item msgid="2494959071796102843">"সিস্টেমের নির্বাচন ব্যবহার করুন (ডিফল্ট)"</item>
<item msgid="4055460186095649420">"SBC"</item>
diff --git a/packages/SettingsLib/res/values-bn/strings.xml b/packages/SettingsLib/res/values-bn/strings.xml
index 9bebe419470b..517191601d2f 100644
--- a/packages/SettingsLib/res/values-bn/strings.xml
+++ b/packages/SettingsLib/res/values-bn/strings.xml
@@ -230,6 +230,8 @@
<string name="bluetooth_enable_gabeldorsche" msgid="9131730396242883416">"Gabeldorsche ফিচার চালু করুন"</string>
<string name="bluetooth_select_avrcp_version_string" msgid="1710571610177659127">"ব্লুটুথ AVRCP ভার্সন"</string>
<string name="bluetooth_select_avrcp_version_dialog_title" msgid="7846922290083709633">"ব্লুটুথ AVRCP ভার্সন বেছে নিন"</string>
+ <string name="bluetooth_select_map_version_string" msgid="526308145174175327">"ব্লুটুথ MAP ভার্সন"</string>
+ <string name="bluetooth_select_map_version_dialog_title" msgid="7085934373987428460">"ব্লুটুথ MAP ভার্সন বেছে নিন"</string>
<string name="bluetooth_select_a2dp_codec_type" msgid="952001408455456494">"ব্লুটুথ অডিও কোডেক"</string>
<string name="bluetooth_select_a2dp_codec_type_dialog_title" msgid="7510542404227225545">"ব্লুটুথ অডিও কোডেক ট্রিগার করুন\nএটি বেছে নেওয়া আছে"</string>
<string name="bluetooth_select_a2dp_codec_sample_rate" msgid="1638623076480928191">"ব্লুটুথ অডিওর নমুনা হার"</string>
@@ -276,7 +278,7 @@
<string name="verify_apps_over_usb_summary" msgid="1317933737581167839">"ক্ষতিকারক ক্রিয়াকলাপ করছে কিনা তার জন্য ADB/ADT মারফত ইনস্টল করা অ্যাপ্লিকেশানগুলি চেক করুন।"</string>
<string name="bluetooth_show_devices_without_names_summary" msgid="780964354377854507">"নামহীন ব্লুটুথ ডিভাইসগুলি দেখানো হবে (শুধুমাত্র MAC অ্যাড্রেস)"</string>
<string name="bluetooth_disable_absolute_volume_summary" msgid="2006309932135547681">"অপ্রত্যাশিত উচ্চ ভলিউম বা নিয়ন্ত্রণের অভাবের মত দূরবর্তী ডিভাইসের ভলিউম সমস্যাগুলির ক্ষেত্রে, ব্লুটুথ চুড়ান্ত ভলিউম বৈশিষ্ট্য অক্ষম করে৷"</string>
- <string name="bluetooth_enable_gabeldorsche_summary" msgid="8472344901097607030">"ব্লুটুথ Gabeldorche ফিচার স্ট্যাক চালু করা হয়েছে।"</string>
+ <string name="bluetooth_enable_gabeldorsche_summary" msgid="2054730331770712629">"ব্লুটুথ Gabeldorche ফিচার স্ট্যাক চালু করে।"</string>
<string name="enable_terminal_title" msgid="3834790541986303654">"স্থানীয় টার্মিনাল"</string>
<string name="enable_terminal_summary" msgid="2481074834856064500">"স্থানীয় শেল অ্যাক্সেসের প্রস্তাব করে এমন টার্মিনাল অ্যাপ্লিকেশন সক্ষম করুন"</string>
<string name="hdcp_checking_title" msgid="3155692785074095986">"HDCP পরীক্ষণ"</string>
diff --git a/packages/SettingsLib/res/values-bs/arrays.xml b/packages/SettingsLib/res/values-bs/arrays.xml
index d8b2bcd25fc1..6489cefdc551 100644
--- a/packages/SettingsLib/res/values-bs/arrays.xml
+++ b/packages/SettingsLib/res/values-bs/arrays.xml
@@ -75,6 +75,16 @@
<item msgid="4398977131424970917">"avrcp15"</item>
<item msgid="1963366694959681026">"avrcp16"</item>
</string-array>
+ <string-array name="bluetooth_map_versions">
+ <item msgid="8786402640610987099">"MAP 1.2 (Zadano)"</item>
+ <item msgid="6817922176194686449">"MAP 1.3"</item>
+ <item msgid="3423518690032737851">"MAP 1.4"</item>
+ </string-array>
+ <string-array name="bluetooth_map_version_values">
+ <item msgid="1164651830068248391">"map12"</item>
+ <item msgid="7073042887003102964">"map13"</item>
+ <item msgid="8147982633566548515">"map14"</item>
+ </string-array>
<string-array name="bluetooth_a2dp_codec_titles">
<item msgid="2494959071796102843">"Korištenje odabira sistema (zadano)"</item>
<item msgid="4055460186095649420">"SBC"</item>
diff --git a/packages/SettingsLib/res/values-bs/strings.xml b/packages/SettingsLib/res/values-bs/strings.xml
index f2446ad7ba07..f74bcee6fd08 100644
--- a/packages/SettingsLib/res/values-bs/strings.xml
+++ b/packages/SettingsLib/res/values-bs/strings.xml
@@ -230,6 +230,8 @@
<string name="bluetooth_enable_gabeldorsche" msgid="9131730396242883416">"Omogući Gabeldorsche"</string>
<string name="bluetooth_select_avrcp_version_string" msgid="1710571610177659127">"Bluetooth AVRCP verzija"</string>
<string name="bluetooth_select_avrcp_version_dialog_title" msgid="7846922290083709633">"Odaberite Bluetooth AVRCP verziju"</string>
+ <string name="bluetooth_select_map_version_string" msgid="526308145174175327">"Bluetooth MAP verzija"</string>
+ <string name="bluetooth_select_map_version_dialog_title" msgid="7085934373987428460">"Odaberite Bluetooth MAP verziju"</string>
<string name="bluetooth_select_a2dp_codec_type" msgid="952001408455456494">"Bluetooth Audio kodek"</string>
<string name="bluetooth_select_a2dp_codec_type_dialog_title" msgid="7510542404227225545">"Aktivirajte Bluetooth Audio Codec\nOdabir"</string>
<string name="bluetooth_select_a2dp_codec_sample_rate" msgid="1638623076480928191">"Brzina uzorkovanja za Bluetooth audio"</string>
@@ -276,7 +278,7 @@
<string name="verify_apps_over_usb_summary" msgid="1317933737581167839">"Provjerava da li se u aplikacijama instaliranim putem ADB-a/ADT-a javlja zlonamjerno ponašanje."</string>
<string name="bluetooth_show_devices_without_names_summary" msgid="780964354377854507">"Prikazat će se Bluetooth uređaji bez naziva (samo MAC adrese)"</string>
<string name="bluetooth_disable_absolute_volume_summary" msgid="2006309932135547681">"Onemogućava funkciju apsolutne jačine zvuka za Bluetooth u slučaju problema s jačinom zvuka na udaljenim uređajima, kao što je neprihvatljivo glasan zvuk ili nedostatak kontrole."</string>
- <string name="bluetooth_enable_gabeldorsche_summary" msgid="8472344901097607030">"Omogućava grupisanje funkcije Bluetooth Gabeldorsche."</string>
+ <string name="bluetooth_enable_gabeldorsche_summary" msgid="2054730331770712629">"Omogućava grupisanje funkcije Bluetooth Gabeldorsche."</string>
<string name="enable_terminal_title" msgid="3834790541986303654">"Lokalni terminal"</string>
<string name="enable_terminal_summary" msgid="2481074834856064500">"Omogući terminalnu aplik. koja nudi pristup lok. kom. okruženju"</string>
<string name="hdcp_checking_title" msgid="3155692785074095986">"HDCP provjera"</string>
diff --git a/packages/SettingsLib/res/values-ca/arrays.xml b/packages/SettingsLib/res/values-ca/arrays.xml
index 600a7ce6c808..950e469cef46 100644
--- a/packages/SettingsLib/res/values-ca/arrays.xml
+++ b/packages/SettingsLib/res/values-ca/arrays.xml
@@ -75,6 +75,16 @@
<item msgid="4398977131424970917">"avrcp15"</item>
<item msgid="1963366694959681026">"avrcp16"</item>
</string-array>
+ <string-array name="bluetooth_map_versions">
+ <item msgid="8786402640610987099">"MAP 1.2 (predeterminada)"</item>
+ <item msgid="6817922176194686449">"MAP 1.3"</item>
+ <item msgid="3423518690032737851">"MAP 1.4"</item>
+ </string-array>
+ <string-array name="bluetooth_map_version_values">
+ <item msgid="1164651830068248391">"map12"</item>
+ <item msgid="7073042887003102964">"map13"</item>
+ <item msgid="8147982633566548515">"map14"</item>
+ </string-array>
<string-array name="bluetooth_a2dp_codec_titles">
<item msgid="2494959071796102843">"Utilitza selecció del sistema (predeterminada)"</item>
<item msgid="4055460186095649420">"SBC"</item>
diff --git a/packages/SettingsLib/res/values-ca/strings.xml b/packages/SettingsLib/res/values-ca/strings.xml
index e33fd29e9a8c..1b23ecfd904b 100644
--- a/packages/SettingsLib/res/values-ca/strings.xml
+++ b/packages/SettingsLib/res/values-ca/strings.xml
@@ -230,6 +230,8 @@
<string name="bluetooth_enable_gabeldorsche" msgid="9131730396242883416">"Activa Gabeldorsche"</string>
<string name="bluetooth_select_avrcp_version_string" msgid="1710571610177659127">"Versió AVRCP de Bluetooth"</string>
<string name="bluetooth_select_avrcp_version_dialog_title" msgid="7846922290083709633">"Selecciona la versió AVRCP de Bluetooth"</string>
+ <string name="bluetooth_select_map_version_string" msgid="526308145174175327">"Versió MAP de Bluetooth"</string>
+ <string name="bluetooth_select_map_version_dialog_title" msgid="7085934373987428460">"Selecciona la versió MAP de Bluetooth"</string>
<string name="bluetooth_select_a2dp_codec_type" msgid="952001408455456494">"Còdec d\'àudio per Bluetooth"</string>
<string name="bluetooth_select_a2dp_codec_type_dialog_title" msgid="7510542404227225545">"Activa el còdec d\'àudio per Bluetooth\nSelecció"</string>
<string name="bluetooth_select_a2dp_codec_sample_rate" msgid="1638623076480928191">"Freqüència de mostratge d’àudio per Bluetooth"</string>
@@ -276,7 +278,7 @@
<string name="verify_apps_over_usb_summary" msgid="1317933737581167839">"Comprova les aplicacions instal·lades mitjançant ADB/ADT per detectar comportaments perillosos"</string>
<string name="bluetooth_show_devices_without_names_summary" msgid="780964354377854507">"Es mostraran els dispositius Bluetooth sense el nom (només l\'adreça MAC)"</string>
<string name="bluetooth_disable_absolute_volume_summary" msgid="2006309932135547681">"Desactiva la funció de volum absolut del Bluetooth en cas que es produeixin problemes de volum amb dispositius remots, com ara un volum massa alt o una manca de control."</string>
- <string name="bluetooth_enable_gabeldorsche_summary" msgid="8472344901097607030">"Activa el conjunt de funcions de Bluetooth Gabeldorsche."</string>
+ <string name="bluetooth_enable_gabeldorsche_summary" msgid="2054730331770712629">"Activa el conjunt de funcions de Bluetooth Gabeldorsche."</string>
<string name="enable_terminal_title" msgid="3834790541986303654">"Terminal local"</string>
<string name="enable_terminal_summary" msgid="2481074834856064500">"Activa l\'aplicació de terminal que ofereix accés al shell local"</string>
<string name="hdcp_checking_title" msgid="3155692785074095986">"Comprovació d\'HDCP"</string>
diff --git a/packages/SettingsLib/res/values-cs/arrays.xml b/packages/SettingsLib/res/values-cs/arrays.xml
index e7474a92c972..16358ee7b106 100644
--- a/packages/SettingsLib/res/values-cs/arrays.xml
+++ b/packages/SettingsLib/res/values-cs/arrays.xml
@@ -75,6 +75,16 @@
<item msgid="4398977131424970917">"avrcp15"</item>
<item msgid="1963366694959681026">"avrcp16"</item>
</string-array>
+ <string-array name="bluetooth_map_versions">
+ <item msgid="8786402640610987099">"MAP 1.2 (výchozí)"</item>
+ <item msgid="6817922176194686449">"MAP 1.3"</item>
+ <item msgid="3423518690032737851">"MAP 1.4"</item>
+ </string-array>
+ <string-array name="bluetooth_map_version_values">
+ <item msgid="1164651830068248391">"map12"</item>
+ <item msgid="7073042887003102964">"map13"</item>
+ <item msgid="8147982633566548515">"map14"</item>
+ </string-array>
<string-array name="bluetooth_a2dp_codec_titles">
<item msgid="2494959071796102843">"Použít systémový výběr (výchozí)"</item>
<item msgid="4055460186095649420">"SBC"</item>
diff --git a/packages/SettingsLib/res/values-cs/strings.xml b/packages/SettingsLib/res/values-cs/strings.xml
index e7875107cadb..22603ccdd804 100644
--- a/packages/SettingsLib/res/values-cs/strings.xml
+++ b/packages/SettingsLib/res/values-cs/strings.xml
@@ -230,6 +230,8 @@
<string name="bluetooth_enable_gabeldorsche" msgid="9131730396242883416">"Zapnout funkci Gabeldorsche"</string>
<string name="bluetooth_select_avrcp_version_string" msgid="1710571610177659127">"Verze profilu Bluetooth AVRCP"</string>
<string name="bluetooth_select_avrcp_version_dialog_title" msgid="7846922290083709633">"Vyberte verzi profilu Bluetooth AVRCP"</string>
+ <string name="bluetooth_select_map_version_string" msgid="526308145174175327">"Verze MAP pro Bluetooth"</string>
+ <string name="bluetooth_select_map_version_dialog_title" msgid="7085934373987428460">"Vyberte verzi MAP pro Bluetooth"</string>
<string name="bluetooth_select_a2dp_codec_type" msgid="952001408455456494">"Bluetooth Audio – kodek"</string>
<string name="bluetooth_select_a2dp_codec_type_dialog_title" msgid="7510542404227225545">"Spustit zvukový kodek Bluetooth\nVýběr"</string>
<string name="bluetooth_select_a2dp_codec_sample_rate" msgid="1638623076480928191">"Bluetooth Audio – vzorkovací frekvence"</string>
@@ -276,7 +278,7 @@
<string name="verify_apps_over_usb_summary" msgid="1317933737581167839">"Kontrolovat škodlivost aplikací nainstalovaných pomocí nástroje ADB/ADT"</string>
<string name="bluetooth_show_devices_without_names_summary" msgid="780964354377854507">"Zařízení Bluetooth se budou zobrazovat bez názvů (pouze adresy MAC)"</string>
<string name="bluetooth_disable_absolute_volume_summary" msgid="2006309932135547681">"Zakáže funkci absolutní hlasitosti Bluetooth. Zabrání tak problémům s hlasitostí vzdálených zařízení (jako je příliš vysoká hlasitost nebo nemožnost ovládání)."</string>
- <string name="bluetooth_enable_gabeldorsche_summary" msgid="8472344901097607030">"Zapnout sadu funkcí Bluetooth Gabeldorche."</string>
+ <string name="bluetooth_enable_gabeldorsche_summary" msgid="2054730331770712629">"Zapne sadu funkcí Bluetooth Gabeldorche."</string>
<string name="enable_terminal_title" msgid="3834790541986303654">"Místní terminál"</string>
<string name="enable_terminal_summary" msgid="2481074834856064500">"Aktivovat terminálovou aplikaci pro místní přístup k prostředí shell"</string>
<string name="hdcp_checking_title" msgid="3155692785074095986">"Kontrola HDCP"</string>
diff --git a/packages/SettingsLib/res/values-da/arrays.xml b/packages/SettingsLib/res/values-da/arrays.xml
index 0394562207a9..b3ce2572dbcf 100644
--- a/packages/SettingsLib/res/values-da/arrays.xml
+++ b/packages/SettingsLib/res/values-da/arrays.xml
@@ -75,6 +75,16 @@
<item msgid="4398977131424970917">"avrcp15"</item>
<item msgid="1963366694959681026">"avrcp16"</item>
</string-array>
+ <string-array name="bluetooth_map_versions">
+ <item msgid="8786402640610987099">"MAP 1.2 (standard)"</item>
+ <item msgid="6817922176194686449">"MAP 1.3"</item>
+ <item msgid="3423518690032737851">"MAP 1.4"</item>
+ </string-array>
+ <string-array name="bluetooth_map_version_values">
+ <item msgid="1164651830068248391">"map12"</item>
+ <item msgid="7073042887003102964">"map13"</item>
+ <item msgid="8147982633566548515">"map14"</item>
+ </string-array>
<string-array name="bluetooth_a2dp_codec_titles">
<item msgid="2494959071796102843">"Brug systemvalg (standard)"</item>
<item msgid="4055460186095649420">"SBC"</item>
diff --git a/packages/SettingsLib/res/values-da/strings.xml b/packages/SettingsLib/res/values-da/strings.xml
index 4e36e388026a..bef1855570a1 100644
--- a/packages/SettingsLib/res/values-da/strings.xml
+++ b/packages/SettingsLib/res/values-da/strings.xml
@@ -230,6 +230,8 @@
<string name="bluetooth_enable_gabeldorsche" msgid="9131730396242883416">"Aktivér Gabeldorsche"</string>
<string name="bluetooth_select_avrcp_version_string" msgid="1710571610177659127">"AVRCP-version for Bluetooth"</string>
<string name="bluetooth_select_avrcp_version_dialog_title" msgid="7846922290083709633">"Vælg AVRCP-version for Bluetooth"</string>
+ <string name="bluetooth_select_map_version_string" msgid="526308145174175327">"MAP-version for Bluetooth"</string>
+ <string name="bluetooth_select_map_version_dialog_title" msgid="7085934373987428460">"Vælg MAP-version for Bluetooth"</string>
<string name="bluetooth_select_a2dp_codec_type" msgid="952001408455456494">"Bluetooth-lydcodec"</string>
<string name="bluetooth_select_a2dp_codec_type_dialog_title" msgid="7510542404227225545">"Udløs codec for Bluetooth-lyd\nValg"</string>
<string name="bluetooth_select_a2dp_codec_sample_rate" msgid="1638623076480928191">"Eksempelfrekvens for Bluetooth-lyd"</string>
@@ -276,7 +278,7 @@
<string name="verify_apps_over_usb_summary" msgid="1317933737581167839">"Tjek apps, der er installeret via ADB/ADT, for skadelig adfærd."</string>
<string name="bluetooth_show_devices_without_names_summary" msgid="780964354377854507">"Bluetooth-enheder uden navne (kun MAC-adresser) vises"</string>
<string name="bluetooth_disable_absolute_volume_summary" msgid="2006309932135547681">"Deaktiverer funktionen til absolut lydstyrke via Bluetooth i tilfælde af problemer med lydstyrken på eksterne enheder, f.eks. uacceptabel høj lyd eller manglende kontrol."</string>
- <string name="bluetooth_enable_gabeldorsche_summary" msgid="8472344901097607030">"Aktiverer funktioner fra Bluetooth Gabeldorche"</string>
+ <string name="bluetooth_enable_gabeldorsche_summary" msgid="2054730331770712629">"Aktiverer funktioner fra Bluetooth Gabeldorsche."</string>
<string name="enable_terminal_title" msgid="3834790541986303654">"Lokal terminal"</string>
<string name="enable_terminal_summary" msgid="2481074834856064500">"Aktivér terminalappen, der giver lokal shell-adgang"</string>
<string name="hdcp_checking_title" msgid="3155692785074095986">"HDCP-kontrol"</string>
diff --git a/packages/SettingsLib/res/values-de/arrays.xml b/packages/SettingsLib/res/values-de/arrays.xml
index d7d3226d9bb4..fdd799c48913 100644
--- a/packages/SettingsLib/res/values-de/arrays.xml
+++ b/packages/SettingsLib/res/values-de/arrays.xml
@@ -75,6 +75,16 @@
<item msgid="4398977131424970917">"avrcp15"</item>
<item msgid="1963366694959681026">"avrcp16"</item>
</string-array>
+ <string-array name="bluetooth_map_versions">
+ <item msgid="8786402640610987099">"MAP 1.2 (Standard)"</item>
+ <item msgid="6817922176194686449">"MAP 1.3"</item>
+ <item msgid="3423518690032737851">"MAP 1.4"</item>
+ </string-array>
+ <string-array name="bluetooth_map_version_values">
+ <item msgid="1164651830068248391">"map12"</item>
+ <item msgid="7073042887003102964">"map13"</item>
+ <item msgid="8147982633566548515">"map14"</item>
+ </string-array>
<string-array name="bluetooth_a2dp_codec_titles">
<item msgid="2494959071796102843">"Systemauswahl verwenden (Standard)"</item>
<item msgid="4055460186095649420">"SBC"</item>
diff --git a/packages/SettingsLib/res/values-de/strings.xml b/packages/SettingsLib/res/values-de/strings.xml
index 63699065a651..c8c97bdf3d42 100644
--- a/packages/SettingsLib/res/values-de/strings.xml
+++ b/packages/SettingsLib/res/values-de/strings.xml
@@ -230,6 +230,8 @@
<string name="bluetooth_enable_gabeldorsche" msgid="9131730396242883416">"Bluetooth-Gabeldorsche aktivieren"</string>
<string name="bluetooth_select_avrcp_version_string" msgid="1710571610177659127">"Bluetooth AVRCP-Version"</string>
<string name="bluetooth_select_avrcp_version_dialog_title" msgid="7846922290083709633">"Bluetooth AVRCP-Version auswählen"</string>
+ <string name="bluetooth_select_map_version_string" msgid="526308145174175327">"Bluetooth MAP-Version"</string>
+ <string name="bluetooth_select_map_version_dialog_title" msgid="7085934373987428460">"Bluetooth MAP-Version auswählen"</string>
<string name="bluetooth_select_a2dp_codec_type" msgid="952001408455456494">"Bluetooth-Audio-Codec"</string>
<string name="bluetooth_select_a2dp_codec_type_dialog_title" msgid="7510542404227225545">"Bluetooth-Audio-Codec auslösen\nAuswahl"</string>
<string name="bluetooth_select_a2dp_codec_sample_rate" msgid="1638623076480928191">"Bluetooth-Audio-Abtastrate"</string>
@@ -276,7 +278,7 @@
<string name="verify_apps_over_usb_summary" msgid="1317933737581167839">"Über ADB/ADT installierte Apps werden auf schädliches Verhalten geprüft"</string>
<string name="bluetooth_show_devices_without_names_summary" msgid="780964354377854507">"Bluetooth-Geräte werden ohne Namen und nur mit ihren MAC-Adressen angezeigt"</string>
<string name="bluetooth_disable_absolute_volume_summary" msgid="2006309932135547681">"Deaktiviert die Funktion \"Absolute Lautstärkeregelung\" für Bluetooth-Geräte, falls auf Remote-Geräten Probleme mit der Lautstärke auftreten, wie beispielsweise übermäßig laute Wiedergabe oder fehlende Steuerungsmöglichkeiten."</string>
- <string name="bluetooth_enable_gabeldorsche_summary" msgid="8472344901097607030">"Aktiviert das Bluetooth-Gabeldorsche-Funktionspaket."</string>
+ <string name="bluetooth_enable_gabeldorsche_summary" msgid="2054730331770712629">"Aktiviert das Bluetooth-Gabeldorsche-Funktionspaket."</string>
<string name="enable_terminal_title" msgid="3834790541986303654">"Lokales Terminal"</string>
<string name="enable_terminal_summary" msgid="2481074834856064500">"Terminal-App mit Zugriff auf lokale Shell aktivieren"</string>
<string name="hdcp_checking_title" msgid="3155692785074095986">"HDCP-Prüfung"</string>
diff --git a/packages/SettingsLib/res/values-el/arrays.xml b/packages/SettingsLib/res/values-el/arrays.xml
index 5c4ef134776b..79f631fc27fc 100644
--- a/packages/SettingsLib/res/values-el/arrays.xml
+++ b/packages/SettingsLib/res/values-el/arrays.xml
@@ -75,6 +75,16 @@
<item msgid="4398977131424970917">"avrcp15"</item>
<item msgid="1963366694959681026">"avrcp16"</item>
</string-array>
+ <string-array name="bluetooth_map_versions">
+ <item msgid="8786402640610987099">"MAP 1.2 (Προεπιλογή)"</item>
+ <item msgid="6817922176194686449">"MAP 1.3"</item>
+ <item msgid="3423518690032737851">"MAP 1.4"</item>
+ </string-array>
+ <string-array name="bluetooth_map_version_values">
+ <item msgid="1164651830068248391">"map12"</item>
+ <item msgid="7073042887003102964">"map13"</item>
+ <item msgid="8147982633566548515">"map14"</item>
+ </string-array>
<string-array name="bluetooth_a2dp_codec_titles">
<item msgid="2494959071796102843">"Χρήση επιλογής συστήματος (Προεπιλογή)"</item>
<item msgid="4055460186095649420">"SBC"</item>
diff --git a/packages/SettingsLib/res/values-el/strings.xml b/packages/SettingsLib/res/values-el/strings.xml
index 194324f7de5c..371075c7acc0 100644
--- a/packages/SettingsLib/res/values-el/strings.xml
+++ b/packages/SettingsLib/res/values-el/strings.xml
@@ -230,6 +230,8 @@
<string name="bluetooth_enable_gabeldorsche" msgid="9131730396242883416">"Ενεργοποίηση Gabeldorsche"</string>
<string name="bluetooth_select_avrcp_version_string" msgid="1710571610177659127">"Έκδοση AVRCP Bluetooth"</string>
<string name="bluetooth_select_avrcp_version_dialog_title" msgid="7846922290083709633">"Επιλογή έκδοσης AVRCP Bluetooth"</string>
+ <string name="bluetooth_select_map_version_string" msgid="526308145174175327">"Έκδοση MAP Bluetooth"</string>
+ <string name="bluetooth_select_map_version_dialog_title" msgid="7085934373987428460">"Επιλογή έκδοσης MAP Bluetooth"</string>
<string name="bluetooth_select_a2dp_codec_type" msgid="952001408455456494">"Κωδικοποιητής ήχου Bluetooth"</string>
<string name="bluetooth_select_a2dp_codec_type_dialog_title" msgid="7510542404227225545">"Ενεργοποίηση κωδικοποιητή ήχου Bluetooth\nΕπιλογή"</string>
<string name="bluetooth_select_a2dp_codec_sample_rate" msgid="1638623076480928191">"Ρυθμός δειγματοληψίας ήχου Bluetooth"</string>
@@ -276,7 +278,7 @@
<string name="verify_apps_over_usb_summary" msgid="1317933737581167839">"Έλεγχος εφαρμογών που έχουν εγκατασταθεί μέσω ADB/ADT για επιβλαβή συμπεριφορά."</string>
<string name="bluetooth_show_devices_without_names_summary" msgid="780964354377854507">"Θα εμφανιστούν οι συσκευές Bluetooth χωρίς ονόματα (μόνο διευθύνσεις MAC)"</string>
<string name="bluetooth_disable_absolute_volume_summary" msgid="2006309932135547681">"Απενεργοποιεί τη δυνατότητα απόλυτης έντασης του Bluetooth σε περίπτωση προβλημάτων έντασης με απομακρυσμένες συσκευές, όπως όταν υπάρχει μη αποδεκτά υψηλή ένταση ή απουσία ελέγχου."</string>
- <string name="bluetooth_enable_gabeldorsche_summary" msgid="8472344901097607030">"Ενεργοποιεί τη στοίβα λειτουργιών Bluetooth Gabeldorche."</string>
+ <string name="bluetooth_enable_gabeldorsche_summary" msgid="2054730331770712629">"Ενεργοποιεί τη στοίβα λειτουργιών Bluetooth Gabeldorsche."</string>
<string name="enable_terminal_title" msgid="3834790541986303654">"Τοπική τερματική εφαρμογή"</string>
<string name="enable_terminal_summary" msgid="2481074834856064500">"Ενεργοπ.τερμ.εφαρμογής που προσφέρει πρόσβαση στο τοπικό κέλυφος"</string>
<string name="hdcp_checking_title" msgid="3155692785074095986">"Έλεγχος HDCP"</string>
diff --git a/packages/SettingsLib/res/values-en-rAU/arrays.xml b/packages/SettingsLib/res/values-en-rAU/arrays.xml
index ae1fb78d97f6..97e598e7600b 100644
--- a/packages/SettingsLib/res/values-en-rAU/arrays.xml
+++ b/packages/SettingsLib/res/values-en-rAU/arrays.xml
@@ -75,6 +75,16 @@
<item msgid="4398977131424970917">"avrcp15"</item>
<item msgid="1963366694959681026">"avrcp16"</item>
</string-array>
+ <string-array name="bluetooth_map_versions">
+ <item msgid="8786402640610987099">"MAP 1.2 (Default)"</item>
+ <item msgid="6817922176194686449">"MAP 1.3"</item>
+ <item msgid="3423518690032737851">"MAP 1.4"</item>
+ </string-array>
+ <string-array name="bluetooth_map_version_values">
+ <item msgid="1164651830068248391">"map12"</item>
+ <item msgid="7073042887003102964">"map13"</item>
+ <item msgid="8147982633566548515">"map14"</item>
+ </string-array>
<string-array name="bluetooth_a2dp_codec_titles">
<item msgid="2494959071796102843">"Use system selection (default)"</item>
<item msgid="4055460186095649420">"SBC"</item>
diff --git a/packages/SettingsLib/res/values-en-rAU/strings.xml b/packages/SettingsLib/res/values-en-rAU/strings.xml
index 92ed8e5359b6..b314d1782585 100644
--- a/packages/SettingsLib/res/values-en-rAU/strings.xml
+++ b/packages/SettingsLib/res/values-en-rAU/strings.xml
@@ -230,6 +230,8 @@
<string name="bluetooth_enable_gabeldorsche" msgid="9131730396242883416">"Enable Gabeldorsche"</string>
<string name="bluetooth_select_avrcp_version_string" msgid="1710571610177659127">"Bluetooth AVRCP version"</string>
<string name="bluetooth_select_avrcp_version_dialog_title" msgid="7846922290083709633">"Select Bluetooth AVRCP Version"</string>
+ <string name="bluetooth_select_map_version_string" msgid="526308145174175327">"Bluetooth MAP version"</string>
+ <string name="bluetooth_select_map_version_dialog_title" msgid="7085934373987428460">"Select Bluetooth MAP version"</string>
<string name="bluetooth_select_a2dp_codec_type" msgid="952001408455456494">"Bluetooth audio codec"</string>
<string name="bluetooth_select_a2dp_codec_type_dialog_title" msgid="7510542404227225545">"Trigger Bluetooth Audio Codec\nSelection"</string>
<string name="bluetooth_select_a2dp_codec_sample_rate" msgid="1638623076480928191">"Bluetooth audio sample rate"</string>
@@ -276,7 +278,7 @@
<string name="verify_apps_over_usb_summary" msgid="1317933737581167839">"Check apps installed via ADB/ADT for harmful behaviour."</string>
<string name="bluetooth_show_devices_without_names_summary" msgid="780964354377854507">"Bluetooth devices without names (MAC addresses only) will be displayed"</string>
<string name="bluetooth_disable_absolute_volume_summary" msgid="2006309932135547681">"Disables the Bluetooth absolute volume feature in case of volume issues with remote devices such as unacceptably loud volume or lack of control."</string>
- <string name="bluetooth_enable_gabeldorsche_summary" msgid="8472344901097607030">"Enables the Bluetooth Gabeldorsche feature stack."</string>
+ <string name="bluetooth_enable_gabeldorsche_summary" msgid="2054730331770712629">"Enables the Bluetooth Gabeldorsche feature stack."</string>
<string name="enable_terminal_title" msgid="3834790541986303654">"Local terminal"</string>
<string name="enable_terminal_summary" msgid="2481074834856064500">"Enable terminal app that offers local shell access"</string>
<string name="hdcp_checking_title" msgid="3155692785074095986">"HDCP checking"</string>
diff --git a/packages/SettingsLib/res/values-en-rCA/arrays.xml b/packages/SettingsLib/res/values-en-rCA/arrays.xml
index ae1fb78d97f6..97e598e7600b 100644
--- a/packages/SettingsLib/res/values-en-rCA/arrays.xml
+++ b/packages/SettingsLib/res/values-en-rCA/arrays.xml
@@ -75,6 +75,16 @@
<item msgid="4398977131424970917">"avrcp15"</item>
<item msgid="1963366694959681026">"avrcp16"</item>
</string-array>
+ <string-array name="bluetooth_map_versions">
+ <item msgid="8786402640610987099">"MAP 1.2 (Default)"</item>
+ <item msgid="6817922176194686449">"MAP 1.3"</item>
+ <item msgid="3423518690032737851">"MAP 1.4"</item>
+ </string-array>
+ <string-array name="bluetooth_map_version_values">
+ <item msgid="1164651830068248391">"map12"</item>
+ <item msgid="7073042887003102964">"map13"</item>
+ <item msgid="8147982633566548515">"map14"</item>
+ </string-array>
<string-array name="bluetooth_a2dp_codec_titles">
<item msgid="2494959071796102843">"Use system selection (default)"</item>
<item msgid="4055460186095649420">"SBC"</item>
diff --git a/packages/SettingsLib/res/values-en-rCA/strings.xml b/packages/SettingsLib/res/values-en-rCA/strings.xml
index 92ed8e5359b6..b314d1782585 100644
--- a/packages/SettingsLib/res/values-en-rCA/strings.xml
+++ b/packages/SettingsLib/res/values-en-rCA/strings.xml
@@ -230,6 +230,8 @@
<string name="bluetooth_enable_gabeldorsche" msgid="9131730396242883416">"Enable Gabeldorsche"</string>
<string name="bluetooth_select_avrcp_version_string" msgid="1710571610177659127">"Bluetooth AVRCP version"</string>
<string name="bluetooth_select_avrcp_version_dialog_title" msgid="7846922290083709633">"Select Bluetooth AVRCP Version"</string>
+ <string name="bluetooth_select_map_version_string" msgid="526308145174175327">"Bluetooth MAP version"</string>
+ <string name="bluetooth_select_map_version_dialog_title" msgid="7085934373987428460">"Select Bluetooth MAP version"</string>
<string name="bluetooth_select_a2dp_codec_type" msgid="952001408455456494">"Bluetooth audio codec"</string>
<string name="bluetooth_select_a2dp_codec_type_dialog_title" msgid="7510542404227225545">"Trigger Bluetooth Audio Codec\nSelection"</string>
<string name="bluetooth_select_a2dp_codec_sample_rate" msgid="1638623076480928191">"Bluetooth audio sample rate"</string>
@@ -276,7 +278,7 @@
<string name="verify_apps_over_usb_summary" msgid="1317933737581167839">"Check apps installed via ADB/ADT for harmful behaviour."</string>
<string name="bluetooth_show_devices_without_names_summary" msgid="780964354377854507">"Bluetooth devices without names (MAC addresses only) will be displayed"</string>
<string name="bluetooth_disable_absolute_volume_summary" msgid="2006309932135547681">"Disables the Bluetooth absolute volume feature in case of volume issues with remote devices such as unacceptably loud volume or lack of control."</string>
- <string name="bluetooth_enable_gabeldorsche_summary" msgid="8472344901097607030">"Enables the Bluetooth Gabeldorsche feature stack."</string>
+ <string name="bluetooth_enable_gabeldorsche_summary" msgid="2054730331770712629">"Enables the Bluetooth Gabeldorsche feature stack."</string>
<string name="enable_terminal_title" msgid="3834790541986303654">"Local terminal"</string>
<string name="enable_terminal_summary" msgid="2481074834856064500">"Enable terminal app that offers local shell access"</string>
<string name="hdcp_checking_title" msgid="3155692785074095986">"HDCP checking"</string>
diff --git a/packages/SettingsLib/res/values-en-rGB/arrays.xml b/packages/SettingsLib/res/values-en-rGB/arrays.xml
index ae1fb78d97f6..97e598e7600b 100644
--- a/packages/SettingsLib/res/values-en-rGB/arrays.xml
+++ b/packages/SettingsLib/res/values-en-rGB/arrays.xml
@@ -75,6 +75,16 @@
<item msgid="4398977131424970917">"avrcp15"</item>
<item msgid="1963366694959681026">"avrcp16"</item>
</string-array>
+ <string-array name="bluetooth_map_versions">
+ <item msgid="8786402640610987099">"MAP 1.2 (Default)"</item>
+ <item msgid="6817922176194686449">"MAP 1.3"</item>
+ <item msgid="3423518690032737851">"MAP 1.4"</item>
+ </string-array>
+ <string-array name="bluetooth_map_version_values">
+ <item msgid="1164651830068248391">"map12"</item>
+ <item msgid="7073042887003102964">"map13"</item>
+ <item msgid="8147982633566548515">"map14"</item>
+ </string-array>
<string-array name="bluetooth_a2dp_codec_titles">
<item msgid="2494959071796102843">"Use system selection (default)"</item>
<item msgid="4055460186095649420">"SBC"</item>
diff --git a/packages/SettingsLib/res/values-en-rGB/strings.xml b/packages/SettingsLib/res/values-en-rGB/strings.xml
index 92ed8e5359b6..b314d1782585 100644
--- a/packages/SettingsLib/res/values-en-rGB/strings.xml
+++ b/packages/SettingsLib/res/values-en-rGB/strings.xml
@@ -230,6 +230,8 @@
<string name="bluetooth_enable_gabeldorsche" msgid="9131730396242883416">"Enable Gabeldorsche"</string>
<string name="bluetooth_select_avrcp_version_string" msgid="1710571610177659127">"Bluetooth AVRCP version"</string>
<string name="bluetooth_select_avrcp_version_dialog_title" msgid="7846922290083709633">"Select Bluetooth AVRCP Version"</string>
+ <string name="bluetooth_select_map_version_string" msgid="526308145174175327">"Bluetooth MAP version"</string>
+ <string name="bluetooth_select_map_version_dialog_title" msgid="7085934373987428460">"Select Bluetooth MAP version"</string>
<string name="bluetooth_select_a2dp_codec_type" msgid="952001408455456494">"Bluetooth audio codec"</string>
<string name="bluetooth_select_a2dp_codec_type_dialog_title" msgid="7510542404227225545">"Trigger Bluetooth Audio Codec\nSelection"</string>
<string name="bluetooth_select_a2dp_codec_sample_rate" msgid="1638623076480928191">"Bluetooth audio sample rate"</string>
@@ -276,7 +278,7 @@
<string name="verify_apps_over_usb_summary" msgid="1317933737581167839">"Check apps installed via ADB/ADT for harmful behaviour."</string>
<string name="bluetooth_show_devices_without_names_summary" msgid="780964354377854507">"Bluetooth devices without names (MAC addresses only) will be displayed"</string>
<string name="bluetooth_disable_absolute_volume_summary" msgid="2006309932135547681">"Disables the Bluetooth absolute volume feature in case of volume issues with remote devices such as unacceptably loud volume or lack of control."</string>
- <string name="bluetooth_enable_gabeldorsche_summary" msgid="8472344901097607030">"Enables the Bluetooth Gabeldorsche feature stack."</string>
+ <string name="bluetooth_enable_gabeldorsche_summary" msgid="2054730331770712629">"Enables the Bluetooth Gabeldorsche feature stack."</string>
<string name="enable_terminal_title" msgid="3834790541986303654">"Local terminal"</string>
<string name="enable_terminal_summary" msgid="2481074834856064500">"Enable terminal app that offers local shell access"</string>
<string name="hdcp_checking_title" msgid="3155692785074095986">"HDCP checking"</string>
diff --git a/packages/SettingsLib/res/values-en-rIN/arrays.xml b/packages/SettingsLib/res/values-en-rIN/arrays.xml
index ae1fb78d97f6..97e598e7600b 100644
--- a/packages/SettingsLib/res/values-en-rIN/arrays.xml
+++ b/packages/SettingsLib/res/values-en-rIN/arrays.xml
@@ -75,6 +75,16 @@
<item msgid="4398977131424970917">"avrcp15"</item>
<item msgid="1963366694959681026">"avrcp16"</item>
</string-array>
+ <string-array name="bluetooth_map_versions">
+ <item msgid="8786402640610987099">"MAP 1.2 (Default)"</item>
+ <item msgid="6817922176194686449">"MAP 1.3"</item>
+ <item msgid="3423518690032737851">"MAP 1.4"</item>
+ </string-array>
+ <string-array name="bluetooth_map_version_values">
+ <item msgid="1164651830068248391">"map12"</item>
+ <item msgid="7073042887003102964">"map13"</item>
+ <item msgid="8147982633566548515">"map14"</item>
+ </string-array>
<string-array name="bluetooth_a2dp_codec_titles">
<item msgid="2494959071796102843">"Use system selection (default)"</item>
<item msgid="4055460186095649420">"SBC"</item>
diff --git a/packages/SettingsLib/res/values-en-rIN/strings.xml b/packages/SettingsLib/res/values-en-rIN/strings.xml
index 92ed8e5359b6..b314d1782585 100644
--- a/packages/SettingsLib/res/values-en-rIN/strings.xml
+++ b/packages/SettingsLib/res/values-en-rIN/strings.xml
@@ -230,6 +230,8 @@
<string name="bluetooth_enable_gabeldorsche" msgid="9131730396242883416">"Enable Gabeldorsche"</string>
<string name="bluetooth_select_avrcp_version_string" msgid="1710571610177659127">"Bluetooth AVRCP version"</string>
<string name="bluetooth_select_avrcp_version_dialog_title" msgid="7846922290083709633">"Select Bluetooth AVRCP Version"</string>
+ <string name="bluetooth_select_map_version_string" msgid="526308145174175327">"Bluetooth MAP version"</string>
+ <string name="bluetooth_select_map_version_dialog_title" msgid="7085934373987428460">"Select Bluetooth MAP version"</string>
<string name="bluetooth_select_a2dp_codec_type" msgid="952001408455456494">"Bluetooth audio codec"</string>
<string name="bluetooth_select_a2dp_codec_type_dialog_title" msgid="7510542404227225545">"Trigger Bluetooth Audio Codec\nSelection"</string>
<string name="bluetooth_select_a2dp_codec_sample_rate" msgid="1638623076480928191">"Bluetooth audio sample rate"</string>
@@ -276,7 +278,7 @@
<string name="verify_apps_over_usb_summary" msgid="1317933737581167839">"Check apps installed via ADB/ADT for harmful behaviour."</string>
<string name="bluetooth_show_devices_without_names_summary" msgid="780964354377854507">"Bluetooth devices without names (MAC addresses only) will be displayed"</string>
<string name="bluetooth_disable_absolute_volume_summary" msgid="2006309932135547681">"Disables the Bluetooth absolute volume feature in case of volume issues with remote devices such as unacceptably loud volume or lack of control."</string>
- <string name="bluetooth_enable_gabeldorsche_summary" msgid="8472344901097607030">"Enables the Bluetooth Gabeldorsche feature stack."</string>
+ <string name="bluetooth_enable_gabeldorsche_summary" msgid="2054730331770712629">"Enables the Bluetooth Gabeldorsche feature stack."</string>
<string name="enable_terminal_title" msgid="3834790541986303654">"Local terminal"</string>
<string name="enable_terminal_summary" msgid="2481074834856064500">"Enable terminal app that offers local shell access"</string>
<string name="hdcp_checking_title" msgid="3155692785074095986">"HDCP checking"</string>
diff --git a/packages/SettingsLib/res/values-en-rXC/arrays.xml b/packages/SettingsLib/res/values-en-rXC/arrays.xml
index af5d7f3d943e..eca7c75fc3b7 100644
--- a/packages/SettingsLib/res/values-en-rXC/arrays.xml
+++ b/packages/SettingsLib/res/values-en-rXC/arrays.xml
@@ -75,6 +75,16 @@
<item msgid="4398977131424970917">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‏‎‏‏‏‏‏‎‏‏‏‏‎‏‎‎‎‎‏‏‎‎‎‏‎‎‏‏‏‎‎‏‏‎‎‏‎‎‏‏‏‎‏‏‎‏‏‎‏‎‎‏‏‎‏‏‏‏‏‎‎‎‏‎‏‎‎‏‎‏‎avrcp15‎‏‎‎‏‎"</item>
<item msgid="1963366694959681026">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‏‎‏‏‏‏‎‏‏‏‎‏‏‎‎‏‏‏‏‏‏‎‏‎‎‎‏‏‏‏‎‎‏‏‎‏‏‎‏‎‏‎‎‎‎‏‏‏‎‎‏‏‏‏‎‎‎‏‏‏‎‎‎‎‎‎‎‏‎‎avrcp16‎‏‎‎‏‎"</item>
</string-array>
+ <string-array name="bluetooth_map_versions">
+ <item msgid="8786402640610987099">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‏‎‏‏‏‏‏‏‏‏‏‏‎‎‏‏‏‏‎‏‏‏‏‏‎‎‏‎‎‏‎‏‎‏‎‎‏‏‎‎‎‏‏‎‏‏‏‎‎‏‎‏‏‎‎‎‎‎‎‏‏‎‎‎‏‎‏‏‎‏‏‎MAP 1.2 (Default)‎‏‎‎‏‎"</item>
+ <item msgid="6817922176194686449">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‏‎‏‏‏‏‏‏‏‎‏‏‏‏‎‏‎‎‏‏‏‏‎‎‎‏‎‎‎‎‎‎‎‎‏‏‎‎‎‏‎‏‎‏‎‏‎‎‏‎‏‎‏‏‏‏‎‏‎‏‏‎‏‏‏‏‏‎‎‎‏‎MAP 1.3‎‏‎‎‏‎"</item>
+ <item msgid="3423518690032737851">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‏‎‏‏‏‏‏‎‏‎‏‏‏‏‏‎‎‎‎‎‏‎‏‏‎‎‏‎‎‎‎‎‎‏‏‏‎‎‎‎‏‎‏‎‎‏‎‏‎‎‏‏‏‏‏‏‎‏‏‏‏‎‎‎‏‏‏‎‏‏‎MAP 1.4‎‏‎‎‏‎"</item>
+ </string-array>
+ <string-array name="bluetooth_map_version_values">
+ <item msgid="1164651830068248391">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‏‎‏‏‏‏‎‏‏‎‎‎‎‎‎‏‎‏‎‎‏‏‎‏‎‏‏‎‎‏‎‏‎‏‎‏‏‎‎‏‏‏‎‏‎‎‎‏‏‏‎‎‏‏‏‏‏‏‏‏‏‎‏‎‎‎‏‏‏‎map12‎‏‎‎‏‎"</item>
+ <item msgid="7073042887003102964">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‏‎‏‏‏‏‏‏‏‏‎‎‎‏‎‎‎‏‎‏‎‎‎‎‏‏‏‏‏‏‏‎‎‎‎‎‏‏‏‏‏‏‏‏‎‎‎‏‏‏‎‏‏‎‎‎‏‎‏‏‏‏‎‏‏‏‏‎‏‎‎‎map13‎‏‎‎‏‎"</item>
+ <item msgid="8147982633566548515">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‏‎‏‏‏‏‏‏‏‏‏‎‎‎‏‎‎‎‏‎‎‏‏‎‏‏‏‎‎‏‏‎‎‎‎‏‎‎‏‎‎‎‎‏‏‎‏‏‏‎‎‏‎‎‏‎‎‏‏‎‎‏‎‎‎‏‎‎‎‏‏‎map14‎‏‎‎‏‎"</item>
+ </string-array>
<string-array name="bluetooth_a2dp_codec_titles">
<item msgid="2494959071796102843">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‏‎‏‏‏‏‏‎‏‎‎‎‏‎‏‎‎‏‏‏‏‏‏‏‏‎‎‎‎‎‎‎‎‎‏‏‏‎‏‎‎‏‎‎‏‏‏‎‎‎‏‎‏‏‏‎‎‎‎‏‏‎‏‎‏‏‏‎‏‏‎Use System Selection (Default)‎‏‎‎‏‎"</item>
<item msgid="4055460186095649420">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‏‎‏‏‏‏‏‎‏‏‏‎‎‎‎‏‎‎‎‏‏‏‏‏‏‎‎‎‏‏‏‎‎‎‏‏‎‏‎‏‏‏‎‎‎‎‏‏‏‏‏‎‎‎‏‎‎‎‎‎‏‎‏‎‎‎‏‏‎‎‎SBC‎‏‎‎‏‎"</item>
diff --git a/packages/SettingsLib/res/values-en-rXC/strings.xml b/packages/SettingsLib/res/values-en-rXC/strings.xml
index 9813efd14427..95944dc9eae1 100644
--- a/packages/SettingsLib/res/values-en-rXC/strings.xml
+++ b/packages/SettingsLib/res/values-en-rXC/strings.xml
@@ -230,6 +230,8 @@
<string name="bluetooth_enable_gabeldorsche" msgid="9131730396242883416">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‏‎‏‏‏‏‏‏‏‏‏‏‏‏‎‏‎‏‏‏‎‏‎‎‏‏‎‏‏‎‎‎‏‏‎‏‎‎‏‏‏‎‏‎‏‎‎‏‎‏‏‎‎‎‏‏‎‏‏‎‎‏‏‎‏‎‏‏‎‎‎‎Enable Gabeldorsche‎‏‎‎‏‎"</string>
<string name="bluetooth_select_avrcp_version_string" msgid="1710571610177659127">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‏‎‏‏‏‏‎‏‏‎‏‏‏‏‎‏‏‏‏‎‏‎‎‏‎‏‎‏‏‏‏‎‏‎‎‎‏‎‎‎‎‎‎‏‏‏‎‎‎‎‎‎‏‏‏‏‎‎‎‎‎‏‏‏‏‎‏‏‏‎Bluetooth AVRCP Version‎‏‎‎‏‎"</string>
<string name="bluetooth_select_avrcp_version_dialog_title" msgid="7846922290083709633">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‏‎‏‏‏‏‏‏‏‏‎‏‏‎‎‏‏‏‎‎‏‎‏‏‏‎‏‏‏‏‎‎‎‏‏‏‏‏‏‏‎‎‎‎‎‎‎‏‎‎‎‏‎‎‎‏‏‎‎‎‎‏‎‏‏‎‎‎‎‎‏‎Select Bluetooth AVRCP Version‎‏‎‎‏‎"</string>
+ <string name="bluetooth_select_map_version_string" msgid="526308145174175327">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‏‎‏‏‏‎‏‏‏‏‏‎‏‎‎‏‏‎‏‏‏‎‏‎‎‏‎‎‏‏‏‏‎‎‎‎‎‏‏‎‎‏‏‏‎‎‎‎‎‎‎‎‏‎‏‏‏‏‎‎‏‎‏‏‏‏‏‎Bluetooth MAP Version‎‏‎‎‏‎"</string>
+ <string name="bluetooth_select_map_version_dialog_title" msgid="7085934373987428460">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‏‎‏‏‏‏‏‏‏‏‎‎‎‏‎‎‏‎‏‎‏‏‎‎‏‎‎‏‎‏‏‏‏‎‎‎‏‎‏‎‎‏‎‏‏‏‏‎‏‎‎‎‎‎‎‎‎‏‎‏‎‎‎‎‏‏‎‏‏‎‎‎Select Bluetooth MAP Version‎‏‎‎‏‎"</string>
<string name="bluetooth_select_a2dp_codec_type" msgid="952001408455456494">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‏‎‏‏‏‏‎‎‏‏‎‏‎‎‏‏‎‏‏‎‎‎‏‏‎‎‎‎‎‎‏‏‏‏‎‎‏‎‏‏‎‎‎‎‏‎‏‎‏‎‎‎‏‎‏‏‎‏‏‎‏‏‏‎‏‏‏‎‎Bluetooth Audio Codec‎‏‎‎‏‎"</string>
<string name="bluetooth_select_a2dp_codec_type_dialog_title" msgid="7510542404227225545">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‏‎‏‏‏‏‏‏‏‏‎‏‎‎‎‎‎‏‏‏‎‏‎‏‏‎‎‏‏‏‎‏‎‎‎‎‏‏‎‎‎‏‎‏‎‏‎‎‏‏‏‏‎‎‎‏‏‎‏‎‏‏‏‏‏‎‎‏‎‎‏‎Trigger Bluetooth Audio Codec‎‏‎‎‏‏‎\n‎‏‎‎‏‏‏‎Selection‎‏‎‎‏‎"</string>
<string name="bluetooth_select_a2dp_codec_sample_rate" msgid="1638623076480928191">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‏‎‏‏‏‏‎‏‏‎‏‏‎‏‎‏‏‏‏‎‏‏‎‎‎‏‏‏‏‎‎‎‎‎‎‎‏‏‎‎‏‏‎‏‎‎‏‏‎‎‏‏‏‎‏‎‎‏‎‎‏‏‎‏‏‏‏‏‏‎Bluetooth Audio Sample Rate‎‏‎‎‏‎"</string>
@@ -276,7 +278,7 @@
<string name="verify_apps_over_usb_summary" msgid="1317933737581167839">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‏‎‏‏‏‏‎‏‏‎‎‏‎‎‏‎‎‏‎‏‎‎‎‏‏‏‏‎‏‏‏‎‎‎‎‎‎‎‏‏‎‏‎‏‎‎‎‎‎‎‏‏‏‎‏‎‎‎‏‎‎‏‏‎‏‏‏‏‏‎Check apps installed via ADB/ADT for harmful behavior.‎‏‎‎‏‎"</string>
<string name="bluetooth_show_devices_without_names_summary" msgid="780964354377854507">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‏‎‏‏‏‏‎‎‏‎‏‎‏‏‎‏‎‏‏‎‏‎‎‎‏‎‏‎‏‏‏‏‎‎‎‏‎‏‎‎‏‏‎‎‏‏‏‎‏‏‏‏‎‎‏‎‏‏‏‎‎‎‏‎‏‎‏‏‎Bluetooth devices without names (MAC addresses only) will be displayed‎‏‎‎‏‎"</string>
<string name="bluetooth_disable_absolute_volume_summary" msgid="2006309932135547681">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‏‎‏‏‏‏‎‏‏‏‎‏‏‏‏‎‏‎‏‏‏‏‏‎‏‏‎‎‎‎‏‎‎‎‎‎‎‏‏‎‏‏‏‏‎‎‏‎‎‎‏‏‏‎‎‎‎‎‎‏‏‎‎‏‎‎‎‎‏‎Disables the Bluetooth absolute volume feature in case of volume issues with remote devices such as unacceptably loud volume or lack of control.‎‏‎‎‏‎"</string>
- <string name="bluetooth_enable_gabeldorsche_summary" msgid="8472344901097607030">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‏‎‏‏‏‏‏‏‏‏‏‎‏‎‏‏‎‎‏‎‎‏‏‏‏‎‏‎‎‎‎‏‏‎‎‏‏‎‎‏‎‎‏‎‏‎‎‏‎‎‎‎‎‏‏‏‏‎‎‏‏‏‏‎‏‏‏‎‏‏‎‎Enables the Bluetooth Gabeldorche feature stack.‎‏‎‎‏‎"</string>
+ <string name="bluetooth_enable_gabeldorsche_summary" msgid="2054730331770712629">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‏‎‏‏‏‏‎‏‏‏‏‎‎‏‎‎‎‎‎‏‏‏‏‎‏‏‏‏‎‎‏‎‏‏‎‎‏‏‎‏‎‏‏‏‎‎‏‏‎‏‎‎‏‏‏‏‏‎‎‏‎‎‎‏‏‎‏‎‏‎Enables the Bluetooth Gabeldorsche feature stack.‎‏‎‎‏‎"</string>
<string name="enable_terminal_title" msgid="3834790541986303654">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‏‎‏‏‏‏‏‎‏‏‎‏‎‏‎‎‏‏‎‏‏‏‏‏‏‎‏‎‎‏‏‎‏‎‏‏‏‎‎‎‏‎‏‎‏‏‎‎‎‏‏‏‏‏‎‎‎‎‏‏‏‎‏‎‏‎‎‏‏‎‎Local terminal‎‏‎‎‏‎"</string>
<string name="enable_terminal_summary" msgid="2481074834856064500">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‏‎‏‏‏‏‏‎‏‎‎‎‏‎‎‏‏‎‏‏‏‎‏‎‎‎‏‏‎‎‎‏‏‎‏‎‏‎‏‏‎‎‎‎‎‎‏‏‎‎‎‎‎‏‏‎‏‏‎‏‎‏‏‏‏‏‎‏‎‎‎Enable terminal app that offers local shell access‎‏‎‎‏‎"</string>
<string name="hdcp_checking_title" msgid="3155692785074095986">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‏‎‏‏‏‏‏‎‏‎‏‎‏‏‏‏‎‎‏‎‏‏‎‏‎‎‎‏‎‏‏‏‎‏‏‏‏‎‎‏‎‏‎‎‏‎‏‎‎‏‏‎‏‎‏‏‎‎‎‏‏‏‎‏‏‏‎‎‏‎‎HDCP checking‎‏‎‎‏‎"</string>
diff --git a/packages/SettingsLib/res/values-es-rUS/arrays.xml b/packages/SettingsLib/res/values-es-rUS/arrays.xml
index d37ffb781087..ad58235abc04 100644
--- a/packages/SettingsLib/res/values-es-rUS/arrays.xml
+++ b/packages/SettingsLib/res/values-es-rUS/arrays.xml
@@ -75,6 +75,16 @@
<item msgid="4398977131424970917">"avrcp15"</item>
<item msgid="1963366694959681026">"avrcp16"</item>
</string-array>
+ <string-array name="bluetooth_map_versions">
+ <item msgid="8786402640610987099">"MAP 1.2 (predeterminado)"</item>
+ <item msgid="6817922176194686449">"MAP 1.3"</item>
+ <item msgid="3423518690032737851">"MAP 1.4"</item>
+ </string-array>
+ <string-array name="bluetooth_map_version_values">
+ <item msgid="1164651830068248391">"map12"</item>
+ <item msgid="7073042887003102964">"map13"</item>
+ <item msgid="8147982633566548515">"map14"</item>
+ </string-array>
<string-array name="bluetooth_a2dp_codec_titles">
<item msgid="2494959071796102843">"Usar selección del sistema (predeterminado)"</item>
<item msgid="4055460186095649420">"SBC"</item>
diff --git a/packages/SettingsLib/res/values-es-rUS/strings.xml b/packages/SettingsLib/res/values-es-rUS/strings.xml
index 8899c072bf5b..c6dfdd3e3ac2 100644
--- a/packages/SettingsLib/res/values-es-rUS/strings.xml
+++ b/packages/SettingsLib/res/values-es-rUS/strings.xml
@@ -230,6 +230,8 @@
<string name="bluetooth_enable_gabeldorsche" msgid="9131730396242883416">"Habilitar Gabeldorsche"</string>
<string name="bluetooth_select_avrcp_version_string" msgid="1710571610177659127">"Versión de AVRCP del Bluetooth"</string>
<string name="bluetooth_select_avrcp_version_dialog_title" msgid="7846922290083709633">"Selecciona la versión de AVRCP del Bluetooth"</string>
+ <string name="bluetooth_select_map_version_string" msgid="526308145174175327">"Versión de MAP de Bluetooth"</string>
+ <string name="bluetooth_select_map_version_dialog_title" msgid="7085934373987428460">"Seleccionar versión de MAP de Bluetooth"</string>
<string name="bluetooth_select_a2dp_codec_type" msgid="952001408455456494">"Códec del audio Bluetooth"</string>
<string name="bluetooth_select_a2dp_codec_type_dialog_title" msgid="7510542404227225545">"Activar el códec de audio por Bluetooth\nSelección"</string>
<string name="bluetooth_select_a2dp_codec_sample_rate" msgid="1638623076480928191">"Frecuencia de muestreo del audio Bluetooth"</string>
@@ -276,7 +278,7 @@
<string name="verify_apps_over_usb_summary" msgid="1317933737581167839">"Comprobar que las aplicaciones instaladas mediante ADB/ADT no ocasionen daños"</string>
<string name="bluetooth_show_devices_without_names_summary" msgid="780964354377854507">"Se mostrarán los dispositivos Bluetooth sin nombre (solo direcciones MAC)"</string>
<string name="bluetooth_disable_absolute_volume_summary" msgid="2006309932135547681">"Inhabilita la función de volumen absoluto de Bluetooth si se producen problemas de volumen con dispositivos remotos (por ejemplo, volumen demasiado alto o falta de control)."</string>
- <string name="bluetooth_enable_gabeldorsche_summary" msgid="8472344901097607030">"Habilita la pila de funciones de Bluetooth Gabeldorsche."</string>
+ <string name="bluetooth_enable_gabeldorsche_summary" msgid="2054730331770712629">"Habilita la pila de funciones de Bluetooth Gabeldorsche"</string>
<string name="enable_terminal_title" msgid="3834790541986303654">"Terminal local"</string>
<string name="enable_terminal_summary" msgid="2481074834856064500">"Habilitar aplicac. de terminal que ofrece acceso al shell local"</string>
<string name="hdcp_checking_title" msgid="3155692785074095986">"Comprobación HDCP"</string>
diff --git a/packages/SettingsLib/res/values-es/arrays.xml b/packages/SettingsLib/res/values-es/arrays.xml
index 04d4b2de5c87..a403e3e6519e 100644
--- a/packages/SettingsLib/res/values-es/arrays.xml
+++ b/packages/SettingsLib/res/values-es/arrays.xml
@@ -75,6 +75,16 @@
<item msgid="4398977131424970917">"avrcp15"</item>
<item msgid="1963366694959681026">"avrcp16"</item>
</string-array>
+ <string-array name="bluetooth_map_versions">
+ <item msgid="8786402640610987099">"MAP 1.2 (predeterminado)"</item>
+ <item msgid="6817922176194686449">"MAP 1.3"</item>
+ <item msgid="3423518690032737851">"MAP 1.4"</item>
+ </string-array>
+ <string-array name="bluetooth_map_version_values">
+ <item msgid="1164651830068248391">"map12"</item>
+ <item msgid="7073042887003102964">"map13"</item>
+ <item msgid="8147982633566548515">"map14"</item>
+ </string-array>
<string-array name="bluetooth_a2dp_codec_titles">
<item msgid="2494959071796102843">"Usar preferencia del sistema (predeterminado)"</item>
<item msgid="4055460186095649420">"SBC"</item>
diff --git a/packages/SettingsLib/res/values-es/strings.xml b/packages/SettingsLib/res/values-es/strings.xml
index 83ae2df2e8aa..ba4a9ff9b245 100644
--- a/packages/SettingsLib/res/values-es/strings.xml
+++ b/packages/SettingsLib/res/values-es/strings.xml
@@ -230,6 +230,8 @@
<string name="bluetooth_enable_gabeldorsche" msgid="9131730396242883416">"Habilitar Gabeldorsche"</string>
<string name="bluetooth_select_avrcp_version_string" msgid="1710571610177659127">"Versión AVRCP de Bluetooth"</string>
<string name="bluetooth_select_avrcp_version_dialog_title" msgid="7846922290083709633">"Selecciona la versión AVRCP de Bluetooth"</string>
+ <string name="bluetooth_select_map_version_string" msgid="526308145174175327">"Versión de MAP de Bluetooth"</string>
+ <string name="bluetooth_select_map_version_dialog_title" msgid="7085934373987428460">"Seleccionar versión de MAP de Bluetooth"</string>
<string name="bluetooth_select_a2dp_codec_type" msgid="952001408455456494">"Códec de audio de Bluetooth"</string>
<string name="bluetooth_select_a2dp_codec_type_dialog_title" msgid="7510542404227225545">"Activar el códec de audio por Bluetooth\nSelección"</string>
<string name="bluetooth_select_a2dp_codec_sample_rate" msgid="1638623076480928191">"Frecuencia de muestreo de audio de Bluetooth"</string>
@@ -276,7 +278,7 @@
<string name="verify_apps_over_usb_summary" msgid="1317933737581167839">"Comprobar las aplicaciones instaladas mediante ADB/ADT para detectar comportamientos dañinos"</string>
<string name="bluetooth_show_devices_without_names_summary" msgid="780964354377854507">"Mostrar dispositivos Bluetooth sin nombre (solo direcciones MAC)"</string>
<string name="bluetooth_disable_absolute_volume_summary" msgid="2006309932135547681">"Inhabilitar la función de volumen absoluto de Bluetooth si se producen problemas de volumen con dispositivos remotos (por ejemplo, volumen demasiado alto o falta de control)"</string>
- <string name="bluetooth_enable_gabeldorsche_summary" msgid="8472344901097607030">"Habilita la pila de funciones de Bluetooth Gabeldorsche."</string>
+ <string name="bluetooth_enable_gabeldorsche_summary" msgid="2054730331770712629">"Habilita la pila de funciones de Bluetooth Gabeldorsche."</string>
<string name="enable_terminal_title" msgid="3834790541986303654">"Terminal local"</string>
<string name="enable_terminal_summary" msgid="2481074834856064500">"Habilitar aplicación de terminal que ofrece acceso a shell local"</string>
<string name="hdcp_checking_title" msgid="3155692785074095986">"Comprobación de HDCP"</string>
diff --git a/packages/SettingsLib/res/values-et/arrays.xml b/packages/SettingsLib/res/values-et/arrays.xml
index 14a68b0e211a..eb5f3471b8e9 100644
--- a/packages/SettingsLib/res/values-et/arrays.xml
+++ b/packages/SettingsLib/res/values-et/arrays.xml
@@ -75,6 +75,16 @@
<item msgid="4398977131424970917">"avrcp15"</item>
<item msgid="1963366694959681026">"avrcp16"</item>
</string-array>
+ <string-array name="bluetooth_map_versions">
+ <item msgid="8786402640610987099">"MAP 1.2 (vaikeseade)"</item>
+ <item msgid="6817922176194686449">"MAP 1.3"</item>
+ <item msgid="3423518690032737851">"MAP 1.4"</item>
+ </string-array>
+ <string-array name="bluetooth_map_version_values">
+ <item msgid="1164651830068248391">"map12"</item>
+ <item msgid="7073042887003102964">"map13"</item>
+ <item msgid="8147982633566548515">"map14"</item>
+ </string-array>
<string-array name="bluetooth_a2dp_codec_titles">
<item msgid="2494959071796102843">"Süsteemi valiku kasutamine (vaikeseade)"</item>
<item msgid="4055460186095649420">"SBC"</item>
diff --git a/packages/SettingsLib/res/values-et/strings.xml b/packages/SettingsLib/res/values-et/strings.xml
index 297e965ca476..df3b792b0e05 100644
--- a/packages/SettingsLib/res/values-et/strings.xml
+++ b/packages/SettingsLib/res/values-et/strings.xml
@@ -230,6 +230,8 @@
<string name="bluetooth_enable_gabeldorsche" msgid="9131730396242883416">"Luba Gabeldorsche"</string>
<string name="bluetooth_select_avrcp_version_string" msgid="1710571610177659127">"Bluetoothi AVRCP versioon"</string>
<string name="bluetooth_select_avrcp_version_dialog_title" msgid="7846922290083709633">"Valige Bluetoothi AVRCP versioon"</string>
+ <string name="bluetooth_select_map_version_string" msgid="526308145174175327">"Bluetoothi MAP-i versioon"</string>
+ <string name="bluetooth_select_map_version_dialog_title" msgid="7085934373987428460">"Bluetoothi MAP-i versiooni valimine"</string>
<string name="bluetooth_select_a2dp_codec_type" msgid="952001408455456494">"Bluetoothi heli kodek"</string>
<string name="bluetooth_select_a2dp_codec_type_dialog_title" msgid="7510542404227225545">"Bluetoothi helikodeki käivitamine\nValik"</string>
<string name="bluetooth_select_a2dp_codec_sample_rate" msgid="1638623076480928191">"Bluetoothi heli diskreetimissagedus"</string>
@@ -276,7 +278,7 @@
<string name="verify_apps_over_usb_summary" msgid="1317933737581167839">"Kontrolli, kas ADB/ADT-ga installitud rakendused on ohtlikud."</string>
<string name="bluetooth_show_devices_without_names_summary" msgid="780964354377854507">"Kuvatakse ilma nimedeta (ainult MAC-aadressidega) Bluetoothi seadmed"</string>
<string name="bluetooth_disable_absolute_volume_summary" msgid="2006309932135547681">"Keelatakse Bluetoothi absoluutse helitugevuse funktsioon, kui kaugseadmetega on helitugevuse probleeme (nt liiga vali heli või juhitavuse puudumine)."</string>
- <string name="bluetooth_enable_gabeldorsche_summary" msgid="8472344901097607030">"Lubab Bluetoothi Gabeldorche\'i funktsiooni virnastamise."</string>
+ <string name="bluetooth_enable_gabeldorsche_summary" msgid="2054730331770712629">"Lubab Bluetooth Gabeldorsche\'i funktsiooni virnastamise."</string>
<string name="enable_terminal_title" msgid="3834790541986303654">"Kohalik terminal"</string>
<string name="enable_terminal_summary" msgid="2481074834856064500">"Luba kohalikku turvalist juurdepääsu pakkuv terminalirakendus"</string>
<string name="hdcp_checking_title" msgid="3155692785074095986">"HDCP-kontrollimine"</string>
diff --git a/packages/SettingsLib/res/values-eu/arrays.xml b/packages/SettingsLib/res/values-eu/arrays.xml
index e87413cd5a47..30ac525f72ff 100644
--- a/packages/SettingsLib/res/values-eu/arrays.xml
+++ b/packages/SettingsLib/res/values-eu/arrays.xml
@@ -75,6 +75,16 @@
<item msgid="4398977131424970917">"avrcp15"</item>
<item msgid="1963366694959681026">"avrcp16"</item>
</string-array>
+ <string-array name="bluetooth_map_versions">
+ <item msgid="8786402640610987099">"1.2 MAPa (lehenetsia)"</item>
+ <item msgid="6817922176194686449">"1.3 MAPa"</item>
+ <item msgid="3423518690032737851">"1.4 MAPa"</item>
+ </string-array>
+ <string-array name="bluetooth_map_version_values">
+ <item msgid="1164651830068248391">"map12"</item>
+ <item msgid="7073042887003102964">"map13"</item>
+ <item msgid="8147982633566548515">"map14"</item>
+ </string-array>
<string-array name="bluetooth_a2dp_codec_titles">
<item msgid="2494959071796102843">"Erabili sistema-hautapena (lehenetsia)"</item>
<item msgid="4055460186095649420">"SBC"</item>
diff --git a/packages/SettingsLib/res/values-eu/strings.xml b/packages/SettingsLib/res/values-eu/strings.xml
index 5b84b1074b4c..fcb320ffe61f 100644
--- a/packages/SettingsLib/res/values-eu/strings.xml
+++ b/packages/SettingsLib/res/values-eu/strings.xml
@@ -230,6 +230,8 @@
<string name="bluetooth_enable_gabeldorsche" msgid="9131730396242883416">"Gaitu Gabeldorsche"</string>
<string name="bluetooth_select_avrcp_version_string" msgid="1710571610177659127">"Bluetooth AVRCP bertsioa"</string>
<string name="bluetooth_select_avrcp_version_dialog_title" msgid="7846922290083709633">"Hautatu Bluetooth AVRCP bertsioa"</string>
+ <string name="bluetooth_select_map_version_string" msgid="526308145174175327">"Bluetooth MAParen bertsioa"</string>
+ <string name="bluetooth_select_map_version_dialog_title" msgid="7085934373987428460">"Hautatu Bluetooth MAParen bertsioa"</string>
<string name="bluetooth_select_a2dp_codec_type" msgid="952001408455456494">"Bluetooth bidezko audioaren kodeka"</string>
<string name="bluetooth_select_a2dp_codec_type_dialog_title" msgid="7510542404227225545">"Abiarazi Bluetooth bidezko audio-kodeka\nHautapena"</string>
<string name="bluetooth_select_a2dp_codec_sample_rate" msgid="1638623076480928191">"Bluetooth bidezko audioaren lagin-abiadura"</string>
@@ -276,7 +278,7 @@
<string name="verify_apps_over_usb_summary" msgid="1317933737581167839">"Egiaztatu ADB/ADT bidez instalatutako aplikazioak portaera kaltegarriak atzemateko"</string>
<string name="bluetooth_show_devices_without_names_summary" msgid="780964354377854507">"Bluetooth gailuak izenik gabe (MAC helbideak soilik) erakutsiko dira"</string>
<string name="bluetooth_disable_absolute_volume_summary" msgid="2006309932135547681">"Bluetooth bidezko bolumen absolutuaren eginbidea desgaitu egiten du urruneko gailuetan arazoak hautematen badira; esaterako, bolumena ozenegia bada edo ezin bada kontrolatu"</string>
- <string name="bluetooth_enable_gabeldorsche_summary" msgid="8472344901097607030">"Bluetooth Gabeldorsche eginbide sorta gaitzen du."</string>
+ <string name="bluetooth_enable_gabeldorsche_summary" msgid="2054730331770712629">"Bluetooth Gabeldorsche eginbide sorta gaitzen du."</string>
<string name="enable_terminal_title" msgid="3834790541986303654">"Tokiko terminala"</string>
<string name="enable_terminal_summary" msgid="2481074834856064500">"Gaitu tokiko shell-sarbidea duen terminal-aplikazioa"</string>
<string name="hdcp_checking_title" msgid="3155692785074095986">"HDCP egiaztapena"</string>
diff --git a/packages/SettingsLib/res/values-fa/arrays.xml b/packages/SettingsLib/res/values-fa/arrays.xml
index ba56d24974ba..3b05075c1d75 100644
--- a/packages/SettingsLib/res/values-fa/arrays.xml
+++ b/packages/SettingsLib/res/values-fa/arrays.xml
@@ -75,6 +75,16 @@
<item msgid="4398977131424970917">"avrcp15"</item>
<item msgid="1963366694959681026">"avrcp16"</item>
</string-array>
+ <string-array name="bluetooth_map_versions">
+ <item msgid="8786402640610987099">"‏MAP نسخه ۱.۲ (پیش‌فرض)"</item>
+ <item msgid="6817922176194686449">"‏MAP نسخه ۱.۳"</item>
+ <item msgid="3423518690032737851">"‏MAP نسخه ۱.۴"</item>
+ </string-array>
+ <string-array name="bluetooth_map_version_values">
+ <item msgid="1164651830068248391">"map12"</item>
+ <item msgid="7073042887003102964">"map13"</item>
+ <item msgid="8147982633566548515">"map14"</item>
+ </string-array>
<string-array name="bluetooth_a2dp_codec_titles">
<item msgid="2494959071796102843">"استفاده از انتخاب سیستم (پیش‌فرض)"</item>
<item msgid="4055460186095649420">"SBC"</item>
diff --git a/packages/SettingsLib/res/values-fa/strings.xml b/packages/SettingsLib/res/values-fa/strings.xml
index 61fe37a81cf4..261a438a4774 100644
--- a/packages/SettingsLib/res/values-fa/strings.xml
+++ b/packages/SettingsLib/res/values-fa/strings.xml
@@ -230,6 +230,8 @@
<string name="bluetooth_enable_gabeldorsche" msgid="9131730396242883416">"‏فعال کردن Gabeldorsche"</string>
<string name="bluetooth_select_avrcp_version_string" msgid="1710571610177659127">"‏نسخه AVRCP بلوتوث"</string>
<string name="bluetooth_select_avrcp_version_dialog_title" msgid="7846922290083709633">"‏انتخاب نسخه AVRCP بلوتوث"</string>
+ <string name="bluetooth_select_map_version_string" msgid="526308145174175327">"‏نسخه MAP بلوتوث"</string>
+ <string name="bluetooth_select_map_version_dialog_title" msgid="7085934373987428460">"‏انتخاب نسخه MAP بلوتوث"</string>
<string name="bluetooth_select_a2dp_codec_type" msgid="952001408455456494">"کدک بلوتوث صوتی"</string>
<string name="bluetooth_select_a2dp_codec_type_dialog_title" msgid="7510542404227225545">"راه‌اندازی کدک صوتی بلوتوثی\nانتخاب"</string>
<string name="bluetooth_select_a2dp_codec_sample_rate" msgid="1638623076480928191">"سرعت نمونه بلوتوث صوتی"</string>
@@ -276,7 +278,7 @@
<string name="verify_apps_over_usb_summary" msgid="1317933737581167839">"‏برنامه‌های نصب‌شده ازطریق ADB/ADT را ازنظر رفتار مخاطره‌آمیز بررسی کنید."</string>
<string name="bluetooth_show_devices_without_names_summary" msgid="780964354377854507">"‏دستگاه‌های بلوتوث بدون نام (فقط نشانی‌های MAC) نشان داده خواهند شد"</string>
<string name="bluetooth_disable_absolute_volume_summary" msgid="2006309932135547681">"درصورت وجود مشکل در صدا با دستگاه‌های راه دور مثل صدای بلند ناخوشایند یا عدم کنترل صدا، ویژگی میزان صدای کامل بلوتوث را غیرفعال کنید."</string>
- <string name="bluetooth_enable_gabeldorsche_summary" msgid="8472344901097607030">"‏دسته ویژگی Gabeldorche، بلوتوث را فعال می‌کند."</string>
+ <string name="bluetooth_enable_gabeldorsche_summary" msgid="2054730331770712629">"‏دسته ویژگی Gabeldorsche، بلوتوث را فعال می‌کند."</string>
<string name="enable_terminal_title" msgid="3834790541986303654">"ترمینال محلی"</string>
<string name="enable_terminal_summary" msgid="2481074834856064500">"فعال کردن ترمینال برنامه‌ کاربردی که دسترسی به برنامه محلی را پیشنهاد می‌کند"</string>
<string name="hdcp_checking_title" msgid="3155692785074095986">"‏بررسی HDCP"</string>
diff --git a/packages/SettingsLib/res/values-fi/arrays.xml b/packages/SettingsLib/res/values-fi/arrays.xml
index 79a46ba71cff..c899d9c8daea 100644
--- a/packages/SettingsLib/res/values-fi/arrays.xml
+++ b/packages/SettingsLib/res/values-fi/arrays.xml
@@ -75,6 +75,16 @@
<item msgid="4398977131424970917">"avrcp15"</item>
<item msgid="1963366694959681026">"avrcp16"</item>
</string-array>
+ <string-array name="bluetooth_map_versions">
+ <item msgid="8786402640610987099">"MAP 1.2 (oletus)"</item>
+ <item msgid="6817922176194686449">"MAP 1.3"</item>
+ <item msgid="3423518690032737851">"MAP 1.4"</item>
+ </string-array>
+ <string-array name="bluetooth_map_version_values">
+ <item msgid="1164651830068248391">"map12"</item>
+ <item msgid="7073042887003102964">"map13"</item>
+ <item msgid="8147982633566548515">"map14"</item>
+ </string-array>
<string-array name="bluetooth_a2dp_codec_titles">
<item msgid="2494959071796102843">"Käytä järjestelmän valintaa (oletus)."</item>
<item msgid="4055460186095649420">"SBC"</item>
diff --git a/packages/SettingsLib/res/values-fi/strings.xml b/packages/SettingsLib/res/values-fi/strings.xml
index 7e8b160c21b1..4ccf430131af 100644
--- a/packages/SettingsLib/res/values-fi/strings.xml
+++ b/packages/SettingsLib/res/values-fi/strings.xml
@@ -230,6 +230,8 @@
<string name="bluetooth_enable_gabeldorsche" msgid="9131730396242883416">"Ota Gabeldorsche käyttöön"</string>
<string name="bluetooth_select_avrcp_version_string" msgid="1710571610177659127">"Bluetoothin AVRCP-versio"</string>
<string name="bluetooth_select_avrcp_version_dialog_title" msgid="7846922290083709633">"Valitse Bluetoothin AVRCP-versio"</string>
+ <string name="bluetooth_select_map_version_string" msgid="526308145174175327">"Bluetoothin MAP-versio"</string>
+ <string name="bluetooth_select_map_version_dialog_title" msgid="7085934373987428460">"Valitse Bluetoothin MAP-versio"</string>
<string name="bluetooth_select_a2dp_codec_type" msgid="952001408455456494">"Bluetooth-äänen koodekki"</string>
<string name="bluetooth_select_a2dp_codec_type_dialog_title" msgid="7510542404227225545">"Käynnistä Bluetooth-äänipakkaus\nValinta"</string>
<string name="bluetooth_select_a2dp_codec_sample_rate" msgid="1638623076480928191">"Bluetooth-ääninäytteen siirtonopeus"</string>
@@ -276,7 +278,7 @@
<string name="verify_apps_over_usb_summary" msgid="1317933737581167839">"Tarkista ADB:n/ADT:n kautta asennetut sovellukset haitallisen toiminnan varalta."</string>
<string name="bluetooth_show_devices_without_names_summary" msgid="780964354377854507">"Näytetään Bluetooth-laitteet, joilla ei ole nimiä (vain MAC-osoitteet)."</string>
<string name="bluetooth_disable_absolute_volume_summary" msgid="2006309932135547681">"Bluetoothin yleinen äänenvoimakkuuden säätö poistetaan käytöstä ongelmien välttämiseksi esimerkiksi silloin, kun laitteen äänenvoimakkuus on liian kova tai sitä ei voi säätää."</string>
- <string name="bluetooth_enable_gabeldorsche_summary" msgid="8472344901097607030">"Bluetoothin Gabeldorche-ominaisuuspino tulee käyttöön."</string>
+ <string name="bluetooth_enable_gabeldorsche_summary" msgid="2054730331770712629">"Bluetoothin Gabeldorsche-ominaisuuspino otetaan käyttöön."</string>
<string name="enable_terminal_title" msgid="3834790541986303654">"Paikallinen pääte"</string>
<string name="enable_terminal_summary" msgid="2481074834856064500">"Ota käyttöön päätesov. joka mahdollistaa paikall. liittymäkäytön"</string>
<string name="hdcp_checking_title" msgid="3155692785074095986">"HDCP-tarkistus"</string>
diff --git a/packages/SettingsLib/res/values-fr-rCA/arrays.xml b/packages/SettingsLib/res/values-fr-rCA/arrays.xml
index 3ee320993876..02b374acdcd7 100644
--- a/packages/SettingsLib/res/values-fr-rCA/arrays.xml
+++ b/packages/SettingsLib/res/values-fr-rCA/arrays.xml
@@ -75,6 +75,16 @@
<item msgid="4398977131424970917">"avrcp15"</item>
<item msgid="1963366694959681026">"avrcp16"</item>
</string-array>
+ <string-array name="bluetooth_map_versions">
+ <item msgid="8786402640610987099">"MAP 1.2 (valeur par défaut)"</item>
+ <item msgid="6817922176194686449">"MAP 1.3"</item>
+ <item msgid="3423518690032737851">"MAP 1.4"</item>
+ </string-array>
+ <string-array name="bluetooth_map_version_values">
+ <item msgid="1164651830068248391">"map12"</item>
+ <item msgid="7073042887003102964">"map13"</item>
+ <item msgid="8147982633566548515">"map14"</item>
+ </string-array>
<string-array name="bluetooth_a2dp_codec_titles">
<item msgid="2494959071796102843">"Utiliser sélect. du système (par défaut)"</item>
<item msgid="4055460186095649420">"SBC"</item>
diff --git a/packages/SettingsLib/res/values-fr-rCA/strings.xml b/packages/SettingsLib/res/values-fr-rCA/strings.xml
index d21eeefe5bb2..84a97973d7c4 100644
--- a/packages/SettingsLib/res/values-fr-rCA/strings.xml
+++ b/packages/SettingsLib/res/values-fr-rCA/strings.xml
@@ -230,6 +230,8 @@
<string name="bluetooth_enable_gabeldorsche" msgid="9131730396242883416">"Activer le Gabeldorsche"</string>
<string name="bluetooth_select_avrcp_version_string" msgid="1710571610177659127">"Version du profil Bluetooth AVRCP"</string>
<string name="bluetooth_select_avrcp_version_dialog_title" msgid="7846922290083709633">"Sélectionner la version du profil Bluetooth AVRCP"</string>
+ <string name="bluetooth_select_map_version_string" msgid="526308145174175327">"Version du profil Bluetooth MAP"</string>
+ <string name="bluetooth_select_map_version_dialog_title" msgid="7085934373987428460">"Sélectionner la version du profil Bluetooth MAP"</string>
<string name="bluetooth_select_a2dp_codec_type" msgid="952001408455456494">"Codec audio Bluetooth"</string>
<string name="bluetooth_select_a2dp_codec_type_dialog_title" msgid="7510542404227225545">"Déclencher le codec audio Bluetooth\nSélection"</string>
<string name="bluetooth_select_a2dp_codec_sample_rate" msgid="1638623076480928191">"Taux d\'échantillonnage pour l\'audio Bluetooth"</string>
@@ -276,7 +278,7 @@
<string name="verify_apps_over_usb_summary" msgid="1317933737581167839">"Vérifier que les applications installées par ADB/ADT ne présentent pas de comportement dangereux."</string>
<string name="bluetooth_show_devices_without_names_summary" msgid="780964354377854507">"Les appareils Bluetooth sans nom (adresses MAC seulement) seront affichés"</string>
<string name="bluetooth_disable_absolute_volume_summary" msgid="2006309932135547681">"Désactive la fonctionnalité de volume absolu par Bluetooth en cas de problème de volume sur les appareils à distance, par exemple si le volume est trop élevé ou s\'il ne peut pas être contrôlé."</string>
- <string name="bluetooth_enable_gabeldorsche_summary" msgid="8472344901097607030">"Active la pile de la fonctionnalité Bluetooth Gabeldorche."</string>
+ <string name="bluetooth_enable_gabeldorsche_summary" msgid="2054730331770712629">"Active la pile de la fonctionnalité Bluetooth Gabeldorsche."</string>
<string name="enable_terminal_title" msgid="3834790541986303654">"Terminal local"</string>
<string name="enable_terminal_summary" msgid="2481074834856064500">"Activer l\'application Terminal permettant l\'accès au shell local"</string>
<string name="hdcp_checking_title" msgid="3155692785074095986">"Vérification HDCP"</string>
diff --git a/packages/SettingsLib/res/values-fr/arrays.xml b/packages/SettingsLib/res/values-fr/arrays.xml
index e23fc6a594ad..9ccaf09d8b8d 100644
--- a/packages/SettingsLib/res/values-fr/arrays.xml
+++ b/packages/SettingsLib/res/values-fr/arrays.xml
@@ -75,6 +75,16 @@
<item msgid="4398977131424970917">"avrcp15"</item>
<item msgid="1963366694959681026">"avrcp16"</item>
</string-array>
+ <string-array name="bluetooth_map_versions">
+ <item msgid="8786402640610987099">"MAP 1.2 (valeur par défaut)"</item>
+ <item msgid="6817922176194686449">"MAP 1.3"</item>
+ <item msgid="3423518690032737851">"MAP 1.4"</item>
+ </string-array>
+ <string-array name="bluetooth_map_version_values">
+ <item msgid="1164651830068248391">"map12"</item>
+ <item msgid="7073042887003102964">"map13"</item>
+ <item msgid="8147982633566548515">"map14"</item>
+ </string-array>
<string-array name="bluetooth_a2dp_codec_titles">
<item msgid="2494959071796102843">"Utiliser la sélection du système (par défaut)"</item>
<item msgid="4055460186095649420">"SBC"</item>
diff --git a/packages/SettingsLib/res/values-fr/strings.xml b/packages/SettingsLib/res/values-fr/strings.xml
index 23dd5a83e113..030a7f9b3b48 100644
--- a/packages/SettingsLib/res/values-fr/strings.xml
+++ b/packages/SettingsLib/res/values-fr/strings.xml
@@ -230,6 +230,8 @@
<string name="bluetooth_enable_gabeldorsche" msgid="9131730396242883416">"Activer Gabeldorsche"</string>
<string name="bluetooth_select_avrcp_version_string" msgid="1710571610177659127">"Version Bluetooth AVRCP"</string>
<string name="bluetooth_select_avrcp_version_dialog_title" msgid="7846922290083709633">"Sélectionner la version Bluetooth AVRCP"</string>
+ <string name="bluetooth_select_map_version_string" msgid="526308145174175327">"Version Bluetooth MAP"</string>
+ <string name="bluetooth_select_map_version_dialog_title" msgid="7085934373987428460">"Sélectionner la version Bluetooth MAP"</string>
<string name="bluetooth_select_a2dp_codec_type" msgid="952001408455456494">"Codec audio Bluetooth"</string>
<string name="bluetooth_select_a2dp_codec_type_dialog_title" msgid="7510542404227225545">"Critère pour déclencher la sélection du codec audio\nBluetooth"</string>
<string name="bluetooth_select_a2dp_codec_sample_rate" msgid="1638623076480928191">"Taux d\'échantillonnage audio Bluetooth"</string>
@@ -276,7 +278,7 @@
<string name="verify_apps_over_usb_summary" msgid="1317933737581167839">"Vérifier que les applications installées par ADB/ADT ne présentent pas de comportement dangereux"</string>
<string name="bluetooth_show_devices_without_names_summary" msgid="780964354377854507">"Les appareils Bluetooth sans nom (adresses MAC seulement) seront affichés"</string>
<string name="bluetooth_disable_absolute_volume_summary" msgid="2006309932135547681">"Désactive la fonctionnalité de volume absolu du Bluetooth en cas de problème de volume sur les appareils à distance, par exemple si le volume est trop élevé ou s\'il ne peut pas être contrôlé"</string>
- <string name="bluetooth_enable_gabeldorsche_summary" msgid="8472344901097607030">"Active la pile de fonctionnalités Bluetooth Gabeldorsche."</string>
+ <string name="bluetooth_enable_gabeldorsche_summary" msgid="2054730331770712629">"Active la pile de fonctionnalités Bluetooth Gabeldorsche."</string>
<string name="enable_terminal_title" msgid="3834790541986303654">"Terminal local"</string>
<string name="enable_terminal_summary" msgid="2481074834856064500">"Activer l\'application Terminal permettant l\'accès au shell local"</string>
<string name="hdcp_checking_title" msgid="3155692785074095986">"Vérification HDCP"</string>
diff --git a/packages/SettingsLib/res/values-gl/arrays.xml b/packages/SettingsLib/res/values-gl/arrays.xml
index c0a5a80782c0..5fad943e16b7 100644
--- a/packages/SettingsLib/res/values-gl/arrays.xml
+++ b/packages/SettingsLib/res/values-gl/arrays.xml
@@ -75,6 +75,16 @@
<item msgid="4398977131424970917">"avrcp15"</item>
<item msgid="1963366694959681026">"avrcp16"</item>
</string-array>
+ <string-array name="bluetooth_map_versions">
+ <item msgid="8786402640610987099">"MAP 1.2 (predeterminada)"</item>
+ <item msgid="6817922176194686449">"MAP 1.3"</item>
+ <item msgid="3423518690032737851">"MAP 1.4"</item>
+ </string-array>
+ <string-array name="bluetooth_map_version_values">
+ <item msgid="1164651830068248391">"map12"</item>
+ <item msgid="7073042887003102964">"map13"</item>
+ <item msgid="8147982633566548515">"map14"</item>
+ </string-array>
<string-array name="bluetooth_a2dp_codec_titles">
<item msgid="2494959071796102843">"Usar selección do sistema (predeterminado)"</item>
<item msgid="4055460186095649420">"SBC"</item>
diff --git a/packages/SettingsLib/res/values-gl/strings.xml b/packages/SettingsLib/res/values-gl/strings.xml
index c8f6f81c3426..af033cf43328 100644
--- a/packages/SettingsLib/res/values-gl/strings.xml
+++ b/packages/SettingsLib/res/values-gl/strings.xml
@@ -230,6 +230,8 @@
<string name="bluetooth_enable_gabeldorsche" msgid="9131730396242883416">"Activar Gabeldorsche"</string>
<string name="bluetooth_select_avrcp_version_string" msgid="1710571610177659127">"Versión de Bluetooth AVRCP"</string>
<string name="bluetooth_select_avrcp_version_dialog_title" msgid="7846922290083709633">"Selecciona a versión de Bluetooth AVRCP"</string>
+ <string name="bluetooth_select_map_version_string" msgid="526308145174175327">"Versión de MAP de Bluetooth"</string>
+ <string name="bluetooth_select_map_version_dialog_title" msgid="7085934373987428460">"Selecciona a versión de MAP de Bluetooth"</string>
<string name="bluetooth_select_a2dp_codec_type" msgid="952001408455456494">"Códec de audio por Bluetooth"</string>
<string name="bluetooth_select_a2dp_codec_type_dialog_title" msgid="7510542404227225545">"Activar códec de audio por Bluetooth\nSelección"</string>
<string name="bluetooth_select_a2dp_codec_sample_rate" msgid="1638623076480928191">"Taxa de mostra de audio por Bluetooth"</string>
@@ -276,7 +278,7 @@
<string name="verify_apps_over_usb_summary" msgid="1317933737581167839">"Comproba as aplicacións instaladas a través de ADB/ADT para detectar comportamento perigoso"</string>
<string name="bluetooth_show_devices_without_names_summary" msgid="780964354377854507">"Mostraranse dispositivos Bluetooth sen nomes (só enderezos MAC)"</string>
<string name="bluetooth_disable_absolute_volume_summary" msgid="2006309932135547681">"Desactiva a función do volume absoluto do Bluetooth en caso de que se produzan problemas de volume cos dispositivos remotos, como volume demasiado alto ou falta de control"</string>
- <string name="bluetooth_enable_gabeldorsche_summary" msgid="8472344901097607030">"Activa a pilla de funcións Bluetooth Gabeldorche."</string>
+ <string name="bluetooth_enable_gabeldorsche_summary" msgid="2054730331770712629">"Activa o conxunto de funcións de Bluetooth Gabeldorsche."</string>
<string name="enable_terminal_title" msgid="3834790541986303654">"Terminal local"</string>
<string name="enable_terminal_summary" msgid="2481074834856064500">"Activa a aplicación terminal que ofrece acceso ao shell local"</string>
<string name="hdcp_checking_title" msgid="3155692785074095986">"Comprobación HDCP"</string>
diff --git a/packages/SettingsLib/res/values-gu/arrays.xml b/packages/SettingsLib/res/values-gu/arrays.xml
index 75c904d5a158..8e28b8b67c2c 100644
--- a/packages/SettingsLib/res/values-gu/arrays.xml
+++ b/packages/SettingsLib/res/values-gu/arrays.xml
@@ -75,6 +75,16 @@
<item msgid="4398977131424970917">"avrcp15"</item>
<item msgid="1963366694959681026">"avrcp16"</item>
</string-array>
+ <string-array name="bluetooth_map_versions">
+ <item msgid="8786402640610987099">"MAP 1.2 (ડિફૉલ્ટ)"</item>
+ <item msgid="6817922176194686449">"MAP 1.3"</item>
+ <item msgid="3423518690032737851">"MAP 1.4"</item>
+ </string-array>
+ <string-array name="bluetooth_map_version_values">
+ <item msgid="1164651830068248391">"map12"</item>
+ <item msgid="7073042887003102964">"map13"</item>
+ <item msgid="8147982633566548515">"map14"</item>
+ </string-array>
<string-array name="bluetooth_a2dp_codec_titles">
<item msgid="2494959071796102843">"સિસ્ટમ પસંદગીનો ઉપયોગ કરો (ડિફૉલ્ટ)"</item>
<item msgid="4055460186095649420">"SBC"</item>
diff --git a/packages/SettingsLib/res/values-gu/strings.xml b/packages/SettingsLib/res/values-gu/strings.xml
index d274674b238b..87fd8767b326 100644
--- a/packages/SettingsLib/res/values-gu/strings.xml
+++ b/packages/SettingsLib/res/values-gu/strings.xml
@@ -230,6 +230,8 @@
<string name="bluetooth_enable_gabeldorsche" msgid="9131730396242883416">"Gabeldorsche ચાલુ કરો"</string>
<string name="bluetooth_select_avrcp_version_string" msgid="1710571610177659127">"બ્લૂટૂથ AVRCP સંસ્કરણ"</string>
<string name="bluetooth_select_avrcp_version_dialog_title" msgid="7846922290083709633">"બ્લૂટૂથ AVRCP સંસ્કરણ પસંદ કરો"</string>
+ <string name="bluetooth_select_map_version_string" msgid="526308145174175327">"બ્લૂટૂથ MAP વર્ઝન"</string>
+ <string name="bluetooth_select_map_version_dialog_title" msgid="7085934373987428460">"બ્લૂટૂથ MAP વર્ઝન પસંદ કરો"</string>
<string name="bluetooth_select_a2dp_codec_type" msgid="952001408455456494">"બ્લૂટૂથ ઑડિઓ કોડેક"</string>
<string name="bluetooth_select_a2dp_codec_type_dialog_title" msgid="7510542404227225545">"બ્લૂટૂથ ઑડિઓ કોડેક\nપસંદગી ટ્રિગર કરો"</string>
<string name="bluetooth_select_a2dp_codec_sample_rate" msgid="1638623076480928191">"બ્લૂટૂથ ઑડિઓ નમૂના દર"</string>
@@ -276,7 +278,7 @@
<string name="verify_apps_over_usb_summary" msgid="1317933737581167839">"હાનિકારક વર્તણૂંક માટે ADB/ADT મારફતે ઇન્સ્ટોલ કરવામાં આવેલી ઍપ્લિકેશનો તપાસો."</string>
<string name="bluetooth_show_devices_without_names_summary" msgid="780964354377854507">"નામ વગરના (ફક્ત MAC ઍડ્રેસવાળા) બ્લૂટૂથ ઉપકરણો બતાવવામાં આવશે"</string>
<string name="bluetooth_disable_absolute_volume_summary" msgid="2006309932135547681">"રિમોટ ઉપકરણોમાં વધુ પડતું ઊંચું વૉલ્યૂમ અથવા નિયંત્રણની કમી જેવી વૉલ્યૂમની સમસ્યાઓની સ્થિતિમાં બ્લૂટૂથ ચોક્કસ વૉલ્યૂમ સુવિધાને અક્ષમ કરે છે."</string>
- <string name="bluetooth_enable_gabeldorsche_summary" msgid="8472344901097607030">"બ્લૂટૂથ Gabeldorche સુવિધા સ્ટૅક ચાલુ કરે છે."</string>
+ <string name="bluetooth_enable_gabeldorsche_summary" msgid="2054730331770712629">"બ્લૂટૂથ Gabeldorsche સુવિધાનું સ્ટૅક ચાલુ કરે છે."</string>
<string name="enable_terminal_title" msgid="3834790541986303654">"સ્થાનિક ટર્મિનલ"</string>
<string name="enable_terminal_summary" msgid="2481074834856064500">"સ્થાનિક શેલ અ‍ૅક્સેસની ઑફર કરતી ટર્મિનલ એપ્લિકેશનને સક્ષમ કરો"</string>
<string name="hdcp_checking_title" msgid="3155692785074095986">"HDCP તપાસણી"</string>
diff --git a/packages/SettingsLib/res/values-hi/arrays.xml b/packages/SettingsLib/res/values-hi/arrays.xml
index ffaf80a21413..3c744e1f5587 100644
--- a/packages/SettingsLib/res/values-hi/arrays.xml
+++ b/packages/SettingsLib/res/values-hi/arrays.xml
@@ -75,6 +75,16 @@
<item msgid="4398977131424970917">"avrcp15"</item>
<item msgid="1963366694959681026">"avrcp16"</item>
</string-array>
+ <string-array name="bluetooth_map_versions">
+ <item msgid="8786402640610987099">"MAP 1.2 (डिफ़ॉल्ट)"</item>
+ <item msgid="6817922176194686449">"MAP 1.3"</item>
+ <item msgid="3423518690032737851">"MAP 1.4"</item>
+ </string-array>
+ <string-array name="bluetooth_map_version_values">
+ <item msgid="1164651830068248391">"map12"</item>
+ <item msgid="7073042887003102964">"map13"</item>
+ <item msgid="8147982633566548515">"map14"</item>
+ </string-array>
<string-array name="bluetooth_a2dp_codec_titles">
<item msgid="2494959071796102843">"सिस्टम से चुने जाने का उपयोग करें (डिफ़ॉल्ट)"</item>
<item msgid="4055460186095649420">"SBC"</item>
diff --git a/packages/SettingsLib/res/values-hi/strings.xml b/packages/SettingsLib/res/values-hi/strings.xml
index d0307ecef47b..02b5c9601ab4 100644
--- a/packages/SettingsLib/res/values-hi/strings.xml
+++ b/packages/SettingsLib/res/values-hi/strings.xml
@@ -230,6 +230,8 @@
<string name="bluetooth_enable_gabeldorsche" msgid="9131730396242883416">"Gabeldorsche चालू करें"</string>
<string name="bluetooth_select_avrcp_version_string" msgid="1710571610177659127">"ब्लूटूथ एवीआरसीपी वर्शन"</string>
<string name="bluetooth_select_avrcp_version_dialog_title" msgid="7846922290083709633">"ब्लूटूथ AVRCP वर्शन चुनें"</string>
+ <string name="bluetooth_select_map_version_string" msgid="526308145174175327">"ब्लूटूथ का MAP वर्शन"</string>
+ <string name="bluetooth_select_map_version_dialog_title" msgid="7085934373987428460">"ब्लूटूथ का MAP वर्शन चुनें"</string>
<string name="bluetooth_select_a2dp_codec_type" msgid="952001408455456494">"ब्लूटूथ ऑडियो कोडेक"</string>
<string name="bluetooth_select_a2dp_codec_type_dialog_title" msgid="7510542404227225545">"ब्लूटूथ ऑडियो कोडेक का\nविकल्प चालू करें"</string>
<string name="bluetooth_select_a2dp_codec_sample_rate" msgid="1638623076480928191">"ब्लूटूथ ऑडियो नमूना दर"</string>
@@ -276,7 +278,7 @@
<string name="verify_apps_over_usb_summary" msgid="1317933737581167839">"नुकसानदेह व्यवहार के लिए ADB/ADT से इंस्टॉल किए गए ऐप्लिकेशन जाँचें."</string>
<string name="bluetooth_show_devices_without_names_summary" msgid="780964354377854507">"बिना नाम वाले ब्लूटूथ डिवाइस (केवल MAC पते वाले) दिखाए जाएंगे"</string>
<string name="bluetooth_disable_absolute_volume_summary" msgid="2006309932135547681">"दूर के डिवाइस पर आवाज़ बहुत बढ़ जाने या उससे नियंत्रण हटने जैसी समस्याएं होने पर, यह ब्लूटूथ के ज़रिए आवाज़ के नियंत्रण की सुविधा रोक देता है."</string>
- <string name="bluetooth_enable_gabeldorsche_summary" msgid="8472344901097607030">"ब्लूटूथ Gabeldorsche सुविधा का स्टैक चालू करें."</string>
+ <string name="bluetooth_enable_gabeldorsche_summary" msgid="2054730331770712629">"ब्लूटूथ सेटिंग में Gabeldorsche सुविधा को चालू करता है."</string>
<string name="enable_terminal_title" msgid="3834790541986303654">"स्थानीय टर्मिनल"</string>
<string name="enable_terminal_summary" msgid="2481074834856064500">"लोकल शेल तक पहुंचने की सुविधा देने वाले टर्मिनल ऐप को चालू करें"</string>
<string name="hdcp_checking_title" msgid="3155692785074095986">"एचडीसीपी जाँच"</string>
diff --git a/packages/SettingsLib/res/values-hr/arrays.xml b/packages/SettingsLib/res/values-hr/arrays.xml
index ec979f6852dc..c573e6c01184 100644
--- a/packages/SettingsLib/res/values-hr/arrays.xml
+++ b/packages/SettingsLib/res/values-hr/arrays.xml
@@ -75,6 +75,16 @@
<item msgid="4398977131424970917">"avrcp15"</item>
<item msgid="1963366694959681026">"avrcp16"</item>
</string-array>
+ <string-array name="bluetooth_map_versions">
+ <item msgid="8786402640610987099">"MAP 1.2 (zadano)"</item>
+ <item msgid="6817922176194686449">"MAP 1.3"</item>
+ <item msgid="3423518690032737851">"MAP 1.4"</item>
+ </string-array>
+ <string-array name="bluetooth_map_version_values">
+ <item msgid="1164651830068248391">"map12"</item>
+ <item msgid="7073042887003102964">"map13"</item>
+ <item msgid="8147982633566548515">"map14"</item>
+ </string-array>
<string-array name="bluetooth_a2dp_codec_titles">
<item msgid="2494959071796102843">"Upotreba odabira sustava (zadano)"</item>
<item msgid="4055460186095649420">"SBC"</item>
diff --git a/packages/SettingsLib/res/values-hr/strings.xml b/packages/SettingsLib/res/values-hr/strings.xml
index 84adcaab19eb..598cfe2aadb2 100644
--- a/packages/SettingsLib/res/values-hr/strings.xml
+++ b/packages/SettingsLib/res/values-hr/strings.xml
@@ -230,6 +230,8 @@
<string name="bluetooth_enable_gabeldorsche" msgid="9131730396242883416">"Omogući Gabeldorsche"</string>
<string name="bluetooth_select_avrcp_version_string" msgid="1710571610177659127">"Verzija AVRCP-a za Bluetooth"</string>
<string name="bluetooth_select_avrcp_version_dialog_title" msgid="7846922290083709633">"Odaberite verziju AVRCP-a za Bluetooth"</string>
+ <string name="bluetooth_select_map_version_string" msgid="526308145174175327">"Verzija MAP-a za Bluetooth"</string>
+ <string name="bluetooth_select_map_version_dialog_title" msgid="7085934373987428460">"Odaberite verziju MAP-a za Bluetooth"</string>
<string name="bluetooth_select_a2dp_codec_type" msgid="952001408455456494">"Kodek za Bluetooth Audio"</string>
<string name="bluetooth_select_a2dp_codec_type_dialog_title" msgid="7510542404227225545">"Pokreni odabir kodeka za Bluetooth\nAudio"</string>
<string name="bluetooth_select_a2dp_codec_sample_rate" msgid="1638623076480928191">"Brzina uzorka za Bluetooth Audio"</string>
@@ -276,7 +278,7 @@
<string name="verify_apps_over_usb_summary" msgid="1317933737581167839">"Provjerite uzrokuju li aplikacije instalirane putem ADB-a/ADT-a poteškoće"</string>
<string name="bluetooth_show_devices_without_names_summary" msgid="780964354377854507">"Prikazivat će se Bluetooth uređaji bez naziva (samo MAC adrese)"</string>
<string name="bluetooth_disable_absolute_volume_summary" msgid="2006309932135547681">"Onemogućuje Bluetoothovu značajku apsolutne glasnoće ako udaljeni uređaji imaju poteškoća sa zvukom, kao što su neprihvatljiva glasnoća ili nepostojanje kontrole"</string>
- <string name="bluetooth_enable_gabeldorsche_summary" msgid="8472344901097607030">"Omogućuje nizove značajke Bluetooth Gabeldorche."</string>
+ <string name="bluetooth_enable_gabeldorsche_summary" msgid="2054730331770712629">"Omogućuje nizove značajke Bluetooth Gabeldorsche."</string>
<string name="enable_terminal_title" msgid="3834790541986303654">"Lokalni terminal"</string>
<string name="enable_terminal_summary" msgid="2481074834856064500">"Omogući aplikaciju terminala koja nudi pristup lokalnoj ovojnici"</string>
<string name="hdcp_checking_title" msgid="3155692785074095986">"HDCP provjera"</string>
diff --git a/packages/SettingsLib/res/values-hu/arrays.xml b/packages/SettingsLib/res/values-hu/arrays.xml
index 64d92e4d7377..608a9e0323a8 100644
--- a/packages/SettingsLib/res/values-hu/arrays.xml
+++ b/packages/SettingsLib/res/values-hu/arrays.xml
@@ -75,6 +75,16 @@
<item msgid="4398977131424970917">"avrcp15"</item>
<item msgid="1963366694959681026">"avrcp16"</item>
</string-array>
+ <string-array name="bluetooth_map_versions">
+ <item msgid="8786402640610987099">"MAP 1.2 (Alapértelmezett)"</item>
+ <item msgid="6817922176194686449">"MAP 1.3"</item>
+ <item msgid="3423518690032737851">"MAP 1.4"</item>
+ </string-array>
+ <string-array name="bluetooth_map_version_values">
+ <item msgid="1164651830068248391">"map12"</item>
+ <item msgid="7073042887003102964">"map13"</item>
+ <item msgid="8147982633566548515">"map14"</item>
+ </string-array>
<string-array name="bluetooth_a2dp_codec_titles">
<item msgid="2494959071796102843">"Rendszerérték (alapértelmezett)"</item>
<item msgid="4055460186095649420">"SBC"</item>
diff --git a/packages/SettingsLib/res/values-hu/strings.xml b/packages/SettingsLib/res/values-hu/strings.xml
index cb87e5628d88..d970c737c3d6 100644
--- a/packages/SettingsLib/res/values-hu/strings.xml
+++ b/packages/SettingsLib/res/values-hu/strings.xml
@@ -230,6 +230,8 @@
<string name="bluetooth_enable_gabeldorsche" msgid="9131730396242883416">"A Gabeldorsche engedélyezése"</string>
<string name="bluetooth_select_avrcp_version_string" msgid="1710571610177659127">"A Bluetooth AVRCP-verziója"</string>
<string name="bluetooth_select_avrcp_version_dialog_title" msgid="7846922290083709633">"A Bluetooth AVRCP-verziójának kiválasztása"</string>
+ <string name="bluetooth_select_map_version_string" msgid="526308145174175327">"A Bluetooth MAP-verziója"</string>
+ <string name="bluetooth_select_map_version_dialog_title" msgid="7085934373987428460">"A Bluetooth MAP-verziójának kiválasztása"</string>
<string name="bluetooth_select_a2dp_codec_type" msgid="952001408455456494">"Bluetooth hang – Kodek"</string>
<string name="bluetooth_select_a2dp_codec_type_dialog_title" msgid="7510542404227225545">"Bluetooth-hangkodek aktiválása\nKiválasztás"</string>
<string name="bluetooth_select_a2dp_codec_sample_rate" msgid="1638623076480928191">"Bluetooth hang – mintavételezési gyakoriság"</string>
@@ -276,7 +278,7 @@
<string name="verify_apps_over_usb_summary" msgid="1317933737581167839">"Az ADB/ADT útján telepített alkalmazások ellenőrzése kártékony viselkedésre."</string>
<string name="bluetooth_show_devices_without_names_summary" msgid="780964354377854507">"Név nélküli Bluetooth-eszközök jelennek meg (csak MAC-címekkel)"</string>
<string name="bluetooth_disable_absolute_volume_summary" msgid="2006309932135547681">"Letiltja a Bluetooth abszolút hangerő funkcióját a távoli eszközökkel kapcsolatos hangerőproblémák – például elfogadhatatlanul magas vagy nem vezérelhető hangerő – esetén."</string>
- <string name="bluetooth_enable_gabeldorsche_summary" msgid="8472344901097607030">"Engedélyezi a Bluetooth Gabeldorche funkcióit."</string>
+ <string name="bluetooth_enable_gabeldorsche_summary" msgid="2054730331770712629">"Engedélyezi a Bluetooth Gabeldorsche funkcióit."</string>
<string name="enable_terminal_title" msgid="3834790541986303654">"Helyi végpont"</string>
<string name="enable_terminal_summary" msgid="2481074834856064500">"Végalkalmazás engedélyezése a helyi rendszerhéj eléréséhez"</string>
<string name="hdcp_checking_title" msgid="3155692785074095986">"HDCP ellenőrzés"</string>
diff --git a/packages/SettingsLib/res/values-hy/arrays.xml b/packages/SettingsLib/res/values-hy/arrays.xml
index b1226f4d76a6..a2de6dfc7387 100644
--- a/packages/SettingsLib/res/values-hy/arrays.xml
+++ b/packages/SettingsLib/res/values-hy/arrays.xml
@@ -75,6 +75,16 @@
<item msgid="4398977131424970917">"avrcp15"</item>
<item msgid="1963366694959681026">"avrcp16"</item>
</string-array>
+ <string-array name="bluetooth_map_versions">
+ <item msgid="8786402640610987099">"MAP 1.2 (կանխադրված)"</item>
+ <item msgid="6817922176194686449">"MAP 1.3"</item>
+ <item msgid="3423518690032737851">"MAP 1.4"</item>
+ </string-array>
+ <string-array name="bluetooth_map_version_values">
+ <item msgid="1164651830068248391">"map12"</item>
+ <item msgid="7073042887003102964">"map13"</item>
+ <item msgid="8147982633566548515">"map14"</item>
+ </string-array>
<string-array name="bluetooth_a2dp_codec_titles">
<item msgid="2494959071796102843">"Օգտագործել համակարգի կարգավորումը (կանխադրված)"</item>
<item msgid="4055460186095649420">"SBC"</item>
diff --git a/packages/SettingsLib/res/values-hy/strings.xml b/packages/SettingsLib/res/values-hy/strings.xml
index 6c30d4ee942a..908693439de0 100644
--- a/packages/SettingsLib/res/values-hy/strings.xml
+++ b/packages/SettingsLib/res/values-hy/strings.xml
@@ -230,6 +230,8 @@
<string name="bluetooth_enable_gabeldorsche" msgid="9131730396242883416">"Միացնել Gabeldorsche-ը"</string>
<string name="bluetooth_select_avrcp_version_string" msgid="1710571610177659127">"Bluetooth AVRCP տարբերակը"</string>
<string name="bluetooth_select_avrcp_version_dialog_title" msgid="7846922290083709633">"Ընտրել Bluetooth AVRCP տարբերակը"</string>
+ <string name="bluetooth_select_map_version_string" msgid="526308145174175327">"Bluetooth MAP-ի տարբերակ"</string>
+ <string name="bluetooth_select_map_version_dialog_title" msgid="7085934373987428460">"Ընտրել Bluetooth MAP-ի տարբերակը"</string>
<string name="bluetooth_select_a2dp_codec_type" msgid="952001408455456494">"Bluetooth աուդիո կոդեկ"</string>
<string name="bluetooth_select_a2dp_codec_type_dialog_title" msgid="7510542404227225545">"Գործարկել Bluetooth աուդիո կոդեկը\nԸնտրություն"</string>
<string name="bluetooth_select_a2dp_codec_sample_rate" msgid="1638623076480928191">"Bluetooth աուդիոյի ընդհատավորման հաճախականությունը"</string>
@@ -276,7 +278,7 @@
<string name="verify_apps_over_usb_summary" msgid="1317933737581167839">"Ստուգել հավելվածների անվտանգությունը ADB/ADT-ի միջոցով տեղադրված լինելու դեպքում։"</string>
<string name="bluetooth_show_devices_without_names_summary" msgid="780964354377854507">"Bluetooth սարքերը կցուցադրվեն առանց անունների (միայն MAC հասցեները)"</string>
<string name="bluetooth_disable_absolute_volume_summary" msgid="2006309932135547681">"Կասեցնում է Bluetooth-ի ձայնի բացարձակ ուժգնության գործառույթը՝ հեռավոր սարքերի հետ ձայնի ուժգնությանը վերաբերող խնդիրներ ունենալու դեպքում (օրինակ՝ երբ ձայնի ուժգնությունն անընդունելի է կամ դրա կառավարումը հնարավոր չէ):"</string>
- <string name="bluetooth_enable_gabeldorsche_summary" msgid="8472344901097607030">"Միացնել Bluetooth Gabeldorche գործառույթի զտիչը"</string>
+ <string name="bluetooth_enable_gabeldorsche_summary" msgid="2054730331770712629">"Միացնել Bluetooth Gabeldorsche գործառույթի զտիչը"</string>
<string name="enable_terminal_title" msgid="3834790541986303654">"Տեղային տերմինալ"</string>
<string name="enable_terminal_summary" msgid="2481074834856064500">"Միացնել տերմինալային հավելվածը, որն առաջարկում է մուտք տեղային խեցի"</string>
<string name="hdcp_checking_title" msgid="3155692785074095986">"HDCP ստուգում"</string>
diff --git a/packages/SettingsLib/res/values-in/arrays.xml b/packages/SettingsLib/res/values-in/arrays.xml
index 9d2528a45255..e73febcb1aa4 100644
--- a/packages/SettingsLib/res/values-in/arrays.xml
+++ b/packages/SettingsLib/res/values-in/arrays.xml
@@ -75,6 +75,16 @@
<item msgid="4398977131424970917">"avrcp15"</item>
<item msgid="1963366694959681026">"avrcp16"</item>
</string-array>
+ <string-array name="bluetooth_map_versions">
+ <item msgid="8786402640610987099">"MAP 1.2 (Default)"</item>
+ <item msgid="6817922176194686449">"MAP 1.3"</item>
+ <item msgid="3423518690032737851">"MAP 1.4"</item>
+ </string-array>
+ <string-array name="bluetooth_map_version_values">
+ <item msgid="1164651830068248391">"map12"</item>
+ <item msgid="7073042887003102964">"map13"</item>
+ <item msgid="8147982633566548515">"map14"</item>
+ </string-array>
<string-array name="bluetooth_a2dp_codec_titles">
<item msgid="2494959071796102843">"Gunakan Pilihan Sistem (Default)"</item>
<item msgid="4055460186095649420">"SBC"</item>
diff --git a/packages/SettingsLib/res/values-in/strings.xml b/packages/SettingsLib/res/values-in/strings.xml
index 654c06cc7b10..3c1504c7f14a 100644
--- a/packages/SettingsLib/res/values-in/strings.xml
+++ b/packages/SettingsLib/res/values-in/strings.xml
@@ -230,6 +230,8 @@
<string name="bluetooth_enable_gabeldorsche" msgid="9131730396242883416">"Aktifkan Gabeldorsche"</string>
<string name="bluetooth_select_avrcp_version_string" msgid="1710571610177659127">"Versi AVRCP Bluetooth"</string>
<string name="bluetooth_select_avrcp_version_dialog_title" msgid="7846922290083709633">"Pilih Versi AVRCP Bluetooth"</string>
+ <string name="bluetooth_select_map_version_string" msgid="526308145174175327">"Versi MAP Bluetooth"</string>
+ <string name="bluetooth_select_map_version_dialog_title" msgid="7085934373987428460">"Pilih Versi Map Bluetooth"</string>
<string name="bluetooth_select_a2dp_codec_type" msgid="952001408455456494">"Codec Audio Bluetooth"</string>
<string name="bluetooth_select_a2dp_codec_type_dialog_title" msgid="7510542404227225545">"Aktifkan Codec Audio Bluetooth\nPilihan"</string>
<string name="bluetooth_select_a2dp_codec_sample_rate" msgid="1638623076480928191">"Frekuensi Sampel Audio Bluetooth"</string>
@@ -276,7 +278,7 @@
<string name="verify_apps_over_usb_summary" msgid="1317933737581167839">"Periksa perilaku membahayakan dalam aplikasi yang terpasang melalui ADB/ADT."</string>
<string name="bluetooth_show_devices_without_names_summary" msgid="780964354377854507">"Perangkat Bluetooth tanpa nama (hanya alamat MAC) akan ditampilkan"</string>
<string name="bluetooth_disable_absolute_volume_summary" msgid="2006309932135547681">"Menonaktifkan fitur volume absolut Bluetooth jika ada masalah volume dengan perangkat jarak jauh, misalnya volume terlalu keras atau kurangnya kontrol."</string>
- <string name="bluetooth_enable_gabeldorsche_summary" msgid="8472344901097607030">"Aktifkan stack fitur Gabeldorche Bluetooth."</string>
+ <string name="bluetooth_enable_gabeldorsche_summary" msgid="2054730331770712629">"Mengaktifkan stack fitur Gabeldorsche Bluetooth."</string>
<string name="enable_terminal_title" msgid="3834790541986303654">"Terminal lokal"</string>
<string name="enable_terminal_summary" msgid="2481074834856064500">"Aktifkan aplikasi terminal yang menawarkan akses kerangka lokal"</string>
<string name="hdcp_checking_title" msgid="3155692785074095986">"Pemeriksaan HDCP"</string>
diff --git a/packages/SettingsLib/res/values-is/arrays.xml b/packages/SettingsLib/res/values-is/arrays.xml
index 1ac19f1ecc48..07b2ef15ca29 100644
--- a/packages/SettingsLib/res/values-is/arrays.xml
+++ b/packages/SettingsLib/res/values-is/arrays.xml
@@ -75,6 +75,16 @@
<item msgid="4398977131424970917">"avrcp15"</item>
<item msgid="1963366694959681026">"avrcp16"</item>
</string-array>
+ <string-array name="bluetooth_map_versions">
+ <item msgid="8786402640610987099">"MAP 1.2 (sjálfgefið)"</item>
+ <item msgid="6817922176194686449">"MAP 1.3"</item>
+ <item msgid="3423518690032737851">"MAP 1.4"</item>
+ </string-array>
+ <string-array name="bluetooth_map_version_values">
+ <item msgid="1164651830068248391">"map12"</item>
+ <item msgid="7073042887003102964">"map13"</item>
+ <item msgid="8147982633566548515">"map14"</item>
+ </string-array>
<string-array name="bluetooth_a2dp_codec_titles">
<item msgid="2494959071796102843">"Nota val kerfisins (sjálfgefið)"</item>
<item msgid="4055460186095649420">"SBC"</item>
diff --git a/packages/SettingsLib/res/values-is/strings.xml b/packages/SettingsLib/res/values-is/strings.xml
index 86626152c077..438e900be4ba 100644
--- a/packages/SettingsLib/res/values-is/strings.xml
+++ b/packages/SettingsLib/res/values-is/strings.xml
@@ -230,6 +230,8 @@
<string name="bluetooth_enable_gabeldorsche" msgid="9131730396242883416">"Virkja Gabeldorsche"</string>
<string name="bluetooth_select_avrcp_version_string" msgid="1710571610177659127">"Bluetooth AVRCP-útgáfa"</string>
<string name="bluetooth_select_avrcp_version_dialog_title" msgid="7846922290083709633">"Velja Bluetooth AVRCP-útgáfu"</string>
+ <string name="bluetooth_select_map_version_string" msgid="526308145174175327">"Bluetooth MAP-útgáfa"</string>
+ <string name="bluetooth_select_map_version_dialog_title" msgid="7085934373987428460">"Veldu Bluetooth MAP-útgáfu"</string>
<string name="bluetooth_select_a2dp_codec_type" msgid="952001408455456494">"Bluetooth hljóðkóðari"</string>
<string name="bluetooth_select_a2dp_codec_type_dialog_title" msgid="7510542404227225545">"Virkja Bluetooth-hljóðkóðara\nVal"</string>
<string name="bluetooth_select_a2dp_codec_sample_rate" msgid="1638623076480928191">"Bluetooth hljóðtökutíðni"</string>
@@ -276,7 +278,7 @@
<string name="verify_apps_over_usb_summary" msgid="1317933737581167839">"Kanna skaðlega hegðun forrita sem sett eru upp frá ADB/ADT."</string>
<string name="bluetooth_show_devices_without_names_summary" msgid="780964354377854507">"Bluetooth-tæki án heita (aðeins MAC-vistfang) verða birt"</string>
<string name="bluetooth_disable_absolute_volume_summary" msgid="2006309932135547681">"Slekkur á samstillingu Bluetooth-hljóðstyrks ef vandamál koma upp með hljóðstyrk hjá fjartengdum tækjum, svo sem of hár hljóðstyrkur eða erfiðleikar við stjórnun."</string>
- <string name="bluetooth_enable_gabeldorsche_summary" msgid="8472344901097607030">"Virkjar Bluetooth Gabeldorche eiginleikastafla."</string>
+ <string name="bluetooth_enable_gabeldorsche_summary" msgid="2054730331770712629">"Kveikir á eiginleikastafla Bluetooth Gabeldorsche."</string>
<string name="enable_terminal_title" msgid="3834790541986303654">"Staðbundin skipanalína"</string>
<string name="enable_terminal_summary" msgid="2481074834856064500">"Virkja skipanalínuforrit sem leyfir staðbundinn skeljaraðgang"</string>
<string name="hdcp_checking_title" msgid="3155692785074095986">"HDCP-athugun"</string>
diff --git a/packages/SettingsLib/res/values-it/arrays.xml b/packages/SettingsLib/res/values-it/arrays.xml
index 44c519b0c20c..0bca8ea75212 100644
--- a/packages/SettingsLib/res/values-it/arrays.xml
+++ b/packages/SettingsLib/res/values-it/arrays.xml
@@ -75,6 +75,16 @@
<item msgid="4398977131424970917">"avrcp15"</item>
<item msgid="1963366694959681026">"avrcp16"</item>
</string-array>
+ <string-array name="bluetooth_map_versions">
+ <item msgid="8786402640610987099">"MAP 1.2 (versione predefinita)"</item>
+ <item msgid="6817922176194686449">"MAP 1.3"</item>
+ <item msgid="3423518690032737851">"MAP 1.4"</item>
+ </string-array>
+ <string-array name="bluetooth_map_version_values">
+ <item msgid="1164651830068248391">"map12"</item>
+ <item msgid="7073042887003102964">"map13"</item>
+ <item msgid="8147982633566548515">"map14"</item>
+ </string-array>
<string-array name="bluetooth_a2dp_codec_titles">
<item msgid="2494959071796102843">"Usa selezione di sistema (predefinita)"</item>
<item msgid="4055460186095649420">"SBC"</item>
diff --git a/packages/SettingsLib/res/values-it/strings.xml b/packages/SettingsLib/res/values-it/strings.xml
index 0e98d981859b..114b33b49206 100644
--- a/packages/SettingsLib/res/values-it/strings.xml
+++ b/packages/SettingsLib/res/values-it/strings.xml
@@ -230,6 +230,8 @@
<string name="bluetooth_enable_gabeldorsche" msgid="9131730396242883416">"Attiva Gabeldorsche"</string>
<string name="bluetooth_select_avrcp_version_string" msgid="1710571610177659127">"Versione Bluetooth AVRCP"</string>
<string name="bluetooth_select_avrcp_version_dialog_title" msgid="7846922290083709633">"Seleziona versione Bluetooth AVRCP"</string>
+ <string name="bluetooth_select_map_version_string" msgid="526308145174175327">"Versione Bluetooth MAP"</string>
+ <string name="bluetooth_select_map_version_dialog_title" msgid="7085934373987428460">"Seleziona versione Bluetooth MAP"</string>
<string name="bluetooth_select_a2dp_codec_type" msgid="952001408455456494">"Codec audio Bluetooth"</string>
<string name="bluetooth_select_a2dp_codec_type_dialog_title" msgid="7510542404227225545">"Attiva il codec audio Bluetooth\nSelezione"</string>
<string name="bluetooth_select_a2dp_codec_sample_rate" msgid="1638623076480928191">"Frequenza campionamento audio Bluetooth"</string>
@@ -276,7 +278,7 @@
<string name="verify_apps_over_usb_summary" msgid="1317933737581167839">"Controlla che le app installate tramite ADB/ADT non abbiano un comportamento dannoso"</string>
<string name="bluetooth_show_devices_without_names_summary" msgid="780964354377854507">"Verranno mostrati solo dispositivi Bluetooth senza nome (solo indirizzo MAC)"</string>
<string name="bluetooth_disable_absolute_volume_summary" msgid="2006309932135547681">"Disattiva la funzione del volume assoluto Bluetooth in caso di problemi con il volume dei dispositivi remoti, ad esempio un volume troppo alto o la mancanza di controllo"</string>
- <string name="bluetooth_enable_gabeldorsche_summary" msgid="8472344901097607030">"Consente di attivare lo stack delle funzionalità Bluetooth Gabeldorche."</string>
+ <string name="bluetooth_enable_gabeldorsche_summary" msgid="2054730331770712629">"Consente di attivare lo stack delle funzionalità Bluetooth Gabeldorsche."</string>
<string name="enable_terminal_title" msgid="3834790541986303654">"Terminale locale"</string>
<string name="enable_terminal_summary" msgid="2481074834856064500">"Abilita l\'app Terminale che offre l\'accesso alla shell locale"</string>
<string name="hdcp_checking_title" msgid="3155692785074095986">"Verifica HDCP"</string>
diff --git a/packages/SettingsLib/res/values-iw/arrays.xml b/packages/SettingsLib/res/values-iw/arrays.xml
index c8fc6d34c258..2f7f310eb8eb 100644
--- a/packages/SettingsLib/res/values-iw/arrays.xml
+++ b/packages/SettingsLib/res/values-iw/arrays.xml
@@ -75,6 +75,16 @@
<item msgid="4398977131424970917">"avrcp15"</item>
<item msgid="1963366694959681026">"avrcp16"</item>
</string-array>
+ <string-array name="bluetooth_map_versions">
+ <item msgid="8786402640610987099">"‏MAP 1.2 (ברירת מחדל)"</item>
+ <item msgid="6817922176194686449">"MAP 1.3"</item>
+ <item msgid="3423518690032737851">"MAP 1.4"</item>
+ </string-array>
+ <string-array name="bluetooth_map_version_values">
+ <item msgid="1164651830068248391">"map12"</item>
+ <item msgid="7073042887003102964">"map13"</item>
+ <item msgid="8147982633566548515">"map14"</item>
+ </string-array>
<string-array name="bluetooth_a2dp_codec_titles">
<item msgid="2494959071796102843">"שימוש בבחירת המערכת (ברירת המחדל)"</item>
<item msgid="4055460186095649420">"SBC"</item>
diff --git a/packages/SettingsLib/res/values-iw/strings.xml b/packages/SettingsLib/res/values-iw/strings.xml
index 30a6295d8e45..62085a85e243 100644
--- a/packages/SettingsLib/res/values-iw/strings.xml
+++ b/packages/SettingsLib/res/values-iw/strings.xml
@@ -230,6 +230,8 @@
<string name="bluetooth_enable_gabeldorsche" msgid="9131730396242883416">"‏הפעלת Gabeldorsche"</string>
<string name="bluetooth_select_avrcp_version_string" msgid="1710571610177659127">"‏Bluetooth גרסה AVRCP"</string>
<string name="bluetooth_select_avrcp_version_dialog_title" msgid="7846922290083709633">"‏בחר Bluetooth גרסה AVRCP"</string>
+ <string name="bluetooth_select_map_version_string" msgid="526308145174175327">"‏גרסת Bluetooth MAP"</string>
+ <string name="bluetooth_select_map_version_dialog_title" msgid="7085934373987428460">"‏יש לבחור גרסה של Bluetooth MAP"</string>
<string name="bluetooth_select_a2dp_codec_type" msgid="952001408455456494">"‏Codec אודיו ל-Bluetooth"</string>
<string name="bluetooth_select_a2dp_codec_type_dialog_title" msgid="7510542404227225545">"‏הפעלת ‏Codec אודיו ל-Bluetooth\nבחירה"</string>
<string name="bluetooth_select_a2dp_codec_sample_rate" msgid="1638623076480928191">"‏קצב דגימה של אודיו ל-Bluetooth"</string>
@@ -276,7 +278,7 @@
<string name="verify_apps_over_usb_summary" msgid="1317933737581167839">"‏בדוק אפליקציות שהותקנו באמצעות ADB/ADT לאיתור התנהגות מזיקה."</string>
<string name="bluetooth_show_devices_without_names_summary" msgid="780964354377854507">"‏יוצגו מכשירי Bluetooth ללא שמות (כתובות MAC בלבד)"</string>
<string name="bluetooth_disable_absolute_volume_summary" msgid="2006309932135547681">"‏משבית את תכונת עוצמת הקול המוחלטת ב-Bluetooth במקרה של בעיות בעוצמת הקול במכשירים מרוחקים, כגון עוצמת קול רמה מדי או חוסר שליטה ברמת העוצמה."</string>
- <string name="bluetooth_enable_gabeldorsche_summary" msgid="8472344901097607030">"‏הפעלת מקבץ הפיצ\'רים של Bluetooth Gabeldorche."</string>
+ <string name="bluetooth_enable_gabeldorsche_summary" msgid="2054730331770712629">"‏הפעלת מקבץ הפיצ\'רים של Bluetooth Gabeldorsche."</string>
<string name="enable_terminal_title" msgid="3834790541986303654">"מסוף מקומי"</string>
<string name="enable_terminal_summary" msgid="2481074834856064500">"הפעל אפליקציית מסוף המציעה גישה מקומית למעטפת"</string>
<string name="hdcp_checking_title" msgid="3155692785074095986">"‏בדיקת HDCP"</string>
diff --git a/packages/SettingsLib/res/values-ja/arrays.xml b/packages/SettingsLib/res/values-ja/arrays.xml
index fdc68c6864dc..2966f09c6c1b 100644
--- a/packages/SettingsLib/res/values-ja/arrays.xml
+++ b/packages/SettingsLib/res/values-ja/arrays.xml
@@ -75,6 +75,16 @@
<item msgid="4398977131424970917">"avrcp15"</item>
<item msgid="1963366694959681026">"avrcp16"</item>
</string-array>
+ <string-array name="bluetooth_map_versions">
+ <item msgid="8786402640610987099">"MAP 1.2(デフォルト)"</item>
+ <item msgid="6817922176194686449">"MAP 1.3"</item>
+ <item msgid="3423518690032737851">"MAP 1.4"</item>
+ </string-array>
+ <string-array name="bluetooth_map_version_values">
+ <item msgid="1164651830068248391">"map12"</item>
+ <item msgid="7073042887003102964">"map13"</item>
+ <item msgid="8147982633566548515">"map14"</item>
+ </string-array>
<string-array name="bluetooth_a2dp_codec_titles">
<item msgid="2494959071796102843">"システムの選択(デフォルト)を使用"</item>
<item msgid="4055460186095649420">"SBC"</item>
diff --git a/packages/SettingsLib/res/values-ja/strings.xml b/packages/SettingsLib/res/values-ja/strings.xml
index 22efe44f2162..28b98ee7c387 100644
--- a/packages/SettingsLib/res/values-ja/strings.xml
+++ b/packages/SettingsLib/res/values-ja/strings.xml
@@ -230,6 +230,8 @@
<string name="bluetooth_enable_gabeldorsche" msgid="9131730396242883416">"Gabeldorsche を有効にする"</string>
<string name="bluetooth_select_avrcp_version_string" msgid="1710571610177659127">"Bluetooth AVRCP バージョン"</string>
<string name="bluetooth_select_avrcp_version_dialog_title" msgid="7846922290083709633">"Bluetooth AVRCP バージョンを選択する"</string>
+ <string name="bluetooth_select_map_version_string" msgid="526308145174175327">"Bluetooth MAP バージョン"</string>
+ <string name="bluetooth_select_map_version_dialog_title" msgid="7085934373987428460">"Bluetooth MAP バージョンの選択"</string>
<string name="bluetooth_select_a2dp_codec_type" msgid="952001408455456494">"Bluetooth オーディオ コーデック"</string>
<string name="bluetooth_select_a2dp_codec_type_dialog_title" msgid="7510542404227225545">"Bluetooth オーディオ コーデックを起動\n選択"</string>
<string name="bluetooth_select_a2dp_codec_sample_rate" msgid="1638623076480928191">"Bluetooth オーディオ サンプルレート"</string>
@@ -276,7 +278,7 @@
<string name="verify_apps_over_usb_summary" msgid="1317933737581167839">"ADB/ADT経由でインストールされたアプリに不正な動作がないかを確認する"</string>
<string name="bluetooth_show_devices_without_names_summary" msgid="780964354377854507">"Bluetooth デバイスを名前なしで(MAC アドレスのみで)表示します"</string>
<string name="bluetooth_disable_absolute_volume_summary" msgid="2006309932135547681">"リモートデバイスで音量に関する問題(音量が大きすぎる、制御できないなど)が発生した場合に、Bluetooth の絶対音量の機能を無効にする"</string>
- <string name="bluetooth_enable_gabeldorsche_summary" msgid="8472344901097607030">"Bluetooth Gabeldorche 機能スタックを有効にします。"</string>
+ <string name="bluetooth_enable_gabeldorsche_summary" msgid="2054730331770712629">"Bluetooth Gabeldorsche 機能スタックを有効にします。"</string>
<string name="enable_terminal_title" msgid="3834790541986303654">"ローカルターミナル"</string>
<string name="enable_terminal_summary" msgid="2481074834856064500">"ローカルシェルアクセスを提供するターミナルアプリを有効にします"</string>
<string name="hdcp_checking_title" msgid="3155692785074095986">"HDCPチェック"</string>
diff --git a/packages/SettingsLib/res/values-ka/arrays.xml b/packages/SettingsLib/res/values-ka/arrays.xml
index dda3b0757d0e..5a86eaee772b 100644
--- a/packages/SettingsLib/res/values-ka/arrays.xml
+++ b/packages/SettingsLib/res/values-ka/arrays.xml
@@ -75,6 +75,16 @@
<item msgid="4398977131424970917">"avrcp15"</item>
<item msgid="1963366694959681026">"avrcp16"</item>
</string-array>
+ <string-array name="bluetooth_map_versions">
+ <item msgid="8786402640610987099">"MAP 1.2 (ნაგულისხმევი)"</item>
+ <item msgid="6817922176194686449">"MAP 1.3"</item>
+ <item msgid="3423518690032737851">"MAP 1.4"</item>
+ </string-array>
+ <string-array name="bluetooth_map_version_values">
+ <item msgid="1164651830068248391">"map12"</item>
+ <item msgid="7073042887003102964">"map13"</item>
+ <item msgid="8147982633566548515">"map14"</item>
+ </string-array>
<string-array name="bluetooth_a2dp_codec_titles">
<item msgid="2494959071796102843">"სისტემის არჩეულის გამოყენება (ნაგულისხმევი)"</item>
<item msgid="4055460186095649420">"SBC"</item>
diff --git a/packages/SettingsLib/res/values-ka/strings.xml b/packages/SettingsLib/res/values-ka/strings.xml
index 0139f586a6f9..6f5d0b39fc1f 100644
--- a/packages/SettingsLib/res/values-ka/strings.xml
+++ b/packages/SettingsLib/res/values-ka/strings.xml
@@ -230,6 +230,8 @@
<string name="bluetooth_enable_gabeldorsche" msgid="9131730396242883416">"Gabeldorsche-ის ჩართვა"</string>
<string name="bluetooth_select_avrcp_version_string" msgid="1710571610177659127">"Bluetooth-ის AVRCP-ის ვერსია"</string>
<string name="bluetooth_select_avrcp_version_dialog_title" msgid="7846922290083709633">"აირჩიეთ Bluetooth-ის AVRCP-ის ვერსია"</string>
+ <string name="bluetooth_select_map_version_string" msgid="526308145174175327">"Bluetooth MAP-ის ვერსია"</string>
+ <string name="bluetooth_select_map_version_dialog_title" msgid="7085934373987428460">"აირჩიეთ Bluetooth MAP-ის ვერსია"</string>
<string name="bluetooth_select_a2dp_codec_type" msgid="952001408455456494">"Bluetooth აუდიოს კოდეკი"</string>
<string name="bluetooth_select_a2dp_codec_type_dialog_title" msgid="7510542404227225545">"Bluetooth-ის აუდიო კოდეკის გაშვება\nარჩევანი"</string>
<string name="bluetooth_select_a2dp_codec_sample_rate" msgid="1638623076480928191">"Bluetooth აუდიოს დისკრეტიზაციის სიხშირე"</string>
@@ -276,7 +278,7 @@
<string name="verify_apps_over_usb_summary" msgid="1317933737581167839">"შეამოწმეთ, რამდენად უსაფრთხოა ADB/ADT-ის საშუალებით ინსტალირებული აპლიკაციები."</string>
<string name="bluetooth_show_devices_without_names_summary" msgid="780964354377854507">"Bluetooth-მოწყობილობები ნაჩვენები იქნება სახელების გარეშე (მხოლოდ MAC-მისამართები)"</string>
<string name="bluetooth_disable_absolute_volume_summary" msgid="2006309932135547681">"გათიშავს Bluetooth-ის ხმის აბსოლუტური სიძლიერის ფუნქციას დისტანციურ მოწყობილობებზე ხმასთან დაკავშირებული ისეთი პრობლემების არსებობის შემთხვევაში, როგორიცაა ხმის დაუშვებლად მაღალი სიძლიერე ან კონტროლის შეუძლებლობა."</string>
- <string name="bluetooth_enable_gabeldorsche_summary" msgid="8472344901097607030">"ჩართავს Bluetooth Gabeldorche-ის ფუნქციების დასტას."</string>
+ <string name="bluetooth_enable_gabeldorsche_summary" msgid="2054730331770712629">"ჩართავს Bluetooth Gabeldorsche-ის ფუნქციების დასტას."</string>
<string name="enable_terminal_title" msgid="3834790541986303654">"ადგილობრივი ტერმინალი"</string>
<string name="enable_terminal_summary" msgid="2481074834856064500">"ლოკალურ გარსზე წვდომის ტერმინალური აპლიკაციის ჩართვა"</string>
<string name="hdcp_checking_title" msgid="3155692785074095986">"HDCP შემოწმება"</string>
diff --git a/packages/SettingsLib/res/values-kk/arrays.xml b/packages/SettingsLib/res/values-kk/arrays.xml
index 70119c870865..3c96f43ca548 100644
--- a/packages/SettingsLib/res/values-kk/arrays.xml
+++ b/packages/SettingsLib/res/values-kk/arrays.xml
@@ -75,6 +75,16 @@
<item msgid="4398977131424970917">"avrcp15"</item>
<item msgid="1963366694959681026">"avrcp16"</item>
</string-array>
+ <string-array name="bluetooth_map_versions">
+ <item msgid="8786402640610987099">"MAP 1.2 (әдепкі)"</item>
+ <item msgid="6817922176194686449">"MAP 1.3"</item>
+ <item msgid="3423518690032737851">"MAP 1.4"</item>
+ </string-array>
+ <string-array name="bluetooth_map_version_values">
+ <item msgid="1164651830068248391">"map12"</item>
+ <item msgid="7073042887003102964">"map13"</item>
+ <item msgid="8147982633566548515">"map14"</item>
+ </string-array>
<string-array name="bluetooth_a2dp_codec_titles">
<item msgid="2494959071796102843">"Жүйенің таңдағанын алу (әдепкі)"</item>
<item msgid="4055460186095649420">"SBC"</item>
diff --git a/packages/SettingsLib/res/values-kk/strings.xml b/packages/SettingsLib/res/values-kk/strings.xml
index f7a773a95aa9..3fe426e6d027 100644
--- a/packages/SettingsLib/res/values-kk/strings.xml
+++ b/packages/SettingsLib/res/values-kk/strings.xml
@@ -230,6 +230,8 @@
<string name="bluetooth_enable_gabeldorsche" msgid="9131730396242883416">"Gabeldorsche функциясын іске қосу"</string>
<string name="bluetooth_select_avrcp_version_string" msgid="1710571610177659127">"Bluetooth AVRCP нұсқасы"</string>
<string name="bluetooth_select_avrcp_version_dialog_title" msgid="7846922290083709633">"Bluetooth AVRCP нұсқасын таңдау"</string>
+ <string name="bluetooth_select_map_version_string" msgid="526308145174175327">"Bluetooth MAP нұсқасы"</string>
+ <string name="bluetooth_select_map_version_dialog_title" msgid="7085934373987428460">"Bluetooth MAP нұсқасын таңдау"</string>
<string name="bluetooth_select_a2dp_codec_type" msgid="952001408455456494">"Bluetooth аудиокодегі"</string>
<string name="bluetooth_select_a2dp_codec_type_dialog_title" msgid="7510542404227225545">"Bluetooth аудиокодегін іске қосу\nТаңдау"</string>
<string name="bluetooth_select_a2dp_codec_sample_rate" msgid="1638623076480928191">"Bluetooth арқылы дыбыс іріктеу жиілігі"</string>
@@ -276,7 +278,7 @@
<string name="verify_apps_over_usb_summary" msgid="1317933737581167839">"ADB/ADT арқылы орнатылған қолданбалардың қауіпсіздігін тексеру."</string>
<string name="bluetooth_show_devices_without_names_summary" msgid="780964354377854507">"Bluetooth құрылғылары атаусыз (тек MAC мекенжайымен) көрсетіледі"</string>
<string name="bluetooth_disable_absolute_volume_summary" msgid="2006309932135547681">"Қашықтағы құрылғыларда дыбыстың тым қатты шығуы немесе реттеуге келмеуі сияқты дыбыс деңгейіне қатысты мәселелер туындағанда, Bluetooth абсолютті дыбыс деңгейі функциясын өшіреді."</string>
- <string name="bluetooth_enable_gabeldorsche_summary" msgid="8472344901097607030">"Bluetooth Gabeldorche функциясын іске қосады."</string>
+ <string name="bluetooth_enable_gabeldorsche_summary" msgid="2054730331770712629">"Bluetooth Gabeldorsche функциясы стегін қосады."</string>
<string name="enable_terminal_title" msgid="3834790541986303654">"Жергілікті терминал"</string>
<string name="enable_terminal_summary" msgid="2481074834856064500">"Жергілікті шелл-код қол жетімділігін ұсынатын терминалды қолданбаны қосу"</string>
<string name="hdcp_checking_title" msgid="3155692785074095986">"HDCP тексеру"</string>
diff --git a/packages/SettingsLib/res/values-km/arrays.xml b/packages/SettingsLib/res/values-km/arrays.xml
index 327754bd43aa..24efd08b7724 100644
--- a/packages/SettingsLib/res/values-km/arrays.xml
+++ b/packages/SettingsLib/res/values-km/arrays.xml
@@ -75,6 +75,16 @@
<item msgid="4398977131424970917">"avrcp15"</item>
<item msgid="1963366694959681026">"avrcp16"</item>
</string-array>
+ <string-array name="bluetooth_map_versions">
+ <item msgid="8786402640610987099">"MAP 1.2 (លំនាំដើម)"</item>
+ <item msgid="6817922176194686449">"MAP 1.3"</item>
+ <item msgid="3423518690032737851">"MAP 1.4"</item>
+ </string-array>
+ <string-array name="bluetooth_map_version_values">
+ <item msgid="1164651830068248391">"map12"</item>
+ <item msgid="7073042887003102964">"map13"</item>
+ <item msgid="8147982633566548515">"map14"</item>
+ </string-array>
<string-array name="bluetooth_a2dp_codec_titles">
<item msgid="2494959071796102843">"ប្រើ​ការ​ជ្រើសរើស​ប្រព័ន្ធ (លំនាំ​ដើម)"</item>
<item msgid="4055460186095649420">"SBC"</item>
diff --git a/packages/SettingsLib/res/values-km/strings.xml b/packages/SettingsLib/res/values-km/strings.xml
index 5c64a403cea8..24bfa35d2368 100644
--- a/packages/SettingsLib/res/values-km/strings.xml
+++ b/packages/SettingsLib/res/values-km/strings.xml
@@ -230,6 +230,8 @@
<string name="bluetooth_enable_gabeldorsche" msgid="9131730396242883416">"បើក Gabeldorsche"</string>
<string name="bluetooth_select_avrcp_version_string" msgid="1710571610177659127">"កំណែប្ល៊ូធូស AVRCP"</string>
<string name="bluetooth_select_avrcp_version_dialog_title" msgid="7846922290083709633">"ជ្រើសរើសកំណែប្ល៊ូធូស AVRCP"</string>
+ <string name="bluetooth_select_map_version_string" msgid="526308145174175327">"កំណែ​ប៊្លូធូស MAP"</string>
+ <string name="bluetooth_select_map_version_dialog_title" msgid="7085934373987428460">"ជ្រើសរើស​កំណែ​ប្ល៊ូធូស MAP"</string>
<string name="bluetooth_select_a2dp_codec_type" msgid="952001408455456494">"កូឌិក​សំឡេង​ប៊្លូធូស"</string>
<string name="bluetooth_select_a2dp_codec_type_dialog_title" msgid="7510542404227225545">"ជំរុញ​ការជ្រើសរើស​កូឌិក​សំឡេង​\n​ប៊្លូធូស"</string>
<string name="bluetooth_select_a2dp_codec_sample_rate" msgid="1638623076480928191">"អត្រា​គំរូ​សំឡេង​ប៊្លូធូស"</string>
@@ -276,7 +278,7 @@
<string name="verify_apps_over_usb_summary" msgid="1317933737581167839">"ពិនិត្យ​កម្មវិធី​បាន​ដំឡើង​តាម​រយៈ ADB/ADT សម្រាប់​ឥរិយាបថ​ដែល​គ្រោះ​ថ្នាក់។"</string>
<string name="bluetooth_show_devices_without_names_summary" msgid="780964354377854507">"​ឧបករណ៍​ប្ល៊ូធូសគ្មានឈ្មោះ​ (អាសយដ្ឋាន MAC តែប៉ុណ្ណោះ) នឹង​បង្ហាញ"</string>
<string name="bluetooth_disable_absolute_volume_summary" msgid="2006309932135547681">"បិទមុខងារកម្រិតសំឡេងឮខ្លាំងពេលភ្ជាប់ប៊្លូធូសក្នុងករណីមានបញ្ហាជាមួយឧបករណ៍បញ្ជាពីចម្ងាយ ដូចជាកម្រិតសំឡេងឮខ្លាំងដែលមិនអាចទទួលយកបាន ឬខ្វះការគ្រប់គ្រង។"</string>
- <string name="bluetooth_enable_gabeldorsche_summary" msgid="8472344901097607030">"បើក​ជង់​មុខងារ​ប៊្លូធូស Gabeldorche​។"</string>
+ <string name="bluetooth_enable_gabeldorsche_summary" msgid="2054730331770712629">"បើកជង់​មុខងារ​ប៊្លូធូស Gabeldorsche។"</string>
<string name="enable_terminal_title" msgid="3834790541986303654">"ស្ថានីយ​មូលដ្ឋាន"</string>
<string name="enable_terminal_summary" msgid="2481074834856064500">"បើក​កម្មវិធី​ស្ថានីយ​ដែល​ផ្ដល់​ការ​ចូល​សែល​មូលដ្ឋាន"</string>
<string name="hdcp_checking_title" msgid="3155692785074095986">"ពិនិត្យ HDCP"</string>
diff --git a/packages/SettingsLib/res/values-kn/arrays.xml b/packages/SettingsLib/res/values-kn/arrays.xml
index b06af1c13f45..4d8bde2d00ae 100644
--- a/packages/SettingsLib/res/values-kn/arrays.xml
+++ b/packages/SettingsLib/res/values-kn/arrays.xml
@@ -75,6 +75,16 @@
<item msgid="4398977131424970917">"avrcp15"</item>
<item msgid="1963366694959681026">"avrcp16"</item>
</string-array>
+ <string-array name="bluetooth_map_versions">
+ <item msgid="8786402640610987099">"MAP 1.2 (ಡೀಫಾಲ್ಟ್)"</item>
+ <item msgid="6817922176194686449">"MAP 1.3"</item>
+ <item msgid="3423518690032737851">"MAP 1.4"</item>
+ </string-array>
+ <string-array name="bluetooth_map_version_values">
+ <item msgid="1164651830068248391">"map12"</item>
+ <item msgid="7073042887003102964">"map13"</item>
+ <item msgid="8147982633566548515">"map14"</item>
+ </string-array>
<string-array name="bluetooth_a2dp_codec_titles">
<item msgid="2494959071796102843">"ಸಿಸ್ಟಂ ಆಯ್ಕೆಯನ್ನು ಬಳಸಿ (ಡಿಫಾಲ್ಟ್)"</item>
<item msgid="4055460186095649420">"SBC"</item>
diff --git a/packages/SettingsLib/res/values-kn/strings.xml b/packages/SettingsLib/res/values-kn/strings.xml
index 08a0db72df29..0699bbcd007a 100644
--- a/packages/SettingsLib/res/values-kn/strings.xml
+++ b/packages/SettingsLib/res/values-kn/strings.xml
@@ -230,6 +230,8 @@
<string name="bluetooth_enable_gabeldorsche" msgid="9131730396242883416">"Gabeldorsche ಅನ್ನು ಸಕ್ರಿಯಗೊಳಿಸಿ"</string>
<string name="bluetooth_select_avrcp_version_string" msgid="1710571610177659127">"ಬ್ಲೂಟೂತ್ AVRCP ಆವೃತ್ತಿ"</string>
<string name="bluetooth_select_avrcp_version_dialog_title" msgid="7846922290083709633">"ಬ್ಲೂಟೂತ್ AVRCP ಆವೃತ್ತಿಯನ್ನು ಆಯ್ಕೆ ಮಾಡಿ"</string>
+ <string name="bluetooth_select_map_version_string" msgid="526308145174175327">"ಬ್ಲೂಟೂತ್ MAP ಆವೃತ್ತಿ"</string>
+ <string name="bluetooth_select_map_version_dialog_title" msgid="7085934373987428460">"ಬ್ಲೂಟೂತ್ MAP ಆವೃತ್ತಿಯನ್ನು ಆಯ್ಕೆಮಾಡಿ"</string>
<string name="bluetooth_select_a2dp_codec_type" msgid="952001408455456494">"ಬ್ಲೂಟೂತ್ ಆಡಿಯೋ ಕೋಡೆಕ್"</string>
<string name="bluetooth_select_a2dp_codec_type_dialog_title" msgid="7510542404227225545">"ಬ್ಲೂಟೂತ್ ಆಡಿಯೋ ಕೋಡೆಕ್ ಅನ್ನು ಟ್ರಿಗ್ಗರ್ ಮಾಡಿ\nಆಯ್ಕೆ"</string>
<string name="bluetooth_select_a2dp_codec_sample_rate" msgid="1638623076480928191">"ಬ್ಲೂಟೂತ್ ಆಡಿಯೋ ಮಾದರಿ ದರ"</string>
@@ -276,7 +278,7 @@
<string name="verify_apps_over_usb_summary" msgid="1317933737581167839">"ಹಾನಿಮಾಡುವಂತಹ ವರ್ತನೆಗಾಗಿ ADB/ADT ಮೂಲಕ ಸ್ಥಾಪಿಸಲಾದ ಅಪ್ಲಿಕೇಶನ್‌ಗಳನ್ನು ಪರಿಶೀಲಿಸಿ."</string>
<string name="bluetooth_show_devices_without_names_summary" msgid="780964354377854507">"ಹೆಸರುಗಳಿಲ್ಲದ (ಕೇವಲ MAC ವಿಳಾಸಗಳು ಮಾತ್ರ) ಬ್ಲೂಟೂತ್ ಸಾಧನಗಳನ್ನು ಪ್ರದರ್ಶಿಸಲಾಗುತ್ತದೆ"</string>
<string name="bluetooth_disable_absolute_volume_summary" msgid="2006309932135547681">"ರಿಮೋಟ್ ಸಾಧನಗಳಲ್ಲಿ ಕಂಡುಬರುವ ಸ್ವೀಕಾರಾರ್ಹವಲ್ಲದ ಜೋರಾದ ವಾಲ್ಯೂಮ್ ಅಥವಾ ನಿಯಂತ್ರಣದ ಕೊರತೆಯಂತಹ ವಾಲ್ಯೂಮ್ ಸಮಸ್ಯೆಗಳಂತಹ ಸಂದರ್ಭದಲ್ಲಿ ಬ್ಲೂಟೂತ್‍ನ ನಿಚ್ಚಳ ವಾಲ್ಯೂಮ್ ವೈಶಿಷ್ಟ್ಯವನ್ನು ನಿಷ್ಕ್ರಿಯಗೊಳಿಸುತ್ತದೆ."</string>
- <string name="bluetooth_enable_gabeldorsche_summary" msgid="8472344901097607030">"ಬ್ಲೂಟೂತ್ Gabeldorche ವೈಶಿಷ್ಟ್ಯದ ಸ್ಟ್ಯಾಕ್‌ ಅನ್ನು ಸಕ್ರಿಯಗೊಳಿಸುತ್ತದೆ."</string>
+ <string name="bluetooth_enable_gabeldorsche_summary" msgid="2054730331770712629">"ಬ್ಲೂಟೂತ್ Gabeldorsche ವೈಶಿಷ್ಟ್ಯದ ಸ್ಟ್ಯಾಕ್‌ ಅನ್ನು ಸಕ್ರಿಯಗೊಳಿಸುತ್ತದೆ."</string>
<string name="enable_terminal_title" msgid="3834790541986303654">"ಸ್ಥಳೀಯ ಟರ್ಮಿನಲ್"</string>
<string name="enable_terminal_summary" msgid="2481074834856064500">"ಸ್ಥಳೀಯ ಶೆಲ್ ಪ್ರವೇಶವನ್ನು ಒದಗಿಸುವ ಟರ್ಮಿನಲ್ ಅಪ್ಲಿಕೇಶನ್ ಸಕ್ರಿಯಗೊಳಿಸಿ"</string>
<string name="hdcp_checking_title" msgid="3155692785074095986">"HDCP ಪರೀಕ್ಷಿಸುವಿಕೆ"</string>
diff --git a/packages/SettingsLib/res/values-ko/arrays.xml b/packages/SettingsLib/res/values-ko/arrays.xml
index 9f7a751e3d62..999f3ae0381a 100644
--- a/packages/SettingsLib/res/values-ko/arrays.xml
+++ b/packages/SettingsLib/res/values-ko/arrays.xml
@@ -75,6 +75,16 @@
<item msgid="4398977131424970917">"avrcp15"</item>
<item msgid="1963366694959681026">"avrcp16"</item>
</string-array>
+ <string-array name="bluetooth_map_versions">
+ <item msgid="8786402640610987099">"MAP 1.2(기본)"</item>
+ <item msgid="6817922176194686449">"MAP 1.3"</item>
+ <item msgid="3423518690032737851">"MAP 1.4"</item>
+ </string-array>
+ <string-array name="bluetooth_map_version_values">
+ <item msgid="1164651830068248391">"map12"</item>
+ <item msgid="7073042887003102964">"map13"</item>
+ <item msgid="8147982633566548515">"map14"</item>
+ </string-array>
<string-array name="bluetooth_a2dp_codec_titles">
<item msgid="2494959071796102843">"시스템 설정 사용(기본)"</item>
<item msgid="4055460186095649420">"SBC"</item>
diff --git a/packages/SettingsLib/res/values-ko/strings.xml b/packages/SettingsLib/res/values-ko/strings.xml
index d93b1cd7ea78..25e9cfe8fa1a 100644
--- a/packages/SettingsLib/res/values-ko/strings.xml
+++ b/packages/SettingsLib/res/values-ko/strings.xml
@@ -230,6 +230,8 @@
<string name="bluetooth_enable_gabeldorsche" msgid="9131730396242883416">"Gabeldorsche 사용 설정"</string>
<string name="bluetooth_select_avrcp_version_string" msgid="1710571610177659127">"블루투스 AVRCP 버전"</string>
<string name="bluetooth_select_avrcp_version_dialog_title" msgid="7846922290083709633">"블루투스 AVRCP 버전 선택"</string>
+ <string name="bluetooth_select_map_version_string" msgid="526308145174175327">"블루투스 MAP 버전"</string>
+ <string name="bluetooth_select_map_version_dialog_title" msgid="7085934373987428460">"블루투스 MAP 버전 선택"</string>
<string name="bluetooth_select_a2dp_codec_type" msgid="952001408455456494">"블루투스 오디오 코덱"</string>
<string name="bluetooth_select_a2dp_codec_type_dialog_title" msgid="7510542404227225545">"블루투스 오디오 코덱 실행\n선택"</string>
<string name="bluetooth_select_a2dp_codec_sample_rate" msgid="1638623076480928191">"블루투스 오디오 샘플링 비율"</string>
@@ -276,7 +278,7 @@
<string name="verify_apps_over_usb_summary" msgid="1317933737581167839">"ADB/ADT를 통해 설치된 앱에 유해한 동작이 있는지 확인"</string>
<string name="bluetooth_show_devices_without_names_summary" msgid="780964354377854507">"이름이 없이 MAC 주소만 있는 블루투스 기기 표시"</string>
<string name="bluetooth_disable_absolute_volume_summary" msgid="2006309932135547681">"참기 어려울 정도로 볼륨이 크거나 제어가 되지 않는 등 원격 기기에서 볼륨 문제가 발생할 경우 블루투스 절대 볼륨 기능을 사용 중지"</string>
- <string name="bluetooth_enable_gabeldorsche_summary" msgid="8472344901097607030">"블루투스 Gabeldorche 기능 스택을 사용 설정합니다."</string>
+ <string name="bluetooth_enable_gabeldorsche_summary" msgid="2054730331770712629">"블루투스 Gabeldorsche 기능 스택을 사용 설정합니다."</string>
<string name="enable_terminal_title" msgid="3834790541986303654">"로컬 터미널"</string>
<string name="enable_terminal_summary" msgid="2481074834856064500">"로컬 셸 액세스를 제공하는 터미널 앱 사용"</string>
<string name="hdcp_checking_title" msgid="3155692785074095986">"HDCP 확인"</string>
diff --git a/packages/SettingsLib/res/values-ky/arrays.xml b/packages/SettingsLib/res/values-ky/arrays.xml
index b2eaf9fee406..fd47dada3315 100644
--- a/packages/SettingsLib/res/values-ky/arrays.xml
+++ b/packages/SettingsLib/res/values-ky/arrays.xml
@@ -75,6 +75,16 @@
<item msgid="4398977131424970917">"avrcp15"</item>
<item msgid="1963366694959681026">"avrcp16"</item>
</string-array>
+ <string-array name="bluetooth_map_versions">
+ <item msgid="8786402640610987099">"КАРТА 1.2 (Демейки)"</item>
+ <item msgid="6817922176194686449">"КАРТА 1.3"</item>
+ <item msgid="3423518690032737851">"КАРТА 1.4"</item>
+ </string-array>
+ <string-array name="bluetooth_map_version_values">
+ <item msgid="1164651830068248391">"карта12"</item>
+ <item msgid="7073042887003102964">"карта13"</item>
+ <item msgid="8147982633566548515">"карта14"</item>
+ </string-array>
<string-array name="bluetooth_a2dp_codec_titles">
<item msgid="2494959071796102843">"Тутум тандаганды колдонуу (демейки)"</item>
<item msgid="4055460186095649420">"SBC"</item>
diff --git a/packages/SettingsLib/res/values-ky/strings.xml b/packages/SettingsLib/res/values-ky/strings.xml
index a24dd65ba8bb..3dfce1eb2a8a 100644
--- a/packages/SettingsLib/res/values-ky/strings.xml
+++ b/packages/SettingsLib/res/values-ky/strings.xml
@@ -230,6 +230,8 @@
<string name="bluetooth_enable_gabeldorsche" msgid="9131730396242883416">"Gabeldorsche функциясын иштетүү"</string>
<string name="bluetooth_select_avrcp_version_string" msgid="1710571610177659127">"Bluetooth AVRCP версиясы"</string>
<string name="bluetooth_select_avrcp_version_dialog_title" msgid="7846922290083709633">"Bluetooth AVRCP версиясын тандоо"</string>
+ <string name="bluetooth_select_map_version_string" msgid="526308145174175327">"Bluetooth MAP версиясы"</string>
+ <string name="bluetooth_select_map_version_dialog_title" msgid="7085934373987428460">"Bluetooth MAP версиясын тандоо"</string>
<string name="bluetooth_select_a2dp_codec_type" msgid="952001408455456494">"Bluetooth аудио кодек"</string>
<string name="bluetooth_select_a2dp_codec_type_dialog_title" msgid="7510542404227225545">"Bluetooth Audio кодегин иштетүү\nТандоо"</string>
<string name="bluetooth_select_a2dp_codec_sample_rate" msgid="1638623076480928191">"Bluetooth аудио үлгүсүнүн ылдамдыгы"</string>
@@ -276,7 +278,7 @@
<string name="verify_apps_over_usb_summary" msgid="1317933737581167839">"ADB/ADT аркылуу орнотулган колдонмолордун коопсуздугу текшерилет."</string>
<string name="bluetooth_show_devices_without_names_summary" msgid="780964354377854507">"Аталышсыз Bluetooth түзмөктөрү (MAC даректери менен гана) көрсөтүлөт"</string>
<string name="bluetooth_disable_absolute_volume_summary" msgid="2006309932135547681">"Алыскы түзмөктөр өтө катуу добуш чыгарып же көзөмөлдөнбөй жатса Bluetooth \"Үндүн абсолюттук деңгээли\" функциясын өчүрөт."</string>
- <string name="bluetooth_enable_gabeldorsche_summary" msgid="8472344901097607030">"Bluetooth Gabeldorche функциясынын топтомун иштетет."</string>
+ <string name="bluetooth_enable_gabeldorsche_summary" msgid="2054730331770712629">"Bluetooth Gabeldorsche функциясынын топтомун иштетет."</string>
<string name="enable_terminal_title" msgid="3834790541986303654">"Жергиликтүү терминал"</string>
<string name="enable_terminal_summary" msgid="2481074834856064500">"Жергиликтүү буйрук кабыгын сунуштаган терминалга уруксат берүү"</string>
<string name="hdcp_checking_title" msgid="3155692785074095986">"HDCP текшерүү"</string>
diff --git a/packages/SettingsLib/res/values-lo/arrays.xml b/packages/SettingsLib/res/values-lo/arrays.xml
index 7e7ea1f86615..5e25ab0790c7 100644
--- a/packages/SettingsLib/res/values-lo/arrays.xml
+++ b/packages/SettingsLib/res/values-lo/arrays.xml
@@ -75,6 +75,16 @@
<item msgid="4398977131424970917">"avrcp15"</item>
<item msgid="1963366694959681026">"avrcp16"</item>
</string-array>
+ <string-array name="bluetooth_map_versions">
+ <item msgid="8786402640610987099">"MAP 1.2 (Default)"</item>
+ <item msgid="6817922176194686449">"MAP 1.3"</item>
+ <item msgid="3423518690032737851">"MAP 1.4"</item>
+ </string-array>
+ <string-array name="bluetooth_map_version_values">
+ <item msgid="1164651830068248391">"map12"</item>
+ <item msgid="7073042887003102964">"map13"</item>
+ <item msgid="8147982633566548515">"map14"</item>
+ </string-array>
<string-array name="bluetooth_a2dp_codec_titles">
<item msgid="2494959071796102843">"ໃຊ້ການເລືອກຂອງລະບົບ (ຄ່າເລີ່ມຕົ້ນ)"</item>
<item msgid="4055460186095649420">"SBC"</item>
diff --git a/packages/SettingsLib/res/values-lo/strings.xml b/packages/SettingsLib/res/values-lo/strings.xml
index 3f93483f5239..48e50933c0ce 100644
--- a/packages/SettingsLib/res/values-lo/strings.xml
+++ b/packages/SettingsLib/res/values-lo/strings.xml
@@ -230,6 +230,8 @@
<string name="bluetooth_enable_gabeldorsche" msgid="9131730396242883416">"ເປີດໃຊ້ Gabeldorsche"</string>
<string name="bluetooth_select_avrcp_version_string" msgid="1710571610177659127">"ເວີຊັນ Bluetooth AVRCP"</string>
<string name="bluetooth_select_avrcp_version_dialog_title" msgid="7846922290083709633">"ເລືອກເວີຊັນ Bluetooth AVRCP"</string>
+ <string name="bluetooth_select_map_version_string" msgid="526308145174175327">"ເວີຊັນ Bluetooth MAP"</string>
+ <string name="bluetooth_select_map_version_dialog_title" msgid="7085934373987428460">"ເລືອກເວີຊັນ Bluetooth MAP"</string>
<string name="bluetooth_select_a2dp_codec_type" msgid="952001408455456494">"Bluetooth Audio Codec"</string>
<string name="bluetooth_select_a2dp_codec_type_dialog_title" msgid="7510542404227225545">"ເປີດໃຊ້ Bluetooth Audio Codec\nການເລືອກ"</string>
<string name="bluetooth_select_a2dp_codec_sample_rate" msgid="1638623076480928191">"Bluetooth Audio Sample Rate"</string>
@@ -276,7 +278,7 @@
<string name="verify_apps_over_usb_summary" msgid="1317933737581167839">"ກວດສອບແອັບທີ່ຕິດຕັ້ງແລ້ວຜ່ານທາງ ADB/ADT ເພື່ອກວດຫາພຶດຕິກຳທີ່ເປັນອັນຕະລາຍ."</string>
<string name="bluetooth_show_devices_without_names_summary" msgid="780964354377854507">"ຈະສະແດງອຸປະກອນ Bluetooth ທີ່ບໍ່ມີຊື່ (ທີ່ຢູ່ MAC ເທົ່ານັ້ນ)"</string>
<string name="bluetooth_disable_absolute_volume_summary" msgid="2006309932135547681">"ປິດໃຊ້ຄຸນສົມບັດລະດັບສຽງສົມບູນຂອງ Bluetooth ໃນກໍລະນີເກີດບັນຫາລະດັບສຽງສົມບູນກັບອຸປະກອນທາງໄກ ເຊັ່ນວ່າ ລະດັບສຽງດັງເກີນຍອມຮັບໄດ້ ຫຼື ຄວບຄຸມບໍ່ໄດ້."</string>
- <string name="bluetooth_enable_gabeldorsche_summary" msgid="8472344901097607030">"ເປີດໃຊ້ການວາງຊ້ອນຄຸນສົມບັດ Bluetooth Gabeldorche."</string>
+ <string name="bluetooth_enable_gabeldorsche_summary" msgid="2054730331770712629">"ເປີດໃຊ້ສະແຕັກຄຸນສົມບັດ Bluetooth Gabeldorsche."</string>
<string name="enable_terminal_title" msgid="3834790541986303654">"Terminal ໃນໂຕເຄື່ອງ"</string>
<string name="enable_terminal_summary" msgid="2481074834856064500">"ເປີດນຳໃຊ້ແອັບຯ Terminal ທີ່ໃຫ້ການເຂົ້າເຖິງ shell ໃນໂຕເຄື່ອງໄດ້"</string>
<string name="hdcp_checking_title" msgid="3155692785074095986">"ການກວດສອບ HDCP"</string>
diff --git a/packages/SettingsLib/res/values-lt/arrays.xml b/packages/SettingsLib/res/values-lt/arrays.xml
index 3356efb94dd5..e4b55ab04b02 100644
--- a/packages/SettingsLib/res/values-lt/arrays.xml
+++ b/packages/SettingsLib/res/values-lt/arrays.xml
@@ -75,6 +75,16 @@
<item msgid="4398977131424970917">"avrcp15"</item>
<item msgid="1963366694959681026">"avrcp16"</item>
</string-array>
+ <string-array name="bluetooth_map_versions">
+ <item msgid="8786402640610987099">"1.2 versijos MRK (numatytoji)"</item>
+ <item msgid="6817922176194686449">"1.3 versijos MRK"</item>
+ <item msgid="3423518690032737851">"1.4 versijos MRK"</item>
+ </string-array>
+ <string-array name="bluetooth_map_version_values">
+ <item msgid="1164651830068248391">"map12"</item>
+ <item msgid="7073042887003102964">"map13"</item>
+ <item msgid="8147982633566548515">"map14"</item>
+ </string-array>
<string-array name="bluetooth_a2dp_codec_titles">
<item msgid="2494959071796102843">"Naudoti sistemos pasirink. (numatytasis)"</item>
<item msgid="4055460186095649420">"SBC"</item>
diff --git a/packages/SettingsLib/res/values-lt/strings.xml b/packages/SettingsLib/res/values-lt/strings.xml
index 940909307b61..8b3fbadbfb39 100644
--- a/packages/SettingsLib/res/values-lt/strings.xml
+++ b/packages/SettingsLib/res/values-lt/strings.xml
@@ -230,6 +230,8 @@
<string name="bluetooth_enable_gabeldorsche" msgid="9131730396242883416">"Įgalinti „Gabeldorsche“"</string>
<string name="bluetooth_select_avrcp_version_string" msgid="1710571610177659127">"„Bluetooth“ AVRCP versija"</string>
<string name="bluetooth_select_avrcp_version_dialog_title" msgid="7846922290083709633">"Pasirinkite „Bluetooth“ AVRCP versiją"</string>
+ <string name="bluetooth_select_map_version_string" msgid="526308145174175327">"„Bluetooth“ MRK versija"</string>
+ <string name="bluetooth_select_map_version_dialog_title" msgid="7085934373987428460">"Pasirinkite „Bluetooth“ MRK versiją"</string>
<string name="bluetooth_select_a2dp_codec_type" msgid="952001408455456494">"„Bluetooth“ garso kodekas"</string>
<string name="bluetooth_select_a2dp_codec_type_dialog_title" msgid="7510542404227225545">"Suaktyvinti „Bluetooth“ garso kodeką\nPasirinkimas"</string>
<string name="bluetooth_select_a2dp_codec_sample_rate" msgid="1638623076480928191">"„Bluetooth“ garso pavyzdžio dažnis"</string>
@@ -276,7 +278,7 @@
<string name="verify_apps_over_usb_summary" msgid="1317933737581167839">"Patikrinkite, ar programų, įdiegtų naudojant ADB / ADT, veikimas nėra žalingas."</string>
<string name="bluetooth_show_devices_without_names_summary" msgid="780964354377854507">"Bus rodomi „Bluetooth“ įrenginiai be pavadinimų (tik MAC adresai)"</string>
<string name="bluetooth_disable_absolute_volume_summary" msgid="2006309932135547681">"Išjungiama „Bluetooth“ didžiausio garso funkcija, jei naudojant nuotolinio valdymo įrenginius kyla problemų dėl garso, pvz., garsas yra per didelis arba jo negalima tinkamai valdyti."</string>
- <string name="bluetooth_enable_gabeldorsche_summary" msgid="8472344901097607030">"Įgalinama „Bluetooth Gabeldorche“ funkcijų grupė."</string>
+ <string name="bluetooth_enable_gabeldorsche_summary" msgid="2054730331770712629">"Įgalinama „Bluetooth Gabeldorsche“ funkcijų grupė."</string>
<string name="enable_terminal_title" msgid="3834790541986303654">"Vietinis terminalas"</string>
<string name="enable_terminal_summary" msgid="2481074834856064500">"Įgal. terminalo progr., siūlančią prieigą prie viet. apvalkalo"</string>
<string name="hdcp_checking_title" msgid="3155692785074095986">"HDCP tikrinimas"</string>
diff --git a/packages/SettingsLib/res/values-lv/arrays.xml b/packages/SettingsLib/res/values-lv/arrays.xml
index 2f0f5072f06f..b90cf225758e 100644
--- a/packages/SettingsLib/res/values-lv/arrays.xml
+++ b/packages/SettingsLib/res/values-lv/arrays.xml
@@ -75,6 +75,16 @@
<item msgid="4398977131424970917">"avrcp15"</item>
<item msgid="1963366694959681026">"avrcp16"</item>
</string-array>
+ <string-array name="bluetooth_map_versions">
+ <item msgid="8786402640610987099">"MAP 1.2 (noklusējums)"</item>
+ <item msgid="6817922176194686449">"MAP 1.3"</item>
+ <item msgid="3423518690032737851">"MAP 1.4"</item>
+ </string-array>
+ <string-array name="bluetooth_map_version_values">
+ <item msgid="1164651830068248391">"map12"</item>
+ <item msgid="7073042887003102964">"map13"</item>
+ <item msgid="8147982633566548515">"map14"</item>
+ </string-array>
<string-array name="bluetooth_a2dp_codec_titles">
<item msgid="2494959071796102843">"Sistēmas atlases izmantošana (nokl.)"</item>
<item msgid="4055460186095649420">"SBC"</item>
diff --git a/packages/SettingsLib/res/values-lv/strings.xml b/packages/SettingsLib/res/values-lv/strings.xml
index b51b69af472c..4fc5b223c384 100644
--- a/packages/SettingsLib/res/values-lv/strings.xml
+++ b/packages/SettingsLib/res/values-lv/strings.xml
@@ -230,6 +230,8 @@
<string name="bluetooth_enable_gabeldorsche" msgid="9131730396242883416">"Iespējot Gabeldorsche"</string>
<string name="bluetooth_select_avrcp_version_string" msgid="1710571610177659127">"Bluetooth AVRCP versija"</string>
<string name="bluetooth_select_avrcp_version_dialog_title" msgid="7846922290083709633">"Atlasiet Bluetooth AVRCP versiju"</string>
+ <string name="bluetooth_select_map_version_string" msgid="526308145174175327">"Bluetooth MAP versija"</string>
+ <string name="bluetooth_select_map_version_dialog_title" msgid="7085934373987428460">"Atlasiet Bluetooth MAP versiju"</string>
<string name="bluetooth_select_a2dp_codec_type" msgid="952001408455456494">"Bluetooth audio kodeks"</string>
<string name="bluetooth_select_a2dp_codec_type_dialog_title" msgid="7510542404227225545">"Aktivizēt Bluetooth audio kodeku\nAtlase"</string>
<string name="bluetooth_select_a2dp_codec_sample_rate" msgid="1638623076480928191">"Bluetooth audio iztveršanas ātrums"</string>
@@ -276,7 +278,7 @@
<string name="verify_apps_over_usb_summary" msgid="1317933737581167839">"Pārbaudīt, vai lietotņu, kuru instalēšanai izmantots ADB/ADT, darbība nav kaitīga."</string>
<string name="bluetooth_show_devices_without_names_summary" msgid="780964354377854507">"Tiks parādītas Bluetooth ierīces bez nosaukumiem (tikai MAC adreses)."</string>
<string name="bluetooth_disable_absolute_volume_summary" msgid="2006309932135547681">"Atspējo Bluetooth absolūtā skaļuma funkciju skaļuma problēmu gadījumiem attālajās ierīcēs, piemēram, ja ir nepieņemami liels skaļums vai nav iespējas kontrolēt skaļumu."</string>
- <string name="bluetooth_enable_gabeldorsche_summary" msgid="8472344901097607030">"Šis iestatījums iespējo funkciju grupu Bluetooth Gabeldorche."</string>
+ <string name="bluetooth_enable_gabeldorsche_summary" msgid="2054730331770712629">"Tiek iespējota funkciju grupa Bluetooth Gabeldorsche."</string>
<string name="enable_terminal_title" msgid="3834790541986303654">"Vietējā beigu lietotne"</string>
<string name="enable_terminal_summary" msgid="2481074834856064500">"Iespējot beigu lietotni, kurā piedāvāta vietējā čaulas piekļuve"</string>
<string name="hdcp_checking_title" msgid="3155692785074095986">"HDCP pārbaude"</string>
diff --git a/packages/SettingsLib/res/values-mk/arrays.xml b/packages/SettingsLib/res/values-mk/arrays.xml
index 3753a51ab674..90956ad99e9e 100644
--- a/packages/SettingsLib/res/values-mk/arrays.xml
+++ b/packages/SettingsLib/res/values-mk/arrays.xml
@@ -75,6 +75,16 @@
<item msgid="4398977131424970917">"avrcp15"</item>
<item msgid="1963366694959681026">"avrcp16"</item>
</string-array>
+ <string-array name="bluetooth_map_versions">
+ <item msgid="8786402640610987099">"MAP 1.2 (стандардна)"</item>
+ <item msgid="6817922176194686449">"MAP 1.3"</item>
+ <item msgid="3423518690032737851">"MAP 1.4"</item>
+ </string-array>
+ <string-array name="bluetooth_map_version_values">
+ <item msgid="1164651830068248391">"map12"</item>
+ <item msgid="7073042887003102964">"map13"</item>
+ <item msgid="8147982633566548515">"map14"</item>
+ </string-array>
<string-array name="bluetooth_a2dp_codec_titles">
<item msgid="2494959071796102843">"Користи избор на системот (стандардно)"</item>
<item msgid="4055460186095649420">"SBC"</item>
diff --git a/packages/SettingsLib/res/values-mk/strings.xml b/packages/SettingsLib/res/values-mk/strings.xml
index d38301e74f32..288e526be4c9 100644
--- a/packages/SettingsLib/res/values-mk/strings.xml
+++ b/packages/SettingsLib/res/values-mk/strings.xml
@@ -230,6 +230,8 @@
<string name="bluetooth_enable_gabeldorsche" msgid="9131730396242883416">"Овозможи Gabeldorsche"</string>
<string name="bluetooth_select_avrcp_version_string" msgid="1710571610177659127">"Верзија Bluetooth AVRCP"</string>
<string name="bluetooth_select_avrcp_version_dialog_title" msgid="7846922290083709633">"Изберете верзија Bluetooth AVRCP"</string>
+ <string name="bluetooth_select_map_version_string" msgid="526308145174175327">"Верзија на Bluetooth MAP"</string>
+ <string name="bluetooth_select_map_version_dialog_title" msgid="7085934373987428460">"Изберете верзија на Bluetooth MAP"</string>
<string name="bluetooth_select_a2dp_codec_type" msgid="952001408455456494">"Кодек за аудио преку Bluetooth"</string>
<string name="bluetooth_select_a2dp_codec_type_dialog_title" msgid="7510542404227225545">"Вклучете го аудио кодекот преку Bluetooth\nСелекција"</string>
<string name="bluetooth_select_a2dp_codec_sample_rate" msgid="1638623076480928191">"Стапка на семпл преку Bluetooth"</string>
@@ -276,7 +278,7 @@
<string name="verify_apps_over_usb_summary" msgid="1317933737581167839">"Провери апликации инсталирани преку ADB/ADT за штетно однесување."</string>
<string name="bluetooth_show_devices_without_names_summary" msgid="780964354377854507">"Уредите со Bluetooth без имиња (само MAC-адреси) ќе се прикажуваат"</string>
<string name="bluetooth_disable_absolute_volume_summary" msgid="2006309932135547681">"Ја оневозможува карактеристиката за апсолутна јачина на звук преку Bluetooth во случај кога ќе настанат проблеми со далечинските уреди, како на пр., неприфатливо силен звук или недоволна контрола."</string>
- <string name="bluetooth_enable_gabeldorsche_summary" msgid="8472344901097607030">"Ја овозможува функцијата Bluetooth Gabeldorche."</string>
+ <string name="bluetooth_enable_gabeldorsche_summary" msgid="2054730331770712629">"Ја овозможува функцијата Bluetooth Gabeldorsche."</string>
<string name="enable_terminal_title" msgid="3834790541986303654">"Локален терминал"</string>
<string name="enable_terminal_summary" msgid="2481074834856064500">"Овозможи апликација на терминал што овозможува локален пристап кон школка."</string>
<string name="hdcp_checking_title" msgid="3155692785074095986">"Проверување HDCP"</string>
diff --git a/packages/SettingsLib/res/values-ml/arrays.xml b/packages/SettingsLib/res/values-ml/arrays.xml
index 1e0799420f06..60eb24ecded9 100644
--- a/packages/SettingsLib/res/values-ml/arrays.xml
+++ b/packages/SettingsLib/res/values-ml/arrays.xml
@@ -75,6 +75,16 @@
<item msgid="4398977131424970917">"avrcp15"</item>
<item msgid="1963366694959681026">"avrcp16"</item>
</string-array>
+ <string-array name="bluetooth_map_versions">
+ <item msgid="8786402640610987099">"MAP 1.2 (ഡിഫോൾട്ട്)"</item>
+ <item msgid="6817922176194686449">"MAP 1.3"</item>
+ <item msgid="3423518690032737851">"MAP 1.4"</item>
+ </string-array>
+ <string-array name="bluetooth_map_version_values">
+ <item msgid="1164651830068248391">"map12"</item>
+ <item msgid="7073042887003102964">"map13"</item>
+ <item msgid="8147982633566548515">"map14"</item>
+ </string-array>
<string-array name="bluetooth_a2dp_codec_titles">
<item msgid="2494959071796102843">"സിസ്റ്റം സെലക്ഷൻ ഉപയോഗിക്കൂ ‌(ഡിഫോൾട്ട്)"</item>
<item msgid="4055460186095649420">"SBC"</item>
diff --git a/packages/SettingsLib/res/values-ml/strings.xml b/packages/SettingsLib/res/values-ml/strings.xml
index 27019d105191..e775297982fd 100644
--- a/packages/SettingsLib/res/values-ml/strings.xml
+++ b/packages/SettingsLib/res/values-ml/strings.xml
@@ -230,6 +230,8 @@
<string name="bluetooth_enable_gabeldorsche" msgid="9131730396242883416">"Gabeldorsche പ്രവർത്തനക്ഷമമാക്കുക"</string>
<string name="bluetooth_select_avrcp_version_string" msgid="1710571610177659127">"Bluetooth AVRCP പതിപ്പ്"</string>
<string name="bluetooth_select_avrcp_version_dialog_title" msgid="7846922290083709633">"Bluetooth AVRCP പതിപ്പ് തിരഞ്ഞെടുക്കുക"</string>
+ <string name="bluetooth_select_map_version_string" msgid="526308145174175327">"Bluetooth MAP പതിപ്പ്"</string>
+ <string name="bluetooth_select_map_version_dialog_title" msgid="7085934373987428460">"Bluetooth MAP പതിപ്പ് തിരഞ്ഞെടുക്കുക"</string>
<string name="bluetooth_select_a2dp_codec_type" msgid="952001408455456494">"Bluetooth ഓഡിയോ കോഡെക്"</string>
<string name="bluetooth_select_a2dp_codec_type_dialog_title" msgid="7510542404227225545">"Bluetooth Audio Codec\nSelection ട്രിഗ്ഗര്‍ ചെയ്യുക"</string>
<string name="bluetooth_select_a2dp_codec_sample_rate" msgid="1638623076480928191">"Bluetooth ഓഡിയോ സാമ്പിൾ നിരക്ക്"</string>
@@ -276,7 +278,7 @@
<string name="verify_apps_over_usb_summary" msgid="1317933737581167839">"ADB/ADT വഴി ഇൻസ്റ്റാൾ ചെയ്‌ത കേടാക്കുന്ന പ്രവർത്തനരീതിയുള്ള ആപ്പുകൾ പരിശോധിക്കുക."</string>
<string name="bluetooth_show_devices_without_names_summary" msgid="780964354377854507">"പേരില്ലാത്ത Bluetooth ഉപകരണങ്ങൾ (MAC വിലാസങ്ങൾ മാത്രം) പ്രദർശിപ്പിക്കും"</string>
<string name="bluetooth_disable_absolute_volume_summary" msgid="2006309932135547681">"അസ്വീകാര്യമായ തരത്തിൽ ഉയർന്ന വോളിയമോ ശബ്ദ നിയന്ത്രണത്തിന്റെ അഭാവമോ പോലെ, വിദൂര ഉപകരണങ്ങളുമായി ബന്ധപ്പെട്ട വോളിയം പ്രശ്നങ്ങൾ ഉണ്ടാകുന്ന സാഹചര്യത്തിൽ, Bluetooth അബ്‌സൊല്യൂട്ട് വോളിയം ഫീച്ചർ പ്രവർത്തനരഹിതമാക്കുന്നു."</string>
- <string name="bluetooth_enable_gabeldorsche_summary" msgid="8472344901097607030">"Bluetooth Gabeldorche ഫീച്ചർ സ്‌റ്റാക്ക് പ്രവർത്തനക്ഷമമാക്കുന്നു."</string>
+ <string name="bluetooth_enable_gabeldorsche_summary" msgid="2054730331770712629">"Bluetooth Gabeldorsche ഫീച്ചർ സ്റ്റാക്ക് പ്രവർത്തനക്ഷമമാക്കുന്നു."</string>
<string name="enable_terminal_title" msgid="3834790541986303654">"പ്രാദേശിക ടെർമിനൽ"</string>
<string name="enable_terminal_summary" msgid="2481074834856064500">"പ്രാദേശിക ഷെൽ ആക്‌സസ് നൽകുന്ന ടെർമിനൽ അപ്ലിക്കേഷൻ പ്രവർത്തനക്ഷമമാക്കുക"</string>
<string name="hdcp_checking_title" msgid="3155692785074095986">"HDCP പരിശോധന"</string>
diff --git a/packages/SettingsLib/res/values-mn/arrays.xml b/packages/SettingsLib/res/values-mn/arrays.xml
index d1eca7be8321..ce868af26bc9 100644
--- a/packages/SettingsLib/res/values-mn/arrays.xml
+++ b/packages/SettingsLib/res/values-mn/arrays.xml
@@ -75,6 +75,16 @@
<item msgid="4398977131424970917">"avrcp15"</item>
<item msgid="1963366694959681026">"avrcp16"</item>
</string-array>
+ <string-array name="bluetooth_map_versions">
+ <item msgid="8786402640610987099">"MAP 1.2 (өгөгдмөл)"</item>
+ <item msgid="6817922176194686449">"MAP 1.3"</item>
+ <item msgid="3423518690032737851">"MAP 1.4"</item>
+ </string-array>
+ <string-array name="bluetooth_map_version_values">
+ <item msgid="1164651830068248391">"map12"</item>
+ <item msgid="7073042887003102964">"map13"</item>
+ <item msgid="8147982633566548515">"map14"</item>
+ </string-array>
<string-array name="bluetooth_a2dp_codec_titles">
<item msgid="2494959071796102843">"Системийн сонголтыг ашиглах (Өгөгдмөл)"</item>
<item msgid="4055460186095649420">"SBC"</item>
diff --git a/packages/SettingsLib/res/values-mn/strings.xml b/packages/SettingsLib/res/values-mn/strings.xml
index f0136c916758..ba69f9b654ab 100644
--- a/packages/SettingsLib/res/values-mn/strings.xml
+++ b/packages/SettingsLib/res/values-mn/strings.xml
@@ -230,6 +230,8 @@
<string name="bluetooth_enable_gabeldorsche" msgid="9131730396242883416">"Gabeldorsche-г идэвхжүүлэх"</string>
<string name="bluetooth_select_avrcp_version_string" msgid="1710571610177659127">"Bluetooth AVRCP хувилбар"</string>
<string name="bluetooth_select_avrcp_version_dialog_title" msgid="7846922290083709633">"Bluetooth AVRCP хувилбарыг сонгох"</string>
+ <string name="bluetooth_select_map_version_string" msgid="526308145174175327">"Bluetooth MAP хувилбар"</string>
+ <string name="bluetooth_select_map_version_dialog_title" msgid="7085934373987428460">"Bluetooth MAP хувилбарыг сонгох"</string>
<string name="bluetooth_select_a2dp_codec_type" msgid="952001408455456494">"Bluetooth аудио кодлогч"</string>
<string name="bluetooth_select_a2dp_codec_type_dialog_title" msgid="7510542404227225545">"Bluetooth-н аудио кодлогчийг өдөөх\nСонголт"</string>
<string name="bluetooth_select_a2dp_codec_sample_rate" msgid="1638623076480928191">"Bluetooth аудио жишээний үнэлгээ"</string>
@@ -276,7 +278,7 @@
<string name="verify_apps_over_usb_summary" msgid="1317933737581167839">"ADB/ADT-р суулгасан апп-уудыг хорлонтой авиртай эсэхийг шалгах."</string>
<string name="bluetooth_show_devices_without_names_summary" msgid="780964354377854507">"Нэргүй Bluetooth төхөөрөмжийг (зөвхөн MAC хаяг) харуулна"</string>
<string name="bluetooth_disable_absolute_volume_summary" msgid="2006309932135547681">"Хэт чанга дуугаралт эсвэл муу тохиргоо зэрэг алсын зайн төхөөрөмжийн дуугаралттай холбоотой асуудлын үед Bluetooth-ийн үнэмлэхүй дууны түвшинг идэвхгүй болго."</string>
- <string name="bluetooth_enable_gabeldorsche_summary" msgid="8472344901097607030">"Bluetooth Gabeldorsche онцлогийн өрөлтийг идэвхжүүлдэг."</string>
+ <string name="bluetooth_enable_gabeldorsche_summary" msgid="2054730331770712629">"Bluetooth Gabeldorsche онцлогийн өрөлтийг идэвхжүүлдэг."</string>
<string name="enable_terminal_title" msgid="3834790541986303654">"Локал терминал"</string>
<string name="enable_terminal_summary" msgid="2481074834856064500">"Локал суурьт хандалт хийх боломж олгодог терминалын апп-г идэвхжүүлэх"</string>
<string name="hdcp_checking_title" msgid="3155692785074095986">"HDCP шалгах"</string>
diff --git a/packages/SettingsLib/res/values-mr/arrays.xml b/packages/SettingsLib/res/values-mr/arrays.xml
index e62e6ff53f0c..3e6e3d0edf17 100644
--- a/packages/SettingsLib/res/values-mr/arrays.xml
+++ b/packages/SettingsLib/res/values-mr/arrays.xml
@@ -75,6 +75,16 @@
<item msgid="4398977131424970917">"avrcp15"</item>
<item msgid="1963366694959681026">"avrcp16"</item>
</string-array>
+ <string-array name="bluetooth_map_versions">
+ <item msgid="8786402640610987099">"MAP 1.2 (डीफॉल्ट)"</item>
+ <item msgid="6817922176194686449">"MAP 1.3"</item>
+ <item msgid="3423518690032737851">"MAP 1.4"</item>
+ </string-array>
+ <string-array name="bluetooth_map_version_values">
+ <item msgid="1164651830068248391">"map12"</item>
+ <item msgid="7073042887003102964">"map13"</item>
+ <item msgid="8147982633566548515">"map14"</item>
+ </string-array>
<string-array name="bluetooth_a2dp_codec_titles">
<item msgid="2494959071796102843">"सिस्टम निवड वापरा (डीफॉल्ट)"</item>
<item msgid="4055460186095649420">"SBC"</item>
diff --git a/packages/SettingsLib/res/values-mr/strings.xml b/packages/SettingsLib/res/values-mr/strings.xml
index 4d8069e8b9ea..1930cdf75e38 100644
--- a/packages/SettingsLib/res/values-mr/strings.xml
+++ b/packages/SettingsLib/res/values-mr/strings.xml
@@ -230,6 +230,8 @@
<string name="bluetooth_enable_gabeldorsche" msgid="9131730396242883416">"गाबलडॉर्ष सुरू करा"</string>
<string name="bluetooth_select_avrcp_version_string" msgid="1710571610177659127">"ब्लूटूथ AVRCP आवृत्ती"</string>
<string name="bluetooth_select_avrcp_version_dialog_title" msgid="7846922290083709633">"ब्लूटूथ AVRCP आवृत्ती निवडा"</string>
+ <string name="bluetooth_select_map_version_string" msgid="526308145174175327">"ब्लूटूथ MAP आवृत्ती"</string>
+ <string name="bluetooth_select_map_version_dialog_title" msgid="7085934373987428460">"ब्लूटूथ MAP आवृत्ती निवडा"</string>
<string name="bluetooth_select_a2dp_codec_type" msgid="952001408455456494">"ब्लूटूथ ऑडिओ कोडेक"</string>
<string name="bluetooth_select_a2dp_codec_type_dialog_title" msgid="7510542404227225545">"ब्लूटूथ ऑडिओ Codec ट्रिगर करा\nनिवड"</string>
<string name="bluetooth_select_a2dp_codec_sample_rate" msgid="1638623076480928191">"ब्लूटूथ ऑडिओ पॅटर्न दर"</string>
@@ -276,7 +278,7 @@
<string name="verify_apps_over_usb_summary" msgid="1317933737581167839">"हानिकारक वर्तनासाठी ADB/ADT द्वारे इंस्टॉल अ‍ॅप्स तपासा."</string>
<string name="bluetooth_show_devices_without_names_summary" msgid="780964354377854507">"नावांशिवाय ब्‍लूटूथ डीव्‍हाइस (फक्‍त MAC पत्‍ते) दाखवले जातील"</string>
<string name="bluetooth_disable_absolute_volume_summary" msgid="2006309932135547681">"रिमोट डिव्हाइसमध्ये सहन न होणारा मोठा आवाज किंवा नियंत्रणाचा अभाव यासारखी आवाजाची समस्या असल्यास ब्लूटूथ संपूर्ण आवाज वैशिष्ट्य बंद करते."</string>
- <string name="bluetooth_enable_gabeldorsche_summary" msgid="8472344901097607030">"ब्लूटूथ गाबलडॉर्ष वैशिष्ट्य स्टॅक सुरू करते."</string>
+ <string name="bluetooth_enable_gabeldorsche_summary" msgid="2054730331770712629">"ब्लूटूथ गाबलडॉर्ष वैशिष्‍ट्य स्टॅक सुरू करा."</string>
<string name="enable_terminal_title" msgid="3834790541986303654">"स्थानिक टर्मिनल"</string>
<string name="enable_terminal_summary" msgid="2481074834856064500">"स्थानिक शेल प्रवेश देणारा टर्मिनल अ‍ॅप सुरू करा"</string>
<string name="hdcp_checking_title" msgid="3155692785074095986">"HDCP तपासणी"</string>
diff --git a/packages/SettingsLib/res/values-ms/arrays.xml b/packages/SettingsLib/res/values-ms/arrays.xml
index 91dd81c62432..a2d314b01e50 100644
--- a/packages/SettingsLib/res/values-ms/arrays.xml
+++ b/packages/SettingsLib/res/values-ms/arrays.xml
@@ -75,6 +75,16 @@
<item msgid="4398977131424970917">"avrcp15"</item>
<item msgid="1963366694959681026">"avrcp16"</item>
</string-array>
+ <string-array name="bluetooth_map_versions">
+ <item msgid="8786402640610987099">"MAP 1.2 (Lalai)"</item>
+ <item msgid="6817922176194686449">"MAP 1.3"</item>
+ <item msgid="3423518690032737851">"MAP 1.4"</item>
+ </string-array>
+ <string-array name="bluetooth_map_version_values">
+ <item msgid="1164651830068248391">"map12"</item>
+ <item msgid="7073042887003102964">"map13"</item>
+ <item msgid="8147982633566548515">"map14"</item>
+ </string-array>
<string-array name="bluetooth_a2dp_codec_titles">
<item msgid="2494959071796102843">"Gunakan Pilihan Sistem (Lalai)"</item>
<item msgid="4055460186095649420">"SBC"</item>
diff --git a/packages/SettingsLib/res/values-ms/strings.xml b/packages/SettingsLib/res/values-ms/strings.xml
index 7efc987598c3..e4931883bacd 100644
--- a/packages/SettingsLib/res/values-ms/strings.xml
+++ b/packages/SettingsLib/res/values-ms/strings.xml
@@ -230,6 +230,8 @@
<string name="bluetooth_enable_gabeldorsche" msgid="9131730396242883416">"Dayakan Gabeldorsche"</string>
<string name="bluetooth_select_avrcp_version_string" msgid="1710571610177659127">"Versi AVRCP Bluetooth"</string>
<string name="bluetooth_select_avrcp_version_dialog_title" msgid="7846922290083709633">"Pilih Versi AVRCP Bluetooth"</string>
+ <string name="bluetooth_select_map_version_string" msgid="526308145174175327">"Versi MAP Bluetooth"</string>
+ <string name="bluetooth_select_map_version_dialog_title" msgid="7085934373987428460">"Pilih Versi MAP Bluetooth"</string>
<string name="bluetooth_select_a2dp_codec_type" msgid="952001408455456494">"Codec Audio Bluetooth"</string>
<string name="bluetooth_select_a2dp_codec_type_dialog_title" msgid="7510542404227225545">"Cetuskan Codec Audio Bluetooth\nPilihan"</string>
<string name="bluetooth_select_a2dp_codec_sample_rate" msgid="1638623076480928191">"Kadar Sampel Audio Bluetooth"</string>
@@ -276,7 +278,7 @@
<string name="verify_apps_over_usb_summary" msgid="1317933737581167839">"Semak apl yang dipasang melalui ADB/ADT untuk tingkah laku yang berbahaya."</string>
<string name="bluetooth_show_devices_without_names_summary" msgid="780964354377854507">"Peranti Bluetooth tanpa nama (alamat MAC sahaja) akan dipaparkan"</string>
<string name="bluetooth_disable_absolute_volume_summary" msgid="2006309932135547681">"Lumpuhkan ciri kelantangan mutlak Bluetooth dalam kes isu kelantangan menggunakan peranti kawalan jauh seperti kelantangan yang sangat kuat atau tidak dapat mengawal."</string>
- <string name="bluetooth_enable_gabeldorsche_summary" msgid="8472344901097607030">"Mendayakan tindanan ciri Bluetooth Gabeldorche."</string>
+ <string name="bluetooth_enable_gabeldorsche_summary" msgid="2054730331770712629">"Mendayakan tindanan ciri Gabeldorche Bluetooth."</string>
<string name="enable_terminal_title" msgid="3834790541986303654">"Terminal setempat"</string>
<string name="enable_terminal_summary" msgid="2481074834856064500">"Dayakan apl terminal yang menawarkan akses shell tempatan"</string>
<string name="hdcp_checking_title" msgid="3155692785074095986">"Penyemakan HDCP"</string>
diff --git a/packages/SettingsLib/res/values-my/arrays.xml b/packages/SettingsLib/res/values-my/arrays.xml
index 9c4a2b933b04..dbeabc0b90da 100644
--- a/packages/SettingsLib/res/values-my/arrays.xml
+++ b/packages/SettingsLib/res/values-my/arrays.xml
@@ -75,6 +75,16 @@
<item msgid="4398977131424970917">"avrcp15"</item>
<item msgid="1963366694959681026">"avrcp16"</item>
</string-array>
+ <string-array name="bluetooth_map_versions">
+ <item msgid="8786402640610987099">"MAP 1.2 (မူရင်း)"</item>
+ <item msgid="6817922176194686449">"MAP 1.3"</item>
+ <item msgid="3423518690032737851">"MAP 1.4"</item>
+ </string-array>
+ <string-array name="bluetooth_map_version_values">
+ <item msgid="1164651830068248391">"map12"</item>
+ <item msgid="7073042887003102964">"map13"</item>
+ <item msgid="8147982633566548515">"map14"</item>
+ </string-array>
<string-array name="bluetooth_a2dp_codec_titles">
<item msgid="2494959071796102843">"စနစ်ရွေးချယ်မှုကို အသုံးပြုပါ (မူရင်း)"</item>
<item msgid="4055460186095649420">"SBC"</item>
diff --git a/packages/SettingsLib/res/values-my/strings.xml b/packages/SettingsLib/res/values-my/strings.xml
index befdaa9e093d..2c4b32c04107 100644
--- a/packages/SettingsLib/res/values-my/strings.xml
+++ b/packages/SettingsLib/res/values-my/strings.xml
@@ -230,6 +230,8 @@
<string name="bluetooth_enable_gabeldorsche" msgid="9131730396242883416">"Gabeldorsche ကို ဖွင့်ရန်"</string>
<string name="bluetooth_select_avrcp_version_string" msgid="1710571610177659127">"ဘလူးတုသ် AVRCP ဗားရှင်း"</string>
<string name="bluetooth_select_avrcp_version_dialog_title" msgid="7846922290083709633">"ဘလူးတုသ် AVRCP ဗားရှင်းကို ရွေးပါ"</string>
+ <string name="bluetooth_select_map_version_string" msgid="526308145174175327">"ဘလူးတုသ် MAP ဗားရှင်း"</string>
+ <string name="bluetooth_select_map_version_dialog_title" msgid="7085934373987428460">"ဘလူးတုသ် MAP ဗားရှင်းကို ရွေးပါ"</string>
<string name="bluetooth_select_a2dp_codec_type" msgid="952001408455456494">"ဘလူးတုသ်အသံ ကိုးဒက်ခ်"</string>
<string name="bluetooth_select_a2dp_codec_type_dialog_title" msgid="7510542404227225545">"ဘလူးတုသ် အသံ LDAC ကိုးဒက်ခ် ဖွင့်ခြင်း\nရွေးချယ်မှု"</string>
<string name="bluetooth_select_a2dp_codec_sample_rate" msgid="1638623076480928191">"ဘလူးတုသ်အသံနမူနာနှုန်း"</string>
@@ -276,7 +278,7 @@
<string name="verify_apps_over_usb_summary" msgid="1317933737581167839">"ADB/ADT မှတစ်ဆင့် ထည့်သွင်းသော အက်ပ်များ အန္တရာယ်ဖြစ်နိုင်ခြင်း ရှိမရှိ စစ်ဆေးသည်။"</string>
<string name="bluetooth_show_devices_without_names_summary" msgid="780964354377854507">"အမည်မရှိသော (MAC လိပ်စာများသာပါသော) ဘလူးတုသ်စက်ပစ္စည်းများကို ပြသပါမည်"</string>
<string name="bluetooth_disable_absolute_volume_summary" msgid="2006309932135547681">"ချိတ်ဆက်ထားသည့် ကိရိယာတွင် လက်မခံနိုင်လောက်အောင် ဆူညံ သို့မဟုတ် ထိန်းညှိမရနိုင်သော အသံပိုင်းပြဿနာ ရှိခဲ့လျှင် ဘလူးတုသ် ပကတိ အသံနှုန်းကို ပိတ်ပါ။"</string>
- <string name="bluetooth_enable_gabeldorsche_summary" msgid="8472344901097607030">"ဘလူးတုသ် Gabeldorche အထူးတည်းဖြတ်ခြင်းကို ဖွင့်သည်။"</string>
+ <string name="bluetooth_enable_gabeldorsche_summary" msgid="2054730331770712629">"ဘလူးတုသ် Gabeldorsche လုပ်ဆောင်ချက်အပိုင်းကို ဖွင့်သည်။"</string>
<string name="enable_terminal_title" msgid="3834790541986303654">"လိုကယ်တာမီနယ်"</string>
<string name="enable_terminal_summary" msgid="2481074834856064500">"local shell အသုံးပြုခွင့်ကမ်းလှမ်းသော တာမင်နယ်အပလီကေးရှင်းဖွင့်ပါ"</string>
<string name="hdcp_checking_title" msgid="3155692785074095986">"HDCP စစ်ဆေးမှု"</string>
diff --git a/packages/SettingsLib/res/values-nb/arrays.xml b/packages/SettingsLib/res/values-nb/arrays.xml
index ed045ad549dd..8d005b32c19b 100644
--- a/packages/SettingsLib/res/values-nb/arrays.xml
+++ b/packages/SettingsLib/res/values-nb/arrays.xml
@@ -75,6 +75,16 @@
<item msgid="4398977131424970917">"avrcp15"</item>
<item msgid="1963366694959681026">"avrcp16"</item>
</string-array>
+ <string-array name="bluetooth_map_versions">
+ <item msgid="8786402640610987099">"MAP 1.2 (standard)"</item>
+ <item msgid="6817922176194686449">"MAP 1.3"</item>
+ <item msgid="3423518690032737851">"MAP 1.4"</item>
+ </string-array>
+ <string-array name="bluetooth_map_version_values">
+ <item msgid="1164651830068248391">"map12"</item>
+ <item msgid="7073042887003102964">"map13"</item>
+ <item msgid="8147982633566548515">"map14"</item>
+ </string-array>
<string-array name="bluetooth_a2dp_codec_titles">
<item msgid="2494959071796102843">"Bruk systemvalg (standard)"</item>
<item msgid="4055460186095649420">"SBC"</item>
diff --git a/packages/SettingsLib/res/values-nb/strings.xml b/packages/SettingsLib/res/values-nb/strings.xml
index cb0931f60502..093c06f20132 100644
--- a/packages/SettingsLib/res/values-nb/strings.xml
+++ b/packages/SettingsLib/res/values-nb/strings.xml
@@ -230,6 +230,8 @@
<string name="bluetooth_enable_gabeldorsche" msgid="9131730396242883416">"Aktiver Gabeldorsche"</string>
<string name="bluetooth_select_avrcp_version_string" msgid="1710571610177659127">"Bluetooth AVRCP-versjon"</string>
<string name="bluetooth_select_avrcp_version_dialog_title" msgid="7846922290083709633">"Velg Bluetooth AVRCP-versjon"</string>
+ <string name="bluetooth_select_map_version_string" msgid="526308145174175327">"Bluetooth MAP-versjon"</string>
+ <string name="bluetooth_select_map_version_dialog_title" msgid="7085934373987428460">"Velg Bluetooth MAP-versjon"</string>
<string name="bluetooth_select_a2dp_codec_type" msgid="952001408455456494">"Kodek for Bluetooth-lyd"</string>
<string name="bluetooth_select_a2dp_codec_type_dialog_title" msgid="7510542404227225545">"Utløs kodek for Bluetooth-lyd\nValg"</string>
<string name="bluetooth_select_a2dp_codec_sample_rate" msgid="1638623076480928191">"Samplefrekvens for Bluetooth-lyd"</string>
@@ -276,7 +278,7 @@
<string name="verify_apps_over_usb_summary" msgid="1317933737581167839">"Sjekk apper som er installert via ADB/ADT, for skadelig atferd."</string>
<string name="bluetooth_show_devices_without_names_summary" msgid="780964354377854507">"Bluetooth-enheter uten navn (bare MAC-adresser) vises"</string>
<string name="bluetooth_disable_absolute_volume_summary" msgid="2006309932135547681">"Slår av funksjonen for absolutt volum via Bluetooth i tilfelle det oppstår volumrelaterte problemer med eksterne enheter, for eksempel uakseptabelt høyt volum eller mangel på kontroll."</string>
- <string name="bluetooth_enable_gabeldorsche_summary" msgid="8472344901097607030">"Aktiverer funksjonsstabelen Bluetooth Gabeldorche."</string>
+ <string name="bluetooth_enable_gabeldorsche_summary" msgid="2054730331770712629">"Aktiverer funksjonsstabelen Bluetooth Gabeldorsche"</string>
<string name="enable_terminal_title" msgid="3834790541986303654">"Lokal terminal"</string>
<string name="enable_terminal_summary" msgid="2481074834856064500">"Aktiver terminalappen som gir lokal kommandolistetilgang"</string>
<string name="hdcp_checking_title" msgid="3155692785074095986">"HDCP-kontroll"</string>
diff --git a/packages/SettingsLib/res/values-ne/arrays.xml b/packages/SettingsLib/res/values-ne/arrays.xml
index c8ee48b86e5e..5d79e80608d0 100644
--- a/packages/SettingsLib/res/values-ne/arrays.xml
+++ b/packages/SettingsLib/res/values-ne/arrays.xml
@@ -75,6 +75,16 @@
<item msgid="4398977131424970917">"avrcp १५"</item>
<item msgid="1963366694959681026">"avrcp १६"</item>
</string-array>
+ <string-array name="bluetooth_map_versions">
+ <item msgid="8786402640610987099">"MAP १.२ (पूर्वनिर्धारित)"</item>
+ <item msgid="6817922176194686449">"MAP १.३"</item>
+ <item msgid="3423518690032737851">"MAP १.४"</item>
+ </string-array>
+ <string-array name="bluetooth_map_version_values">
+ <item msgid="1164651830068248391">"map12"</item>
+ <item msgid="7073042887003102964">"map13"</item>
+ <item msgid="8147982633566548515">"map14"</item>
+ </string-array>
<string-array name="bluetooth_a2dp_codec_titles">
<item msgid="2494959071796102843">"प्रणालीको चयन प्रयोग गर्नुहोस् (पूर्वनिर्धारित)"</item>
<item msgid="4055460186095649420">"SBC"</item>
diff --git a/packages/SettingsLib/res/values-ne/strings.xml b/packages/SettingsLib/res/values-ne/strings.xml
index c7ffc6400f1d..fb8b7377e35d 100644
--- a/packages/SettingsLib/res/values-ne/strings.xml
+++ b/packages/SettingsLib/res/values-ne/strings.xml
@@ -230,6 +230,8 @@
<string name="bluetooth_enable_gabeldorsche" msgid="9131730396242883416">"Gabeldorsche सक्षम पार्नुहोस्"</string>
<string name="bluetooth_select_avrcp_version_string" msgid="1710571610177659127">"ब्लुटुथको AVRCP संस्करण"</string>
<string name="bluetooth_select_avrcp_version_dialog_title" msgid="7846922290083709633">"ब्लुटुथको AVRCP संस्करण चयन गर्नुहोस्"</string>
+ <string name="bluetooth_select_map_version_string" msgid="526308145174175327">"ब्लुटुथको MAP संस्करण"</string>
+ <string name="bluetooth_select_map_version_dialog_title" msgid="7085934373987428460">"ब्लुटुथको MAP संस्करण चयन गर्नुहोस्"</string>
<string name="bluetooth_select_a2dp_codec_type" msgid="952001408455456494">"ब्लुटुथ अडियोको कोडेक"</string>
<string name="bluetooth_select_a2dp_codec_type_dialog_title" msgid="7510542404227225545">"ब्लुटुथ अडियो कोडेक ट्रिगर गर्नुहोस्\nचयन"</string>
<string name="bluetooth_select_a2dp_codec_sample_rate" msgid="1638623076480928191">"ब्लुटुथ अडियोको नमूना दर"</string>
@@ -276,7 +278,7 @@
<string name="verify_apps_over_usb_summary" msgid="1317933737581167839">"हानिकारक व्यवहारको लागि ADB/ADT को माध्यमबाट स्थापित अनुप्रयोगहरूको जाँच गर्नुहोस्।"</string>
<string name="bluetooth_show_devices_without_names_summary" msgid="780964354377854507">"नामकरण नगरिएका ब्लुटुथ यन्त्रहरू (MAC ठेगाना भएका मात्र) देखाइनेछ"</string>
<string name="bluetooth_disable_absolute_volume_summary" msgid="2006309932135547681">"रिमोट यन्त्रहरूमा अस्वीकार्य चर्को आवाज वा नियन्त्रणमा कमी जस्ता आवाज सम्बन्धी समस्याहरूको अवस्थामा ब्लुटुथ निरपेक्ष आवाज सुविधालाई असक्षम गराउँछ।"</string>
- <string name="bluetooth_enable_gabeldorsche_summary" msgid="8472344901097607030">"ब्लुटुथ Gabeldorche सुविधाको स्ट्याक सक्षम पार्नुहोस्।"</string>
+ <string name="bluetooth_enable_gabeldorsche_summary" msgid="2054730331770712629">"ब्लुटुथ Gabeldorsche सुविधाको स्ट्याक सक्षम पार्नुहोस्।"</string>
<string name="enable_terminal_title" msgid="3834790541986303654">"स्थानीय टर्मिनल"</string>
<string name="enable_terminal_summary" msgid="2481074834856064500">"स्थानीय सेल पहुँच प्रदान गर्ने टर्मिनल अनुप्रयोग सक्षम गर्नुहोस्"</string>
<string name="hdcp_checking_title" msgid="3155692785074095986">"HDCP जाँच गर्दै"</string>
diff --git a/packages/SettingsLib/res/values-nl/arrays.xml b/packages/SettingsLib/res/values-nl/arrays.xml
index d86dab687530..9b94ae503798 100644
--- a/packages/SettingsLib/res/values-nl/arrays.xml
+++ b/packages/SettingsLib/res/values-nl/arrays.xml
@@ -75,6 +75,16 @@
<item msgid="4398977131424970917">"avrcp15"</item>
<item msgid="1963366694959681026">"avrcp16"</item>
</string-array>
+ <string-array name="bluetooth_map_versions">
+ <item msgid="8786402640610987099">"MAP 1.2 (standaard)"</item>
+ <item msgid="6817922176194686449">"MAP 1.3"</item>
+ <item msgid="3423518690032737851">"MAP 1.4"</item>
+ </string-array>
+ <string-array name="bluetooth_map_version_values">
+ <item msgid="1164651830068248391">"map12"</item>
+ <item msgid="7073042887003102964">"map13"</item>
+ <item msgid="8147982633566548515">"map14"</item>
+ </string-array>
<string-array name="bluetooth_a2dp_codec_titles">
<item msgid="2494959071796102843">"Systeemselectie gebruiken (standaard)"</item>
<item msgid="4055460186095649420">"SBC"</item>
diff --git a/packages/SettingsLib/res/values-nl/strings.xml b/packages/SettingsLib/res/values-nl/strings.xml
index a196ccf1c651..267dab4cdee8 100644
--- a/packages/SettingsLib/res/values-nl/strings.xml
+++ b/packages/SettingsLib/res/values-nl/strings.xml
@@ -230,6 +230,8 @@
<string name="bluetooth_enable_gabeldorsche" msgid="9131730396242883416">"Gabeldorsche inschakelen"</string>
<string name="bluetooth_select_avrcp_version_string" msgid="1710571610177659127">"Bluetooth-AVRCP-versie"</string>
<string name="bluetooth_select_avrcp_version_dialog_title" msgid="7846922290083709633">"Bluetooth-AVRCP-versie selecteren"</string>
+ <string name="bluetooth_select_map_version_string" msgid="526308145174175327">"MAP-versie voor bluetooth"</string>
+ <string name="bluetooth_select_map_version_dialog_title" msgid="7085934373987428460">"MAP-versie voor bluetooth selecteren"</string>
<string name="bluetooth_select_a2dp_codec_type" msgid="952001408455456494">"Bluetooth-audiocodec"</string>
<string name="bluetooth_select_a2dp_codec_type_dialog_title" msgid="7510542404227225545">"Codec voor Bluetooth-audio activeren\nSelectie"</string>
<string name="bluetooth_select_a2dp_codec_sample_rate" msgid="1638623076480928191">"Sample rate van Bluetooth-audio"</string>
@@ -276,7 +278,7 @@
<string name="verify_apps_over_usb_summary" msgid="1317933737581167839">"Apps die zijn geïnstalleerd via ADB/ADT, controleren op schadelijk gedrag"</string>
<string name="bluetooth_show_devices_without_names_summary" msgid="780964354377854507">"Bluetooth-apparaten zonder namen (alleen MAC-adressen) worden weergegeven"</string>
<string name="bluetooth_disable_absolute_volume_summary" msgid="2006309932135547681">"Hiermee wordt de functie voor absoluut volume van Bluetooth uitgeschakeld in geval van volumeproblemen met externe apparaten, zoals een onacceptabel hoog volume of geen volumeregeling."</string>
- <string name="bluetooth_enable_gabeldorsche_summary" msgid="8472344901097607030">"Hierdoor wordt de Gabeldorsche-functiestack voor bluetooth ingeschakeld"</string>
+ <string name="bluetooth_enable_gabeldorsche_summary" msgid="2054730331770712629">"Hierdoor wordt de Gabeldorsche-functiestack voor bluetooth ingeschakeld."</string>
<string name="enable_terminal_title" msgid="3834790541986303654">"Lokale terminal"</string>
<string name="enable_terminal_summary" msgid="2481074834856064500">"Terminal-app inschakelen die lokale shell-toegang biedt"</string>
<string name="hdcp_checking_title" msgid="3155692785074095986">"HDCP-controle"</string>
diff --git a/packages/SettingsLib/res/values-or/arrays.xml b/packages/SettingsLib/res/values-or/arrays.xml
index 2553978a5742..a0214465125e 100644
--- a/packages/SettingsLib/res/values-or/arrays.xml
+++ b/packages/SettingsLib/res/values-or/arrays.xml
@@ -75,6 +75,16 @@
<item msgid="4398977131424970917">"avrcp15"</item>
<item msgid="1963366694959681026">"avrcp16"</item>
</string-array>
+ <string-array name="bluetooth_map_versions">
+ <item msgid="8786402640610987099">"MAP 1.2 (ଡିଫଲ୍ଟ)"</item>
+ <item msgid="6817922176194686449">"MAP 1.3"</item>
+ <item msgid="3423518690032737851">"MAP 1.4"</item>
+ </string-array>
+ <string-array name="bluetooth_map_version_values">
+ <item msgid="1164651830068248391">"map12"</item>
+ <item msgid="7073042887003102964">"map13"</item>
+ <item msgid="8147982633566548515">"map14"</item>
+ </string-array>
<string-array name="bluetooth_a2dp_codec_titles">
<item msgid="2494959071796102843">"ସିଷ୍ଟମ୍ ଚୟନ ବ୍ୟବହାର କରନ୍ତୁ (ଡିଫଲ୍ଟ)"</item>
<item msgid="4055460186095649420">"SBC"</item>
diff --git a/packages/SettingsLib/res/values-or/strings.xml b/packages/SettingsLib/res/values-or/strings.xml
index faa399dfe336..d8ae3bfb9a72 100644
--- a/packages/SettingsLib/res/values-or/strings.xml
+++ b/packages/SettingsLib/res/values-or/strings.xml
@@ -230,6 +230,8 @@
<string name="bluetooth_enable_gabeldorsche" msgid="9131730396242883416">"ଗାବେଲ୍‌ଡୋର୍ସ ସକ୍ରିୟ କରନ୍ତୁ"</string>
<string name="bluetooth_select_avrcp_version_string" msgid="1710571610177659127">"ବ୍ଲୁଟୂଥ୍‌ AVRCP ଭର୍ସନ୍"</string>
<string name="bluetooth_select_avrcp_version_dialog_title" msgid="7846922290083709633">"ବ୍ଲୁଟୂଥ୍‍‌ AVRCP ଭର୍ସନ୍‌"</string>
+ <string name="bluetooth_select_map_version_string" msgid="526308145174175327">"ବ୍ଲୁଟୁଥ୍ MAP ସଂସ୍କରଣ"</string>
+ <string name="bluetooth_select_map_version_dialog_title" msgid="7085934373987428460">"ବ୍ଲୁଟୁଥ୍ MAP ସଂସ୍କରଣ ଚୟନ କରନ୍ତୁ"</string>
<string name="bluetooth_select_a2dp_codec_type" msgid="952001408455456494">"ବ୍ଲୁଟୁଥ୍‌ ଅଡିଓ କୋଡେକ୍‌"</string>
<string name="bluetooth_select_a2dp_codec_type_dialog_title" msgid="7510542404227225545">"ବ୍ଲୁଟୂଥ୍‍ ଅଡିଓ କୋଡେକ୍\nସିଲେକ୍ସନ୍‌କୁ ଗତିଶୀଳ କରନ୍ତୁ"</string>
<string name="bluetooth_select_a2dp_codec_sample_rate" msgid="1638623076480928191">"ବ୍ଲୁଟୂଥ୍‌ ଅଡିଓ ସାମ୍ପଲ୍‌ ରେଟ୍‌"</string>
@@ -276,7 +278,7 @@
<string name="verify_apps_over_usb_summary" msgid="1317933737581167839">"ADB/ADT ମାଧ୍ୟମରେ ଇନଷ୍ଟଲ ହୋଇଥିବା ଆପ୍‌ଗୁଡ଼ିକ କ୍ଷତିକାରକ କି ନୁହେଁ ଯାଞ୍ଚ କରନ୍ତୁ।"</string>
<string name="bluetooth_show_devices_without_names_summary" msgid="780964354377854507">"(କେବଳ MAC ଠିକଣା ଥାଇ) ନାମ ବିନା ବ୍ଲୁଟୂଥ ଡିଭାଇସଗୁଡ଼ିକ ପ୍ରଦର୍ଶିତ ହେବ"</string>
<string name="bluetooth_disable_absolute_volume_summary" msgid="2006309932135547681">"ରିମୋଟ୍‌ ଡିଭାଇସ୍‌ଗୁଡ଼ିକରେ ଯଦି ଅସ୍ୱୀକାର୍ଯ୍ୟ ଭାବେ ଉଚ୍ଚ ଭଲ୍ୟୁମ୍ କିମ୍ବା ନିୟନ୍ତ୍ରଣର ଅଭାବ ପରି ଭଲ୍ୟୁମ୍ ସମସ୍ୟା ଥାଏ, ବ୍ଲୁଟୂଥ୍‌ ପୂର୍ଣ୍ଣ ଭଲ୍ୟୁମ୍ ଫିଚର୍ ଅକ୍ଷମ କରିଥାଏ।"</string>
- <string name="bluetooth_enable_gabeldorsche_summary" msgid="8472344901097607030">"ବ୍ଲୁଟୁଥ୍ ଗାବେଲ୍‌ଡୋର୍ସ ଫିଚର୍ ଷ୍ଟକ୍ ସକ୍ଷମ କରେ।"</string>
+ <string name="bluetooth_enable_gabeldorsche_summary" msgid="2054730331770712629">"ବ୍ଲୁଟୁଥ୍ ଗାବେଲଡୋର୍ସ ଫିଚର୍ ଷ୍ଟକ୍ ସକ୍ଷମ କରେ।"</string>
<string name="enable_terminal_title" msgid="3834790541986303654">"ସ୍ଥାନୀୟ ଟର୍ମିନାଲ୍‌"</string>
<string name="enable_terminal_summary" msgid="2481074834856064500">"ସ୍ଥାନୀୟ ଶେଲ୍‌କୁ ଆକ‌ସେସ୍‌ ଦେଉଥିବା ଟର୍ମିନଲ୍‌ ଆପ୍‌କୁ ସକ୍ଷମ କରନ୍ତୁ"</string>
<string name="hdcp_checking_title" msgid="3155692785074095986">"HDCP ଯାଞ୍ଚ କରୁଛି"</string>
diff --git a/packages/SettingsLib/res/values-pa/arrays.xml b/packages/SettingsLib/res/values-pa/arrays.xml
index 8acc4391adac..48e7fb404f11 100644
--- a/packages/SettingsLib/res/values-pa/arrays.xml
+++ b/packages/SettingsLib/res/values-pa/arrays.xml
@@ -75,6 +75,16 @@
<item msgid="4398977131424970917">"avrcp15"</item>
<item msgid="1963366694959681026">"avrcp16"</item>
</string-array>
+ <string-array name="bluetooth_map_versions">
+ <item msgid="8786402640610987099">"MAP 1.2 (ਪੂਰਵ-ਨਿਰਧਾਰਤ)"</item>
+ <item msgid="6817922176194686449">"MAP 1.3"</item>
+ <item msgid="3423518690032737851">"MAP 1.4"</item>
+ </string-array>
+ <string-array name="bluetooth_map_version_values">
+ <item msgid="1164651830068248391">"map12"</item>
+ <item msgid="7073042887003102964">"map13"</item>
+ <item msgid="8147982633566548515">"map14"</item>
+ </string-array>
<string-array name="bluetooth_a2dp_codec_titles">
<item msgid="2494959071796102843">"ਸਿਸਟਮ ਚੋਣ ਦੀ ਵਰਤੋਂ ਕਰੋ (ਪੂਰਵ-ਨਿਰਧਾਰਤ)"</item>
<item msgid="4055460186095649420">"SBC"</item>
diff --git a/packages/SettingsLib/res/values-pa/strings.xml b/packages/SettingsLib/res/values-pa/strings.xml
index cd83c2cb4bee..6a784865b12c 100644
--- a/packages/SettingsLib/res/values-pa/strings.xml
+++ b/packages/SettingsLib/res/values-pa/strings.xml
@@ -230,6 +230,8 @@
<string name="bluetooth_enable_gabeldorsche" msgid="9131730396242883416">"Gabeldorsche ਨੂੰ ਚਾਲੂ ਕਰੋ"</string>
<string name="bluetooth_select_avrcp_version_string" msgid="1710571610177659127">"ਬਲੂਟੁੱਥ AVRCP ਵਰਜਨ"</string>
<string name="bluetooth_select_avrcp_version_dialog_title" msgid="7846922290083709633">"ਬਲੂਟੁੱਥ AVRCP ਵਰਜਨ ਚੁਣੋ"</string>
+ <string name="bluetooth_select_map_version_string" msgid="526308145174175327">"Bluetooth MAP ਵਰਜਨ"</string>
+ <string name="bluetooth_select_map_version_dialog_title" msgid="7085934373987428460">"Bluetooth MAP ਵਰਜਨ ਚੁਣੋ"</string>
<string name="bluetooth_select_a2dp_codec_type" msgid="952001408455456494">"ਬਲੂਟੁੱਥ ਆਡੀਓ ਕੋਡੇਕ"</string>
<string name="bluetooth_select_a2dp_codec_type_dialog_title" msgid="7510542404227225545">"ਬਲੂਟੁੱਥ ਆਡੀਓ ਕੋਡੇਕ\nਚੋਣ ਨੂੰ ਟ੍ਰਿਗਰ ਕਰੋ"</string>
<string name="bluetooth_select_a2dp_codec_sample_rate" msgid="1638623076480928191">"ਬਲੂਟੁੱਥ ਆਡੀਓ ਸੈਂਪਲ ਰੇਟ"</string>
@@ -276,7 +278,7 @@
<string name="verify_apps_over_usb_summary" msgid="1317933737581167839">"ਹਾਨੀਕਾਰਕ ਵਿਵਹਾਰ ਲਈ ADB/ADT ਰਾਹੀਂ ਸਥਾਪਤ ਕੀਤੀਆਂ ਐਪਾਂ ਦੀ ਜਾਂਚ ਕਰੋ।"</string>
<string name="bluetooth_show_devices_without_names_summary" msgid="780964354377854507">"ਅਨਾਮ ਬਲੂਟੁੱਥ ਡੀਵਾਈਸਾਂ ਦਿਖਾਈਆਂ ਜਾਣਗੀਆਂ (ਸਿਰਫ਼ MAC ਪਤੇ)"</string>
<string name="bluetooth_disable_absolute_volume_summary" msgid="2006309932135547681">"ਰਿਮੋਟ ਡੀਵਾਈਸਾਂ ਨਾਲ ਅਵਾਜ਼ੀ ਸਮੱਸਿਆਵਾਂ ਜਿਵੇਂ ਕਿ ਨਾ ਪਸੰਦ ਕੀਤੀ ਜਾਣ ਵਾਲੀ ਉੱਚੀ ਅਵਾਜ਼ ਜਾਂ ਕੰਟਰੋਲ ਦੀ ਕਮੀ ਵਰਗੀ ਹਾਲਤ ਵਿੱਚ ਬਲੂਟੁੱਥ ਪੂਰਨ ਅਵਾਜ਼ ਵਿਸ਼ੇਸ਼ਤਾ ਨੂੰ ਬੰਦ ਕਰਦਾ ਹੈ।"</string>
- <string name="bluetooth_enable_gabeldorsche_summary" msgid="8472344901097607030">"ਬਲੂਟੁੱਥ Gabeldorche ਵਿਸ਼ੇਸ਼ਤਾ ਸਟੈਕ ਨੂੰ ਚਾਲੂ ਕਰਦਾ ਹੈ।"</string>
+ <string name="bluetooth_enable_gabeldorsche_summary" msgid="2054730331770712629">"ਬਲੂਟੁੱਥ Gabeldorsche ਵਿਸ਼ੇਸ਼ਤਾ ਸਟੈਕ ਨੂੰ ਚਾਲੂ ਕਰਦਾ ਹੈ।"</string>
<string name="enable_terminal_title" msgid="3834790541986303654">"ਸਥਾਨਕ ਟਰਮੀਨਲ"</string>
<string name="enable_terminal_summary" msgid="2481074834856064500">"ਟਰਮੀਨਲ ਐਪ ਨੂੰ ਚਾਲੂ ਕਰੋ ਜੋ ਸਥਾਨਕ ਸ਼ੈਲ ਪਹੁੰਚ ਪੇਸ਼ਕਸ਼ ਕਰਦਾ ਹੈ"</string>
<string name="hdcp_checking_title" msgid="3155692785074095986">"HDCP ਜਾਂਚ"</string>
diff --git a/packages/SettingsLib/res/values-pl/arrays.xml b/packages/SettingsLib/res/values-pl/arrays.xml
index 00b23bca41ad..43b8f5f0ccba 100644
--- a/packages/SettingsLib/res/values-pl/arrays.xml
+++ b/packages/SettingsLib/res/values-pl/arrays.xml
@@ -75,6 +75,16 @@
<item msgid="4398977131424970917">"avrcp15"</item>
<item msgid="1963366694959681026">"avrcp16"</item>
</string-array>
+ <string-array name="bluetooth_map_versions">
+ <item msgid="8786402640610987099">"MAP 1.2 (domyślny)"</item>
+ <item msgid="6817922176194686449">"MAP 1.3"</item>
+ <item msgid="3423518690032737851">"MAP 1.4"</item>
+ </string-array>
+ <string-array name="bluetooth_map_version_values">
+ <item msgid="1164651830068248391">"map12"</item>
+ <item msgid="7073042887003102964">"map13"</item>
+ <item msgid="8147982633566548515">"map14"</item>
+ </string-array>
<string-array name="bluetooth_a2dp_codec_titles">
<item msgid="2494959071796102843">"Użyj wyboru systemu (domyślnie)"</item>
<item msgid="4055460186095649420">"SBC"</item>
diff --git a/packages/SettingsLib/res/values-pl/strings.xml b/packages/SettingsLib/res/values-pl/strings.xml
index b47365b49f5e..8c5547c2791d 100644
--- a/packages/SettingsLib/res/values-pl/strings.xml
+++ b/packages/SettingsLib/res/values-pl/strings.xml
@@ -230,6 +230,8 @@
<string name="bluetooth_enable_gabeldorsche" msgid="9131730396242883416">"Włącz Gabeldorsche"</string>
<string name="bluetooth_select_avrcp_version_string" msgid="1710571610177659127">"Wersja AVRCP Bluetooth"</string>
<string name="bluetooth_select_avrcp_version_dialog_title" msgid="7846922290083709633">"Wybierz wersję AVRCP Bluetooth"</string>
+ <string name="bluetooth_select_map_version_string" msgid="526308145174175327">"Wersja MAP Bluetooth"</string>
+ <string name="bluetooth_select_map_version_dialog_title" msgid="7085934373987428460">"Wybierz wersję MAP Bluetooth"</string>
<string name="bluetooth_select_a2dp_codec_type" msgid="952001408455456494">"Kodek dźwięku Bluetooth"</string>
<string name="bluetooth_select_a2dp_codec_type_dialog_title" msgid="7510542404227225545">"Uruchom kodek dźwięku Bluetooth\nWybór"</string>
<string name="bluetooth_select_a2dp_codec_sample_rate" msgid="1638623076480928191">"Dźwięk Bluetooth – współczynnik próbkowania"</string>
@@ -276,7 +278,7 @@
<string name="verify_apps_over_usb_summary" msgid="1317933737581167839">"Sprawdź, czy aplikacje zainstalowane przez ADB/ADT nie zachowują się w szkodliwy sposób"</string>
<string name="bluetooth_show_devices_without_names_summary" msgid="780964354377854507">"Zostaną wyświetlone urządzenia Bluetooth bez nazw (tylko adresy MAC)"</string>
<string name="bluetooth_disable_absolute_volume_summary" msgid="2006309932135547681">"Wyłącza funkcję Głośność bezwzględna Bluetooth, jeśli występują problemy z urządzeniami zdalnymi, np. zbyt duża głośność lub brak kontroli."</string>
- <string name="bluetooth_enable_gabeldorsche_summary" msgid="8472344901097607030">"Włącza funkcje Bluetooth Gabeldorche."</string>
+ <string name="bluetooth_enable_gabeldorsche_summary" msgid="2054730331770712629">"Włącza funkcje Bluetooth Gabeldorsche."</string>
<string name="enable_terminal_title" msgid="3834790541986303654">"Terminal lokalny"</string>
<string name="enable_terminal_summary" msgid="2481074834856064500">"Włącz terminal, który umożliwia dostęp do powłoki lokalnej"</string>
<string name="hdcp_checking_title" msgid="3155692785074095986">"Sprawdzanie HDCP"</string>
diff --git a/packages/SettingsLib/res/values-pt-rBR/arrays.xml b/packages/SettingsLib/res/values-pt-rBR/arrays.xml
index 4e23c197d430..4658ffdd859a 100644
--- a/packages/SettingsLib/res/values-pt-rBR/arrays.xml
+++ b/packages/SettingsLib/res/values-pt-rBR/arrays.xml
@@ -75,6 +75,16 @@
<item msgid="4398977131424970917">"avrcp15"</item>
<item msgid="1963366694959681026">"avrcp16"</item>
</string-array>
+ <string-array name="bluetooth_map_versions">
+ <item msgid="8786402640610987099">"MAP 1.2 (padrão)"</item>
+ <item msgid="6817922176194686449">"MAP 1.3"</item>
+ <item msgid="3423518690032737851">"MAP 1.4"</item>
+ </string-array>
+ <string-array name="bluetooth_map_version_values">
+ <item msgid="1164651830068248391">"map12"</item>
+ <item msgid="7073042887003102964">"map13"</item>
+ <item msgid="8147982633566548515">"map14"</item>
+ </string-array>
<string-array name="bluetooth_a2dp_codec_titles">
<item msgid="2494959071796102843">"Usar seleção do sistema (padrão)"</item>
<item msgid="4055460186095649420">"SBC"</item>
diff --git a/packages/SettingsLib/res/values-pt-rBR/strings.xml b/packages/SettingsLib/res/values-pt-rBR/strings.xml
index 4cccad4eab69..8c036164e140 100644
--- a/packages/SettingsLib/res/values-pt-rBR/strings.xml
+++ b/packages/SettingsLib/res/values-pt-rBR/strings.xml
@@ -230,6 +230,8 @@
<string name="bluetooth_enable_gabeldorsche" msgid="9131730396242883416">"Ativar Gabeldorsche"</string>
<string name="bluetooth_select_avrcp_version_string" msgid="1710571610177659127">"Versão do Bluetooth AVRCP"</string>
<string name="bluetooth_select_avrcp_version_dialog_title" msgid="7846922290083709633">"Selecionar versão do Bluetooth AVRCP"</string>
+ <string name="bluetooth_select_map_version_string" msgid="526308145174175327">"Versão MAP do Bluetooth"</string>
+ <string name="bluetooth_select_map_version_dialog_title" msgid="7085934373987428460">"Selecionar versão MAP do Bluetooth"</string>
<string name="bluetooth_select_a2dp_codec_type" msgid="952001408455456494">"Codec de áudio Bluetooth"</string>
<string name="bluetooth_select_a2dp_codec_type_dialog_title" msgid="7510542404227225545">"Acionar codec de áudio Bluetooth\nSeleção"</string>
<string name="bluetooth_select_a2dp_codec_sample_rate" msgid="1638623076480928191">"Taxa de amostra do áudio Bluetooth"</string>
@@ -276,7 +278,7 @@
<string name="verify_apps_over_usb_summary" msgid="1317933737581167839">"Verificar comportamento nocivo em apps instalados via ADB/ADT"</string>
<string name="bluetooth_show_devices_without_names_summary" msgid="780964354377854507">"Dispositivos Bluetooth sem nomes (somente endereços MAC) serão exibidos"</string>
<string name="bluetooth_disable_absolute_volume_summary" msgid="2006309932135547681">"Desativa o recurso Bluetooth de volume absoluto em caso de problemas com o volume em dispositivos remotos, como volume excessivamente alto ou falta de controle"</string>
- <string name="bluetooth_enable_gabeldorsche_summary" msgid="8472344901097607030">"Ativa a pilha de recursos Bluetooth Gabeldorsche."</string>
+ <string name="bluetooth_enable_gabeldorsche_summary" msgid="2054730331770712629">"Ativa a pilha de recursos Bluetooth Gabeldorsche."</string>
<string name="enable_terminal_title" msgid="3834790541986303654">"Terminal local"</string>
<string name="enable_terminal_summary" msgid="2481074834856064500">"Ativar o app terminal que oferece acesso ao shell local"</string>
<string name="hdcp_checking_title" msgid="3155692785074095986">"Verificação HDCP"</string>
diff --git a/packages/SettingsLib/res/values-pt-rPT/arrays.xml b/packages/SettingsLib/res/values-pt-rPT/arrays.xml
index 98e9c8746459..527f74061535 100644
--- a/packages/SettingsLib/res/values-pt-rPT/arrays.xml
+++ b/packages/SettingsLib/res/values-pt-rPT/arrays.xml
@@ -75,6 +75,16 @@
<item msgid="4398977131424970917">"avrcp15"</item>
<item msgid="1963366694959681026">"avrcp16"</item>
</string-array>
+ <string-array name="bluetooth_map_versions">
+ <item msgid="8786402640610987099">"MAP 1.2 (predefinição)"</item>
+ <item msgid="6817922176194686449">"MAP 1.3"</item>
+ <item msgid="3423518690032737851">"MAP 1.4"</item>
+ </string-array>
+ <string-array name="bluetooth_map_version_values">
+ <item msgid="1164651830068248391">"map12"</item>
+ <item msgid="7073042887003102964">"map13"</item>
+ <item msgid="8147982633566548515">"map14"</item>
+ </string-array>
<string-array name="bluetooth_a2dp_codec_titles">
<item msgid="2494959071796102843">"Utilizar seleção do sistema (predefinido)"</item>
<item msgid="4055460186095649420">"SBC"</item>
diff --git a/packages/SettingsLib/res/values-pt-rPT/strings.xml b/packages/SettingsLib/res/values-pt-rPT/strings.xml
index 6e80bd2258b3..6aeff1cb271c 100644
--- a/packages/SettingsLib/res/values-pt-rPT/strings.xml
+++ b/packages/SettingsLib/res/values-pt-rPT/strings.xml
@@ -230,6 +230,8 @@
<string name="bluetooth_enable_gabeldorsche" msgid="9131730396242883416">"Ativar o Gabeldorsche"</string>
<string name="bluetooth_select_avrcp_version_string" msgid="1710571610177659127">"Versão de Bluetooth AVRCP"</string>
<string name="bluetooth_select_avrcp_version_dialog_title" msgid="7846922290083709633">"Selecionar versão de Bluetooth AVRCP"</string>
+ <string name="bluetooth_select_map_version_string" msgid="526308145174175327">"Versão do MAP do Bluetooth"</string>
+ <string name="bluetooth_select_map_version_dialog_title" msgid="7085934373987428460">"Selecione a versão do MAP do Bluetooth"</string>
<string name="bluetooth_select_a2dp_codec_type" msgid="952001408455456494">"Codec de áudio Bluetooth"</string>
<string name="bluetooth_select_a2dp_codec_type_dialog_title" msgid="7510542404227225545">"Acionar o codec de áudio Bluetooth\nSeleção"</string>
<string name="bluetooth_select_a2dp_codec_sample_rate" msgid="1638623076480928191">"Taxa de amostragem de áudio Bluetooth"</string>
@@ -241,7 +243,7 @@
<string name="bluetooth_select_a2dp_codec_channel_mode_dialog_title" msgid="2076949781460359589">"Acionar o codec de áudio Bluetooth\nSeleção: modo de canal"</string>
<string name="bluetooth_select_a2dp_codec_ldac_playback_quality" msgid="3233402355917446304">"Codec LDAC de áudio Bluetooth: qualidade de reprodução"</string>
<string name="bluetooth_select_a2dp_codec_ldac_playback_quality_dialog_title" msgid="7274396574659784285">"Acionar a seleção do codec LDAC de áudio\nBluetooth: Qualidade de reprodução"</string>
- <string name="bluetooth_select_a2dp_codec_streaming_label" msgid="2040810756832027227">"Transmissão em fluxo contínuo: <xliff:g id="STREAMING_PARAMETER">%1$s</xliff:g>"</string>
+ <string name="bluetooth_select_a2dp_codec_streaming_label" msgid="2040810756832027227">"Stream: <xliff:g id="STREAMING_PARAMETER">%1$s</xliff:g>"</string>
<string name="select_private_dns_configuration_title" msgid="7887550926056143018">"DNS privado"</string>
<string name="select_private_dns_configuration_dialog_title" msgid="3731422918335951912">"Selecionar modo DNS privado"</string>
<string name="private_dns_mode_off" msgid="7065962499349997041">"Desativado"</string>
@@ -276,7 +278,7 @@
<string name="verify_apps_over_usb_summary" msgid="1317933737581167839">"Verificar as aplicações instaladas via ADB/ADT para detetar comportamento perigoso."</string>
<string name="bluetooth_show_devices_without_names_summary" msgid="780964354377854507">"São apresentados os dispositivos Bluetooth sem nomes (apenas endereços MAC)"</string>
<string name="bluetooth_disable_absolute_volume_summary" msgid="2006309932135547681">"Desativa a funcionalidade de volume absoluto do Bluetooth caso existam problemas de volume com dispositivos remotos, como um volume insuportavelmente alto ou a ausência de controlo."</string>
- <string name="bluetooth_enable_gabeldorsche_summary" msgid="8472344901097607030">"Ativa a pilha de funcionalidades Bluetooth Gabeldorche."</string>
+ <string name="bluetooth_enable_gabeldorsche_summary" msgid="2054730331770712629">"Ativa a pilha de funcionalidades Bluetooth Gabeldorche."</string>
<string name="enable_terminal_title" msgid="3834790541986303654">"Terminal local"</string>
<string name="enable_terminal_summary" msgid="2481074834856064500">"Ativar aplicação terminal que oferece acesso local à shell"</string>
<string name="hdcp_checking_title" msgid="3155692785074095986">"Verificação HDCP"</string>
diff --git a/packages/SettingsLib/res/values-pt/arrays.xml b/packages/SettingsLib/res/values-pt/arrays.xml
index 4e23c197d430..4658ffdd859a 100644
--- a/packages/SettingsLib/res/values-pt/arrays.xml
+++ b/packages/SettingsLib/res/values-pt/arrays.xml
@@ -75,6 +75,16 @@
<item msgid="4398977131424970917">"avrcp15"</item>
<item msgid="1963366694959681026">"avrcp16"</item>
</string-array>
+ <string-array name="bluetooth_map_versions">
+ <item msgid="8786402640610987099">"MAP 1.2 (padrão)"</item>
+ <item msgid="6817922176194686449">"MAP 1.3"</item>
+ <item msgid="3423518690032737851">"MAP 1.4"</item>
+ </string-array>
+ <string-array name="bluetooth_map_version_values">
+ <item msgid="1164651830068248391">"map12"</item>
+ <item msgid="7073042887003102964">"map13"</item>
+ <item msgid="8147982633566548515">"map14"</item>
+ </string-array>
<string-array name="bluetooth_a2dp_codec_titles">
<item msgid="2494959071796102843">"Usar seleção do sistema (padrão)"</item>
<item msgid="4055460186095649420">"SBC"</item>
diff --git a/packages/SettingsLib/res/values-pt/strings.xml b/packages/SettingsLib/res/values-pt/strings.xml
index 4cccad4eab69..8c036164e140 100644
--- a/packages/SettingsLib/res/values-pt/strings.xml
+++ b/packages/SettingsLib/res/values-pt/strings.xml
@@ -230,6 +230,8 @@
<string name="bluetooth_enable_gabeldorsche" msgid="9131730396242883416">"Ativar Gabeldorsche"</string>
<string name="bluetooth_select_avrcp_version_string" msgid="1710571610177659127">"Versão do Bluetooth AVRCP"</string>
<string name="bluetooth_select_avrcp_version_dialog_title" msgid="7846922290083709633">"Selecionar versão do Bluetooth AVRCP"</string>
+ <string name="bluetooth_select_map_version_string" msgid="526308145174175327">"Versão MAP do Bluetooth"</string>
+ <string name="bluetooth_select_map_version_dialog_title" msgid="7085934373987428460">"Selecionar versão MAP do Bluetooth"</string>
<string name="bluetooth_select_a2dp_codec_type" msgid="952001408455456494">"Codec de áudio Bluetooth"</string>
<string name="bluetooth_select_a2dp_codec_type_dialog_title" msgid="7510542404227225545">"Acionar codec de áudio Bluetooth\nSeleção"</string>
<string name="bluetooth_select_a2dp_codec_sample_rate" msgid="1638623076480928191">"Taxa de amostra do áudio Bluetooth"</string>
@@ -276,7 +278,7 @@
<string name="verify_apps_over_usb_summary" msgid="1317933737581167839">"Verificar comportamento nocivo em apps instalados via ADB/ADT"</string>
<string name="bluetooth_show_devices_without_names_summary" msgid="780964354377854507">"Dispositivos Bluetooth sem nomes (somente endereços MAC) serão exibidos"</string>
<string name="bluetooth_disable_absolute_volume_summary" msgid="2006309932135547681">"Desativa o recurso Bluetooth de volume absoluto em caso de problemas com o volume em dispositivos remotos, como volume excessivamente alto ou falta de controle"</string>
- <string name="bluetooth_enable_gabeldorsche_summary" msgid="8472344901097607030">"Ativa a pilha de recursos Bluetooth Gabeldorsche."</string>
+ <string name="bluetooth_enable_gabeldorsche_summary" msgid="2054730331770712629">"Ativa a pilha de recursos Bluetooth Gabeldorsche."</string>
<string name="enable_terminal_title" msgid="3834790541986303654">"Terminal local"</string>
<string name="enable_terminal_summary" msgid="2481074834856064500">"Ativar o app terminal que oferece acesso ao shell local"</string>
<string name="hdcp_checking_title" msgid="3155692785074095986">"Verificação HDCP"</string>
diff --git a/packages/SettingsLib/res/values-ro/arrays.xml b/packages/SettingsLib/res/values-ro/arrays.xml
index befb771624dc..5d25101b5697 100644
--- a/packages/SettingsLib/res/values-ro/arrays.xml
+++ b/packages/SettingsLib/res/values-ro/arrays.xml
@@ -75,6 +75,16 @@
<item msgid="4398977131424970917">"avrcp15"</item>
<item msgid="1963366694959681026">"avrcp16"</item>
</string-array>
+ <string-array name="bluetooth_map_versions">
+ <item msgid="8786402640610987099">"MAP 1.2 (prestabilit)"</item>
+ <item msgid="6817922176194686449">"MAP 1.3"</item>
+ <item msgid="3423518690032737851">"MAP 1.4"</item>
+ </string-array>
+ <string-array name="bluetooth_map_version_values">
+ <item msgid="1164651830068248391">"map12"</item>
+ <item msgid="7073042887003102964">"map13"</item>
+ <item msgid="8147982633566548515">"map14"</item>
+ </string-array>
<string-array name="bluetooth_a2dp_codec_titles">
<item msgid="2494959071796102843">"Folosiți selectarea sistemului (prestabilit)"</item>
<item msgid="4055460186095649420">"SBC"</item>
diff --git a/packages/SettingsLib/res/values-ro/strings.xml b/packages/SettingsLib/res/values-ro/strings.xml
index a7429328ab06..387441f32b56 100644
--- a/packages/SettingsLib/res/values-ro/strings.xml
+++ b/packages/SettingsLib/res/values-ro/strings.xml
@@ -230,6 +230,8 @@
<string name="bluetooth_enable_gabeldorsche" msgid="9131730396242883416">"Activați Gabeldorsche"</string>
<string name="bluetooth_select_avrcp_version_string" msgid="1710571610177659127">"Versiunea AVRCP pentru Bluetooth"</string>
<string name="bluetooth_select_avrcp_version_dialog_title" msgid="7846922290083709633">"Selectați versiunea AVRCP pentru Bluetooth"</string>
+ <string name="bluetooth_select_map_version_string" msgid="526308145174175327">"Versiunea MAP pentru Bluetooth"</string>
+ <string name="bluetooth_select_map_version_dialog_title" msgid="7085934373987428460">"Selectați versiunea MAP pentru Bluetooth"</string>
<string name="bluetooth_select_a2dp_codec_type" msgid="952001408455456494">"Codec audio Bluetooth"</string>
<string name="bluetooth_select_a2dp_codec_type_dialog_title" msgid="7510542404227225545">"Declanșați codecul audio Bluetooth\nSelecție"</string>
<string name="bluetooth_select_a2dp_codec_sample_rate" msgid="1638623076480928191">"Rată de eșantionare audio Bluetooth"</string>
@@ -276,7 +278,7 @@
<string name="verify_apps_over_usb_summary" msgid="1317933737581167839">"Verificați aplicațiile instalate utilizând ADB/ADT, pentru a detecta un comportament dăunător."</string>
<string name="bluetooth_show_devices_without_names_summary" msgid="780964354377854507">"Vor fi afișate dispozitivele Bluetooth fără nume (numai adresele MAC)"</string>
<string name="bluetooth_disable_absolute_volume_summary" msgid="2006309932135547681">"Dezactivează funcția Bluetooth de volum absolut în cazul problemelor de volum apărute la dispozitivele la distanță, cum ar fi volumul mult prea ridicat sau lipsa de control asupra acestuia."</string>
- <string name="bluetooth_enable_gabeldorsche_summary" msgid="8472344901097607030">"Activează setul de funcții Bluetooth Gabeldorche."</string>
+ <string name="bluetooth_enable_gabeldorsche_summary" msgid="2054730331770712629">"Activează setul de funcții Bluetooth Gabeldorsche."</string>
<string name="enable_terminal_title" msgid="3834790541986303654">"Aplicație terminal locală"</string>
<string name="enable_terminal_summary" msgid="2481074834856064500">"Activați aplicația terminal care oferă acces la shell local"</string>
<string name="hdcp_checking_title" msgid="3155692785074095986">"Verificare HDCP"</string>
diff --git a/packages/SettingsLib/res/values-ru/arrays.xml b/packages/SettingsLib/res/values-ru/arrays.xml
index d0d04d6d5b6c..f5367a44cd91 100644
--- a/packages/SettingsLib/res/values-ru/arrays.xml
+++ b/packages/SettingsLib/res/values-ru/arrays.xml
@@ -75,6 +75,16 @@
<item msgid="4398977131424970917">"avrcp15"</item>
<item msgid="1963366694959681026">"avrcp16"</item>
</string-array>
+ <string-array name="bluetooth_map_versions">
+ <item msgid="8786402640610987099">"MAP 1.2 (по умолчанию)"</item>
+ <item msgid="6817922176194686449">"MAP 1.3"</item>
+ <item msgid="3423518690032737851">"MAP 1.4"</item>
+ </string-array>
+ <string-array name="bluetooth_map_version_values">
+ <item msgid="1164651830068248391">"map12"</item>
+ <item msgid="7073042887003102964">"map13"</item>
+ <item msgid="8147982633566548515">"map14"</item>
+ </string-array>
<string-array name="bluetooth_a2dp_codec_titles">
<item msgid="2494959071796102843">"Выбор системы (по умолчанию)"</item>
<item msgid="4055460186095649420">"SBC"</item>
diff --git a/packages/SettingsLib/res/values-ru/strings.xml b/packages/SettingsLib/res/values-ru/strings.xml
index 769b5f3c2687..361e29ff452e 100644
--- a/packages/SettingsLib/res/values-ru/strings.xml
+++ b/packages/SettingsLib/res/values-ru/strings.xml
@@ -230,6 +230,8 @@
<string name="bluetooth_enable_gabeldorsche" msgid="9131730396242883416">"Включить Gabeldorsche"</string>
<string name="bluetooth_select_avrcp_version_string" msgid="1710571610177659127">"Версия Bluetooth AVRCP"</string>
<string name="bluetooth_select_avrcp_version_dialog_title" msgid="7846922290083709633">"Выберите версию Bluetooth AVRCP"</string>
+ <string name="bluetooth_select_map_version_string" msgid="526308145174175327">"Версия Bluetooth MAP"</string>
+ <string name="bluetooth_select_map_version_dialog_title" msgid="7085934373987428460">"Выберите версию Bluetooth MAP"</string>
<string name="bluetooth_select_a2dp_codec_type" msgid="952001408455456494">"Аудиокодек Bluetooth"</string>
<string name="bluetooth_select_a2dp_codec_type_dialog_title" msgid="7510542404227225545">"Запустить аудиокодек для Bluetooth\nВыбор"</string>
<string name="bluetooth_select_a2dp_codec_sample_rate" msgid="1638623076480928191">"Частота дискретизации аудио Bluetooth"</string>
@@ -276,7 +278,7 @@
<string name="verify_apps_over_usb_summary" msgid="1317933737581167839">"Выполнять проверку безопасности приложений при установке через ADB/ADT"</string>
<string name="bluetooth_show_devices_without_names_summary" msgid="780964354377854507">"Показывать Bluetooth-устройства без названий (только с MAC-адресами)"</string>
<string name="bluetooth_disable_absolute_volume_summary" msgid="2006309932135547681">"Отключить абсолютный уровень громкости Bluetooth при возникновении проблем на удаленных устройствах, например при слишком громком звучании или невозможности контролировать настройку"</string>
- <string name="bluetooth_enable_gabeldorsche_summary" msgid="8472344901097607030">"Включить стек Bluetooth Gabeldorche"</string>
+ <string name="bluetooth_enable_gabeldorsche_summary" msgid="2054730331770712629">"Включить стек Bluetooth Gabeldorsche"</string>
<string name="enable_terminal_title" msgid="3834790541986303654">"Локальный терминальный доступ"</string>
<string name="enable_terminal_summary" msgid="2481074834856064500">"Разрешить терминальный доступ к локальной оболочке"</string>
<string name="hdcp_checking_title" msgid="3155692785074095986">"Проверка HDCP"</string>
diff --git a/packages/SettingsLib/res/values-si/arrays.xml b/packages/SettingsLib/res/values-si/arrays.xml
index 4764d4768ead..f8c871e99202 100644
--- a/packages/SettingsLib/res/values-si/arrays.xml
+++ b/packages/SettingsLib/res/values-si/arrays.xml
@@ -75,6 +75,16 @@
<item msgid="4398977131424970917">"avrcp15"</item>
<item msgid="1963366694959681026">"avrcp16"</item>
</string-array>
+ <string-array name="bluetooth_map_versions">
+ <item msgid="8786402640610987099">"MAP 1.2 (පෙරනිමි)"</item>
+ <item msgid="6817922176194686449">"MAP 1.3"</item>
+ <item msgid="3423518690032737851">"MAP 1.4"</item>
+ </string-array>
+ <string-array name="bluetooth_map_version_values">
+ <item msgid="1164651830068248391">"map12"</item>
+ <item msgid="7073042887003102964">"map13"</item>
+ <item msgid="8147982633566548515">"map14"</item>
+ </string-array>
<string-array name="bluetooth_a2dp_codec_titles">
<item msgid="2494959071796102843">"පද්ධති තේරීම භාවිත කරන්න (පෙරනිමි)"</item>
<item msgid="4055460186095649420">"SBC"</item>
diff --git a/packages/SettingsLib/res/values-si/strings.xml b/packages/SettingsLib/res/values-si/strings.xml
index 1d925bfda8d5..faa848fec830 100644
--- a/packages/SettingsLib/res/values-si/strings.xml
+++ b/packages/SettingsLib/res/values-si/strings.xml
@@ -230,6 +230,8 @@
<string name="bluetooth_enable_gabeldorsche" msgid="9131730396242883416">"Gabeldorsche සබල කරන්න"</string>
<string name="bluetooth_select_avrcp_version_string" msgid="1710571610177659127">"බ්ලූටූත් AVRCP අනුවාදය"</string>
<string name="bluetooth_select_avrcp_version_dialog_title" msgid="7846922290083709633">"බ්ලූටූත් AVRCP අනුවාදය තෝරන්න"</string>
+ <string name="bluetooth_select_map_version_string" msgid="526308145174175327">"Bluetooth MAP අනුවාදය"</string>
+ <string name="bluetooth_select_map_version_dialog_title" msgid="7085934373987428460">"Bluetooth MAP අනුවාදය තෝරන්න"</string>
<string name="bluetooth_select_a2dp_codec_type" msgid="952001408455456494">"බ්ලූටූත් ශ්‍රව්‍ය Codec"</string>
<string name="bluetooth_select_a2dp_codec_type_dialog_title" msgid="7510542404227225545">"බ්ලූටූත් ශ්‍රව්‍ය කෝඩෙක් ක්‍රියාරම්භ කරන්න\nතෝරා ගැනීම"</string>
<string name="bluetooth_select_a2dp_codec_sample_rate" msgid="1638623076480928191">"බ්ලූටූත් ශ්‍රව්‍ය නියැදි අනුපාතය"</string>
@@ -276,7 +278,7 @@
<string name="verify_apps_over_usb_summary" msgid="1317933737581167839">"ADB/ADT හරහා ස්ථාපනය වූ යෙදුම්, විනාශකාරී ක්‍රියාවන් ඇත්දැයි පරික්ෂාකර බලන්න."</string>
<string name="bluetooth_show_devices_without_names_summary" msgid="780964354377854507">"නම් නොමැති බ්ලූටූත් උපාංග (MAC ලිපින පමණි) සංදර්ශනය කරනු ඇත"</string>
<string name="bluetooth_disable_absolute_volume_summary" msgid="2006309932135547681">"පිළිගත නොහැකි ලෙස වැඩි හඩ පරිමාව හෝ පාලනය නොමැති වීම යනාදී දුරස්ථ උපාංග සමගින් වන හඬ පරිමා ගැටලුවලදී බ්ලූටූත් නිරපේක්ෂ හඬ පරිමා විශේෂාංගය අබල කරයි."</string>
- <string name="bluetooth_enable_gabeldorsche_summary" msgid="8472344901097607030">"බ්ලූටූත් Gabeldorche විශේෂාංග අට්ටිය සබල කරයි."</string>
+ <string name="bluetooth_enable_gabeldorsche_summary" msgid="2054730331770712629">"Bluetooth Gabeldorsche විශේෂාංග අට්ටිය සබල කරයි."</string>
<string name="enable_terminal_title" msgid="3834790541986303654">"අභ්‍යන්තර අන්තය"</string>
<string name="enable_terminal_summary" msgid="2481074834856064500">"දේශීය ෂෙල් ප්‍රවේශනය පිරිනමන ටර්මිනල් යෙදුම සබල කරන්න"</string>
<string name="hdcp_checking_title" msgid="3155692785074095986">"HDCP පරික්ෂාව"</string>
diff --git a/packages/SettingsLib/res/values-sk/arrays.xml b/packages/SettingsLib/res/values-sk/arrays.xml
index 427ee45bcfa2..f862d88ff493 100644
--- a/packages/SettingsLib/res/values-sk/arrays.xml
+++ b/packages/SettingsLib/res/values-sk/arrays.xml
@@ -75,6 +75,16 @@
<item msgid="4398977131424970917">"avrcp15"</item>
<item msgid="1963366694959681026">"avrcp16"</item>
</string-array>
+ <string-array name="bluetooth_map_versions">
+ <item msgid="8786402640610987099">"MAP 1.2 (predvolené)"</item>
+ <item msgid="6817922176194686449">"MAP 1.3"</item>
+ <item msgid="3423518690032737851">"MAP 1.4"</item>
+ </string-array>
+ <string-array name="bluetooth_map_version_values">
+ <item msgid="1164651830068248391">"map12"</item>
+ <item msgid="7073042887003102964">"map13"</item>
+ <item msgid="8147982633566548515">"map14"</item>
+ </string-array>
<string-array name="bluetooth_a2dp_codec_titles">
<item msgid="2494959071796102843">"Použiť voľbu systému (predvolené)"</item>
<item msgid="4055460186095649420">"SBC"</item>
diff --git a/packages/SettingsLib/res/values-sk/strings.xml b/packages/SettingsLib/res/values-sk/strings.xml
index e022c363b7f8..2035d88c75f0 100644
--- a/packages/SettingsLib/res/values-sk/strings.xml
+++ b/packages/SettingsLib/res/values-sk/strings.xml
@@ -230,6 +230,8 @@
<string name="bluetooth_enable_gabeldorsche" msgid="9131730396242883416">"Povoliť Gabeldorsche"</string>
<string name="bluetooth_select_avrcp_version_string" msgid="1710571610177659127">"Verzia rozhrania Bluetooth AVRCP"</string>
<string name="bluetooth_select_avrcp_version_dialog_title" msgid="7846922290083709633">"Zvoľte verziu rozhrania Bluetooth AVRCP"</string>
+ <string name="bluetooth_select_map_version_string" msgid="526308145174175327">"Verzia profilu Bluetooth MAP"</string>
+ <string name="bluetooth_select_map_version_dialog_title" msgid="7085934373987428460">"Výber verzie profilu Bluetooth MAP"</string>
<string name="bluetooth_select_a2dp_codec_type" msgid="952001408455456494">"Bluetooth Audio – kodek"</string>
<string name="bluetooth_select_a2dp_codec_type_dialog_title" msgid="7510542404227225545">"Spustiť zvukový kodek Bluetooth\nVýber"</string>
<string name="bluetooth_select_a2dp_codec_sample_rate" msgid="1638623076480928191">"Bluetooth Audio – vzorkovacia frekvencia"</string>
@@ -276,7 +278,7 @@
<string name="verify_apps_over_usb_summary" msgid="1317933737581167839">"Kontrolovať škodlivosť aplikácií nainštalovaných pomocou nástroja ADB alebo ADT"</string>
<string name="bluetooth_show_devices_without_names_summary" msgid="780964354377854507">"Zariadenia Bluetooth sa budú zobrazovať bez názvov (iba adresy MAC)"</string>
<string name="bluetooth_disable_absolute_volume_summary" msgid="2006309932135547681">"Umožňuje zakázať funkciu absolútnej hlasitosti rozhrania Bluetooth v prípade problémov s hlasitosťou vo vzdialených zariadeniach, ako je napríklad neprijateľne vysoká hlasitosť alebo absencia ovládacích prvkov."</string>
- <string name="bluetooth_enable_gabeldorsche_summary" msgid="8472344901097607030">"Umožňuje povoliť skupiny funkcií Bluetooth Gabeldorche."</string>
+ <string name="bluetooth_enable_gabeldorsche_summary" msgid="2054730331770712629">"Umožňuje povoliť skupinu funkcií Bluetooth Gabeldorche."</string>
<string name="enable_terminal_title" msgid="3834790541986303654">"Miestny terminál"</string>
<string name="enable_terminal_summary" msgid="2481074834856064500">"Povoliť terminálovú apl. na miestny prístup k prostrediu shell"</string>
<string name="hdcp_checking_title" msgid="3155692785074095986">"Kontrola HDCP"</string>
diff --git a/packages/SettingsLib/res/values-sl/arrays.xml b/packages/SettingsLib/res/values-sl/arrays.xml
index d946316af95d..eb860743b796 100644
--- a/packages/SettingsLib/res/values-sl/arrays.xml
+++ b/packages/SettingsLib/res/values-sl/arrays.xml
@@ -75,6 +75,16 @@
<item msgid="4398977131424970917">"avrcp15"</item>
<item msgid="1963366694959681026">"avrcp16"</item>
</string-array>
+ <string-array name="bluetooth_map_versions">
+ <item msgid="8786402640610987099">"MAP 1.2 (privzeto)"</item>
+ <item msgid="6817922176194686449">"MAP 1.3"</item>
+ <item msgid="3423518690032737851">"MAP 1.4"</item>
+ </string-array>
+ <string-array name="bluetooth_map_version_values">
+ <item msgid="1164651830068248391">"map12"</item>
+ <item msgid="7073042887003102964">"map13"</item>
+ <item msgid="8147982633566548515">"map14"</item>
+ </string-array>
<string-array name="bluetooth_a2dp_codec_titles">
<item msgid="2494959071796102843">"Uporabi sistemsko izbiro (privzeto)"</item>
<item msgid="4055460186095649420">"SBC"</item>
diff --git a/packages/SettingsLib/res/values-sl/strings.xml b/packages/SettingsLib/res/values-sl/strings.xml
index efd7c083eae4..288961947269 100644
--- a/packages/SettingsLib/res/values-sl/strings.xml
+++ b/packages/SettingsLib/res/values-sl/strings.xml
@@ -230,6 +230,8 @@
<string name="bluetooth_enable_gabeldorsche" msgid="9131730396242883416">"Omogoči Gabeldorsche"</string>
<string name="bluetooth_select_avrcp_version_string" msgid="1710571610177659127">"Različica profila AVRCP za Bluetooth"</string>
<string name="bluetooth_select_avrcp_version_dialog_title" msgid="7846922290083709633">"Izberite različico profila AVRCP za Bluetooth"</string>
+ <string name="bluetooth_select_map_version_string" msgid="526308145174175327">"Različica profila MAP za Bluetooth"</string>
+ <string name="bluetooth_select_map_version_dialog_title" msgid="7085934373987428460">"Izbira različice profila MAP za Bluetooth"</string>
<string name="bluetooth_select_a2dp_codec_type" msgid="952001408455456494">"Zvočni kodek za Bluetooth"</string>
<string name="bluetooth_select_a2dp_codec_type_dialog_title" msgid="7510542404227225545">"Sproži zvočni kodek za Bluetooth\nIzbor"</string>
<string name="bluetooth_select_a2dp_codec_sample_rate" msgid="1638623076480928191">"Hitrost vzorčenja zvoka prek Bluetootha"</string>
@@ -276,7 +278,7 @@
<string name="verify_apps_over_usb_summary" msgid="1317933737581167839">"Preveri, ali so aplikacije, nameščene prek ADB/ADT, škodljive."</string>
<string name="bluetooth_show_devices_without_names_summary" msgid="780964354377854507">"Prikazane bodo naprave Bluetooth brez imen (samo z naslovi MAC)"</string>
<string name="bluetooth_disable_absolute_volume_summary" msgid="2006309932135547681">"Onemogoči funkcijo absolutne glasnosti za Bluetooth, če pride do težav z glasnostjo z oddaljenimi napravami, kot je nesprejemljivo visoka glasnost ali pomanjkanje nadzora."</string>
- <string name="bluetooth_enable_gabeldorsche_summary" msgid="8472344901097607030">"Omogoči sklad funkcij Bluetooth Gabeldorche."</string>
+ <string name="bluetooth_enable_gabeldorsche_summary" msgid="2054730331770712629">"Omogoči sklad funkcij Bluetooth Gabeldorsche."</string>
<string name="enable_terminal_title" msgid="3834790541986303654">"Lokalni terminal"</string>
<string name="enable_terminal_summary" msgid="2481074834856064500">"Omogočanje terminalske aplikacije za dostop do lokalne lupine"</string>
<string name="hdcp_checking_title" msgid="3155692785074095986">"Preverjanje HDCP"</string>
diff --git a/packages/SettingsLib/res/values-sq/arrays.xml b/packages/SettingsLib/res/values-sq/arrays.xml
index 26ba289b96fe..1363e8354ef9 100644
--- a/packages/SettingsLib/res/values-sq/arrays.xml
+++ b/packages/SettingsLib/res/values-sq/arrays.xml
@@ -75,6 +75,16 @@
<item msgid="4398977131424970917">"avrcp15"</item>
<item msgid="1963366694959681026">"avrcp16"</item>
</string-array>
+ <string-array name="bluetooth_map_versions">
+ <item msgid="8786402640610987099">"MAP 1.2 (parazgjedhja)"</item>
+ <item msgid="6817922176194686449">"MAP 1.3"</item>
+ <item msgid="3423518690032737851">"MAP 1.4"</item>
+ </string-array>
+ <string-array name="bluetooth_map_version_values">
+ <item msgid="1164651830068248391">"map12"</item>
+ <item msgid="7073042887003102964">"map13"</item>
+ <item msgid="8147982633566548515">"map14"</item>
+ </string-array>
<string-array name="bluetooth_a2dp_codec_titles">
<item msgid="2494959071796102843">"Përdor përzgjedhjen e sistemit (e parazgjedhur)"</item>
<item msgid="4055460186095649420">"SBC"</item>
diff --git a/packages/SettingsLib/res/values-sq/strings.xml b/packages/SettingsLib/res/values-sq/strings.xml
index c7c423018cdc..ccd4e3066d9f 100644
--- a/packages/SettingsLib/res/values-sq/strings.xml
+++ b/packages/SettingsLib/res/values-sq/strings.xml
@@ -230,6 +230,8 @@
<string name="bluetooth_enable_gabeldorsche" msgid="9131730396242883416">"Aktivizo Gabeldorsche"</string>
<string name="bluetooth_select_avrcp_version_string" msgid="1710571610177659127">"Versioni AVRCP i Bluetooth-it"</string>
<string name="bluetooth_select_avrcp_version_dialog_title" msgid="7846922290083709633">"Zgjidh versionin AVRCP të Bluetooth-it"</string>
+ <string name="bluetooth_select_map_version_string" msgid="526308145174175327">"Versioni MAP i Bluetooth-it"</string>
+ <string name="bluetooth_select_map_version_dialog_title" msgid="7085934373987428460">"Zgjidh versionin MAP të Bluetooth-it"</string>
<string name="bluetooth_select_a2dp_codec_type" msgid="952001408455456494">"Kodeku Bluetooth Audio"</string>
<string name="bluetooth_select_a2dp_codec_type_dialog_title" msgid="7510542404227225545">"Aktivizo kodekun e audios me Bluetooth\nZgjedhja"</string>
<string name="bluetooth_select_a2dp_codec_sample_rate" msgid="1638623076480928191">"Shpejtësia e shembullit të Bluetooth Audio"</string>
@@ -276,7 +278,7 @@
<string name="verify_apps_over_usb_summary" msgid="1317933737581167839">"Kontrollo aplikacionet e instaluara nëpërmjet ADB/ADT për sjellje të dëmshme."</string>
<string name="bluetooth_show_devices_without_names_summary" msgid="780964354377854507">"Pajisjet me Bluetooth do të shfaqen pa emra (vetëm adresat MAC)"</string>
<string name="bluetooth_disable_absolute_volume_summary" msgid="2006309932135547681">"Çaktivizon funksionin e volumit absolut të Bluetooth në rast të problemeve të volumit me pajisjet në largësi, si p.sh. një volum i lartë i papranueshëm ose mungesa e kontrollit."</string>
- <string name="bluetooth_enable_gabeldorsche_summary" msgid="8472344901097607030">"Aktivizon grupin e veçorive të Bluetooth Gabeldorche."</string>
+ <string name="bluetooth_enable_gabeldorsche_summary" msgid="2054730331770712629">"Aktivizon grupin e veçorive të Bluetooth Gabeldorsche."</string>
<string name="enable_terminal_title" msgid="3834790541986303654">"Terminali lokal"</string>
<string name="enable_terminal_summary" msgid="2481074834856064500">"Aktivizo aplikacionin terminal që ofron qasje në guaskën lokale"</string>
<string name="hdcp_checking_title" msgid="3155692785074095986">"Kontrolli HDCP"</string>
diff --git a/packages/SettingsLib/res/values-sr/arrays.xml b/packages/SettingsLib/res/values-sr/arrays.xml
index c543ac1a7fde..a4e9156c3a72 100644
--- a/packages/SettingsLib/res/values-sr/arrays.xml
+++ b/packages/SettingsLib/res/values-sr/arrays.xml
@@ -75,6 +75,16 @@
<item msgid="4398977131424970917">"avrcp15"</item>
<item msgid="1963366694959681026">"avrcp16"</item>
</string-array>
+ <string-array name="bluetooth_map_versions">
+ <item msgid="8786402640610987099">"MAP 1.2 (подразумевано)"</item>
+ <item msgid="6817922176194686449">"MAP 1.3"</item>
+ <item msgid="3423518690032737851">"MAP 1.4"</item>
+ </string-array>
+ <string-array name="bluetooth_map_version_values">
+ <item msgid="1164651830068248391">"map12"</item>
+ <item msgid="7073042887003102964">"map13"</item>
+ <item msgid="8147982633566548515">"map14"</item>
+ </string-array>
<string-array name="bluetooth_a2dp_codec_titles">
<item msgid="2494959071796102843">"Користи избор система (подразумевано)"</item>
<item msgid="4055460186095649420">"SBC"</item>
diff --git a/packages/SettingsLib/res/values-sr/strings.xml b/packages/SettingsLib/res/values-sr/strings.xml
index a395d7b96725..08e2bc85db4e 100644
--- a/packages/SettingsLib/res/values-sr/strings.xml
+++ b/packages/SettingsLib/res/values-sr/strings.xml
@@ -230,6 +230,8 @@
<string name="bluetooth_enable_gabeldorsche" msgid="9131730396242883416">"Омогући Gabeldorsche"</string>
<string name="bluetooth_select_avrcp_version_string" msgid="1710571610177659127">"Верзија Bluetooth AVRCP-а"</string>
<string name="bluetooth_select_avrcp_version_dialog_title" msgid="7846922290083709633">"Изаберите верзију Bluetooth AVRCP-а"</string>
+ <string name="bluetooth_select_map_version_string" msgid="526308145174175327">"Верзија Bluetooth MAP-а"</string>
+ <string name="bluetooth_select_map_version_dialog_title" msgid="7085934373987428460">"Изаберите верзију Bluetooth MAP-а"</string>
<string name="bluetooth_select_a2dp_codec_type" msgid="952001408455456494">"Bluetooth аудио кодек"</string>
<string name="bluetooth_select_a2dp_codec_type_dialog_title" msgid="7510542404227225545">"Изаберите Bluetooth аудио кодек\n"</string>
<string name="bluetooth_select_a2dp_codec_sample_rate" msgid="1638623076480928191">"Брзина узорковања за Bluetooth аудио"</string>
@@ -276,7 +278,7 @@
<string name="verify_apps_over_usb_summary" msgid="1317933737581167839">"Проверава да ли су апликације инсталиране преко ADB-а/ADT-а штетне."</string>
<string name="bluetooth_show_devices_without_names_summary" msgid="780964354377854507">"Биће приказани Bluetooth уређаји без назива (само са MAC адресама)"</string>
<string name="bluetooth_disable_absolute_volume_summary" msgid="2006309932135547681">"Онемогућава главно подешавање јачине звука на Bluetooth уређају у случају проблема са јачином звука на даљинским уређајима, као што су изузетно велика јачина звука или недостатак контроле."</string>
- <string name="bluetooth_enable_gabeldorsche_summary" msgid="8472344901097607030">"Омогућава групу Bluetooth Gabeldorche функција."</string>
+ <string name="bluetooth_enable_gabeldorsche_summary" msgid="2054730331770712629">"Омогућава групу Bluetooth Gabeldorsche функција."</string>
<string name="enable_terminal_title" msgid="3834790541986303654">"Локални терминал"</string>
<string name="enable_terminal_summary" msgid="2481074834856064500">"Омогући апл. терминала за приступ локалном командном окружењу"</string>
<string name="hdcp_checking_title" msgid="3155692785074095986">"HDCP провера"</string>
diff --git a/packages/SettingsLib/res/values-sv/arrays.xml b/packages/SettingsLib/res/values-sv/arrays.xml
index c31b80c0eac8..b5b1186aba3c 100644
--- a/packages/SettingsLib/res/values-sv/arrays.xml
+++ b/packages/SettingsLib/res/values-sv/arrays.xml
@@ -75,6 +75,16 @@
<item msgid="4398977131424970917">"avrcp15"</item>
<item msgid="1963366694959681026">"avrcp16"</item>
</string-array>
+ <string-array name="bluetooth_map_versions">
+ <item msgid="8786402640610987099">"MAP 1.2 (standard)"</item>
+ <item msgid="6817922176194686449">"MAP 1.3"</item>
+ <item msgid="3423518690032737851">"MAP 1.4"</item>
+ </string-array>
+ <string-array name="bluetooth_map_version_values">
+ <item msgid="1164651830068248391">"map12"</item>
+ <item msgid="7073042887003102964">"map13"</item>
+ <item msgid="8147982633566548515">"map14"</item>
+ </string-array>
<string-array name="bluetooth_a2dp_codec_titles">
<item msgid="2494959071796102843">"Använd systemval (standardinställning)"</item>
<item msgid="4055460186095649420">"SBC"</item>
diff --git a/packages/SettingsLib/res/values-sv/strings.xml b/packages/SettingsLib/res/values-sv/strings.xml
index f021cc2db25c..c0cdbc913aea 100644
--- a/packages/SettingsLib/res/values-sv/strings.xml
+++ b/packages/SettingsLib/res/values-sv/strings.xml
@@ -230,6 +230,8 @@
<string name="bluetooth_enable_gabeldorsche" msgid="9131730396242883416">"Aktivera Gabeldorsche"</string>
<string name="bluetooth_select_avrcp_version_string" msgid="1710571610177659127">"AVRCP-version för Bluetooth"</string>
<string name="bluetooth_select_avrcp_version_dialog_title" msgid="7846922290083709633">"Välj AVRCP-version för Bluetooth"</string>
+ <string name="bluetooth_select_map_version_string" msgid="526308145174175327">"MAP-version för Bluetooth"</string>
+ <string name="bluetooth_select_map_version_dialog_title" msgid="7085934373987428460">"Välj MAP-version för Bluetooth"</string>
<string name="bluetooth_select_a2dp_codec_type" msgid="952001408455456494">"Ljudkodek för Bluetooth"</string>
<string name="bluetooth_select_a2dp_codec_type_dialog_title" msgid="7510542404227225545">"Aktivera ljudkodek för Bluetooth\nVal"</string>
<string name="bluetooth_select_a2dp_codec_sample_rate" msgid="1638623076480928191">"Samplingsfrekvens för Bluetooth-ljud"</string>
@@ -276,7 +278,7 @@
<string name="verify_apps_over_usb_summary" msgid="1317933737581167839">"Kontrollera om appar som installeras via ADB/ADT kan vara skadliga."</string>
<string name="bluetooth_show_devices_without_names_summary" msgid="780964354377854507">"Bluetooth-enheter utan namn (enbart MAC-adresser) visas"</string>
<string name="bluetooth_disable_absolute_volume_summary" msgid="2006309932135547681">"Inaktivera Bluetooth-funktionen Absolute volume om det skulle uppstå problem med volymen på fjärrenheter, t.ex. alldeles för hög volym eller brist på kontroll."</string>
- <string name="bluetooth_enable_gabeldorsche_summary" msgid="8472344901097607030">"Aktiverar funktionsgruppen Bluetooth Gabeldorche."</string>
+ <string name="bluetooth_enable_gabeldorsche_summary" msgid="2054730331770712629">"Aktiverar funktionsgruppen Bluetooth Gabeldorsche."</string>
<string name="enable_terminal_title" msgid="3834790541986303654">"Lokal terminal"</string>
<string name="enable_terminal_summary" msgid="2481074834856064500">"Aktivera en terminalapp som ger åtkomst till hyllor lokalt"</string>
<string name="hdcp_checking_title" msgid="3155692785074095986">"HDCP-kontroll"</string>
diff --git a/packages/SettingsLib/res/values-sw/arrays.xml b/packages/SettingsLib/res/values-sw/arrays.xml
index ff488583fa68..a29b74e6d17d 100644
--- a/packages/SettingsLib/res/values-sw/arrays.xml
+++ b/packages/SettingsLib/res/values-sw/arrays.xml
@@ -75,6 +75,16 @@
<item msgid="4398977131424970917">"avrcp15"</item>
<item msgid="1963366694959681026">"avrcp16"</item>
</string-array>
+ <string-array name="bluetooth_map_versions">
+ <item msgid="8786402640610987099">"RAMANI YA 1.2 (Chaguomsingi)"</item>
+ <item msgid="6817922176194686449">"RAMANI YA 1.3"</item>
+ <item msgid="3423518690032737851">"RAMANI YA 1.4"</item>
+ </string-array>
+ <string-array name="bluetooth_map_version_values">
+ <item msgid="1164651830068248391">"ramani ya 12"</item>
+ <item msgid="7073042887003102964">"ramani ya 13"</item>
+ <item msgid="8147982633566548515">"ramani ya 14"</item>
+ </string-array>
<string-array name="bluetooth_a2dp_codec_titles">
<item msgid="2494959071796102843">"Tumia Uteuzi wa Mfumo (Chaguomsingi)"</item>
<item msgid="4055460186095649420">"SBC"</item>
diff --git a/packages/SettingsLib/res/values-sw/strings.xml b/packages/SettingsLib/res/values-sw/strings.xml
index 42422fb26133..f00dea3822cf 100644
--- a/packages/SettingsLib/res/values-sw/strings.xml
+++ b/packages/SettingsLib/res/values-sw/strings.xml
@@ -230,6 +230,8 @@
<string name="bluetooth_enable_gabeldorsche" msgid="9131730396242883416">"Washa Gabeldorsche"</string>
<string name="bluetooth_select_avrcp_version_string" msgid="1710571610177659127">"Toleo la Bluetooth AVRCP"</string>
<string name="bluetooth_select_avrcp_version_dialog_title" msgid="7846922290083709633">"Chagua Toleo la Bluetooth AVRCP"</string>
+ <string name="bluetooth_select_map_version_string" msgid="526308145174175327">"Toleo la Ramani ya Bluetooth"</string>
+ <string name="bluetooth_select_map_version_dialog_title" msgid="7085934373987428460">"Chagua Toleo la Ramani ya Bluetooth"</string>
<string name="bluetooth_select_a2dp_codec_type" msgid="952001408455456494">"Kodeki ya Sauti ya Bluetooth"</string>
<string name="bluetooth_select_a2dp_codec_type_dialog_title" msgid="7510542404227225545">"Weka Kodeki ya Sauti ya Bluetooth\nUteuzi"</string>
<string name="bluetooth_select_a2dp_codec_sample_rate" msgid="1638623076480928191">"Kiwango cha Sampuli ya Sauti ya Bluetooth"</string>
@@ -276,7 +278,7 @@
<string name="verify_apps_over_usb_summary" msgid="1317933737581167839">"Kagua iwapo programu zilizosakinishwa kupitia ADB/ADT zina tabia ya kudhuru."</string>
<string name="bluetooth_show_devices_without_names_summary" msgid="780964354377854507">"Itaonyesha vifaa vya Bluetooth bila majina (anwani za MAC pekee)"</string>
<string name="bluetooth_disable_absolute_volume_summary" msgid="2006309932135547681">"Huzima kipengele cha Bluetooth cha sauti kamili kunapotokea matatizo ya sauti katika vifaa vya mbali kama vile sauti ya juu mno au inaposhindikana kuidhibiti."</string>
- <string name="bluetooth_enable_gabeldorsche_summary" msgid="8472344901097607030">"Huwasha rafu ya kipengele cha Bluetooth Gabeldorche."</string>
+ <string name="bluetooth_enable_gabeldorsche_summary" msgid="2054730331770712629">"Huwasha rafu ya kipengele ya Bluetooth Gabeldorsche."</string>
<string name="enable_terminal_title" msgid="3834790541986303654">"Kituo cha karibu"</string>
<string name="enable_terminal_summary" msgid="2481074834856064500">"Washa programu ya mwisho inayotoa ufikiaji mkuu wa karibu"</string>
<string name="hdcp_checking_title" msgid="3155692785074095986">"Inakagua HDCP"</string>
diff --git a/packages/SettingsLib/res/values-ta/arrays.xml b/packages/SettingsLib/res/values-ta/arrays.xml
index 5668b6d8c327..0f19148435d7 100644
--- a/packages/SettingsLib/res/values-ta/arrays.xml
+++ b/packages/SettingsLib/res/values-ta/arrays.xml
@@ -75,6 +75,16 @@
<item msgid="4398977131424970917">"avrcp15"</item>
<item msgid="1963366694959681026">"avrcp16"</item>
</string-array>
+ <string-array name="bluetooth_map_versions">
+ <item msgid="8786402640610987099">"MAP 1.2 (இயல்பாக)"</item>
+ <item msgid="6817922176194686449">"MAP 1.3"</item>
+ <item msgid="3423518690032737851">"MAP 1.4"</item>
+ </string-array>
+ <string-array name="bluetooth_map_version_values">
+ <item msgid="1164651830068248391">"map12"</item>
+ <item msgid="7073042887003102964">"map13"</item>
+ <item msgid="8147982633566548515">"map14"</item>
+ </string-array>
<string-array name="bluetooth_a2dp_codec_titles">
<item msgid="2494959071796102843">"சாதனத் தேர்வைப் பயன்படுத்து (இயல்பு)"</item>
<item msgid="4055460186095649420">"SBC"</item>
diff --git a/packages/SettingsLib/res/values-ta/strings.xml b/packages/SettingsLib/res/values-ta/strings.xml
index 295399d4a046..52e0363147da 100644
--- a/packages/SettingsLib/res/values-ta/strings.xml
+++ b/packages/SettingsLib/res/values-ta/strings.xml
@@ -227,10 +227,11 @@
<string name="tethering_hardware_offload" msgid="4116053719006939161">"வன்பொருள் விரைவுப்படுத்துதல் இணைப்பு முறை"</string>
<string name="bluetooth_show_devices_without_names" msgid="923584526471885819">"பெயர்கள் இல்லாத புளூடூத் சாதனங்களைக் காட்டு"</string>
<string name="bluetooth_disable_absolute_volume" msgid="1452342324349203434">"அப்சல்யூட் ஒலியளவு அம்சத்தை முடக்கு"</string>
- <!-- no translation found for bluetooth_enable_gabeldorsche (9131730396242883416) -->
- <skip />
+ <string name="bluetooth_enable_gabeldorsche" msgid="9131730396242883416">"Gabeldorscheவை இயக்கு"</string>
<string name="bluetooth_select_avrcp_version_string" msgid="1710571610177659127">"புளூடூத் AVRCP பதிப்பு"</string>
<string name="bluetooth_select_avrcp_version_dialog_title" msgid="7846922290083709633">"புளூடூத் AVRCP பதிப்பைத் தேர்ந்தெடு"</string>
+ <string name="bluetooth_select_map_version_string" msgid="526308145174175327">"புளூடூத்தின் MAP பதிப்பு"</string>
+ <string name="bluetooth_select_map_version_dialog_title" msgid="7085934373987428460">"புளூடூத்தின் MAP பதிப்பைத் தேர்வுசெய்க"</string>
<string name="bluetooth_select_a2dp_codec_type" msgid="952001408455456494">"புளூடூத் ஆடியோ கோடெக்"</string>
<string name="bluetooth_select_a2dp_codec_type_dialog_title" msgid="7510542404227225545">"புளூடூத் ஆடியோ கோடெக்கைத் தொடங்கு\nதேர்வு"</string>
<string name="bluetooth_select_a2dp_codec_sample_rate" msgid="1638623076480928191">"புளூடூத் ஆடியோ சாம்பிள் ரேட்"</string>
@@ -277,8 +278,7 @@
<string name="verify_apps_over_usb_summary" msgid="1317933737581167839">"தீங்கு விளைவிக்கும் செயல்பாட்டை அறிய ADB/ADT மூலம் நிறுவப்பட்ட ஆப்ஸைச் சரிபார்."</string>
<string name="bluetooth_show_devices_without_names_summary" msgid="780964354377854507">"பெயர்கள் இல்லாத புளூடூத் சாதனங்கள் (MAC முகவரிகள் மட்டும்) காட்டப்படும்"</string>
<string name="bluetooth_disable_absolute_volume_summary" msgid="2006309932135547681">"மிகவும் அதிகமான ஒலியளவு அல்லது கட்டுப்பாடு இழப்பு போன்ற தொலைநிலைச் சாதனங்களில் ஏற்படும் ஒலி தொடர்பான சிக்கல்கள் இருக்கும் சமயங்களில், புளூடூத் அப்சல்யூட் ஒலியளவு அம்சத்தை முடக்கும்."</string>
- <!-- no translation found for bluetooth_enable_gabeldorsche_summary (8472344901097607030) -->
- <skip />
+ <string name="bluetooth_enable_gabeldorsche_summary" msgid="2054730331770712629">"புளூடூத்தின் Gabeldorsche அம்சங்களை இயக்கும்."</string>
<string name="enable_terminal_title" msgid="3834790541986303654">"அக முனையம்"</string>
<string name="enable_terminal_summary" msgid="2481074834856064500">"அக ஷெல் அணுகலை வழங்கும் இறுதிப் ஆப்ஸை இயக்கு"</string>
<string name="hdcp_checking_title" msgid="3155692785074095986">"HDCP சரிபார்ப்பு"</string>
diff --git a/packages/SettingsLib/res/values-te/arrays.xml b/packages/SettingsLib/res/values-te/arrays.xml
index 70068bfe0033..23256eeb7d03 100644
--- a/packages/SettingsLib/res/values-te/arrays.xml
+++ b/packages/SettingsLib/res/values-te/arrays.xml
@@ -75,6 +75,16 @@
<item msgid="4398977131424970917">"avrcp15"</item>
<item msgid="1963366694959681026">"avrcp16"</item>
</string-array>
+ <string-array name="bluetooth_map_versions">
+ <item msgid="8786402640610987099">"MAP 1.2 (డిఫాల్ట్)"</item>
+ <item msgid="6817922176194686449">"MAP 1.3"</item>
+ <item msgid="3423518690032737851">"MAP 1.4"</item>
+ </string-array>
+ <string-array name="bluetooth_map_version_values">
+ <item msgid="1164651830068248391">"map12"</item>
+ <item msgid="7073042887003102964">"map13"</item>
+ <item msgid="8147982633566548515">"map14"</item>
+ </string-array>
<string-array name="bluetooth_a2dp_codec_titles">
<item msgid="2494959071796102843">"సిస్టమ్ ఎంపికను ఉపయోగించండి (డిఫాల్ట్)"</item>
<item msgid="4055460186095649420">"SBC"</item>
diff --git a/packages/SettingsLib/res/values-te/strings.xml b/packages/SettingsLib/res/values-te/strings.xml
index f92b8af24cf7..a39c4e14cddd 100644
--- a/packages/SettingsLib/res/values-te/strings.xml
+++ b/packages/SettingsLib/res/values-te/strings.xml
@@ -230,6 +230,8 @@
<string name="bluetooth_enable_gabeldorsche" msgid="9131730396242883416">"Gabeldorscheను ఎనేబుల్ చేయి"</string>
<string name="bluetooth_select_avrcp_version_string" msgid="1710571610177659127">"బ్లూటూత్ AVRCP వెర్షన్"</string>
<string name="bluetooth_select_avrcp_version_dialog_title" msgid="7846922290083709633">"బ్లూటూత్ AVRCP సంస్కరణను ఎంచుకోండి"</string>
+ <string name="bluetooth_select_map_version_string" msgid="526308145174175327">"బ్లూటూత్ MAP వెర్షన్‌"</string>
+ <string name="bluetooth_select_map_version_dialog_title" msgid="7085934373987428460">"బ్లూటూత్ MAP వెర్షన్‌ను ఎంచుకోండి"</string>
<string name="bluetooth_select_a2dp_codec_type" msgid="952001408455456494">"బ్లూటూత్ ఆడియో కోడెక్"</string>
<string name="bluetooth_select_a2dp_codec_type_dialog_title" msgid="7510542404227225545">"బ్లూటూత్ ఆడియో కోడెక్‌ని సక్రియం చేయండి\nఎంపిక"</string>
<string name="bluetooth_select_a2dp_codec_sample_rate" msgid="1638623076480928191">"బ్లూటూత్ ఆడియో నమూనా రేట్"</string>
@@ -276,7 +278,7 @@
<string name="verify_apps_over_usb_summary" msgid="1317933737581167839">"హానికరమైన ప్రవర్తన కోసం ADB/ADT ద్వారా ఇన్‌స్టాల్ చేయబడిన యాప్‌లను తనిఖీ చేయి."</string>
<string name="bluetooth_show_devices_without_names_summary" msgid="780964354377854507">"పేర్లు (MAC చిరునామాలు మాత్రమే) లేని బ్లూటూత్ పరికరాలు ప్రదర్శించబడతాయి"</string>
<string name="bluetooth_disable_absolute_volume_summary" msgid="2006309932135547681">"రిమోట్ పరికరాల్లో ఆమోదించలేని స్థాయిలో అధిక వాల్యూమ్ ఉండటం లేదా వాల్యూమ్ నియంత్రణ లేకపోవడం వంటి సమస్యలు ఉంటే బ్లూటూత్ సంపూర్ణ వాల్యూమ్ ఫీచర్‌ని నిలిపివేస్తుంది."</string>
- <string name="bluetooth_enable_gabeldorsche_summary" msgid="8472344901097607030">"బ్లూటూత్ ఫీచర్ స్ట్యాక్‌ను ఎనేబుల్ చేస్తుంది."</string>
+ <string name="bluetooth_enable_gabeldorsche_summary" msgid="2054730331770712629">"బ్లూటూత్ Gabeldorsche ఫీచర్ స్ట్యాక్‌ను ఎనేబుల్ చేస్తుంది."</string>
<string name="enable_terminal_title" msgid="3834790541986303654">"స్థానిక టెర్మినల్"</string>
<string name="enable_terminal_summary" msgid="2481074834856064500">"స్థానిక షెల్ ప్రాప్యతను అందించే టెర్మినల్ అనువర్తనాన్ని ప్రారంభించు"</string>
<string name="hdcp_checking_title" msgid="3155692785074095986">"HDCP తనిఖీ"</string>
diff --git a/packages/SettingsLib/res/values-th/arrays.xml b/packages/SettingsLib/res/values-th/arrays.xml
index 20333b72aff7..8aac165da6d3 100644
--- a/packages/SettingsLib/res/values-th/arrays.xml
+++ b/packages/SettingsLib/res/values-th/arrays.xml
@@ -75,6 +75,16 @@
<item msgid="4398977131424970917">"avrcp15"</item>
<item msgid="1963366694959681026">"avrcp16"</item>
</string-array>
+ <string-array name="bluetooth_map_versions">
+ <item msgid="8786402640610987099">"MAP 1.2 (ค่าเริ่มต้น)"</item>
+ <item msgid="6817922176194686449">"MAP 1.3"</item>
+ <item msgid="3423518690032737851">"MAP 1.4"</item>
+ </string-array>
+ <string-array name="bluetooth_map_version_values">
+ <item msgid="1164651830068248391">"map12"</item>
+ <item msgid="7073042887003102964">"map13"</item>
+ <item msgid="8147982633566548515">"map14"</item>
+ </string-array>
<string-array name="bluetooth_a2dp_codec_titles">
<item msgid="2494959071796102843">"ใช้การเลือกของระบบ (ค่าเริ่มต้น)"</item>
<item msgid="4055460186095649420">"SBC"</item>
diff --git a/packages/SettingsLib/res/values-th/strings.xml b/packages/SettingsLib/res/values-th/strings.xml
index 19ae491d4763..635d77a77a35 100644
--- a/packages/SettingsLib/res/values-th/strings.xml
+++ b/packages/SettingsLib/res/values-th/strings.xml
@@ -230,6 +230,8 @@
<string name="bluetooth_enable_gabeldorsche" msgid="9131730396242883416">"เปิดใช้ Gabeldorsche"</string>
<string name="bluetooth_select_avrcp_version_string" msgid="1710571610177659127">"เวอร์ชันของบลูทูธ AVRCP"</string>
<string name="bluetooth_select_avrcp_version_dialog_title" msgid="7846922290083709633">"เลือกเวอร์ชันของบลูทูธ AVRCP"</string>
+ <string name="bluetooth_select_map_version_string" msgid="526308145174175327">"เวอร์ชัน MAP ของบลูทูธ"</string>
+ <string name="bluetooth_select_map_version_dialog_title" msgid="7085934373987428460">"เลือกเวอร์ชัน MAP ของบลูทูธ"</string>
<string name="bluetooth_select_a2dp_codec_type" msgid="952001408455456494">"ตัวแปลงสัญญาณเสียงบลูทูธ"</string>
<string name="bluetooth_select_a2dp_codec_type_dialog_title" msgid="7510542404227225545">"ทริกเกอร์การเลือกตัวแปลงรหัส\nเสียงบลูทูธ"</string>
<string name="bluetooth_select_a2dp_codec_sample_rate" msgid="1638623076480928191">"อัตราตัวอย่างเสียงบลูทูธ"</string>
@@ -276,7 +278,7 @@
<string name="verify_apps_over_usb_summary" msgid="1317933737581167839">"ตรวจสอบแอปที่ติดตั้งผ่าน ADB/ADT เพื่อตรวจดูพฤติกรรมที่เป็นอันตราย"</string>
<string name="bluetooth_show_devices_without_names_summary" msgid="780964354377854507">"ระบบจะแสดงอุปกรณ์บลูทูธที่ไม่มีชื่อ (มีเฉพาะที่อยู่ MAC)"</string>
<string name="bluetooth_disable_absolute_volume_summary" msgid="2006309932135547681">"ปิดใช้ฟีเจอร์การควบคุมระดับเสียงของอุปกรณ์อื่นผ่านบลูทูธในกรณีที่มีปัญหาเกี่ยวกับระดับเสียงของอุปกรณ์ระยะไกล เช่น ระดับเสียงที่ดังเกินไปหรือระดับเสียงที่ไม่มีการควบคุม"</string>
- <string name="bluetooth_enable_gabeldorsche_summary" msgid="8472344901097607030">"เปิดใช้สแต็กฟีเจอร์ Bluetooth Gabeldorche"</string>
+ <string name="bluetooth_enable_gabeldorsche_summary" msgid="2054730331770712629">"เปิดใช้สแต็กฟีเจอร์ Bluetooth Gabeldorsche"</string>
<string name="enable_terminal_title" msgid="3834790541986303654">"เทอร์มินัลในตัวเครื่อง"</string>
<string name="enable_terminal_summary" msgid="2481074834856064500">"เปิดใช้งานแอปเทอร์มินัลที่ให้การเข้าถึงเชลล์ในตัวเครื่อง"</string>
<string name="hdcp_checking_title" msgid="3155692785074095986">"การตรวจสอบ HDCP"</string>
diff --git a/packages/SettingsLib/res/values-tl/arrays.xml b/packages/SettingsLib/res/values-tl/arrays.xml
index 473480722213..9e08b8fd3ed8 100644
--- a/packages/SettingsLib/res/values-tl/arrays.xml
+++ b/packages/SettingsLib/res/values-tl/arrays.xml
@@ -75,6 +75,16 @@
<item msgid="4398977131424970917">"avrcp15"</item>
<item msgid="1963366694959681026">"avrcp16"</item>
</string-array>
+ <string-array name="bluetooth_map_versions">
+ <item msgid="8786402640610987099">"MAP 1.2 (Default)"</item>
+ <item msgid="6817922176194686449">"MAP 1.3"</item>
+ <item msgid="3423518690032737851">"MAP 1.4"</item>
+ </string-array>
+ <string-array name="bluetooth_map_version_values">
+ <item msgid="1164651830068248391">"map12"</item>
+ <item msgid="7073042887003102964">"map13"</item>
+ <item msgid="8147982633566548515">"map14"</item>
+ </string-array>
<string-array name="bluetooth_a2dp_codec_titles">
<item msgid="2494959071796102843">"Gamitin ang Pagpili ng System (Default)"</item>
<item msgid="4055460186095649420">"SBC"</item>
diff --git a/packages/SettingsLib/res/values-tl/strings.xml b/packages/SettingsLib/res/values-tl/strings.xml
index f6dfdba83b2e..3f7f0ff56f8a 100644
--- a/packages/SettingsLib/res/values-tl/strings.xml
+++ b/packages/SettingsLib/res/values-tl/strings.xml
@@ -230,6 +230,8 @@
<string name="bluetooth_enable_gabeldorsche" msgid="9131730396242883416">"I-enable ang Gabeldorsche"</string>
<string name="bluetooth_select_avrcp_version_string" msgid="1710571610177659127">"Bersyon ng AVRCP ng Bluetooth"</string>
<string name="bluetooth_select_avrcp_version_dialog_title" msgid="7846922290083709633">"Pumili ng Bersyon ng AVRCP ng Bluetooth"</string>
+ <string name="bluetooth_select_map_version_string" msgid="526308145174175327">"Bersyon ng MAP ng Bluetooth"</string>
+ <string name="bluetooth_select_map_version_dialog_title" msgid="7085934373987428460">"Pumili ng Bersyon ng MAP ng Bluetooth"</string>
<string name="bluetooth_select_a2dp_codec_type" msgid="952001408455456494">"Bluetooth Audio Codec"</string>
<string name="bluetooth_select_a2dp_codec_type_dialog_title" msgid="7510542404227225545">"I-trigger ang Pagpili sa Audio Codec ng\nBluetooth"</string>
<string name="bluetooth_select_a2dp_codec_sample_rate" msgid="1638623076480928191">"Sample na Rate ng Bluetooth Audio"</string>
@@ -276,7 +278,7 @@
<string name="verify_apps_over_usb_summary" msgid="1317933737581167839">"Tingnan kung may nakakahamak na pagkilos sa apps na na-install sa pamamagitan ng ADB/ADT."</string>
<string name="bluetooth_show_devices_without_names_summary" msgid="780964354377854507">"Ipapakita ang mga Bluetooth device na walang pangalan (mga MAC address lang)"</string>
<string name="bluetooth_disable_absolute_volume_summary" msgid="2006309932135547681">"Dini-disable ang absolute volume feature ng Bluetooth kung may mga isyu sa volume ang mga malayong device gaya ng hindi katanggap-tanggap na malakas na volume o kawalan ng kontrol."</string>
- <string name="bluetooth_enable_gabeldorsche_summary" msgid="8472344901097607030">"Ine-enable ang stack ng feature ng Bluetooth Gabeldorche."</string>
+ <string name="bluetooth_enable_gabeldorsche_summary" msgid="2054730331770712629">"Ine-enable ang stack ng feature ng Bluetooth Gabeldorsche."</string>
<string name="enable_terminal_title" msgid="3834790541986303654">"Lokal na terminal"</string>
<string name="enable_terminal_summary" msgid="2481074834856064500">"Paganahin ang terminal app na nag-aalok ng lokal na shell access"</string>
<string name="hdcp_checking_title" msgid="3155692785074095986">"Pagsusuring HDCP"</string>
diff --git a/packages/SettingsLib/res/values-tr/arrays.xml b/packages/SettingsLib/res/values-tr/arrays.xml
index ac6e0f502bfb..7ce6c24d321e 100644
--- a/packages/SettingsLib/res/values-tr/arrays.xml
+++ b/packages/SettingsLib/res/values-tr/arrays.xml
@@ -75,6 +75,16 @@
<item msgid="4398977131424970917">"avrcp15"</item>
<item msgid="1963366694959681026">"avrcp16"</item>
</string-array>
+ <string-array name="bluetooth_map_versions">
+ <item msgid="8786402640610987099">"MAP 1.2 (Varsayılan)"</item>
+ <item msgid="6817922176194686449">"MAP 1.3"</item>
+ <item msgid="3423518690032737851">"MAP 1.4"</item>
+ </string-array>
+ <string-array name="bluetooth_map_version_values">
+ <item msgid="1164651830068248391">"map12"</item>
+ <item msgid="7073042887003102964">"map13"</item>
+ <item msgid="8147982633566548515">"map14"</item>
+ </string-array>
<string-array name="bluetooth_a2dp_codec_titles">
<item msgid="2494959071796102843">"Sistem Seçimini Kullan (Varsayılan)"</item>
<item msgid="4055460186095649420">"SBC"</item>
diff --git a/packages/SettingsLib/res/values-tr/strings.xml b/packages/SettingsLib/res/values-tr/strings.xml
index 554d62e7164d..7ad6fcd24ea1 100644
--- a/packages/SettingsLib/res/values-tr/strings.xml
+++ b/packages/SettingsLib/res/values-tr/strings.xml
@@ -230,6 +230,8 @@
<string name="bluetooth_enable_gabeldorsche" msgid="9131730396242883416">"Gabeldorsche\'yi etkileştir"</string>
<string name="bluetooth_select_avrcp_version_string" msgid="1710571610177659127">"Bluetooth AVRCP Sürümü"</string>
<string name="bluetooth_select_avrcp_version_dialog_title" msgid="7846922290083709633">"Bluetooth AVRCP Sürümünü seçin"</string>
+ <string name="bluetooth_select_map_version_string" msgid="526308145174175327">"Bluetooth MAP Sürümü"</string>
+ <string name="bluetooth_select_map_version_dialog_title" msgid="7085934373987428460">"Bluetooth MAP Sürümünü seçin"</string>
<string name="bluetooth_select_a2dp_codec_type" msgid="952001408455456494">"Bluetooth Ses Codec\'i"</string>
<string name="bluetooth_select_a2dp_codec_type_dialog_title" msgid="7510542404227225545">"Bluetooth Ses Codec\'i Tetikleme\nSeçimi"</string>
<string name="bluetooth_select_a2dp_codec_sample_rate" msgid="1638623076480928191">"Bluetooth Ses Örnek Hızı"</string>
@@ -276,7 +278,7 @@
<string name="verify_apps_over_usb_summary" msgid="1317933737581167839">"ADB/ADT üzerinden yüklenen uygulamaları zararlı davranışlara karşı denetle."</string>
<string name="bluetooth_show_devices_without_names_summary" msgid="780964354377854507">"Adsız Bluetooth cihazları (yalnızca MAC adresleri) gösterilecek"</string>
<string name="bluetooth_disable_absolute_volume_summary" msgid="2006309932135547681">"Uzak cihazda sesin aşırı yüksek olması veya kontrol edilememesi gibi ses sorunları olması ihtimaline karşı Bluetooh mutlak ses özelliğini iptal eder."</string>
- <string name="bluetooth_enable_gabeldorsche_summary" msgid="8472344901097607030">"Bluetooth Gabeldorche özellik grubunu etkinleştirir."</string>
+ <string name="bluetooth_enable_gabeldorsche_summary" msgid="2054730331770712629">"Bluetooth Gabeldorsche özellik yığınını etkinleştirir."</string>
<string name="enable_terminal_title" msgid="3834790541986303654">"Yerel terminal"</string>
<string name="enable_terminal_summary" msgid="2481074834856064500">"Yerel kabuk erişimi sunan terminal uygulamasını etkinleştir"</string>
<string name="hdcp_checking_title" msgid="3155692785074095986">"HDCP denetimi"</string>
diff --git a/packages/SettingsLib/res/values-uk/arrays.xml b/packages/SettingsLib/res/values-uk/arrays.xml
index effd49608921..2d0abe09a377 100644
--- a/packages/SettingsLib/res/values-uk/arrays.xml
+++ b/packages/SettingsLib/res/values-uk/arrays.xml
@@ -75,6 +75,16 @@
<item msgid="4398977131424970917">"avrcp15"</item>
<item msgid="1963366694959681026">"avrcp16"</item>
</string-array>
+ <string-array name="bluetooth_map_versions">
+ <item msgid="8786402640610987099">"MAP 1.2 (за умовчанням)"</item>
+ <item msgid="6817922176194686449">"MAP 1.3"</item>
+ <item msgid="3423518690032737851">"MAP 1.4"</item>
+ </string-array>
+ <string-array name="bluetooth_map_version_values">
+ <item msgid="1164651830068248391">"map12"</item>
+ <item msgid="7073042887003102964">"map13"</item>
+ <item msgid="8147982633566548515">"map14"</item>
+ </string-array>
<string-array name="bluetooth_a2dp_codec_titles">
<item msgid="2494959071796102843">"Використовувати вибір системи (за умовчанням)"</item>
<item msgid="4055460186095649420">"SBC"</item>
diff --git a/packages/SettingsLib/res/values-uk/strings.xml b/packages/SettingsLib/res/values-uk/strings.xml
index 17f2393e9320..b5dd61898470 100644
--- a/packages/SettingsLib/res/values-uk/strings.xml
+++ b/packages/SettingsLib/res/values-uk/strings.xml
@@ -230,6 +230,8 @@
<string name="bluetooth_enable_gabeldorsche" msgid="9131730396242883416">"Увімкнути Gabeldorsche"</string>
<string name="bluetooth_select_avrcp_version_string" msgid="1710571610177659127">"Версія Bluetooth AVRCP"</string>
<string name="bluetooth_select_avrcp_version_dialog_title" msgid="7846922290083709633">"Виберіть версію Bluetooth AVRCP"</string>
+ <string name="bluetooth_select_map_version_string" msgid="526308145174175327">"Версія Bluetooth MAP"</string>
+ <string name="bluetooth_select_map_version_dialog_title" msgid="7085934373987428460">"Виберіть версію Bluetooth MAP"</string>
<string name="bluetooth_select_a2dp_codec_type" msgid="952001408455456494">"Кодек для аудіо Bluetooth"</string>
<string name="bluetooth_select_a2dp_codec_type_dialog_title" msgid="7510542404227225545">"Активувати кодек для аудіо Bluetooth\nВибір"</string>
<string name="bluetooth_select_a2dp_codec_sample_rate" msgid="1638623076480928191">"Частота вибірки для аудіо Bluetooth"</string>
@@ -276,7 +278,7 @@
<string name="verify_apps_over_usb_summary" msgid="1317933737581167839">"Перевіряти безпеку додатків, установлених через ADB/ADT."</string>
<string name="bluetooth_show_devices_without_names_summary" msgid="780964354377854507">"Пристрої Bluetooth відображатимуться без назв (лише MAC-адреси)"</string>
<string name="bluetooth_disable_absolute_volume_summary" msgid="2006309932135547681">"Функція абсолютної гучності Bluetooth вимикається, якщо на віддалених пристроях виникають проблеми, як-от надто висока гучність або втрата контролю."</string>
- <string name="bluetooth_enable_gabeldorsche_summary" msgid="8472344901097607030">"Вмикає функції Bluetooth Gabeldorche."</string>
+ <string name="bluetooth_enable_gabeldorsche_summary" msgid="2054730331770712629">"Вмикає функції Bluetooth Gabeldorsche."</string>
<string name="enable_terminal_title" msgid="3834790541986303654">"Локальний термінал"</string>
<string name="enable_terminal_summary" msgid="2481074834856064500">"Увімк. програму-термінал, що надає локальний доступ до оболонки"</string>
<string name="hdcp_checking_title" msgid="3155692785074095986">"Перевірка HDCP"</string>
diff --git a/packages/SettingsLib/res/values-ur/arrays.xml b/packages/SettingsLib/res/values-ur/arrays.xml
index d5a59ac78a5b..e056c1c1ecc1 100644
--- a/packages/SettingsLib/res/values-ur/arrays.xml
+++ b/packages/SettingsLib/res/values-ur/arrays.xml
@@ -75,6 +75,16 @@
<item msgid="4398977131424970917">"avrcp15"</item>
<item msgid="1963366694959681026">"avrcp16"</item>
</string-array>
+ <string-array name="bluetooth_map_versions">
+ <item msgid="8786402640610987099">"‏MAP 1.2 ‏(ڈیفالٹ)"</item>
+ <item msgid="6817922176194686449">"MAP 1.3"</item>
+ <item msgid="3423518690032737851">"MAP 1.4"</item>
+ </string-array>
+ <string-array name="bluetooth_map_version_values">
+ <item msgid="1164651830068248391">"map12"</item>
+ <item msgid="7073042887003102964">"map13"</item>
+ <item msgid="8147982633566548515">"map14"</item>
+ </string-array>
<string-array name="bluetooth_a2dp_codec_titles">
<item msgid="2494959071796102843">"سسٹم انتخاب کا استعمال کریں (ڈیفالٹ)"</item>
<item msgid="4055460186095649420">"SBC"</item>
diff --git a/packages/SettingsLib/res/values-ur/strings.xml b/packages/SettingsLib/res/values-ur/strings.xml
index 6830c595ef2d..ef9b2a1b294e 100644
--- a/packages/SettingsLib/res/values-ur/strings.xml
+++ b/packages/SettingsLib/res/values-ur/strings.xml
@@ -230,6 +230,8 @@
<string name="bluetooth_enable_gabeldorsche" msgid="9131730396242883416">"‏Gabeldorsche فعال کریں"</string>
<string name="bluetooth_select_avrcp_version_string" msgid="1710571610177659127">"‏بلوٹوتھ AVRCP ورژن"</string>
<string name="bluetooth_select_avrcp_version_dialog_title" msgid="7846922290083709633">"‏بلوٹوتھ AVRCP ورژن منتخب کریں"</string>
+ <string name="bluetooth_select_map_version_string" msgid="526308145174175327">"‏بلوٹوتھ MAP ورژن"</string>
+ <string name="bluetooth_select_map_version_dialog_title" msgid="7085934373987428460">"‏بلوٹوتھ MAP ورژن منتخب کریں"</string>
<string name="bluetooth_select_a2dp_codec_type" msgid="952001408455456494">"بلوٹوتھ آڈیو کوڈیک"</string>
<string name="bluetooth_select_a2dp_codec_type_dialog_title" msgid="7510542404227225545">"بلوٹوتھ آڈیو کوڈیک کو ٹریگر کریں\nانتخاب"</string>
<string name="bluetooth_select_a2dp_codec_sample_rate" msgid="1638623076480928191">"بلوٹوتھ آڈیو کے نمونے کی شرح"</string>
@@ -276,7 +278,7 @@
<string name="verify_apps_over_usb_summary" msgid="1317933737581167839">"‏نقصان دہ رویے کے مدنظر ADB/ADT کی معرفت انسٹال شدہ ایپس کی جانچ کریں۔"</string>
<string name="bluetooth_show_devices_without_names_summary" msgid="780964354377854507">"‏بغیر نام والے بلوٹوتھ آلات (صرف MAC پتے) ڈسپلے کئے جائیں گے"</string>
<string name="bluetooth_disable_absolute_volume_summary" msgid="2006309932135547681">"ریموٹ آلات کے ساتھ والیوم کے مسائل مثلاً نا قابل قبول حد تک بلند والیوم یا کنٹرول نہ ہونے کی صورت میں بلو ٹوتھ مطلق والیوم والی خصوصیت کو غیر فعال کریں۔"</string>
- <string name="bluetooth_enable_gabeldorsche_summary" msgid="8472344901097607030">"‏بلوٹوتھ Gabeldorche خصوصیت کے انبار کو فعال کرتا ہے۔"</string>
+ <string name="bluetooth_enable_gabeldorsche_summary" msgid="2054730331770712629">"‏بلوٹوتھ Gabeldorsche خصوصیت کے انبار کو فعال کرتا ہے۔"</string>
<string name="enable_terminal_title" msgid="3834790541986303654">"مقامی ٹرمینل"</string>
<string name="enable_terminal_summary" msgid="2481074834856064500">"مقامی شیل رسائی پیش کرنے والی ٹرمینل ایپ فعال کریں"</string>
<string name="hdcp_checking_title" msgid="3155692785074095986">"‏HDCP چیکنگ"</string>
diff --git a/packages/SettingsLib/res/values-uz/arrays.xml b/packages/SettingsLib/res/values-uz/arrays.xml
index 4d30e4638902..892ebe0a6e9e 100644
--- a/packages/SettingsLib/res/values-uz/arrays.xml
+++ b/packages/SettingsLib/res/values-uz/arrays.xml
@@ -75,6 +75,16 @@
<item msgid="4398977131424970917">"avrcp15"</item>
<item msgid="1963366694959681026">"avrcp16"</item>
</string-array>
+ <string-array name="bluetooth_map_versions">
+ <item msgid="8786402640610987099">"MAP 1.2 (Standart)"</item>
+ <item msgid="6817922176194686449">"MAP 1.3"</item>
+ <item msgid="3423518690032737851">"MAP 1.4"</item>
+ </string-array>
+ <string-array name="bluetooth_map_version_values">
+ <item msgid="1164651830068248391">"map12"</item>
+ <item msgid="7073042887003102964">"map13"</item>
+ <item msgid="8147982633566548515">"map14"</item>
+ </string-array>
<string-array name="bluetooth_a2dp_codec_titles">
<item msgid="2494959071796102843">"Tizim tanlovi (birlamchi)"</item>
<item msgid="4055460186095649420">"SBC"</item>
diff --git a/packages/SettingsLib/res/values-uz/strings.xml b/packages/SettingsLib/res/values-uz/strings.xml
index 52ec545d9e80..b202d6444965 100644
--- a/packages/SettingsLib/res/values-uz/strings.xml
+++ b/packages/SettingsLib/res/values-uz/strings.xml
@@ -230,6 +230,8 @@
<string name="bluetooth_enable_gabeldorsche" msgid="9131730396242883416">"Gabeldorsche funksiyasini yoqish"</string>
<string name="bluetooth_select_avrcp_version_string" msgid="1710571610177659127">"Bluetooth AVRCP versiyasi"</string>
<string name="bluetooth_select_avrcp_version_dialog_title" msgid="7846922290083709633">"Bluetooth AVRCP versiyasini tanlang"</string>
+ <string name="bluetooth_select_map_version_string" msgid="526308145174175327">"Bluetooth MAP versiyasi"</string>
+ <string name="bluetooth_select_map_version_dialog_title" msgid="7085934373987428460">"Bluetooth MAP versiyasini tanlang"</string>
<string name="bluetooth_select_a2dp_codec_type" msgid="952001408455456494">"Bluetooth audio kodeki"</string>
<string name="bluetooth_select_a2dp_codec_type_dialog_title" msgid="7510542404227225545">"Bluetooth orqali uzatish uchun audiokodek\nTanlash"</string>
<string name="bluetooth_select_a2dp_codec_sample_rate" msgid="1638623076480928191">"Bluetooth audio namunasi chastotasi"</string>
@@ -276,7 +278,7 @@
<string name="verify_apps_over_usb_summary" msgid="1317933737581167839">"ADB/ADT orqali o‘rnatilgan ilovalar xavfsizligini tekshiring"</string>
<string name="bluetooth_show_devices_without_names_summary" msgid="780964354377854507">"Bluetooth qurilmalari nomsiz (faqat MAC manzillari) ko‘rsatiladi"</string>
<string name="bluetooth_disable_absolute_volume_summary" msgid="2006309932135547681">"Masofadan ulanadigan qurilmalar bilan muammolar yuz berganda, jumladan, juda baland ovoz yoki sozlamalarni boshqarib bo‘lmaydigan holatlarda Bluetooth ovozi balandligining mutlaq darajasini o‘chirib qo‘yadi."</string>
- <string name="bluetooth_enable_gabeldorsche_summary" msgid="8472344901097607030">"Bluetooth Gabeldorche funksiyasini ishga tushiradi."</string>
+ <string name="bluetooth_enable_gabeldorsche_summary" msgid="2054730331770712629">"Bluetooth Gabeldorsche funksiyasini ishga tushiradi."</string>
<string name="enable_terminal_title" msgid="3834790541986303654">"Mahalliy terminal"</string>
<string name="enable_terminal_summary" msgid="2481074834856064500">"Mahalliy terminalga kirishga ruxsat beruvchi terminal ilovani faollashtirish"</string>
<string name="hdcp_checking_title" msgid="3155692785074095986">"HDCP tekshiruvi"</string>
diff --git a/packages/SettingsLib/res/values-vi/arrays.xml b/packages/SettingsLib/res/values-vi/arrays.xml
index edfe89e0b0ee..db29bc86e8a8 100644
--- a/packages/SettingsLib/res/values-vi/arrays.xml
+++ b/packages/SettingsLib/res/values-vi/arrays.xml
@@ -75,6 +75,16 @@
<item msgid="4398977131424970917">"avrcp15"</item>
<item msgid="1963366694959681026">"avrcp16"</item>
</string-array>
+ <string-array name="bluetooth_map_versions">
+ <item msgid="8786402640610987099">"MAP 1.2 (Mặc định)"</item>
+ <item msgid="6817922176194686449">"MAP 1.3"</item>
+ <item msgid="3423518690032737851">"MAP 1.4"</item>
+ </string-array>
+ <string-array name="bluetooth_map_version_values">
+ <item msgid="1164651830068248391">"map12"</item>
+ <item msgid="7073042887003102964">"map13"</item>
+ <item msgid="8147982633566548515">"map14"</item>
+ </string-array>
<string-array name="bluetooth_a2dp_codec_titles">
<item msgid="2494959071796102843">"Sử dụng lựa chọn của hệ thống (Mặc định)"</item>
<item msgid="4055460186095649420">"SBC"</item>
diff --git a/packages/SettingsLib/res/values-vi/strings.xml b/packages/SettingsLib/res/values-vi/strings.xml
index 2a124646cd5f..cda42d348c45 100644
--- a/packages/SettingsLib/res/values-vi/strings.xml
+++ b/packages/SettingsLib/res/values-vi/strings.xml
@@ -230,6 +230,8 @@
<string name="bluetooth_enable_gabeldorsche" msgid="9131730396242883416">"Bật tính năng Gabeldorsche"</string>
<string name="bluetooth_select_avrcp_version_string" msgid="1710571610177659127">"Phiên bản Bluetooth AVRCP"</string>
<string name="bluetooth_select_avrcp_version_dialog_title" msgid="7846922290083709633">"Chọn phiên bản Bluetooth AVRCP"</string>
+ <string name="bluetooth_select_map_version_string" msgid="526308145174175327">"Phiên bản Bluetooth MAP"</string>
+ <string name="bluetooth_select_map_version_dialog_title" msgid="7085934373987428460">"Chọn phiên bản Bluetooth MAP"</string>
<string name="bluetooth_select_a2dp_codec_type" msgid="952001408455456494">"Codec âm thanh Bluetooth"</string>
<string name="bluetooth_select_a2dp_codec_type_dialog_title" msgid="7510542404227225545">"Kích hoạt chế độ chọn codec\nâm thanh Bluetooth"</string>
<string name="bluetooth_select_a2dp_codec_sample_rate" msgid="1638623076480928191">"Tốc độ lấy mẫu âm thanh Bluetooth"</string>
@@ -276,7 +278,7 @@
<string name="verify_apps_over_usb_summary" msgid="1317933737581167839">"Kiểm tra các ứng dụng được cài đặt qua ADB/ADT để xem có hoạt động gây hại hay không."</string>
<string name="bluetooth_show_devices_without_names_summary" msgid="780964354377854507">"Các thiết bị Bluetooth không có tên (chỉ có địa chỉ MAC) sẽ được hiển thị"</string>
<string name="bluetooth_disable_absolute_volume_summary" msgid="2006309932135547681">"Vô hiệu hóa tính năng âm lượng tuyệt đối qua Bluetooth trong trường hợp xảy ra sự cố về âm lượng với các thiết bị từ xa, chẳng hạn như âm lượng lớn không thể chấp nhận được hoặc thiếu kiểm soát."</string>
- <string name="bluetooth_enable_gabeldorsche_summary" msgid="8472344901097607030">"Bật ngăn xếp tính năng Bluetooth Gabeldorche."</string>
+ <string name="bluetooth_enable_gabeldorsche_summary" msgid="2054730331770712629">"Bật ngăn xếp tính năng Bluetooth Gabeldorsche."</string>
<string name="enable_terminal_title" msgid="3834790541986303654">"Dòng lệnh cục bộ"</string>
<string name="enable_terminal_summary" msgid="2481074834856064500">"Bật ứng dụng dòng lệnh cung cấp quyền truy cập vỏ cục bộ"</string>
<string name="hdcp_checking_title" msgid="3155692785074095986">"Kiểm tra HDCP"</string>
diff --git a/packages/SettingsLib/res/values-zh-rCN/arrays.xml b/packages/SettingsLib/res/values-zh-rCN/arrays.xml
index 992e3e083358..3016f65905e2 100644
--- a/packages/SettingsLib/res/values-zh-rCN/arrays.xml
+++ b/packages/SettingsLib/res/values-zh-rCN/arrays.xml
@@ -75,6 +75,16 @@
<item msgid="4398977131424970917">"avrcp15"</item>
<item msgid="1963366694959681026">"avrcp16"</item>
</string-array>
+ <string-array name="bluetooth_map_versions">
+ <item msgid="8786402640610987099">"MAP 1.2(默认)"</item>
+ <item msgid="6817922176194686449">"MAP 1.3"</item>
+ <item msgid="3423518690032737851">"MAP 1.4"</item>
+ </string-array>
+ <string-array name="bluetooth_map_version_values">
+ <item msgid="1164651830068248391">"map12"</item>
+ <item msgid="7073042887003102964">"map13"</item>
+ <item msgid="8147982633566548515">"map14"</item>
+ </string-array>
<string-array name="bluetooth_a2dp_codec_titles">
<item msgid="2494959071796102843">"使用系统选择(默认)"</item>
<item msgid="4055460186095649420">"SBC"</item>
diff --git a/packages/SettingsLib/res/values-zh-rCN/strings.xml b/packages/SettingsLib/res/values-zh-rCN/strings.xml
index 3fe925b11293..418370b916e6 100644
--- a/packages/SettingsLib/res/values-zh-rCN/strings.xml
+++ b/packages/SettingsLib/res/values-zh-rCN/strings.xml
@@ -230,6 +230,8 @@
<string name="bluetooth_enable_gabeldorsche" msgid="9131730396242883416">"启用“Gabeldorsche”"</string>
<string name="bluetooth_select_avrcp_version_string" msgid="1710571610177659127">"蓝牙 AVRCP 版本"</string>
<string name="bluetooth_select_avrcp_version_dialog_title" msgid="7846922290083709633">"选择蓝牙 AVRCP 版本"</string>
+ <string name="bluetooth_select_map_version_string" msgid="526308145174175327">"蓝牙 MAP 版本"</string>
+ <string name="bluetooth_select_map_version_dialog_title" msgid="7085934373987428460">"选择蓝牙 MAP 版本"</string>
<string name="bluetooth_select_a2dp_codec_type" msgid="952001408455456494">"蓝牙音频编解码器"</string>
<string name="bluetooth_select_a2dp_codec_type_dialog_title" msgid="7510542404227225545">"触发蓝牙音频编解码器\n选择"</string>
<string name="bluetooth_select_a2dp_codec_sample_rate" msgid="1638623076480928191">"蓝牙音频采样率"</string>
@@ -276,7 +278,7 @@
<string name="verify_apps_over_usb_summary" msgid="1317933737581167839">"检查通过 ADB/ADT 安装的应用是否存在有害行为。"</string>
<string name="bluetooth_show_devices_without_names_summary" msgid="780964354377854507">"系统将显示没有名称(只有 MAC 地址)的蓝牙设备"</string>
<string name="bluetooth_disable_absolute_volume_summary" msgid="2006309932135547681">"停用蓝牙绝对音量功能,即可避免在连接到远程设备时出现音量问题(例如音量高得让人无法接受或无法控制音量等)。"</string>
- <string name="bluetooth_enable_gabeldorsche_summary" msgid="8472344901097607030">"启用“蓝牙 Gabeldorche”功能堆栈。"</string>
+ <string name="bluetooth_enable_gabeldorsche_summary" msgid="2054730331770712629">"启用“蓝牙 Gabeldorsche”功能堆栈。"</string>
<string name="enable_terminal_title" msgid="3834790541986303654">"本地终端"</string>
<string name="enable_terminal_summary" msgid="2481074834856064500">"启用终端应用,以便在本地访问 Shell"</string>
<string name="hdcp_checking_title" msgid="3155692785074095986">"HDCP 检查"</string>
diff --git a/packages/SettingsLib/res/values-zh-rHK/arrays.xml b/packages/SettingsLib/res/values-zh-rHK/arrays.xml
index d91e61ec3032..0b57af9932d1 100644
--- a/packages/SettingsLib/res/values-zh-rHK/arrays.xml
+++ b/packages/SettingsLib/res/values-zh-rHK/arrays.xml
@@ -75,6 +75,16 @@
<item msgid="4398977131424970917">"avrcp15"</item>
<item msgid="1963366694959681026">"avrcp16"</item>
</string-array>
+ <string-array name="bluetooth_map_versions">
+ <item msgid="8786402640610987099">"MAP 1.2 (預設)"</item>
+ <item msgid="6817922176194686449">"MAP 1.3"</item>
+ <item msgid="3423518690032737851">"MAP 1.4"</item>
+ </string-array>
+ <string-array name="bluetooth_map_version_values">
+ <item msgid="1164651830068248391">"map12"</item>
+ <item msgid="7073042887003102964">"map13"</item>
+ <item msgid="8147982633566548515">"map14"</item>
+ </string-array>
<string-array name="bluetooth_a2dp_codec_titles">
<item msgid="2494959071796102843">"使用系統選擇 (預設)"</item>
<item msgid="4055460186095649420">"SBC"</item>
diff --git a/packages/SettingsLib/res/values-zh-rHK/strings.xml b/packages/SettingsLib/res/values-zh-rHK/strings.xml
index ed6d5054ba8c..79b55796bda2 100644
--- a/packages/SettingsLib/res/values-zh-rHK/strings.xml
+++ b/packages/SettingsLib/res/values-zh-rHK/strings.xml
@@ -230,6 +230,8 @@
<string name="bluetooth_enable_gabeldorsche" msgid="9131730396242883416">"啟用 Gabeldorsche"</string>
<string name="bluetooth_select_avrcp_version_string" msgid="1710571610177659127">"藍牙 AVRCP 版本"</string>
<string name="bluetooth_select_avrcp_version_dialog_title" msgid="7846922290083709633">"選擇藍牙 AVRCP 版本"</string>
+ <string name="bluetooth_select_map_version_string" msgid="526308145174175327">"藍牙 MAP 版本"</string>
+ <string name="bluetooth_select_map_version_dialog_title" msgid="7085934373987428460">"選擇藍牙 MAP 版本"</string>
<string name="bluetooth_select_a2dp_codec_type" msgid="952001408455456494">"藍牙音訊編解碼器"</string>
<string name="bluetooth_select_a2dp_codec_type_dialog_title" msgid="7510542404227225545">"觸發藍牙音訊編解碼器\n選項"</string>
<string name="bluetooth_select_a2dp_codec_sample_rate" msgid="1638623076480928191">"藍牙音訊取樣率"</string>
@@ -276,7 +278,7 @@
<string name="verify_apps_over_usb_summary" msgid="1317933737581167839">"透過 ADB/ADT 檢查安裝的應用程式有否有害的行為。"</string>
<string name="bluetooth_show_devices_without_names_summary" msgid="780964354377854507">"系統將顯示沒有名稱 (只有 MAC 位址) 的藍牙裝置"</string>
<string name="bluetooth_disable_absolute_volume_summary" msgid="2006309932135547681">"連線至遠端裝置時,如發生音量過大或無法控制音量等問題,請停用藍牙絕對音量功能。"</string>
- <string name="bluetooth_enable_gabeldorsche_summary" msgid="8472344901097607030">"啟用藍牙 Gabeldorche 功能組合。"</string>
+ <string name="bluetooth_enable_gabeldorsche_summary" msgid="2054730331770712629">"啟用藍牙 Gabeldorsche 功能組合。"</string>
<string name="enable_terminal_title" msgid="3834790541986303654">"本機終端機"</string>
<string name="enable_terminal_summary" msgid="2481074834856064500">"啟用可提供本機命令介面存取權的終端機應用程式"</string>
<string name="hdcp_checking_title" msgid="3155692785074095986">"HDCP 檢查"</string>
diff --git a/packages/SettingsLib/res/values-zh-rTW/arrays.xml b/packages/SettingsLib/res/values-zh-rTW/arrays.xml
index f39ab84c56bc..7b25772056a2 100644
--- a/packages/SettingsLib/res/values-zh-rTW/arrays.xml
+++ b/packages/SettingsLib/res/values-zh-rTW/arrays.xml
@@ -75,6 +75,16 @@
<item msgid="4398977131424970917">"avrcp15"</item>
<item msgid="1963366694959681026">"avrcp16"</item>
</string-array>
+ <string-array name="bluetooth_map_versions">
+ <item msgid="8786402640610987099">"MAP 1.2 (預設)"</item>
+ <item msgid="6817922176194686449">"MAP 1.3"</item>
+ <item msgid="3423518690032737851">"MAP 1.4"</item>
+ </string-array>
+ <string-array name="bluetooth_map_version_values">
+ <item msgid="1164651830068248391">"map12"</item>
+ <item msgid="7073042887003102964">"map13"</item>
+ <item msgid="8147982633566548515">"map14"</item>
+ </string-array>
<string-array name="bluetooth_a2dp_codec_titles">
<item msgid="2494959071796102843">"系統自動選擇 (預設)"</item>
<item msgid="4055460186095649420">"SBC"</item>
diff --git a/packages/SettingsLib/res/values-zh-rTW/strings.xml b/packages/SettingsLib/res/values-zh-rTW/strings.xml
index 45866d4fde92..47ab7641b7ad 100644
--- a/packages/SettingsLib/res/values-zh-rTW/strings.xml
+++ b/packages/SettingsLib/res/values-zh-rTW/strings.xml
@@ -230,6 +230,8 @@
<string name="bluetooth_enable_gabeldorsche" msgid="9131730396242883416">"啟用 Gabeldorsche"</string>
<string name="bluetooth_select_avrcp_version_string" msgid="1710571610177659127">"藍牙 AVRCP 版本"</string>
<string name="bluetooth_select_avrcp_version_dialog_title" msgid="7846922290083709633">"選取藍牙 AVRCP 版本"</string>
+ <string name="bluetooth_select_map_version_string" msgid="526308145174175327">"藍牙 MAP 版本"</string>
+ <string name="bluetooth_select_map_version_dialog_title" msgid="7085934373987428460">"選取 Bluetooth MAP 版本"</string>
<string name="bluetooth_select_a2dp_codec_type" msgid="952001408455456494">"藍牙音訊轉碼器"</string>
<string name="bluetooth_select_a2dp_codec_type_dialog_title" msgid="7510542404227225545">"觸發藍牙音訊轉碼器\n選項"</string>
<string name="bluetooth_select_a2dp_codec_sample_rate" msgid="1638623076480928191">"藍牙音訊取樣率"</string>
@@ -276,7 +278,7 @@
<string name="verify_apps_over_usb_summary" msgid="1317933737581167839">"檢查透過 ADB/ADT 安裝的應用程式是否具有有害行為。"</string>
<string name="bluetooth_show_devices_without_names_summary" msgid="780964354377854507">"系統會顯示沒有名稱 (僅具有 MAC 位址) 的藍牙裝置"</string>
<string name="bluetooth_disable_absolute_volume_summary" msgid="2006309932135547681">"只要停用藍牙絕對音量功能,即可避免在連線到遠端裝置時,發生音量過大或無法控制音量等問題。"</string>
- <string name="bluetooth_enable_gabeldorsche_summary" msgid="8472344901097607030">"啟用藍牙 Gabeldorsche 功能堆疊。"</string>
+ <string name="bluetooth_enable_gabeldorsche_summary" msgid="2054730331770712629">"啟用藍牙 Gabeldorsche 功能堆疊。"</string>
<string name="enable_terminal_title" msgid="3834790541986303654">"本機終端機"</string>
<string name="enable_terminal_summary" msgid="2481074834856064500">"啟用可提供本機命令介面存取權的終端機應用程式"</string>
<string name="hdcp_checking_title" msgid="3155692785074095986">"HDCP 檢查"</string>
diff --git a/packages/SettingsLib/res/values-zu/arrays.xml b/packages/SettingsLib/res/values-zu/arrays.xml
index 5c93cc5b16b1..517d1c85f966 100644
--- a/packages/SettingsLib/res/values-zu/arrays.xml
+++ b/packages/SettingsLib/res/values-zu/arrays.xml
@@ -75,6 +75,16 @@
<item msgid="4398977131424970917">"I-avrcp15"</item>
<item msgid="1963366694959681026">"I-avrcp16"</item>
</string-array>
+ <string-array name="bluetooth_map_versions">
+ <item msgid="8786402640610987099">"IMEPHU 1.2 (Okuzenzakalelayo)"</item>
+ <item msgid="6817922176194686449">"IMEPHU 1.3"</item>
+ <item msgid="3423518690032737851">"IMEPHU 1.4"</item>
+ </string-array>
+ <string-array name="bluetooth_map_version_values">
+ <item msgid="1164651830068248391">"Imephu12"</item>
+ <item msgid="7073042887003102964">"Imephu13"</item>
+ <item msgid="8147982633566548515">"Imephu14"</item>
+ </string-array>
<string-array name="bluetooth_a2dp_codec_titles">
<item msgid="2494959071796102843">"Sebenzisa ukukhetha kwesistimu (Okuzenzakalelayo)"</item>
<item msgid="4055460186095649420">"SBC"</item>
diff --git a/packages/SettingsLib/res/values-zu/strings.xml b/packages/SettingsLib/res/values-zu/strings.xml
index 8b004f96d4f3..87f45de36c58 100644
--- a/packages/SettingsLib/res/values-zu/strings.xml
+++ b/packages/SettingsLib/res/values-zu/strings.xml
@@ -230,6 +230,8 @@
<string name="bluetooth_enable_gabeldorsche" msgid="9131730396242883416">"Nika amandla i-Gabeldorsche"</string>
<string name="bluetooth_select_avrcp_version_string" msgid="1710571610177659127">"Inguqulo ye-Bluetooth ye-AVRCP"</string>
<string name="bluetooth_select_avrcp_version_dialog_title" msgid="7846922290083709633">"Khetha inguqulo ye-Bluetooth AVRCP"</string>
+ <string name="bluetooth_select_map_version_string" msgid="526308145174175327">"Inguqulo ye-Bluetooth MAP"</string>
+ <string name="bluetooth_select_map_version_dialog_title" msgid="7085934373987428460">"Khetha inguqulo ye-Bluetooth MAP"</string>
<string name="bluetooth_select_a2dp_codec_type" msgid="952001408455456494">"I-Bluetooth Audio Codec"</string>
<string name="bluetooth_select_a2dp_codec_type_dialog_title" msgid="7510542404227225545">"Qalisa i-codec ye-bluetooth yomsindo\nUkukhethwa"</string>
<string name="bluetooth_select_a2dp_codec_sample_rate" msgid="1638623076480928191">"Isilinganiso sesampula yomsindo we-Bluetooth"</string>
@@ -276,7 +278,7 @@
<string name="verify_apps_over_usb_summary" msgid="1317933737581167839">"Hlola izinhlelo zokusebenza ezifakiwe nge-ADB/ADT ngokuziphatha okuyingozi."</string>
<string name="bluetooth_show_devices_without_names_summary" msgid="780964354377854507">"Amadivayisi e-Bluetooth anganawo amagama (Amakheli e-MAC kuphela) azoboniswa"</string>
<string name="bluetooth_disable_absolute_volume_summary" msgid="2006309932135547681">"Ikhubaza isici esiphelele sevolumu ye-Bluetooth uma kuba nezinkinga zevolumu ngamadivayisi esilawuli kude ezifana nevolumu ephezulu noma eshoda ngokulawuleka."</string>
- <string name="bluetooth_enable_gabeldorsche_summary" msgid="8472344901097607030">"Inika amandla isitaki sesici se-Bluetooth Gabeldorche."</string>
+ <string name="bluetooth_enable_gabeldorsche_summary" msgid="2054730331770712629">"Inika amandla isitaki sesici se-Bluetooth Gabeldorsche."</string>
<string name="enable_terminal_title" msgid="3834790541986303654">"Itheminali yasendaweni"</string>
<string name="enable_terminal_summary" msgid="2481074834856064500">"Nika amandla uhlelo lokusebenza letheminali olunikeza ukufinyelela kwasendaweni kwe-shell"</string>
<string name="hdcp_checking_title" msgid="3155692785074095986">"Ihlola i-HDCP"</string>
diff --git a/packages/SettingsLib/src/com/android/settingslib/deviceinfo/AbstractImsStatusPreferenceController.java b/packages/SettingsLib/src/com/android/settingslib/deviceinfo/AbstractImsStatusPreferenceController.java
index 4c3e605e3a94..d427f7a20dba 100644
--- a/packages/SettingsLib/src/com/android/settingslib/deviceinfo/AbstractImsStatusPreferenceController.java
+++ b/packages/SettingsLib/src/com/android/settingslib/deviceinfo/AbstractImsStatusPreferenceController.java
@@ -23,7 +23,9 @@ import android.net.wifi.WifiManager;
import android.os.PersistableBundle;
import android.telephony.CarrierConfigManager;
import android.telephony.SubscriptionManager;
-import android.telephony.TelephonyManager;
+import android.telephony.ims.ImsMmTelManager;
+import android.telephony.ims.RegistrationManager;
+import android.util.Log;
import androidx.annotation.VisibleForTesting;
import androidx.preference.Preference;
@@ -32,15 +34,26 @@ import androidx.preference.PreferenceScreen;
import com.android.settingslib.R;
import com.android.settingslib.core.lifecycle.Lifecycle;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import java.util.concurrent.Semaphore;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.atomic.AtomicBoolean;
+import java.util.function.Consumer;
+
/**
* Preference controller for IMS status
*/
public abstract class AbstractImsStatusPreferenceController
extends AbstractConnectivityPreferenceController {
+ private static final String LOG_TAG = "AbstractImsPrefController";
+
@VisibleForTesting
static final String KEY_IMS_REGISTRATION_STATE = "ims_reg_state";
+ private static final long MAX_THREAD_BLOCKING_TIME_MS = 2000;
+
private static final String[] CONNECTIVITY_INTENTS = {
BluetoothAdapter.ACTION_STATE_CHANGED,
ConnectivityManager.CONNECTIVITY_ACTION,
@@ -57,8 +70,9 @@ public abstract class AbstractImsStatusPreferenceController
@Override
public boolean isAvailable() {
- CarrierConfigManager configManager = mContext.getSystemService(CarrierConfigManager.class);
- int subId = SubscriptionManager.getDefaultDataSubscriptionId();
+ final CarrierConfigManager configManager =
+ mContext.getSystemService(CarrierConfigManager.class);
+ final int subId = SubscriptionManager.getDefaultDataSubscriptionId();
PersistableBundle config = null;
if (configManager != null) {
config = configManager.getConfigForSubId(subId);
@@ -86,11 +100,57 @@ public abstract class AbstractImsStatusPreferenceController
@Override
protected void updateConnectivity() {
- int subId = SubscriptionManager.getDefaultDataSubscriptionId();
- if (mImsStatus != null) {
- TelephonyManager tm = mContext.getSystemService(TelephonyManager.class);
- mImsStatus.setSummary((tm != null && tm.isImsRegistered(subId)) ?
- R.string.ims_reg_status_registered : R.string.ims_reg_status_not_registered);
+ if (mImsStatus == null) {
+ return;
+ }
+ final int subId = SubscriptionManager.getDefaultDataSubscriptionId();
+ if (!SubscriptionManager.isValidSubscriptionId(subId)) {
+ mImsStatus.setSummary(R.string.ims_reg_status_not_registered);
+ return;
+ }
+ final ExecutorService executors = Executors.newSingleThreadExecutor();
+ final StateCallback stateCallback = new StateCallback();
+
+ final ImsMmTelManager imsMmTelManager = ImsMmTelManager.createForSubscriptionId(subId);
+ try {
+ imsMmTelManager.getRegistrationState(executors, stateCallback);
+ } catch (Exception ex) {
+ }
+
+ mImsStatus.setSummary(stateCallback.waitUntilResult()
+ ? R.string.ims_reg_status_registered : R.string.ims_reg_status_not_registered);
+
+ try {
+ executors.shutdownNow();
+ } catch (Exception exception) {
+ }
+ }
+
+ private final class StateCallback extends AtomicBoolean implements Consumer<Integer> {
+ private StateCallback() {
+ super(false);
+ mSemaphore = new Semaphore(0);
+ }
+
+ private final Semaphore mSemaphore;
+
+ public void accept(Integer state) {
+ set(state == RegistrationManager.REGISTRATION_STATE_REGISTERED);
+ try {
+ mSemaphore.release();
+ } catch (Exception ex) {
+ }
+ }
+
+ public boolean waitUntilResult() {
+ try {
+ if (!mSemaphore.tryAcquire(MAX_THREAD_BLOCKING_TIME_MS, TimeUnit.MILLISECONDS)) {
+ Log.w(LOG_TAG, "IMS registration state query timeout");
+ return false;
+ }
+ } catch (Exception ex) {
+ }
+ return get();
}
}
}
diff --git a/packages/SettingsLib/src/com/android/settingslib/net/DataUsageUtils.java b/packages/SettingsLib/src/com/android/settingslib/net/DataUsageUtils.java
index 05a6ce4578db..9d7e2c821297 100644
--- a/packages/SettingsLib/src/com/android/settingslib/net/DataUsageUtils.java
+++ b/packages/SettingsLib/src/com/android/settingslib/net/DataUsageUtils.java
@@ -38,7 +38,7 @@ public class DataUsageUtils {
final SubscriptionManager subscriptionManager = context.getSystemService(
SubscriptionManager.class);
final NetworkTemplate mobileAll = NetworkTemplate.buildTemplateMobileAll(
- telephonyManager.createForSubscriptionId(subId).getSubscriberId());
+ telephonyManager.getSubscriberId());
if (!subscriptionManager.isActiveSubscriptionId(subId)) {
Log.i(TAG, "Subscription is not active: " + subId);
diff --git a/packages/SystemUI/AndroidManifest.xml b/packages/SystemUI/AndroidManifest.xml
index 0bcadce7a9c6..6aeb0a159bea 100644
--- a/packages/SystemUI/AndroidManifest.xml
+++ b/packages/SystemUI/AndroidManifest.xml
@@ -174,6 +174,9 @@
<!-- Adding Quick Settings tiles -->
<uses-permission android:name="android.permission.BIND_QUICK_SETTINGS_TILE" />
+ <!-- Access Quick Access Wallet cards -->
+ <uses-permission android:name="android.permission.BIND_QUICK_ACCESS_WALLET_SERVICE" />
+
<!-- Adding Controls to SystemUI -->
<uses-permission android:name="android.permission.BIND_CONTROLS" />
diff --git a/services/core/java/com/android/server/BluetoothAirplaneModeListener.java b/services/core/java/com/android/server/BluetoothAirplaneModeListener.java
new file mode 100644
index 000000000000..31cd5d519d87
--- /dev/null
+++ b/services/core/java/com/android/server/BluetoothAirplaneModeListener.java
@@ -0,0 +1,258 @@
+/*
+ * Copyright 2019 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.server;
+
+import android.bluetooth.BluetoothA2dp;
+import android.bluetooth.BluetoothAdapter;
+import android.bluetooth.BluetoothHearingAid;
+import android.bluetooth.BluetoothProfile;
+import android.bluetooth.BluetoothProfile.ServiceListener;
+import android.content.Context;
+import android.content.res.Resources;
+import android.database.ContentObserver;
+import android.os.Handler;
+import android.os.Looper;
+import android.os.Message;
+import android.provider.Settings;
+import android.util.Log;
+import android.widget.Toast;
+
+import com.android.internal.R;
+import com.android.internal.annotations.VisibleForTesting;
+
+/**
+ * The BluetoothAirplaneModeListener handles system airplane mode change callback and checks
+ * whether we need to inform BluetoothManagerService on this change.
+ *
+ * The information of airplane mode turns on would not be passed to the BluetoothManagerService
+ * when Bluetooth is on and Bluetooth is in one of the following situations:
+ * 1. Bluetooth A2DP is connected.
+ * 2. Bluetooth Hearing Aid profile is connected.
+ */
+class BluetoothAirplaneModeListener {
+ private static final String TAG = "BluetoothAirplaneModeListener";
+ @VisibleForTesting static final String TOAST_COUNT = "bluetooth_airplane_toast_count";
+
+ private static final int MSG_AIRPLANE_MODE_CHANGED = 0;
+
+ @VisibleForTesting static final int MAX_TOAST_COUNT = 10; // 10 times
+
+ private final BluetoothManagerService mBluetoothManager;
+ private final BluetoothAirplaneModeHandler mHandler;
+ private AirplaneModeHelper mAirplaneHelper;
+
+ @VisibleForTesting int mToastCount = 0;
+
+ BluetoothAirplaneModeListener(BluetoothManagerService service, Looper looper, Context context) {
+ mBluetoothManager = service;
+
+ mHandler = new BluetoothAirplaneModeHandler(looper);
+ context.getContentResolver().registerContentObserver(
+ Settings.Global.getUriFor(Settings.Global.AIRPLANE_MODE_ON), true,
+ mAirplaneModeObserver);
+ }
+
+ private final ContentObserver mAirplaneModeObserver = new ContentObserver(null) {
+ @Override
+ public void onChange(boolean unused) {
+ // Post from system main thread to android_io thread.
+ Message msg = mHandler.obtainMessage(MSG_AIRPLANE_MODE_CHANGED);
+ mHandler.sendMessage(msg);
+ }
+ };
+
+ private class BluetoothAirplaneModeHandler extends Handler {
+ BluetoothAirplaneModeHandler(Looper looper) {
+ super(looper);
+ }
+
+ @Override
+ public void handleMessage(Message msg) {
+ switch (msg.what) {
+ case MSG_AIRPLANE_MODE_CHANGED:
+ handleAirplaneModeChange();
+ break;
+ default:
+ Log.e(TAG, "Invalid message: " + msg.what);
+ break;
+ }
+ }
+ }
+
+ /**
+ * Call after boot complete
+ */
+ @VisibleForTesting
+ void start(AirplaneModeHelper helper) {
+ Log.i(TAG, "start");
+ mAirplaneHelper = helper;
+ mToastCount = mAirplaneHelper.getSettingsInt(TOAST_COUNT);
+ }
+
+ @VisibleForTesting
+ boolean shouldPopToast() {
+ if (mToastCount >= MAX_TOAST_COUNT) {
+ return false;
+ }
+ mToastCount++;
+ mAirplaneHelper.setSettingsInt(TOAST_COUNT, mToastCount);
+ return true;
+ }
+
+ @VisibleForTesting
+ void handleAirplaneModeChange() {
+ if (shouldSkipAirplaneModeChange()) {
+ Log.i(TAG, "Ignore airplane mode change");
+ // We have to store Bluetooth state here, so if user turns off Bluetooth
+ // after airplane mode is turned on, we don't forget to turn on Bluetooth
+ // when airplane mode turns off.
+ mAirplaneHelper.setSettingsInt(Settings.Global.BLUETOOTH_ON,
+ BluetoothManagerService.BLUETOOTH_ON_AIRPLANE);
+ if (shouldPopToast()) {
+ mAirplaneHelper.showToastMessage();
+ }
+ return;
+ }
+ mAirplaneHelper.onAirplaneModeChanged(mBluetoothManager);
+ }
+
+ @VisibleForTesting
+ boolean shouldSkipAirplaneModeChange() {
+ if (mAirplaneHelper == null) {
+ return false;
+ }
+ if (!mAirplaneHelper.isBluetoothOn() || !mAirplaneHelper.isAirplaneModeOn()
+ || !mAirplaneHelper.isA2dpOrHearingAidConnected()) {
+ return false;
+ }
+ return true;
+ }
+
+ /**
+ * Helper class that handles callout and callback methods without
+ * complex logic.
+ */
+ @VisibleForTesting
+ public static class AirplaneModeHelper {
+ private volatile BluetoothA2dp mA2dp;
+ private volatile BluetoothHearingAid mHearingAid;
+ private final BluetoothAdapter mAdapter;
+ private final Context mContext;
+
+ AirplaneModeHelper(Context context) {
+ mAdapter = BluetoothAdapter.getDefaultAdapter();
+ mContext = context;
+
+ mAdapter.getProfileProxy(mContext, mProfileServiceListener, BluetoothProfile.A2DP);
+ mAdapter.getProfileProxy(mContext, mProfileServiceListener,
+ BluetoothProfile.HEARING_AID);
+ }
+
+ private final ServiceListener mProfileServiceListener = new ServiceListener() {
+ @Override
+ public void onServiceConnected(int profile, BluetoothProfile proxy) {
+ // Setup Bluetooth profile proxies
+ switch (profile) {
+ case BluetoothProfile.A2DP:
+ mA2dp = (BluetoothA2dp) proxy;
+ break;
+ case BluetoothProfile.HEARING_AID:
+ mHearingAid = (BluetoothHearingAid) proxy;
+ break;
+ default:
+ break;
+ }
+ }
+
+ @Override
+ public void onServiceDisconnected(int profile) {
+ // Clear Bluetooth profile proxies
+ switch (profile) {
+ case BluetoothProfile.A2DP:
+ mA2dp = null;
+ break;
+ case BluetoothProfile.HEARING_AID:
+ mHearingAid = null;
+ break;
+ default:
+ break;
+ }
+ }
+ };
+
+ @VisibleForTesting
+ public boolean isA2dpOrHearingAidConnected() {
+ return isA2dpConnected() || isHearingAidConnected();
+ }
+
+ @VisibleForTesting
+ public boolean isBluetoothOn() {
+ final BluetoothAdapter adapter = mAdapter;
+ if (adapter == null) {
+ return false;
+ }
+ return adapter.getLeState() == BluetoothAdapter.STATE_ON;
+ }
+
+ @VisibleForTesting
+ public boolean isAirplaneModeOn() {
+ return Settings.Global.getInt(mContext.getContentResolver(),
+ Settings.Global.AIRPLANE_MODE_ON, 0) == 1;
+ }
+
+ @VisibleForTesting
+ public void onAirplaneModeChanged(BluetoothManagerService managerService) {
+ managerService.onAirplaneModeChanged();
+ }
+
+ @VisibleForTesting
+ public int getSettingsInt(String name) {
+ return Settings.Global.getInt(mContext.getContentResolver(),
+ name, 0);
+ }
+
+ @VisibleForTesting
+ public void setSettingsInt(String name, int value) {
+ Settings.Global.putInt(mContext.getContentResolver(),
+ name, value);
+ }
+
+ @VisibleForTesting
+ public void showToastMessage() {
+ Resources r = mContext.getResources();
+ final CharSequence text = r.getString(
+ R.string.bluetooth_airplane_mode_toast, 0);
+ Toast.makeText(mContext, text, Toast.LENGTH_LONG).show();
+ }
+
+ private boolean isA2dpConnected() {
+ final BluetoothA2dp a2dp = mA2dp;
+ if (a2dp == null) {
+ return false;
+ }
+ return a2dp.getConnectedDevices().size() > 0;
+ }
+
+ private boolean isHearingAidConnected() {
+ final BluetoothHearingAid hearingAid = mHearingAid;
+ if (hearingAid == null) {
+ return false;
+ }
+ return hearingAid.getConnectedDevices().size() > 0;
+ }
+ };
+}
diff --git a/services/core/java/com/android/server/BluetoothManagerService.java b/services/core/java/com/android/server/BluetoothManagerService.java
index 470300e6485c..3774b645339d 100644
--- a/services/core/java/com/android/server/BluetoothManagerService.java
+++ b/services/core/java/com/android/server/BluetoothManagerService.java
@@ -72,6 +72,7 @@ import android.util.Slog;
import android.util.StatsLog;
import com.android.internal.R;
+import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.util.DumpUtils;
import com.android.server.pm.UserRestrictionsUtils;
@@ -143,7 +144,8 @@ class BluetoothManagerService extends IBluetoothManager.Stub {
// Bluetooth persisted setting is on
// but Airplane mode will affect Bluetooth state at start up
// and Airplane mode will have higher priority.
- private static final int BLUETOOTH_ON_AIRPLANE = 2;
+ @VisibleForTesting
+ static final int BLUETOOTH_ON_AIRPLANE = 2;
private static final int SERVICE_IBLUETOOTH = 1;
private static final int SERVICE_IBLUETOOTHGATT = 2;
@@ -164,6 +166,8 @@ class BluetoothManagerService extends IBluetoothManager.Stub {
private boolean mBinding;
private boolean mUnbinding;
+ private BluetoothAirplaneModeListener mBluetoothAirplaneModeListener;
+
// used inside handler thread
private boolean mQuietEnable = false;
private boolean mEnable;
@@ -262,68 +266,65 @@ class BluetoothManagerService extends IBluetoothManager.Stub {
}
};
- private final ContentObserver mAirplaneModeObserver = new ContentObserver(null) {
- @Override
- public void onChange(boolean unused) {
- synchronized (this) {
- if (isBluetoothPersistedStateOn()) {
- if (isAirplaneModeOn()) {
- persistBluetoothSetting(BLUETOOTH_ON_AIRPLANE);
- } else {
- persistBluetoothSetting(BLUETOOTH_ON_BLUETOOTH);
- }
+ public void onAirplaneModeChanged() {
+ synchronized (this) {
+ if (isBluetoothPersistedStateOn()) {
+ if (isAirplaneModeOn()) {
+ persistBluetoothSetting(BLUETOOTH_ON_AIRPLANE);
+ } else {
+ persistBluetoothSetting(BLUETOOTH_ON_BLUETOOTH);
}
+ }
- int st = BluetoothAdapter.STATE_OFF;
- try {
- mBluetoothLock.readLock().lock();
- if (mBluetooth != null) {
- st = mBluetooth.getState();
- }
- } catch (RemoteException e) {
- Slog.e(TAG, "Unable to call getState", e);
- return;
- } finally {
- mBluetoothLock.readLock().unlock();
+ int st = BluetoothAdapter.STATE_OFF;
+ try {
+ mBluetoothLock.readLock().lock();
+ if (mBluetooth != null) {
+ st = mBluetooth.getState();
}
+ } catch (RemoteException e) {
+ Slog.e(TAG, "Unable to call getState", e);
+ return;
+ } finally {
+ mBluetoothLock.readLock().unlock();
+ }
- Slog.d(TAG,
- "Airplane Mode change - current state: " + BluetoothAdapter.nameForState(
- st) + ", isAirplaneModeOn()=" + isAirplaneModeOn());
+ Slog.d(TAG,
+ "Airplane Mode change - current state: " + BluetoothAdapter.nameForState(
+ st) + ", isAirplaneModeOn()=" + isAirplaneModeOn());
- if (isAirplaneModeOn()) {
- // Clear registered LE apps to force shut-off
- clearBleApps();
+ if (isAirplaneModeOn()) {
+ // Clear registered LE apps to force shut-off
+ clearBleApps();
- // If state is BLE_ON make sure we trigger disableBLE
- if (st == BluetoothAdapter.STATE_BLE_ON) {
- try {
- mBluetoothLock.readLock().lock();
- if (mBluetooth != null) {
- addActiveLog(
- BluetoothProtoEnums.ENABLE_DISABLE_REASON_AIRPLANE_MODE,
- mContext.getPackageName(), false);
- mBluetooth.onBrEdrDown();
- mEnable = false;
- mEnableExternal = false;
- }
- } catch (RemoteException e) {
- Slog.e(TAG, "Unable to call onBrEdrDown", e);
- } finally {
- mBluetoothLock.readLock().unlock();
+ // If state is BLE_ON make sure we trigger disableBLE
+ if (st == BluetoothAdapter.STATE_BLE_ON) {
+ try {
+ mBluetoothLock.readLock().lock();
+ if (mBluetooth != null) {
+ addActiveLog(
+ BluetoothProtoEnums.ENABLE_DISABLE_REASON_AIRPLANE_MODE,
+ mContext.getPackageName(), false);
+ mBluetooth.onBrEdrDown();
+ mEnable = false;
+ mEnableExternal = false;
}
- } else if (st == BluetoothAdapter.STATE_ON) {
- sendDisableMsg(BluetoothProtoEnums.ENABLE_DISABLE_REASON_AIRPLANE_MODE,
- mContext.getPackageName());
+ } catch (RemoteException e) {
+ Slog.e(TAG, "Unable to call onBrEdrDown", e);
+ } finally {
+ mBluetoothLock.readLock().unlock();
}
- } else if (mEnableExternal) {
- sendEnableMsg(mQuietEnableExternal,
- BluetoothProtoEnums.ENABLE_DISABLE_REASON_AIRPLANE_MODE,
+ } else if (st == BluetoothAdapter.STATE_ON) {
+ sendDisableMsg(BluetoothProtoEnums.ENABLE_DISABLE_REASON_AIRPLANE_MODE,
mContext.getPackageName());
}
+ } else if (mEnableExternal) {
+ sendEnableMsg(mQuietEnableExternal,
+ BluetoothProtoEnums.ENABLE_DISABLE_REASON_AIRPLANE_MODE,
+ mContext.getPackageName());
}
}
- };
+ }
private final BroadcastReceiver mReceiver = new BroadcastReceiver() {
@Override
@@ -435,9 +436,8 @@ class BluetoothManagerService extends IBluetoothManager.Stub {
Settings.Global.getString(mContentResolver, Settings.Global.AIRPLANE_MODE_RADIOS);
if (airplaneModeRadios == null || airplaneModeRadios.contains(
Settings.Global.RADIO_BLUETOOTH)) {
- mContentResolver.registerContentObserver(
- Settings.Global.getUriFor(Settings.Global.AIRPLANE_MODE_ON), true,
- mAirplaneModeObserver);
+ mBluetoothAirplaneModeListener = new BluetoothAirplaneModeListener(
+ this, IoThread.get().getLooper(), context);
}
int systemUiUid = -1;
@@ -483,6 +483,17 @@ class BluetoothManagerService extends IBluetoothManager.Stub {
return state != BLUETOOTH_OFF;
}
+ private boolean isBluetoothPersistedStateOnAirplane() {
+ if (!supportBluetoothPersistedState()) {
+ return false;
+ }
+ int state = Settings.Global.getInt(mContentResolver, Settings.Global.BLUETOOTH_ON, -1);
+ if (DBG) {
+ Slog.d(TAG, "Bluetooth persisted state: " + state);
+ }
+ return state == BLUETOOTH_ON_AIRPLANE;
+ }
+
/**
* Returns true if the Bluetooth saved state is BLUETOOTH_ON_BLUETOOTH
*/
@@ -988,10 +999,12 @@ class BluetoothManagerService extends IBluetoothManager.Stub {
}
synchronized (mReceiver) {
- if (persist) {
- persistBluetoothSetting(BLUETOOTH_OFF);
+ if (!isBluetoothPersistedStateOnAirplane()) {
+ if (persist) {
+ persistBluetoothSetting(BLUETOOTH_OFF);
+ }
+ mEnableExternal = false;
}
- mEnableExternal = false;
sendDisableMsg(BluetoothProtoEnums.ENABLE_DISABLE_REASON_APPLICATION_REQUEST,
packageName);
}
@@ -1219,6 +1232,10 @@ class BluetoothManagerService extends IBluetoothManager.Stub {
Message getMsg = mHandler.obtainMessage(MESSAGE_GET_NAME_AND_ADDRESS);
mHandler.sendMessage(getMsg);
}
+ if (mBluetoothAirplaneModeListener != null) {
+ mBluetoothAirplaneModeListener.start(
+ new BluetoothAirplaneModeListener.AirplaneModeHelper(mContext));
+ }
}
/**
diff --git a/services/core/java/com/android/server/TelephonyRegistry.java b/services/core/java/com/android/server/TelephonyRegistry.java
index 1cae5f2fcc4d..68574f5fbc2c 100644
--- a/services/core/java/com/android/server/TelephonyRegistry.java
+++ b/services/core/java/com/android/server/TelephonyRegistry.java
@@ -289,7 +289,10 @@ public class TelephonyRegistry extends ITelephonyRegistry.Stub {
static final int PRECISE_PHONE_STATE_PERMISSION_MASK =
PhoneStateListener.LISTEN_PRECISE_CALL_STATE
- | PhoneStateListener.LISTEN_PRECISE_DATA_CONNECTION_STATE;
+ | PhoneStateListener.LISTEN_PRECISE_DATA_CONNECTION_STATE
+ | PhoneStateListener.LISTEN_CALL_DISCONNECT_CAUSES
+ | PhoneStateListener.LISTEN_CALL_ATTRIBUTES_CHANGED
+ | PhoneStateListener.LISTEN_IMS_CALL_DISCONNECT_CAUSES;
static final int READ_ACTIVE_EMERGENCY_SESSION_PERMISSION_MASK =
PhoneStateListener.LISTEN_OUTGOING_EMERGENCY_CALL
@@ -2518,8 +2521,14 @@ public class TelephonyRegistry extends ITelephonyRegistry.Stub {
}
if ((events & PRECISE_PHONE_STATE_PERMISSION_MASK) != 0) {
- mContext.enforceCallingOrSelfPermission(
- android.Manifest.permission.READ_PRECISE_PHONE_STATE, null);
+ // check if calling app has either permission READ_PRECISE_PHONE_STATE
+ // or with carrier privileges
+ try {
+ mContext.enforceCallingOrSelfPermission(
+ android.Manifest.permission.READ_PRECISE_PHONE_STATE, null);
+ } catch (SecurityException se) {
+ TelephonyPermissions.enforceCallingOrSelfCarrierPrivilege(mContext, subId, message);
+ }
}
if ((events & READ_ACTIVE_EMERGENCY_SESSION_PERMISSION_MASK) != 0) {
@@ -2542,16 +2551,6 @@ public class TelephonyRegistry extends ITelephonyRegistry.Stub {
android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE, null);
}
- if ((events & PhoneStateListener.LISTEN_CALL_DISCONNECT_CAUSES) != 0) {
- mContext.enforceCallingOrSelfPermission(
- android.Manifest.permission.READ_PRECISE_PHONE_STATE, null);
- }
-
- if ((events & PhoneStateListener.LISTEN_CALL_ATTRIBUTES_CHANGED) != 0) {
- mContext.enforceCallingOrSelfPermission(
- android.Manifest.permission.READ_PRECISE_PHONE_STATE, null);
- }
-
if ((events & PhoneStateListener.LISTEN_RADIO_POWER_STATE_CHANGED) != 0) {
mContext.enforceCallingOrSelfPermission(
android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE, null);
@@ -2562,11 +2561,6 @@ public class TelephonyRegistry extends ITelephonyRegistry.Stub {
android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE, null);
}
- if ((events & PhoneStateListener.LISTEN_IMS_CALL_DISCONNECT_CAUSES) != 0) {
- mContext.enforceCallingOrSelfPermission(
- android.Manifest.permission.READ_PRECISE_PHONE_STATE, null);
- }
-
return true;
}
diff --git a/services/core/java/com/android/server/adb/AdbService.java b/services/core/java/com/android/server/adb/AdbService.java
index 7fd98e0043c9..c125b1baf860 100644
--- a/services/core/java/com/android/server/adb/AdbService.java
+++ b/services/core/java/com/android/server/adb/AdbService.java
@@ -17,6 +17,7 @@ package com.android.server.adb;
import android.content.ContentResolver;
import android.content.Context;
+import android.content.pm.PackageManager;
import android.database.ContentObserver;
import android.debug.AdbManagerInternal;
import android.debug.IAdbManager;
@@ -260,6 +261,30 @@ public class AdbService extends IAdbManager.Stub {
}
}
+ /**
+ * @return true if the device supports secure ADB over Wi-Fi.
+ * @hide
+ */
+ @Override
+ public boolean isAdbWifiSupported() {
+ mContext.enforceCallingPermission(
+ android.Manifest.permission.MANAGE_DEBUGGING, "AdbService");
+ return mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_WIFI);
+ }
+
+ /**
+ * @return true if the device supports secure ADB over Wi-Fi and device pairing by
+ * QR code.
+ * @hide
+ */
+ @Override
+ public boolean isAdbWifiQrSupported() {
+ mContext.enforceCallingPermission(
+ android.Manifest.permission.MANAGE_DEBUGGING, "AdbService");
+ return isAdbWifiSupported() && mContext.getPackageManager().hasSystemFeature(
+ PackageManager.FEATURE_CAMERA_ANY);
+ }
+
private void setAdbEnabled(boolean enable) {
if (DEBUG) Slog.d(TAG, "setAdbEnabled(" + enable + "), mAdbEnabled=" + mAdbEnabled);
diff --git a/services/core/java/com/android/server/am/CarUserSwitchingDialog.java b/services/core/java/com/android/server/am/CarUserSwitchingDialog.java
index 549051df65ea..60754fbc5cd3 100644
--- a/services/core/java/com/android/server/am/CarUserSwitchingDialog.java
+++ b/services/core/java/com/android/server/am/CarUserSwitchingDialog.java
@@ -32,8 +32,8 @@ import android.graphics.Rect;
import android.graphics.RectF;
import android.graphics.drawable.ColorDrawable;
import android.graphics.drawable.Drawable;
-import android.os.Build;
import android.os.UserManager;
+import android.provider.Settings;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.ImageView;
@@ -83,9 +83,13 @@ final class CarUserSwitchingDialog extends UserSwitchingDialog {
}
TextView msgView = view.findViewById(R.id.user_loading);
- // TODO: use developer settings instead
- if (Build.IS_DEBUGGABLE) {
- // TODO: use specific string
+
+ // TODO(b/145132885): use constant from CarSettings
+ boolean showInfo = "true".equals(Settings.Global.getString(
+ getContext().getContentResolver(),
+ "android.car.ENABLE_USER_SWITCH_DEVELOPER_MESSAGE"));
+
+ if (showInfo) {
msgView.setText(res.getString(R.string.car_loading_profile) + " user\n(from "
+ mOldUser.id + " to " + mNewUser.id + ")");
} else {
diff --git a/services/core/java/com/android/server/audio/AudioService.java b/services/core/java/com/android/server/audio/AudioService.java
index eedeeea5cdb3..46972d90ce3b 100644
--- a/services/core/java/com/android/server/audio/AudioService.java
+++ b/services/core/java/com/android/server/audio/AudioService.java
@@ -63,6 +63,7 @@ import android.hardware.input.InputManager;
import android.hardware.usb.UsbManager;
import android.hidl.manager.V1_0.IServiceManager;
import android.media.AudioAttributes;
+import android.media.AudioAttributes.AttributeSystemUsage;
import android.media.AudioDeviceAddress;
import android.media.AudioDeviceInfo;
import android.media.AudioFocusInfo;
@@ -570,6 +571,11 @@ public class AudioService extends IAudioService.Stub
@GuardedBy("mSettingsLock")
private int mAssistantUid;
+ private final Object mSupportedSystemUsagesLock = new Object();
+ @GuardedBy("mSupportedSystemUsagesLock")
+ private @AttributeSystemUsage int[] mSupportedSystemUsages =
+ new int[]{AudioAttributes.USAGE_CALL_ASSISTANT};
+
// Defines the format for the connection "address" for ALSA devices
public static String makeAlsaAddressString(int card, int device) {
return "card=" + card + ";device=" + device + ";";
@@ -1043,6 +1049,10 @@ public class AudioService extends IAudioService.Stub
}
}
+ synchronized (mSupportedSystemUsagesLock) {
+ AudioSystem.setSupportedSystemUsages(mSupportedSystemUsages);
+ }
+
synchronized (mAudioPolicies) {
for (AudioPolicyProxy policy : mAudioPolicies.values()) {
final int status = policy.connectMixes();
@@ -1099,6 +1109,37 @@ public class AudioService extends IAudioService.Stub
}
/**
+ * @see AudioManager#setSupportedSystemUsages(int[])
+ */
+ public void setSupportedSystemUsages(@NonNull @AttributeSystemUsage int[] systemUsages) {
+ enforceModifyAudioRoutingPermission();
+ verifySystemUsages(systemUsages);
+
+ synchronized (mSupportedSystemUsagesLock) {
+ AudioSystem.setSupportedSystemUsages(systemUsages);
+ mSupportedSystemUsages = systemUsages;
+ }
+ }
+
+ /**
+ * @see AudioManager#getSupportedSystemUsages()
+ */
+ public @NonNull @AttributeSystemUsage int[] getSupportedSystemUsages() {
+ enforceModifyAudioRoutingPermission();
+ synchronized (mSupportedSystemUsagesLock) {
+ return Arrays.copyOf(mSupportedSystemUsages, mSupportedSystemUsages.length);
+ }
+ }
+
+ private void verifySystemUsages(@NonNull int[] systemUsages) {
+ for (int i = 0; i < systemUsages.length; i++) {
+ if (!AudioAttributes.isSystemUsage(systemUsages[i])) {
+ throw new IllegalArgumentException("Non-system usage provided: " + systemUsages[i]);
+ }
+ }
+ }
+
+ /**
* @return the {@link android.media.audiopolicy.AudioProductStrategy} discovered from the
* platform configuration file.
*/
@@ -5720,10 +5761,48 @@ public class AudioService extends IAudioService.Stub
return false;
}
+ private boolean isSupportedSystemUsage(@AudioAttributes.AttributeUsage int usage) {
+ synchronized (mSupportedSystemUsagesLock) {
+ for (int i = 0; i < mSupportedSystemUsages.length; i++) {
+ if (mSupportedSystemUsages[i] == usage) {
+ return true;
+ }
+ }
+ return false;
+ }
+ }
+
+ private void validateAudioAttributesUsage(@NonNull AudioAttributes audioAttributes) {
+ @AudioAttributes.AttributeUsage int usage = audioAttributes.getSystemUsage();
+ if (AudioAttributes.isSystemUsage(usage)) {
+ if (callerHasPermission(Manifest.permission.MODIFY_AUDIO_ROUTING)) {
+ if (!isSupportedSystemUsage(usage)) {
+ throw new IllegalArgumentException(
+ "Unsupported usage " + AudioAttributes.usageToString(usage));
+ }
+ } else {
+ throw new SecurityException("Missing MODIFY_AUDIO_ROUTING permission");
+ }
+ }
+ }
+
+ private boolean isValidAudioAttributesUsage(@NonNull AudioAttributes audioAttributes) {
+ @AudioAttributes.AttributeUsage int usage = audioAttributes.getSystemUsage();
+ if (AudioAttributes.isSystemUsage(usage)) {
+ return callerHasPermission(Manifest.permission.MODIFY_AUDIO_ROUTING)
+ && isSupportedSystemUsage(usage);
+ }
+ return true;
+ }
+
public int requestAudioFocus(AudioAttributes aa, int durationHint, IBinder cb,
IAudioFocusDispatcher fd, String clientId, String callingPackageName, int flags,
IAudioPolicyCallback pcb, int sdk) {
// permission checks
+ if (aa != null && !isValidAudioAttributesUsage(aa)) {
+ Log.w(TAG, "Request using unsupported usage.");
+ return AudioManager.AUDIOFOCUS_REQUEST_FAILED;
+ }
if ((flags & AudioManager.AUDIOFOCUS_FLAG_LOCK) == AudioManager.AUDIOFOCUS_FLAG_LOCK) {
if (AudioSystem.IN_VOICE_COMM_FOCUS_ID.equals(clientId)) {
if (PackageManager.PERMISSION_GRANTED != mContext.checkCallingOrSelfPermission(
@@ -5754,6 +5833,10 @@ public class AudioService extends IAudioService.Stub
public int abandonAudioFocus(IAudioFocusDispatcher fd, String clientId, AudioAttributes aa,
String callingPackageName) {
+ if (aa != null && !isValidAudioAttributesUsage(aa)) {
+ Log.w(TAG, "Request using unsupported usage.");
+ return AudioManager.AUDIOFOCUS_REQUEST_FAILED;
+ }
return mMediaFocusControl.abandonAudioFocus(fd, clientId, aa, callingPackageName);
}
@@ -6313,6 +6396,17 @@ public class AudioService extends IAudioService.Stub
sForceUseLogger.dump(pw);
pw.println("\n");
sVolumeLogger.dump(pw);
+ pw.println("\n");
+ dumpSupportedSystemUsage(pw);
+ }
+
+ private void dumpSupportedSystemUsage(PrintWriter pw) {
+ pw.println("Supported System Usages:");
+ synchronized (mSupportedSystemUsagesLock) {
+ for (int i = 0; i < mSupportedSystemUsages.length; i++) {
+ pw.printf("\t%s\n", AudioAttributes.usageToString(mSupportedSystemUsages[i]));
+ }
+ }
}
private static String safeMediaVolumeStateToString(int state) {
@@ -7090,10 +7184,16 @@ public class AudioService extends IAudioService.Stub
}
public int trackPlayer(PlayerBase.PlayerIdCard pic) {
+ if (pic != null && pic.mAttributes != null) {
+ validateAudioAttributesUsage(pic.mAttributes);
+ }
return mPlaybackMonitor.trackPlayer(pic);
}
public void playerAttributes(int piid, AudioAttributes attr) {
+ if (attr != null) {
+ validateAudioAttributesUsage(attr);
+ }
mPlaybackMonitor.playerAttributes(piid, attr, Binder.getCallingUid());
}
diff --git a/services/core/java/com/android/server/audio/MediaFocusControl.java b/services/core/java/com/android/server/audio/MediaFocusControl.java
index c845981fea7e..7bf2bc842176 100644
--- a/services/core/java/com/android/server/audio/MediaFocusControl.java
+++ b/services/core/java/com/android/server/audio/MediaFocusControl.java
@@ -727,6 +727,7 @@ public class MediaFocusControl implements PlayerFocusEnforcer {
case AudioAttributes.USAGE_ASSISTANT:
case AudioAttributes.USAGE_ASSISTANCE_ACCESSIBILITY:
case AudioAttributes.USAGE_ASSISTANCE_NAVIGATION_GUIDANCE:
+ case AudioAttributes.USAGE_ANNOUNCEMENT:
return 700;
case AudioAttributes.USAGE_VOICE_COMMUNICATION:
case AudioAttributes.USAGE_VOICE_COMMUNICATION_SIGNALLING:
@@ -736,7 +737,10 @@ public class MediaFocusControl implements PlayerFocusEnforcer {
case AudioAttributes.USAGE_NOTIFICATION_COMMUNICATION_DELAYED:
case AudioAttributes.USAGE_NOTIFICATION_EVENT:
case AudioAttributes.USAGE_ASSISTANCE_SONIFICATION:
+ case AudioAttributes.USAGE_VEHICLE_STATUS:
return 500;
+ case AudioAttributes.USAGE_EMERGENCY:
+ case AudioAttributes.USAGE_SAFETY:
case AudioAttributes.USAGE_UNKNOWN:
default:
return 0;
diff --git a/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java b/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java
index 0bf65bd6f739..905a94f57262 100644
--- a/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java
+++ b/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java
@@ -758,6 +758,14 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
private final WeakHashMap<IBinder, IBinder> mImeTargetWindowMap = new WeakHashMap<>();
/**
+ * Map of generated token to windowToken that is requesting
+ * {@link InputMethodManager#showSoftInput(View, int)}.
+ * This map tracks origin of showSoftInput requests.
+ */
+ @GuardedBy("mMethodMap")
+ private final WeakHashMap<IBinder, IBinder> mShowRequestWindowMap = new WeakHashMap<>();
+
+ /**
* A ring buffer to store the history of {@link StartInputInfo}.
*/
private static final class StartInputHistory {
@@ -974,7 +982,8 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
hideCurrentInputLocked(0, null);
mShowRequested = showRequested;
} else if (mShowRequested) {
- showCurrentInputLocked(InputMethodManager.SHOW_IMPLICIT, null);
+ showCurrentInputLocked(
+ mCurFocusedWindow, InputMethodManager.SHOW_IMPLICIT, null);
}
} else {
boolean enabledChanged = false;
@@ -2075,7 +2084,7 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
startInputToken, session, mCurInputContext, mCurAttribute));
if (mShowRequested) {
if (DEBUG) Slog.v(TAG, "Attach new input asks to show input");
- showCurrentInputLocked(getAppShowFlags(), null);
+ showCurrentInputLocked(mCurFocusedWindow, getAppShowFlags(), null);
}
return new InputBindResult(InputBindResult.ResultCode.SUCCESS_WITH_IME_SESSION,
session.session, (session.channel != null ? session.channel.dup() : null),
@@ -2789,7 +2798,7 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
}
@Override
- public boolean showSoftInput(IInputMethodClient client, int flags,
+ public boolean showSoftInput(IInputMethodClient client, IBinder windowToken, int flags,
ResultReceiver resultReceiver) {
int uid = Binder.getCallingUid();
synchronized (mMethodMap) {
@@ -2814,7 +2823,7 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
}
}
if (DEBUG) Slog.v(TAG, "Client requesting input be shown");
- return showCurrentInputLocked(flags, resultReceiver);
+ return showCurrentInputLocked(windowToken, flags, resultReceiver);
} finally {
Binder.restoreCallingIdentity(ident);
}
@@ -2822,7 +2831,7 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
}
@GuardedBy("mMethodMap")
- boolean showCurrentInputLocked(int flags, ResultReceiver resultReceiver) {
+ boolean showCurrentInputLocked(IBinder windowToken, int flags, ResultReceiver resultReceiver) {
mShowRequested = true;
if (mAccessibilityRequestingNoSoftKeyboard) {
return false;
@@ -2842,9 +2851,12 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
boolean res = false;
if (mCurMethod != null) {
if (DEBUG) Slog.d(TAG, "showCurrentInputLocked: mCurToken=" + mCurToken);
- executeOrSendMessage(mCurMethod, mCaller.obtainMessageIOO(
+ // create a dummy token for IMS so that IMS cannot inject windows into client app.
+ Binder showInputToken = new Binder();
+ mShowRequestWindowMap.put(showInputToken, windowToken);
+ executeOrSendMessage(mCurMethod, mCaller.obtainMessageIOOO(
MSG_SHOW_SOFT_INPUT, getImeShowFlags(), mCurMethod,
- resultReceiver));
+ resultReceiver, showInputToken));
mInputShown = true;
if (mHaveConnection && !mVisibleBound) {
bindCurrentInputMethodServiceLocked(
@@ -3145,7 +3157,7 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
attribute, startInputFlags, startInputReason);
didStart = true;
}
- showCurrentInputLocked(InputMethodManager.SHOW_IMPLICIT, null);
+ showCurrentInputLocked(windowToken, InputMethodManager.SHOW_IMPLICIT, null);
}
break;
case LayoutParams.SOFT_INPUT_STATE_UNCHANGED:
@@ -3171,7 +3183,7 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
attribute, startInputFlags, startInputReason);
didStart = true;
}
- showCurrentInputLocked(InputMethodManager.SHOW_IMPLICIT, null);
+ showCurrentInputLocked(windowToken, InputMethodManager.SHOW_IMPLICIT, null);
} else {
Slog.e(TAG, "SOFT_INPUT_STATE_VISIBLE is ignored because"
+ " there is no focused view that also returns true from"
@@ -3188,7 +3200,7 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
attribute, startInputFlags, startInputReason);
didStart = true;
}
- showCurrentInputLocked(InputMethodManager.SHOW_IMPLICIT, null);
+ showCurrentInputLocked(windowToken, InputMethodManager.SHOW_IMPLICIT, null);
} else {
Slog.e(TAG, "SOFT_INPUT_STATE_ALWAYS_VISIBLE is ignored because"
+ " there is no focused view that also returns true from"
@@ -3627,7 +3639,7 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
}
@BinderThread
- private void applyImeVisibility(IBinder token, boolean setVisible) {
+ private void applyImeVisibility(IBinder token, IBinder windowToken, boolean setVisible) {
synchronized (mMethodMap) {
if (!calledWithValidTokenLocked(token)) {
return;
@@ -3644,7 +3656,7 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
}
} else {
// Send to window manager to show IME after IME layout finishes.
- mWindowManagerInternal.showImePostLayout(mLastImeTargetWindow);
+ mWindowManagerInternal.showImePostLayout(mShowRequestWindowMap.get(windowToken));
}
}
}
@@ -3695,7 +3707,7 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
}
long ident = Binder.clearCallingIdentity();
try {
- showCurrentInputLocked(flags, null);
+ showCurrentInputLocked(mLastImeTargetWindow, flags, null);
} finally {
Binder.restoreCallingIdentity(ident);
}
@@ -3780,7 +3792,8 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
try {
if (DEBUG) Slog.v(TAG, "Calling " + args.arg1 + ".showSoftInput("
+ msg.arg1 + ", " + args.arg2 + ")");
- ((IInputMethod)args.arg1).showSoftInput(msg.arg1, (ResultReceiver)args.arg2);
+ ((IInputMethod) args.arg1).showSoftInput(
+ (IBinder) args.arg3, msg.arg1, (ResultReceiver) args.arg2);
} catch (RemoteException e) {
}
args.recycle();
@@ -5346,8 +5359,8 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
@BinderThread
@Override
- public void applyImeVisibility(boolean setVisible) {
- mImms.applyImeVisibility(mToken, setVisible);
+ public void applyImeVisibility(IBinder windowToken, boolean setVisible) {
+ mImms.applyImeVisibility(mToken, windowToken, setVisible);
}
}
}
diff --git a/services/core/java/com/android/server/inputmethod/MultiClientInputMethodManagerService.java b/services/core/java/com/android/server/inputmethod/MultiClientInputMethodManagerService.java
index f09795fbea01..d09c478e320f 100644
--- a/services/core/java/com/android/server/inputmethod/MultiClientInputMethodManagerService.java
+++ b/services/core/java/com/android/server/inputmethod/MultiClientInputMethodManagerService.java
@@ -1449,7 +1449,8 @@ public final class MultiClientInputMethodManagerService {
@BinderThread
@Override
public boolean showSoftInput(
- IInputMethodClient client, int flags, ResultReceiver resultReceiver) {
+ IInputMethodClient client, IBinder token, int flags,
+ ResultReceiver resultReceiver) {
final int callingUid = Binder.getCallingUid();
final int callingPid = Binder.getCallingPid();
final int userId = UserHandle.getUserId(callingUid);
diff --git a/services/core/java/com/android/server/pm/CrossProfileAppsServiceImpl.java b/services/core/java/com/android/server/pm/CrossProfileAppsServiceImpl.java
index 3635004987e8..fc08ddeddf82 100644
--- a/services/core/java/com/android/server/pm/CrossProfileAppsServiceImpl.java
+++ b/services/core/java/com/android/server/pm/CrossProfileAppsServiceImpl.java
@@ -173,6 +173,50 @@ public class CrossProfileAppsServiceImpl extends ICrossProfileApps.Stub {
}
@Override
+ public void startActivityAsUserByIntent(
+ IApplicationThread caller,
+ String callingPackage,
+ Intent intent,
+ @UserIdInt int userId) throws RemoteException {
+ Objects.requireNonNull(callingPackage);
+ Objects.requireNonNull(intent);
+ Objects.requireNonNull(intent.getComponent(), "The intent must have a Component set");
+
+ verifyCallingPackage(callingPackage);
+
+ final int callerUserId = mInjector.getCallingUserId();
+ final int callingUid = mInjector.getCallingUid();
+
+ List<UserHandle> allowedTargetUsers = getTargetUserProfilesUnchecked(
+ callingPackage, callerUserId);
+ if (callerUserId != userId && !allowedTargetUsers.contains(UserHandle.of(userId))) {
+ throw new SecurityException(callingPackage + " cannot access unrelated user " + userId);
+ }
+
+ Intent launchIntent = new Intent(intent);
+ launchIntent.setPackage(callingPackage);
+
+ if (!callingPackage.equals(launchIntent.getComponent().getPackageName())) {
+ throw new SecurityException(
+ callingPackage + " attempts to start an activity in other package - "
+ + launchIntent.getComponent().getPackageName());
+ }
+
+ if (callerUserId != userId) {
+ if (!hasInteractAcrossProfilesPermission(callingPackage)) {
+ throw new SecurityException("Attempt to launch activity without required "
+ + android.Manifest.permission.INTERACT_ACROSS_PROFILES + " permission"
+ + " or target user is not in the same profile group.");
+ }
+ }
+
+ verifyActivityCanHandleIntent(launchIntent, callingUid, userId);
+
+ mInjector.getActivityTaskManagerInternal().startActivityAsUser(
+ caller, callingPackage, launchIntent, /* options= */ null, userId);
+ }
+
+ @Override
public boolean canRequestInteractAcrossProfiles(String callingPackage) {
Objects.requireNonNull(callingPackage);
verifyCallingPackage(callingPackage);
@@ -214,6 +258,11 @@ public class CrossProfileAppsServiceImpl extends ICrossProfileApps.Stub {
if (targetUserProfiles.isEmpty()) {
return false;
}
+
+ return hasInteractAcrossProfilesPermission(callingPackage);
+ }
+
+ private boolean hasInteractAcrossProfilesPermission(String callingPackage) {
final int callingUid = mInjector.getCallingUid();
final int callingPid = mInjector.getCallingPid();
return isPermissionGranted(Manifest.permission.INTERACT_ACROSS_USERS_FULL, callingUid)
@@ -275,6 +324,27 @@ public class CrossProfileAppsServiceImpl extends ICrossProfileApps.Stub {
}
}
+ private void verifyActivityCanHandleIntent(
+ Intent launchIntent, int callingUid, @UserIdInt int userId) {
+ final long ident = mInjector.clearCallingIdentity();
+ try {
+ final List<ResolveInfo> activities =
+ mInjector.getPackageManagerInternal().queryIntentActivities(
+ launchIntent,
+ launchIntent.resolveTypeIfNeeded(mContext.getContentResolver()),
+ MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE,
+ callingUid,
+ userId);
+
+ if (!activities.isEmpty()) {
+ return;
+ }
+ throw new SecurityException("Activity cannot handle intent");
+ } finally {
+ mInjector.restoreCallingIdentity(ident);
+ }
+ }
+
/**
* Verify that the specified intent does resolved to the specified component and the resolved
* activity is exported.
diff --git a/services/core/java/com/android/server/pm/PackageManagerShellCommand.java b/services/core/java/com/android/server/pm/PackageManagerShellCommand.java
index ad4f6ff2b003..83840067ecc2 100644
--- a/services/core/java/com/android/server/pm/PackageManagerShellCommand.java
+++ b/services/core/java/com/android/server/pm/PackageManagerShellCommand.java
@@ -1227,7 +1227,7 @@ class PackageManagerShellCommand extends ShellCommand {
}
abandonSession = false;
- if (!params.sessionParams.isStaged || !params.waitForStagedSessionReady) {
+ if (!params.sessionParams.isStaged || !params.mWaitForStagedSessionReady) {
pw.println("Success");
return 0;
}
@@ -1265,7 +1265,7 @@ class PackageManagerShellCommand extends ShellCommand {
+ si.getStagedSessionErrorMessage() + "]");
return 1;
}
- pw.println("Success");
+ pw.println("Success. Reboot device to apply staged session");
return 0;
} finally {
if (abandonSession) {
@@ -2615,7 +2615,7 @@ class PackageManagerShellCommand extends ShellCommand {
SessionParams sessionParams;
String installerPackageName;
int userId = UserHandle.USER_ALL;
- boolean waitForStagedSessionReady = false;
+ boolean mWaitForStagedSessionReady = true;
long timeoutMs = DEFAULT_WAIT_MS;
}
@@ -2743,13 +2743,16 @@ class PackageManagerShellCommand extends ShellCommand {
sessionParams.installFlags |= PackageManager.INSTALL_ENABLE_ROLLBACK;
break;
case "--wait":
- params.waitForStagedSessionReady = true;
+ params.mWaitForStagedSessionReady = true;
try {
params.timeoutMs = Long.parseLong(peekNextArg());
getNextArg();
} catch (NumberFormatException ignore) {
}
break;
+ case "--no-wait":
+ params.mWaitForStagedSessionReady = false;
+ break;
default:
throw new IllegalArgumentException("Unknown option " + opt);
}
diff --git a/services/core/java/com/android/server/soundtrigger_middleware/SoundTriggerModule.java b/services/core/java/com/android/server/soundtrigger_middleware/SoundTriggerModule.java
index adf16fafc000..372c1f501d7b 100644
--- a/services/core/java/com/android/server/soundtrigger_middleware/SoundTriggerModule.java
+++ b/services/core/java/com/android/server/soundtrigger_middleware/SoundTriggerModule.java
@@ -174,7 +174,17 @@ class SoundTriggerModule implements IHwBinder.DeathRecipient {
for (Session session : mActiveSessions) {
session.moduleDied();
}
+ reset();
+ }
+
+ /**
+ * Resets the transient state of this object.
+ */
+ private void reset() {
attachToHal();
+ // We conservatively assume that external capture is active until explicitly told otherwise.
+ mRecognitionAvailable = mProperties.concurrentCapture;
+ mNumLoadedModels = 0;
}
/**
diff --git a/services/core/java/com/android/server/stats/pull/StatsPullAtomService.java b/services/core/java/com/android/server/stats/pull/StatsPullAtomService.java
index 3c41c1077e5c..a0e6be4d9a6b 100644
--- a/services/core/java/com/android/server/stats/pull/StatsPullAtomService.java
+++ b/services/core/java/com/android/server/stats/pull/StatsPullAtomService.java
@@ -2274,20 +2274,104 @@ public class StatsPullAtomService extends SystemService {
return StatsManager.PULL_SUCCESS;
}
+ private final Object mDebugElapsedClockLock = new Object();
+ private long mDebugElapsedClockPreviousValue = 0;
+ private long mDebugElapsedClockPullCount = 0;
+
private void registerDebugElapsedClock() {
- // No op.
+ int tagId = StatsLog.DEBUG_ELAPSED_CLOCK;
+ PullAtomMetadata metadata = PullAtomMetadata.newBuilder()
+ .setAdditiveFields(new int[] {1, 2, 3, 4})
+ .build();
+ mStatsManager.registerPullAtomCallback(
+ tagId,
+ metadata,
+ (atomTag, data) -> pullDebugElapsedClock(atomTag, data),
+ BackgroundThread.getExecutor()
+ );
}
- private void pullDebugElapsedClock() {
- // No op.
+ private int pullDebugElapsedClock(int atomTag, List<StatsEvent> pulledData) {
+ final long elapsedMillis = SystemClock.elapsedRealtime();
+
+ synchronized (mDebugElapsedClockLock) {
+ final long clockDiffMillis = mDebugElapsedClockPreviousValue == 0
+ ? 0 : elapsedMillis - mDebugElapsedClockPreviousValue;
+
+ StatsEvent e = StatsEvent.newBuilder()
+ .setAtomId(atomTag)
+ .writeLong(mDebugElapsedClockPullCount)
+ .writeLong(elapsedMillis)
+ // Log it twice to be able to test multi-value aggregation from ValueMetric.
+ .writeLong(elapsedMillis)
+ .writeLong(clockDiffMillis)
+ .writeInt(1 /* always set */)
+ .build();
+ pulledData.add(e);
+
+ if (mDebugElapsedClockPullCount % 2 == 1) {
+ StatsEvent e2 = StatsEvent.newBuilder()
+ .setAtomId(atomTag)
+ .writeLong(mDebugElapsedClockPullCount)
+ .writeLong(elapsedMillis)
+ // Log it twice to be able to test multi-value aggregation from ValueMetric.
+ .writeLong(elapsedMillis)
+ .writeLong(clockDiffMillis)
+ .writeInt(2 /* set on odd pulls */)
+ .build();
+ pulledData.add(e2);
+ }
+
+ mDebugElapsedClockPullCount++;
+ mDebugElapsedClockPreviousValue = elapsedMillis;
+ }
+
+ return StatsManager.PULL_SUCCESS;
}
+ private final Object mDebugFailingElapsedClockLock = new Object();
+ private long mDebugFailingElapsedClockPreviousValue = 0;
+ private long mDebugFailingElapsedClockPullCount = 0;
+
private void registerDebugFailingElapsedClock() {
- // No op.
+ int tagId = StatsLog.DEBUG_FAILING_ELAPSED_CLOCK;
+ PullAtomMetadata metadata = PullAtomMetadata.newBuilder()
+ .setAdditiveFields(new int[] {1, 2, 3, 4})
+ .build();
+ mStatsManager.registerPullAtomCallback(
+ tagId,
+ metadata,
+ (atomTag, data) -> pullDebugFailingElapsedClock(atomTag, data),
+ BackgroundThread.getExecutor()
+ );
}
- private void pullDebugFailingElapsedClock() {
- // No op.
+ private int pullDebugFailingElapsedClock(int atomTag, List<StatsEvent> pulledData) {
+ final long elapsedMillis = SystemClock.elapsedRealtime();
+
+ synchronized (mDebugFailingElapsedClockLock) {
+ // Fails every 5 buckets.
+ if (mDebugFailingElapsedClockPullCount++ % 5 == 0) {
+ mDebugFailingElapsedClockPreviousValue = elapsedMillis;
+ Slog.e(TAG, "Failing debug elapsed clock");
+ return StatsManager.PULL_SKIP;
+ }
+
+ StatsEvent e = StatsEvent.newBuilder()
+ .setAtomId(atomTag)
+ .writeLong(mDebugFailingElapsedClockPullCount)
+ .writeLong(elapsedMillis)
+ // Log it twice to be able to test multi-value aggregation from ValueMetric.
+ .writeLong(elapsedMillis)
+ .writeLong(mDebugFailingElapsedClockPreviousValue == 0
+ ? 0 : elapsedMillis - mDebugFailingElapsedClockPreviousValue)
+ .build();
+ pulledData.add(e);
+
+ mDebugFailingElapsedClockPreviousValue = elapsedMillis;
+ }
+
+ return StatsManager.PULL_SUCCESS;
}
private void registerBuildInformation() {
diff --git a/services/core/java/com/android/server/tv/TvInputHardwareManager.java b/services/core/java/com/android/server/tv/TvInputHardwareManager.java
index 6ea274d8a814..8f71943129fa 100755
--- a/services/core/java/com/android/server/tv/TvInputHardwareManager.java
+++ b/services/core/java/com/android/server/tv/TvInputHardwareManager.java
@@ -44,6 +44,7 @@ import android.media.tv.ITvInputHardware;
import android.media.tv.ITvInputHardwareCallback;
import android.media.tv.TvInputHardwareInfo;
import android.media.tv.TvInputInfo;
+import android.media.tv.TvInputService.PriorityHintUseCaseType;
import android.media.tv.TvStreamConfig;
import android.os.Handler;
import android.os.IBinder;
@@ -363,7 +364,8 @@ class TvInputHardwareManager implements TvInputHal.Callback {
* release is notified via ITvInputHardwareCallback.onReleased().
*/
public ITvInputHardware acquireHardware(int deviceId, ITvInputHardwareCallback callback,
- TvInputInfo info, int callingUid, int resolvedUserId) {
+ TvInputInfo info, int callingUid, int resolvedUserId,
+ String tvInputSessionId, @PriorityHintUseCaseType int priorityHint) {
if (callback == null) {
throw new NullPointerException();
}
@@ -373,6 +375,8 @@ class TvInputHardwareManager implements TvInputHal.Callback {
Slog.e(TAG, "Invalid deviceId : " + deviceId);
return null;
}
+ // TODO: check with TRM to compare the client's priority with the current holder's
+ // priority. If lower, do nothing.
if (checkUidChangedLocked(connection, callingUid, resolvedUserId)) {
TvInputHardwareImpl hardware =
new TvInputHardwareImpl(connection.getHardwareInfoLocked());
diff --git a/services/core/java/com/android/server/tv/TvInputManagerService.java b/services/core/java/com/android/server/tv/TvInputManagerService.java
index eb7c5caa62aa..e8704ab789f2 100755
--- a/services/core/java/com/android/server/tv/TvInputManagerService.java
+++ b/services/core/java/com/android/server/tv/TvInputManagerService.java
@@ -1736,8 +1736,9 @@ public final class TvInputManagerService extends SystemService {
@Override
public ITvInputHardware acquireTvInputHardware(int deviceId,
- ITvInputHardwareCallback callback, TvInputInfo info, int userId)
- throws RemoteException {
+ ITvInputHardwareCallback callback, TvInputInfo info, int userId,
+ String tvInputSessionId,
+ @TvInputService.PriorityHintUseCaseType int priorityHint) throws RemoteException {
if (mContext.checkCallingPermission(android.Manifest.permission.TV_INPUT_HARDWARE)
!= PackageManager.PERMISSION_GRANTED) {
return null;
@@ -1749,7 +1750,8 @@ public final class TvInputManagerService extends SystemService {
userId, "acquireTvInputHardware");
try {
return mTvInputHardwareManager.acquireHardware(
- deviceId, callback, info, callingUid, resolvedUserId);
+ deviceId, callback, info, callingUid, resolvedUserId,
+ tvInputSessionId, priorityHint);
} finally {
Binder.restoreCallingIdentity(identity);
}
diff --git a/services/tests/servicestests/src/com/android/server/BluetoothAirplaneModeListenerTest.java b/services/tests/servicestests/src/com/android/server/BluetoothAirplaneModeListenerTest.java
new file mode 100644
index 000000000000..968a402ff3b7
--- /dev/null
+++ b/services/tests/servicestests/src/com/android/server/BluetoothAirplaneModeListenerTest.java
@@ -0,0 +1,125 @@
+/*
+ * Copyright 2019 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.server;
+
+import static org.mockito.Mockito.*;
+
+import android.bluetooth.BluetoothAdapter;
+import android.content.Context;
+import android.os.Looper;
+import android.provider.Settings;
+
+import androidx.test.InstrumentationRegistry;
+import androidx.test.filters.MediumTest;
+import androidx.test.runner.AndroidJUnit4;
+
+import com.android.server.BluetoothAirplaneModeListener.AirplaneModeHelper;
+
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+
+@MediumTest
+@RunWith(AndroidJUnit4.class)
+public class BluetoothAirplaneModeListenerTest {
+ private Context mContext;
+ private BluetoothAirplaneModeListener mBluetoothAirplaneModeListener;
+ private BluetoothAdapter mBluetoothAdapter;
+ private AirplaneModeHelper mHelper;
+
+ @Mock BluetoothManagerService mBluetoothManagerService;
+
+ @Before
+ public void setUp() throws Exception {
+ mContext = InstrumentationRegistry.getTargetContext();
+
+ mHelper = mock(AirplaneModeHelper.class);
+ when(mHelper.getSettingsInt(BluetoothAirplaneModeListener.TOAST_COUNT))
+ .thenReturn(BluetoothAirplaneModeListener.MAX_TOAST_COUNT);
+ doNothing().when(mHelper).setSettingsInt(anyString(), anyInt());
+ doNothing().when(mHelper).showToastMessage();
+ doNothing().when(mHelper).onAirplaneModeChanged(any(BluetoothManagerService.class));
+
+ mBluetoothAirplaneModeListener = new BluetoothAirplaneModeListener(
+ mBluetoothManagerService, Looper.getMainLooper(), mContext);
+ mBluetoothAirplaneModeListener.start(mHelper);
+ }
+
+ @Test
+ public void testIgnoreOnAirplanModeChange() {
+ Assert.assertFalse(mBluetoothAirplaneModeListener.shouldSkipAirplaneModeChange());
+
+ when(mHelper.isBluetoothOn()).thenReturn(true);
+ Assert.assertFalse(mBluetoothAirplaneModeListener.shouldSkipAirplaneModeChange());
+
+ when(mHelper.isA2dpOrHearingAidConnected()).thenReturn(true);
+ Assert.assertFalse(mBluetoothAirplaneModeListener.shouldSkipAirplaneModeChange());
+
+ when(mHelper.isAirplaneModeOn()).thenReturn(true);
+ Assert.assertTrue(mBluetoothAirplaneModeListener.shouldSkipAirplaneModeChange());
+ }
+
+ @Test
+ public void testHandleAirplaneModeChange_InvokeAirplaneModeChanged() {
+ mBluetoothAirplaneModeListener.handleAirplaneModeChange();
+ verify(mHelper).onAirplaneModeChanged(mBluetoothManagerService);
+ }
+
+ @Test
+ public void testHandleAirplaneModeChange_NotInvokeAirplaneModeChanged_NotPopToast() {
+ mBluetoothAirplaneModeListener.mToastCount = BluetoothAirplaneModeListener.MAX_TOAST_COUNT;
+ when(mHelper.isBluetoothOn()).thenReturn(true);
+ when(mHelper.isA2dpOrHearingAidConnected()).thenReturn(true);
+ when(mHelper.isAirplaneModeOn()).thenReturn(true);
+ mBluetoothAirplaneModeListener.handleAirplaneModeChange();
+
+ verify(mHelper).setSettingsInt(Settings.Global.BLUETOOTH_ON,
+ BluetoothManagerService.BLUETOOTH_ON_AIRPLANE);
+ verify(mHelper, times(0)).showToastMessage();
+ verify(mHelper, times(0)).onAirplaneModeChanged(mBluetoothManagerService);
+ }
+
+ @Test
+ public void testHandleAirplaneModeChange_NotInvokeAirplaneModeChanged_PopToast() {
+ mBluetoothAirplaneModeListener.mToastCount = 0;
+ when(mHelper.isBluetoothOn()).thenReturn(true);
+ when(mHelper.isA2dpOrHearingAidConnected()).thenReturn(true);
+ when(mHelper.isAirplaneModeOn()).thenReturn(true);
+ mBluetoothAirplaneModeListener.handleAirplaneModeChange();
+
+ verify(mHelper).setSettingsInt(Settings.Global.BLUETOOTH_ON,
+ BluetoothManagerService.BLUETOOTH_ON_AIRPLANE);
+ verify(mHelper).showToastMessage();
+ verify(mHelper, times(0)).onAirplaneModeChanged(mBluetoothManagerService);
+ }
+
+ @Test
+ public void testIsPopToast_PopToast() {
+ mBluetoothAirplaneModeListener.mToastCount = 0;
+ Assert.assertTrue(mBluetoothAirplaneModeListener.shouldPopToast());
+ verify(mHelper).setSettingsInt(BluetoothAirplaneModeListener.TOAST_COUNT, 1);
+ }
+
+ @Test
+ public void testIsPopToast_NotPopToast() {
+ mBluetoothAirplaneModeListener.mToastCount = BluetoothAirplaneModeListener.MAX_TOAST_COUNT;
+ Assert.assertFalse(mBluetoothAirplaneModeListener.shouldPopToast());
+ verify(mHelper, times(0)).setSettingsInt(anyString(), anyInt());
+ }
+}
diff --git a/telephony/java/android/telephony/AccessNetworkConstants.java b/telephony/java/android/telephony/AccessNetworkConstants.java
index 6d2ac9dbb737..b1d647fec0c5 100644
--- a/telephony/java/android/telephony/AccessNetworkConstants.java
+++ b/telephony/java/android/telephony/AccessNetworkConstants.java
@@ -67,6 +67,22 @@ public final class AccessNetworkConstants {
}
}
+ /**
+ * Access network type
+ * @hide
+ */
+ @Retention(RetentionPolicy.SOURCE)
+ @IntDef(prefix = {"RADIO_ACCESS_NETWORK_TYPE_"},
+ value = {
+ AccessNetworkType.UNKNOWN,
+ AccessNetworkType.GERAN,
+ AccessNetworkType.UTRAN,
+ AccessNetworkType.EUTRAN,
+ AccessNetworkType.CDMA2000,
+ AccessNetworkType.IWLAN,
+ AccessNetworkType.NGRAN})
+ public @interface RadioAccessNetworkType {}
+
public static final class AccessNetworkType {
public static final int UNKNOWN = 0;
public static final int GERAN = 1;
diff --git a/telephony/java/android/telephony/PhoneCapability.java b/telephony/java/android/telephony/PhoneCapability.java
index 8a75831a75b8..90244b3df350 100644
--- a/telephony/java/android/telephony/PhoneCapability.java
+++ b/telephony/java/android/telephony/PhoneCapability.java
@@ -16,13 +16,20 @@
package android.telephony;
+import android.annotation.LongDef;
import android.annotation.NonNull;
-import android.annotation.SystemApi;
+import android.annotation.Nullable;
import android.os.Parcel;
import android.os.Parcelable;
+import android.telephony.AccessNetworkConstants.AccessNetworkType;
+import android.telephony.AccessNetworkConstants.RadioAccessNetworkType;
+import android.telephony.TelephonyManager.NetworkTypeBitMask;
+import com.android.internal.util.CollectionUtils;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
import java.util.ArrayList;
-import java.util.Arrays;
import java.util.List;
import java.util.Objects;
@@ -31,68 +38,365 @@ import java.util.Objects;
* are shared between those modems defined by list of modem IDs.
*/
public final class PhoneCapability implements Parcelable {
- // Hardcoded default DSDS capability.
+ /** Modem feature indicating 3GPP2 capability. */
+ public static final long MODEM_FEATURE_3GPP2_REG = 1 << 0;
+ /** Modem feature indicating 3GPP capability. */
+ public static final long MODEM_FEATURE_3GPP_REG = 1 << 1;
+ /** Modem feature indicating CDMA 2000 with EHRPD capability. */
+ public static final long MODEM_FEATURE_CDMA2000_EHRPD_REG = 1 << 2;
+ /** Modem feature indicating GSM capability. */
+ public static final long MODEM_FEATURE_GERAN_REG = 1 << 3;
+ /** Modem feature indicating UMTS capability. */
+ public static final long MODEM_FEATURE_UTRAN_REG = 1 << 4;
+ /** Modem feature indicating LTE capability. */
+ public static final long MODEM_FEATURE_EUTRAN_REG = 1 << 5;
+ /** Modem feature indicating 5G capability.*/
+ public static final long MODEM_FEATURE_NGRAN_REG = 1 << 6;
+ /** Modem feature indicating EN-DC capability. */
+ public static final long MODEM_FEATURE_EUTRA_NR_DUAL_CONNECTIVITY_REG = 1 << 7;
+ /** Modem feature indicating VoLTE capability (IMS registered). */
+ public static final long MODEM_FEATURE_PS_VOICE_REG = 1 << 8;
+ /** Modem feature indicating CS voice call capability. */
+ public static final long MODEM_FEATURE_CS_VOICE_SESSION = 1 << 9;
+ /** Modem feature indicating Internet connection capability. */
+ public static final long MODEM_FEATURE_INTERACTIVE_DATA_SESSION = 1 << 10;
+ /**
+ * Modem feature indicating dedicated bearer capability.
+ * For services that require a high level QoS (eg. VoLTE), the network can create
+ * a dedicated bearer with the required QoS on top of an established default bearer.
+ * This will provide a dedicated tunnel for one or more specific traffic types.
+ */
+ public static final long MODEM_FEATURE_DEDICATED_BEARER = 1 << 11;
+ /** Modem feature indicating network scan capability. */
+ public static final long MODEM_FEATURE_NETWORK_SCAN = 1 << 12;
+ /** Modem feature indicating corresponding SIM has CDMA capability. */
+ public static final long MODEM_FEATURE_CSIM = 1 << 13;
+
/** @hide */
+ @LongDef(flag = true, prefix = {"MODEM_FEATURE_" }, value = {
+ MODEM_FEATURE_3GPP2_REG,
+ MODEM_FEATURE_3GPP_REG,
+ MODEM_FEATURE_CDMA2000_EHRPD_REG,
+ MODEM_FEATURE_GERAN_REG,
+ MODEM_FEATURE_UTRAN_REG,
+ MODEM_FEATURE_EUTRAN_REG,
+ MODEM_FEATURE_NGRAN_REG,
+ MODEM_FEATURE_EUTRA_NR_DUAL_CONNECTIVITY_REG,
+ MODEM_FEATURE_PS_VOICE_REG,
+ MODEM_FEATURE_CS_VOICE_SESSION,
+ MODEM_FEATURE_INTERACTIVE_DATA_SESSION,
+ MODEM_FEATURE_DEDICATED_BEARER,
+ MODEM_FEATURE_NETWORK_SCAN,
+ MODEM_FEATURE_CSIM,
+ })
+ @Retention(RetentionPolicy.SOURCE)
+ public @interface ModemFeature {
+ }
+
+ /**
+ * Hardcoded default DSDS capability.
+ * @hide
+ */
public static final PhoneCapability DEFAULT_DSDS_CAPABILITY;
- // Hardcoded default Single SIM single standby capability.
- /** @hide */
+ /**
+ * Hardcoded default Single SIM single standby capability.
+ * @hide
+ */
public static final PhoneCapability DEFAULT_SSSS_CAPABILITY;
static {
- ModemInfo modemInfo1 = new ModemInfo(0, 0, true, true);
- ModemInfo modemInfo2 = new ModemInfo(1, 0, true, true);
+ List<List<Long>> capabilities = new ArrayList<>();
+ List<Long> modem1 = new ArrayList<>();
+ List<Long> modem2 = new ArrayList<>();
+ modem1.add(MODEM_FEATURE_GERAN_REG | MODEM_FEATURE_UTRAN_REG | MODEM_FEATURE_EUTRAN_REG
+ | MODEM_FEATURE_PS_VOICE_REG | MODEM_FEATURE_CS_VOICE_SESSION
+ | MODEM_FEATURE_INTERACTIVE_DATA_SESSION | MODEM_FEATURE_DEDICATED_BEARER);
+ modem2.add(MODEM_FEATURE_GERAN_REG | MODEM_FEATURE_UTRAN_REG | MODEM_FEATURE_EUTRAN_REG
+ | MODEM_FEATURE_PS_VOICE_REG | MODEM_FEATURE_INTERACTIVE_DATA_SESSION
+ | MODEM_FEATURE_DEDICATED_BEARER);
+ capabilities.add(modem1);
+ capabilities.add(modem2);
+ List<String> uuids = new ArrayList<>();
+ uuids.add("com.xxxx.lm0");
+ uuids.add("com.xxxx.lm1");
+ long rats = TelephonyManager.NETWORK_TYPE_BITMASK_GSM
+ | TelephonyManager.NETWORK_TYPE_BITMASK_GPRS
+ | TelephonyManager.NETWORK_TYPE_BITMASK_EDGE
+ | TelephonyManager.NETWORK_TYPE_BITMASK_UMTS
+ | TelephonyManager.NETWORK_TYPE_BITMASK_LTE;
+ DEFAULT_DSDS_CAPABILITY = new PhoneCapability(0, 0, 0, 0, 0, rats, null, null, null, null,
+ uuids, null, capabilities);
+
+ capabilities = new ArrayList<>();
+ capabilities.add(modem1);
+ uuids = new ArrayList<>();
+ uuids.add("com.xxxx.lm0");
+ DEFAULT_SSSS_CAPABILITY = new PhoneCapability(0, 0, 0, 0, 0, rats, null, null, null, null,
+ uuids, null, capabilities);
+ }
- List<ModemInfo> logicalModemList = new ArrayList<>();
- logicalModemList.add(modemInfo1);
- logicalModemList.add(modemInfo2);
- DEFAULT_DSDS_CAPABILITY = new PhoneCapability(1, 1, 0, logicalModemList, false);
+ private final int mUtranUeCategoryDl;
+ private final int mUtranUeCategoryUl;
+ private final int mEutranUeCategoryDl;
+ private final int mEutranUeCategoryUl;
+ private final long mPsDataConnectionLingerTimeMillis;
+ private final @NetworkTypeBitMask long mSupportedRats;
+ private final List<Integer> mGeranBands;
+ private final List<Integer> mUtranBands;
+ private final List<Integer> mEutranBands;
+ private final List<Integer> mNgranBands;
+ private final List<String> mLogicalModemUuids;
+ private final List<SimSlotCapability> mSimSlotCapabilities;
+ private final @ModemFeature List<List<Long>> mConcurrentFeaturesSupport;
- logicalModemList = new ArrayList<>();
- logicalModemList.add(modemInfo1);
- DEFAULT_SSSS_CAPABILITY = new PhoneCapability(1, 1, 0, logicalModemList, false);
+ /**
+ * Default constructor to create a PhoneCapability object.
+ * @param utranUeCategoryDl 3GPP UE category for UTRAN downlink.
+ * @param utranUeCategoryUl 3GPP UE category for UTRAN uplink.
+ * @param eutranUeCategoryDl 3GPP UE category for EUTRAN downlink.
+ * @param eutranUeCategoryUl 3GPP UE category for EUTRAN uplink.
+ * @param psDataConnectionLingerTimeMillis length of the grace period to allow a smooth
+ * "handover" between data connections.
+ * @param supportedRats all radio access technologies this phone is capable of supporting.
+ * @param geranBands list of supported {@link AccessNetworkConstants.GeranBand}.
+ * @param utranBands list of supported {@link AccessNetworkConstants.UtranBand}.
+ * @param eutranBands list of supported {@link AccessNetworkConstants.EutranBand}.
+ * @param ngranBands list of supported {@link AccessNetworkConstants.NgranBands}.
+ * @param logicalModemUuids list of logical modem UUIDs, typically of the form
+ * "com.xxxx.lmX", where X is the logical modem ID.
+ * @param simSlotCapabilities list of {@link SimSlotCapability} for the device
+ * @param concurrentFeaturesSupport list of list of concurrently supportable modem feature sets.
+ * @hide
+ */
+ public PhoneCapability(int utranUeCategoryDl, int utranUeCategoryUl, int eutranUeCategoryDl,
+ int eutranUeCategoryUl, long psDataConnectionLingerTimeMillis,
+ @NetworkTypeBitMask long supportedRats, @Nullable List<Integer> geranBands,
+ @Nullable List<Integer> utranBands, @Nullable List<Integer> eutranBands,
+ @Nullable List<Integer> ngranBands, @Nullable List<String> logicalModemUuids,
+ @Nullable List<SimSlotCapability> simSlotCapabilities,
+ @Nullable @ModemFeature List<List<Long>> concurrentFeaturesSupport) {
+ this.mUtranUeCategoryDl = utranUeCategoryDl;
+ this.mUtranUeCategoryUl = utranUeCategoryUl;
+ this.mEutranUeCategoryDl = eutranUeCategoryDl;
+ this.mEutranUeCategoryUl = eutranUeCategoryUl;
+ this.mPsDataConnectionLingerTimeMillis = psDataConnectionLingerTimeMillis;
+ this.mSupportedRats = supportedRats;
+ this.mGeranBands = CollectionUtils.emptyIfNull(geranBands);
+ this.mUtranBands = CollectionUtils.emptyIfNull(utranBands);
+ this.mEutranBands = CollectionUtils.emptyIfNull(eutranBands);
+ this.mNgranBands = CollectionUtils.emptyIfNull(ngranBands);
+ this.mLogicalModemUuids = CollectionUtils.emptyIfNull(logicalModemUuids);
+ this.mSimSlotCapabilities = CollectionUtils.emptyIfNull(simSlotCapabilities);
+ this.mConcurrentFeaturesSupport = CollectionUtils.emptyIfNull(concurrentFeaturesSupport);
}
- /** @hide */
- public final int maxActiveVoiceCalls;
- /** @hide */
- public final int maxActiveData;
- /** @hide */
- public final int max5G;
- /** @hide */
- public final boolean validationBeforeSwitchSupported;
- /** @hide */
- public final List<ModemInfo> logicalModemList;
- /** @hide */
- public PhoneCapability(int maxActiveVoiceCalls, int maxActiveData, int max5G,
- List<ModemInfo> logicalModemList, boolean validationBeforeSwitchSupported) {
- this.maxActiveVoiceCalls = maxActiveVoiceCalls;
- this.maxActiveData = maxActiveData;
- this.max5G = max5G;
- // Make sure it's not null.
- this.logicalModemList = logicalModemList == null ? new ArrayList<>() : logicalModemList;
- this.validationBeforeSwitchSupported = validationBeforeSwitchSupported;
+ private PhoneCapability(Parcel in) {
+ mUtranUeCategoryDl = in.readInt();
+ mUtranUeCategoryUl = in.readInt();
+ mEutranUeCategoryDl = in.readInt();
+ mEutranUeCategoryUl = in.readInt();
+ mPsDataConnectionLingerTimeMillis = in.readLong();
+ mSupportedRats = in.readLong();
+ mGeranBands = new ArrayList<>();
+ in.readList(mGeranBands, Integer.class.getClassLoader());
+ mUtranBands = new ArrayList<>();
+ in.readList(mUtranBands, Integer.class.getClassLoader());
+ mEutranBands = new ArrayList<>();
+ in.readList(mEutranBands, Integer.class.getClassLoader());
+ mNgranBands = new ArrayList<>();
+ in.readList(mNgranBands, Integer.class.getClassLoader());
+ mLogicalModemUuids = in.createStringArrayList();
+ mSimSlotCapabilities = in.createTypedArrayList(SimSlotCapability.CREATOR);
+ int length = in.readInt();
+ mConcurrentFeaturesSupport = new ArrayList<>();
+ for (int i = 0; i < length; i++) {
+ ArrayList<Long> feature = new ArrayList<>();
+ in.readList(feature, Long.class.getClassLoader());
+ mConcurrentFeaturesSupport.add(feature);
+ }
}
- @Override
- public String toString() {
- return "maxActiveVoiceCalls=" + maxActiveVoiceCalls + " maxActiveData=" + maxActiveData
- + " max5G=" + max5G + "logicalModemList:"
- + Arrays.toString(logicalModemList.toArray());
+ /**
+ * 3GPP UE category for a given Radio Access Network and direction.
+ *
+ * References are:
+ * TS 25.306 Table 4.1a EUTRAN downlink
+ * TS 25.306 Table 5.1a-2 EUTRAN uplink
+ * TS 25.306 Table 5.1a UTRAN downlink
+ * TS 25.306 Table 5.1g UTRAN uplink
+ *
+ * @param uplink true for uplink direction and false for downlink direction.
+ * @param accessNetworkType accessNetworkType, defined in {@link AccessNetworkType}.
+ * @return the UE category, or -1 if it is not supported.
+ */
+ public int getUeCategory(boolean uplink, @RadioAccessNetworkType int accessNetworkType) {
+ if (uplink) {
+ switch (accessNetworkType) {
+ case AccessNetworkType.UTRAN: return mUtranUeCategoryUl;
+ case AccessNetworkType.EUTRAN: return mEutranUeCategoryUl;
+ default: return -1;
+ }
+ } else {
+ switch (accessNetworkType) {
+ case AccessNetworkType.UTRAN: return mUtranUeCategoryDl;
+ case AccessNetworkType.EUTRAN: return mEutranUeCategoryDl;
+ default: return -1;
+ }
+ }
}
- private PhoneCapability(Parcel in) {
- maxActiveVoiceCalls = in.readInt();
- maxActiveData = in.readInt();
- max5G = in.readInt();
- validationBeforeSwitchSupported = in.readBoolean();
- logicalModemList = new ArrayList<>();
- in.readList(logicalModemList, ModemInfo.class.getClassLoader());
+ /**
+ * In cellular devices that support a greater number of logical modems than
+ * Internet connections, some devices support a grace period to allow a smooth "handover"
+ * between those connections. If that feature is supported, then this API will provide
+ * the length of that grace period in milliseconds. If it is not supported, the default value
+ * for the grace period is 0.
+ * @return handover linger time in milliseconds, or 0 if it is not supported.
+ */
+ public long getPsDataConnectionLingerTimeMillis() {
+ return mPsDataConnectionLingerTimeMillis;
+ }
+
+ /**
+ * The radio access technologies this device is capable of supporting.
+ * @return a bitfield of all supported network types, defined in {@link TelephonyManager}
+ */
+ public @NetworkTypeBitMask long getSupportedRats() {
+ return mSupportedRats;
+ }
+
+ /**
+ * List of supported cellular bands for the given accessNetworkType.
+ * @param accessNetworkType accessNetworkType, defined in {@link AccessNetworkType}.
+ * @return a list of bands, or an empty list if the access network type is unsupported.
+ */
+ public @NonNull List<Integer> getBands(@RadioAccessNetworkType int accessNetworkType) {
+ switch (accessNetworkType) {
+ case AccessNetworkType.GERAN: return mGeranBands;
+ case AccessNetworkType.UTRAN: return mUtranBands;
+ case AccessNetworkType.EUTRAN: return mEutranBands;
+ case AccessNetworkType.NGRAN: return mNgranBands;
+ default: return new ArrayList<>();
+ }
+ }
+
+ /**
+ * List of logical modem UUIDs, each typically "com.xxxx.lmX", where X is the logical modem ID.
+ * @return a list of modem UUIDs, one for every logical modem the device has.
+ */
+ public @NonNull List<String> getLogicalModemUuids() {
+ return mLogicalModemUuids;
+ }
+
+ /**
+ * List of {@link SimSlotCapability} for the device. The order of SIMs corresponds to the
+ * order of modems in {@link #getLogicalModemUuids}.
+ * @return a list of SIM slot capabilities, one for every SIM slot the device has.
+ */
+ public @NonNull List<SimSlotCapability> getSimSlotCapabilities() {
+ return mSimSlotCapabilities;
+ }
+
+ /**
+ * A List of Lists of concurrently supportable modem feature sets.
+ *
+ * Each entry in the top-level list is an independent configuration across all modems
+ * that describes the capabilities of the device as a whole.
+ *
+ * Each entry in the second-level list is a bitfield of ModemFeatures that describes
+ * the capabilities for a single modem. In the second-level list, the order of the modems
+ * corresponds to order of the UUIDs in {@link #getLogicalModemUuids}.
+ *
+ * For symmetric capabilities that can only be active on one modem at a time, there will be
+ * multiple configurations (equal to the number of modems) that shows it active on each modem.
+ * For asymmetric capabilities that are only available on one of the modems, all configurations
+ * will have that capability on just that one modem.
+ *
+ * The example below shows the concurrentFeaturesSupport for a 3-modem device with
+ * theoretical capabilities SYMMETRIC (available on all modems, but only one at a time) and
+ * ASYMMETRIC (only available on the first modem):
+ * {
+ * Configuration 1: ASYMMETRIC and SYMMETRIC on modem 1, modem 2 empty, modem 3 empty
+ * {(ASYMMETRIC | SYMMETRIC), (), ()},
+ *
+ * Configuration 2: ASYMMETRIC on modem 1, SYMMETRIC on modem 2, modem 3 empty
+ * {(ASYMMETRIC), (SYMMETRIC), ()},
+ *
+ * Configuration 3: ASYMMETRIC on modem 1, modem 2 empty, SYMMETRIC on modem 3
+ * {(ASYMMETRIC), (), (SYMMETRIC)}
+ * }
+ *
+ * @return List of all concurrently supportable modem features.
+ */
+ public @NonNull @ModemFeature List<List<Long>> getConcurrentFeaturesSupport() {
+ return mConcurrentFeaturesSupport;
+ }
+
+ /**
+ * How many modems can simultaneously have PS attached.
+ * @return maximum number of active PS voice connections.
+ */
+ public int getMaxActivePsVoice() {
+ return countFeature(MODEM_FEATURE_PS_VOICE_REG);
+ }
+
+ /**
+ * How many modems can simultaneously support active data connections.
+ * For DSDS, this will be 1, and for DSDA this will be 2.
+ * @return maximum number of active Internet data sessions.
+ */
+ public int getMaxActiveInternetData() {
+ return countFeature(MODEM_FEATURE_INTERACTIVE_DATA_SESSION);
+ }
+
+ /**
+ * How many modems can simultaneously have dedicated bearer capability.
+ * @return maximum number of active dedicated bearers.
+ */
+ public int getMaxActiveDedicatedBearers() {
+ return countFeature(MODEM_FEATURE_DEDICATED_BEARER);
+ }
+
+ /**
+ * Whether the CBRS band 48 is supported or not.
+ * @return true if any RadioAccessNetwork supports CBRS and false if none do.
+ * @hide
+ */
+ public boolean isCbrsSupported() {
+ return mEutranBands.contains(AccessNetworkConstants.EutranBand.BAND_48)
+ || mNgranBands.contains(AccessNetworkConstants.NgranBands.BAND_48);
+ }
+
+ private int countFeature(@ModemFeature long feature) {
+ int count = 0;
+ for (long featureSet : mConcurrentFeaturesSupport.get(0)) {
+ if ((featureSet & feature) != 0) {
+ count++;
+ }
+ }
+ return count;
+ }
+
+ @Override
+ public String toString() {
+ return "utranUeCategoryDl=" + mUtranUeCategoryDl
+ + " utranUeCategoryUl=" + mUtranUeCategoryUl
+ + " eutranUeCategoryDl=" + mEutranUeCategoryDl
+ + " eutranUeCategoryUl=" + mEutranUeCategoryUl
+ + " psDataConnectionLingerTimeMillis=" + mPsDataConnectionLingerTimeMillis
+ + " supportedRats=" + mSupportedRats + " geranBands=" + mGeranBands
+ + " utranBands=" + mUtranBands + " eutranBands=" + mEutranBands
+ + " ngranBands=" + mNgranBands + " logicalModemUuids=" + mLogicalModemUuids
+ + " simSlotCapabilities=" + mSimSlotCapabilities
+ + " concurrentFeaturesSupport=" + mConcurrentFeaturesSupport;
}
@Override
public int hashCode() {
- return Objects.hash(maxActiveVoiceCalls, maxActiveData, max5G, logicalModemList,
- validationBeforeSwitchSupported);
+ return Objects.hash(mUtranUeCategoryDl, mUtranUeCategoryUl, mEutranUeCategoryDl,
+ mEutranUeCategoryUl, mPsDataConnectionLingerTimeMillis, mSupportedRats, mGeranBands,
+ mUtranBands, mEutranBands, mNgranBands, mLogicalModemUuids, mSimSlotCapabilities,
+ mConcurrentFeaturesSupport);
}
@Override
@@ -107,11 +411,19 @@ public final class PhoneCapability implements Parcelable {
PhoneCapability s = (PhoneCapability) o;
- return (maxActiveVoiceCalls == s.maxActiveVoiceCalls
- && maxActiveData == s.maxActiveData
- && max5G == s.max5G
- && validationBeforeSwitchSupported == s.validationBeforeSwitchSupported
- && logicalModemList.equals(s.logicalModemList));
+ return (mUtranUeCategoryDl == s.mUtranUeCategoryDl
+ && mUtranUeCategoryUl == s.mUtranUeCategoryUl
+ && mEutranUeCategoryDl == s.mEutranUeCategoryDl
+ && mEutranUeCategoryUl == s.mEutranUeCategoryUl
+ && mPsDataConnectionLingerTimeMillis == s.mPsDataConnectionLingerTimeMillis
+ && mSupportedRats == s.mSupportedRats
+ && mGeranBands.equals(s.mGeranBands)
+ && mUtranBands.equals(s.mUtranBands)
+ && mEutranBands.equals(s.mEutranBands)
+ && mNgranBands.equals(s.mNgranBands)
+ && mLogicalModemUuids.equals(s.mLogicalModemUuids)
+ && mSimSlotCapabilities.equals(s.mSimSlotCapabilities)
+ && mConcurrentFeaturesSupport.equals(s.mConcurrentFeaturesSupport));
}
/**
@@ -125,20 +437,32 @@ public final class PhoneCapability implements Parcelable {
* {@link Parcelable#writeToParcel}
*/
public void writeToParcel(@NonNull Parcel dest, @Parcelable.WriteFlags int flags) {
- dest.writeInt(maxActiveVoiceCalls);
- dest.writeInt(maxActiveData);
- dest.writeInt(max5G);
- dest.writeBoolean(validationBeforeSwitchSupported);
- dest.writeList(logicalModemList);
+ dest.writeInt(mUtranUeCategoryDl);
+ dest.writeInt(mUtranUeCategoryUl);
+ dest.writeInt(mEutranUeCategoryDl);
+ dest.writeInt(mEutranUeCategoryUl);
+ dest.writeLong(mPsDataConnectionLingerTimeMillis);
+ dest.writeLong(mSupportedRats);
+ dest.writeList(mGeranBands);
+ dest.writeList(mUtranBands);
+ dest.writeList(mEutranBands);
+ dest.writeList(mNgranBands);
+ dest.writeStringList(mLogicalModemUuids);
+ dest.writeTypedList(mSimSlotCapabilities);
+ dest.writeInt(mConcurrentFeaturesSupport.size());
+ for (List<Long> feature : mConcurrentFeaturesSupport) {
+ dest.writeList(feature);
+ }
}
- public static final @android.annotation.NonNull Parcelable.Creator<PhoneCapability> CREATOR = new Parcelable.Creator() {
- public PhoneCapability createFromParcel(Parcel in) {
- return new PhoneCapability(in);
- }
+ public static final @NonNull Parcelable.Creator<PhoneCapability> CREATOR =
+ new Parcelable.Creator() {
+ public PhoneCapability createFromParcel(Parcel in) {
+ return new PhoneCapability(in);
+ }
- public PhoneCapability[] newArray(int size) {
- return new PhoneCapability[size];
- }
- };
+ public PhoneCapability[] newArray(int size) {
+ return new PhoneCapability[size];
+ }
+ };
}
diff --git a/telephony/java/android/telephony/PhoneNumberUtils.java b/telephony/java/android/telephony/PhoneNumberUtils.java
index 2f9e6ac0f9ff..0074772a221d 100644
--- a/telephony/java/android/telephony/PhoneNumberUtils.java
+++ b/telephony/java/android/telephony/PhoneNumberUtils.java
@@ -28,7 +28,6 @@ import android.content.Context;
import android.content.Intent;
import android.content.res.Resources;
import android.database.Cursor;
-import android.location.CountryDetector;
import android.net.Uri;
import android.os.PersistableBundle;
import android.provider.Contacts;
@@ -2032,6 +2031,7 @@ public class PhoneNumberUtils {
private static boolean isEmergencyNumberInternal(int subId, String number,
String defaultCountryIso,
boolean useExactMatch) {
+ // TODO: clean up all the callers that pass in a defaultCountryIso, since it's ignored now.
try {
if (useExactMatch) {
return TelephonyManager.getDefault().isEmergencyNumber(number);
@@ -2193,18 +2193,7 @@ public class PhoneNumberUtils {
private static boolean isLocalEmergencyNumberInternal(int subId, String number,
Context context,
boolean useExactMatch) {
- String countryIso;
- CountryDetector detector = (CountryDetector) context.getSystemService(
- Context.COUNTRY_DETECTOR);
- if (detector != null && detector.detectCountry() != null) {
- countryIso = detector.detectCountry().getCountryIso();
- } else {
- Locale locale = context.getResources().getConfiguration().locale;
- countryIso = locale.getCountry();
- Rlog.w(LOG_TAG, "No CountryDetector; falling back to countryIso based on locale: "
- + countryIso);
- }
- return isEmergencyNumberInternal(subId, number, countryIso, useExactMatch);
+ return isEmergencyNumberInternal(subId, number, null /* unused */, useExactMatch);
}
/**
diff --git a/telephony/java/android/telephony/SimSlotCapability.java b/telephony/java/android/telephony/SimSlotCapability.java
new file mode 100644
index 000000000000..3d38d0429908
--- /dev/null
+++ b/telephony/java/android/telephony/SimSlotCapability.java
@@ -0,0 +1,130 @@
+/*
+ * Copyright (C) 2019 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 android.telephony;
+
+import android.annotation.IntDef;
+import android.annotation.NonNull;
+import android.os.Parcel;
+import android.os.Parcelable;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.util.Objects;
+
+/**
+ * Capabilities for a SIM Slot.
+ */
+public final class SimSlotCapability implements Parcelable {
+ /** Slot type for UICC (removable SIM). */
+ public static final int SLOT_TYPE_UICC = 1;
+ /** Slot type for iUICC/iSIM (integrated SIM). */
+ public static final int SLOT_TYPE_IUICC = 2;
+ /** Slot type for eUICC/eSIM (embedded SIM). */
+ public static final int SLOT_TYPE_EUICC = 3;
+ /** Slot type for soft SIM (no physical SIM). */
+ public static final int SLOT_TYPE_SOFT_SIM = 4;
+
+ /** @hide */
+ @IntDef(prefix = {"SLOT_TYPE_" }, value = {
+ SLOT_TYPE_UICC,
+ SLOT_TYPE_IUICC,
+ SLOT_TYPE_EUICC,
+ SLOT_TYPE_SOFT_SIM,
+ })
+ @Retention(RetentionPolicy.SOURCE)
+ public @interface SlotType {
+ }
+
+ private final int mPhysicalSlotIndex;
+ private final int mSlotType;
+
+ /** @hide */
+ public SimSlotCapability(int physicalSlotId, int slotType) {
+ this.mPhysicalSlotIndex = physicalSlotId;
+ this.mSlotType = slotType;
+ }
+
+ private SimSlotCapability(Parcel in) {
+ mPhysicalSlotIndex = in.readInt();
+ mSlotType = in.readInt();
+ }
+
+ /**
+ * @return physical SIM slot index
+ */
+ public int getPhysicalSlotIndex() {
+ return mPhysicalSlotIndex;
+ }
+
+ /**
+ * @return type of SIM {@link SlotType}
+ */
+ public @SlotType int getSlotType() {
+ return mSlotType;
+ }
+
+ @Override
+ public String toString() {
+ return "mPhysicalSlotIndex=" + mPhysicalSlotIndex + " slotType=" + mSlotType;
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(mPhysicalSlotIndex, mSlotType);
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (o == null || !(o instanceof SimSlotCapability) || hashCode() != o.hashCode()) {
+ return false;
+ }
+
+ if (this == o) {
+ return true;
+ }
+
+ SimSlotCapability s = (SimSlotCapability) o;
+
+ return (mPhysicalSlotIndex == s.mPhysicalSlotIndex && mSlotType == s.mSlotType);
+ }
+
+ /**
+ * {@link Parcelable#describeContents}
+ */
+ public @ContentsFlags int describeContents() {
+ return 0;
+ }
+
+ /**
+ * {@link Parcelable#writeToParcel}
+ */
+ public void writeToParcel(@NonNull Parcel dest, @WriteFlags int flags) {
+ dest.writeInt(mPhysicalSlotIndex);
+ dest.writeInt(mSlotType);
+ }
+
+ public static final @NonNull Parcelable.Creator<SimSlotCapability> CREATOR =
+ new Parcelable.Creator() {
+ public SimSlotCapability createFromParcel(Parcel in) {
+ return new SimSlotCapability(in);
+ }
+
+ public SimSlotCapability[] newArray(int size) {
+ return new SimSlotCapability[size];
+ }
+ };
+}
diff --git a/telephony/java/android/telephony/TelephonyManager.java b/telephony/java/android/telephony/TelephonyManager.java
index 7e25d70da91b..075b56b72c19 100644
--- a/telephony/java/android/telephony/TelephonyManager.java
+++ b/telephony/java/android/telephony/TelephonyManager.java
@@ -94,6 +94,7 @@ import android.util.Pair;
import com.android.ims.internal.IImsServiceFeatureCallback;
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.telephony.CellNetworkScanResult;
+import com.android.internal.telephony.IBooleanConsumer;
import com.android.internal.telephony.INumberVerificationCallback;
import com.android.internal.telephony.IOns;
import com.android.internal.telephony.IPhoneSubInfo;
@@ -193,11 +194,8 @@ public class TelephonyManager {
NETWORK_SELECTION_MODE_MANUAL})
public @interface NetworkSelectionMode {}
- /** @hide */
public static final int NETWORK_SELECTION_MODE_UNKNOWN = 0;
- /** @hide */
public static final int NETWORK_SELECTION_MODE_AUTO = 1;
- /** @hide */
public static final int NETWORK_SELECTION_MODE_MANUAL = 2;
/** The otaspMode passed to PhoneStateListener#onOtaspChanged */
@@ -1786,6 +1784,24 @@ public class TelephonyManager {
//
/**
+ * Returns the {@link PhoneCapability} for the device or null if it is not available.
+ * <p>
+ * Requires Permission: READ_PHONE_STATE or that the calling app has
+ * carrier privileges (see {@link #hasCarrierPrivileges}).
+ */
+ @RequiresPermission(android.Manifest.permission.READ_PHONE_STATE)
+ @Nullable
+ public PhoneCapability getPhoneCapability() {
+ try {
+ ITelephony telephony = getITelephony();
+ return telephony == null ? null :
+ telephony.getPhoneCapability(getSubId(), getOpPackageName(), getFeatureId());
+ } catch (RemoteException ex) {
+ return null;
+ }
+ }
+
+ /**
* Returns the software version number for the device, for example,
* the IMEI/SV for GSM phones. Return null if the software version is
* not available.
@@ -7951,14 +7967,18 @@ public class TelephonyManager {
*
* <p>If this object has been created with {@link #createForSubscriptionId}, applies to the
* given subId. Otherwise, applies to {@link SubscriptionManager#getDefaultSubscriptionId()}
-
- * @return the network selection mode.
+ * <p>Requires Permission: {@link android.Manifest.permission#READ_PRECISE_PHONE_STATE
+ * READ_PRECISE_PHONE_STATE}
+ * or that the calling app has carrier privileges (see {@link #hasCarrierPrivileges}).
*
- * @hide
+ * @return the network selection mode.
*/
- @NetworkSelectionMode
- @RequiresPermission(android.Manifest.permission.READ_PHONE_STATE)
- public int getNetworkSelectionMode() {
+ @SuppressAutoDoc // No support for carrier privileges (b/72967236).
+ @RequiresPermission(anyOf = {
+ android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE,
+ android.Manifest.permission.READ_PRECISE_PHONE_STATE
+ })
+ public @NetworkSelectionMode int getNetworkSelectionMode() {
int mode = NETWORK_SELECTION_MODE_UNKNOWN;
try {
ITelephony telephony = getITelephony();
@@ -12525,6 +12545,51 @@ public class TelephonyManager {
}
/**
+ * Specify which bands modem's background scan must act on.
+ * If {@code specifiers} is non-empty, the scan will be restricted to the bands specified.
+ * Otherwise, it scans all bands.
+ *
+ * For example, CBRS is only on LTE band 48. By specifying this band,
+ * modem saves more power.
+ *
+ * @param specifiers which bands to scan.
+ * @param executor The executor to execute the callback on
+ * @param callback The callback that gets invoked when the radio responds to the request. Called
+ * with {@code true} if the request succeeded, {@code false} otherwise.
+ * @hide
+ */
+ @SystemApi
+ @TestApi
+ @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE)
+ public void setSystemSelectionChannels(@NonNull List<RadioAccessSpecifier> specifiers,
+ @Nullable @CallbackExecutor Executor executor,
+ @Nullable Consumer<Boolean> callback) {
+ Objects.requireNonNull(specifiers, "Specifiers must not be null.");
+ if (callback != null) {
+ Objects.requireNonNull(executor, "Executor must not be null when"
+ + " the callback is nonnull");
+ }
+
+ IBooleanConsumer aidlConsumer = callback == null ? null : new IBooleanConsumer.Stub() {
+ @Override
+ public void accept(boolean result) {
+ executor.execute(() -> callback.accept(result));
+ }
+ };
+
+ try {
+ ITelephony service = getITelephony();
+ if (service != null) {
+ service.setSystemSelectionChannels(specifiers, getSubId(), aidlConsumer);
+ }
+ } catch (RemoteException ex) {
+ if (!isSystemProcess()) {
+ ex.rethrowAsRuntimeException();
+ }
+ }
+ }
+
+ /**
* Verifies whether the input MCC/MNC and MVNO correspond to the current carrier.
*
* @param mccmnc the carrier's mccmnc that you want to match
diff --git a/telephony/java/android/telephony/ims/ProvisioningManager.java b/telephony/java/android/telephony/ims/ProvisioningManager.java
index 8c11df41cf64..037084608d26 100644
--- a/telephony/java/android/telephony/ims/ProvisioningManager.java
+++ b/telephony/java/android/telephony/ims/ProvisioningManager.java
@@ -101,6 +101,101 @@ public class ProvisioningManager {
// Inheriting values from ImsConfig for backwards compatibility.
/**
+ * AMR CODEC Mode Value set, 0-7 in comma separated sequence.
+ * <p>
+ * This corresponds to the {@code mode-set} parameter for the AMR codec.
+ * See 3GPP TS 26.101 Table 1A for more information.
+ * <p>
+ * <UL>
+ * <LI>0 - AMR 4.75 kbit/s</LI>
+ * <LI>1 - AMR 5.15 kbit/s</LI>
+ * <LI>2 - AMR 5.90 kbit/s</LI>
+ * <LI>3 - AMR 6.70 kbit/s (PDC-EFR)</LI>
+ * <LI>4 - AMR 7.40 kbit/s (TDMA-EFR)</LI>
+ * <LI>5 - AMR 7.95 kbit/s</LI>
+ * <LI>6 - AMR 10.2 kbit/s</LI>
+ * <LI>7 - AMR 12.2 kbit/s (GSM-EFR)</LI>
+ * </UL>
+ * <p>
+ * Value is in String format.
+ * @see #setProvisioningIntValue(int, int)
+ * @see #getProvisioningIntValue(int)
+ */
+ public static final int KEY_AMR_CODEC_MODE_SET_VALUES = 0;
+
+ /**
+ * Wide Band AMR CODEC Mode Value set,0-7 in comma separated sequence.
+ * <p>
+ * This corresponds to the {@code mode-set} parameter for the AMR wideband codec.
+ * See 3GPP TS 26.101 Table 1A for more information.
+ * <p>
+ * <UL>
+ * <LI>0 - AMR 4.75 kbit/s</LI>
+ * <LI>1 - AMR 5.15 kbit/s</LI>
+ * <LI>2 - AMR 5.90 kbit/s</LI>
+ * <LI>3 - AMR 6.70 kbit/s (PDC-EFR)</LI>
+ * <LI>4 - AMR 7.40 kbit/s (TDMA-EFR)</LI>
+ * <LI>5 - AMR 7.95 kbit/s</LI>
+ * <LI>6 - AMR 10.2 kbit/s</LI>
+ * <LI>7 - AMR 12.2 kbit/s (GSM-EFR)</LI>
+ * </UL>
+ * <p>
+ * Value is in String format.
+ * @see #setProvisioningStringValue(int, String)
+ * @see #getProvisioningStringValue(int)
+ */
+ public static final int KEY_AMR_WB_CODEC_MODE_SET_VALUES = 1;
+
+ /**
+ * SIP Session Timer value (seconds).
+ * <p>
+ * See RFC4028 for more information.
+ * <p>
+ * Value is in Integer format.
+ * @see #setProvisioningIntValue(int, int)
+ * @see #getProvisioningIntValue(int)
+ */
+ public static final int KEY_SIP_SESSION_TIMER_SEC = 2;
+
+ /**
+ * Minimum SIP Session Expiration Timer in (seconds).
+ * <p>
+ * See RFC4028 for more information.
+ * <p>
+ * Value is in Integer format.
+ * @see #setProvisioningIntValue(int, int)
+ * @see #getProvisioningIntValue(int)
+ */
+ public static final int KEY_MINIMUM_SIP_SESSION_EXPIRATION_TIMER_SEC = 3;
+
+ /**
+ * SIP_INVITE cancellation time out value (in milliseconds). Integer format.
+ * <p>
+ * See RFC4028 for more information.
+ * <p>
+ * Value is in Integer format.
+ * @see #setProvisioningIntValue(int, int)
+ * @see #getProvisioningIntValue(int)
+ */
+ public static final int KEY_SIP_INVITE_CANCELLATION_TIMER_MS = 4;
+
+ /**
+ * Delay time when an iRAT transitions from eHRPD/HRPD/1xRTT to LTE.
+ * Value is in Integer format.
+ * @see #setProvisioningIntValue(int, int)
+ * @see #getProvisioningIntValue(int)
+ */
+ public static final int KEY_TRANSITION_TO_LTE_DELAY_MS = 5;
+
+ /**
+ * Silent redial status of Enabled (True), or Disabled (False).
+ * Value is in boolean format.
+ * @see #setProvisioningIntValue(int, int)
+ * @see #getProvisioningIntValue(int)
+ */
+ public static final int KEY_ENABLE_SILENT_REDIAL = 6;
+
+ /**
* An integer key representing the SIP T1 timer value in milliseconds for the associated
* subscription.
* <p>
@@ -116,6 +211,28 @@ public class ProvisioningManager {
public static final int KEY_T1_TIMER_VALUE_MS = 7;
/**
+ * SIP T2 timer value in milliseconds. See RFC 3261 for information.
+ * <p>
+ * The T2 timer is the maximum retransmit interval for non-INVITE requests and INVITE responses.
+ * <p>
+ * Value is in Integer format.
+ * @see #setProvisioningIntValue(int, int)
+ * @see #getProvisioningIntValue(int)
+ */
+ public static final int KEY_T2_TIMER_VALUE_MS = 8;
+
+ /**
+ * SIP TF timer value in milliseconds. See RFC 3261 for information.
+ * <p>
+ * The TF timer is the non-INVITE transaction timeout timer.
+ * <p>
+ * Value is in Integer format.
+ * @see #setProvisioningIntValue(int, int)
+ * @see #getProvisioningIntValue(int)
+ */
+ public static final int KEY_TF_TIMER_VALUE_MS = 9;
+
+ /**
* An integer key representing the voice over LTE (VoLTE) provisioning status for the
* associated subscription. Determines whether the user can register for voice services over
* LTE.
@@ -140,6 +257,43 @@ public class ProvisioningManager {
public static final int KEY_VT_PROVISIONING_STATUS = 11;
/**
+ * Domain Name for the device to populate the request URI for REGISTRATION.
+ * Value is in String format.
+ * @see #setProvisioningStringValue(int, String)
+ * @see #getProvisioningStringValue(int)
+ */
+ public static final int KEY_REGISTRATION_DOMAIN_NAME = 12;
+
+ /**
+ * Device Outgoing SMS based on either 3GPP or 3GPP2 standards.
+ * Value is in Integer format.
+ * Valid values are {@link #SMS_FORMAT_3GPP} and {@link #SMS_FORMAT_3GPP2}.
+ * @see #setProvisioningIntValue(int, int)
+ * @see #getProvisioningIntValue(int)
+ */
+ public static final int KEY_SMS_FORMAT = 13;
+
+ /**
+ * Value used with {@link #KEY_SMS_FORMAT} to indicate 3GPP2 SMS format is used.
+ * See {@link android.telephony.SmsMessage#FORMAT_3GPP2} for more information.
+ */
+ public static final int SMS_FORMAT_3GPP2 = 0;
+
+ /**
+ * Value used with {@link #KEY_SMS_FORMAT} to indicate 3GPP SMS format is used.
+ * See {@link android.telephony.SmsMessage#FORMAT_3GPP} for more information.
+ */
+ public static final int SMS_FORMAT_3GPP = 1;
+
+ /**
+ * Turns SMS over IMS ON/OFF on the device.
+ * Value is in Integer format. ON (1), OFF(0).
+ * @see #setProvisioningIntValue(int, int)
+ * @see #getProvisioningIntValue(int)
+ */
+ public static final int KEY_SMS_OVER_IP_ENABLED = 14;
+
+ /**
* An integer key associated with the carrier configured SIP PUBLISH timer, which dictates the
* expiration time in seconds for published online availability in RCS presence.
* <p>
@@ -222,7 +376,7 @@ public class ProvisioningManager {
public static final int KEY_RCS_MAX_NUM_ENTRIES_IN_RCL = 22;
/**
- * An integer associated with the expiration timer used duriing the SIP subscription of a
+ * An integer associated with the expiration timer used during the SIP subscription of a
* Request Contained List (RCL), which is used to retrieve the RCS capabilities of the contact
* book.
* <p>
@@ -233,6 +387,14 @@ public class ProvisioningManager {
public static final int KEY_RCS_CAPABILITY_POLL_LIST_SUB_EXP_SEC = 23;
/**
+ * Applies compression to LIST Subscription.
+ * Value is in Integer format. Enable (1), Disable(0).
+ * @see #setProvisioningIntValue(int, int)
+ * @see #getProvisioningIntValue(int)
+ */
+ public static final int KEY_USE_GZIP_FOR_LIST_SUBSCRIPTION = 24;
+
+ /**
* An integer key representing the RCS enhanced address book (EAB) provisioning status for the
* associated subscription. Determines whether or not SIP OPTIONS or presence will be used to
* retrieve RCS capabilities for the user's contacts.
@@ -270,6 +432,349 @@ public class ProvisioningManager {
public static final int KEY_VOICE_OVER_WIFI_MODE_OVERRIDE = 27;
/**
+ * Enable voice over wifi. Enabled (1), or Disabled (0).
+ * Value is in Integer format.
+ * @see #setProvisioningIntValue(int, int)
+ * @see #getProvisioningIntValue(int)
+ */
+ public static final int KEY_VOICE_OVER_WIFI_ENABLED_OVERRIDE = 28;
+
+ /**
+ * Mobile data enabled.
+ * Value is in Integer format. On (1), OFF(0).
+ * @see #setProvisioningIntValue(int, int)
+ * @see #getProvisioningIntValue(int)
+ */
+ public static final int KEY_MOBILE_DATA_ENABLED = 29;
+
+ /**
+ * VoLTE user opted in status.
+ * Value is in Integer format. Opted-in (1) Opted-out (0).
+ * @see #setProvisioningIntValue(int, int)
+ * @see #getProvisioningIntValue(int)
+ */
+ public static final int KEY_VOLTE_USER_OPT_IN_STATUS = 30;
+
+ /**
+ * Proxy for Call Session Control Function(P-CSCF) address for Local-BreakOut(LBO).
+ * Value is in String format.
+ */
+ public static final int KEY_LOCAL_BREAKOUT_PCSCF_ADDRESS = 31;
+
+ /**
+ * Keep Alive Enabled for SIP.
+ * Value is in Integer format.
+ * @see #setProvisioningIntValue(int, int)
+ * @see #getProvisioningIntValue(int)
+ */
+ public static final int KEY_SIP_KEEP_ALIVE_ENABLED = 32;
+
+ /**
+ * Registration retry Base Time value in seconds.
+ * Value is in Integer format.
+ * @see #setProvisioningIntValue(int, int)
+ * @see #getProvisioningIntValue(int)
+ */
+ public static final int KEY_REGISTRATION_RETRY_BASE_TIME_SEC = 33;
+
+ /**
+ * Registration retry Max Time value in seconds.
+ * Value is in Integer format.
+ * @see #setProvisioningIntValue(int, int)
+ * @see #getProvisioningIntValue(int)
+ */
+ public static final int KEY_REGISTRATION_RETRY_MAX_TIME_SEC = 34;
+
+ /**
+ * Smallest RTP port for speech codec.
+ * Value is in integer format.
+ * @see #setProvisioningIntValue(int, int)
+ * @see #getProvisioningIntValue(int)
+ */
+
+ public static final int KEY_RTP_SPEECH_START_PORT = 35;
+
+ /**
+ * Largest RTP port for speech code.
+ * Value is in Integer format.
+ * @see #setProvisioningIntValue(int, int)
+ * @see #getProvisioningIntValue(int)
+ */
+ public static final int KEY_RTP_SPEECH_END_PORT = 36;
+
+ /**
+ * SIP Timer A's value in milliseconds. Timer A is the INVITE request retransmit interval (in
+ * milliseconds), for UDP only.
+ * Value is in Integer format.
+ * @see #setProvisioningIntValue(int, int)
+ * @see #getProvisioningIntValue(int)
+ */
+ public static final int KEY_SIP_INVITE_REQUEST_TRANSMIT_INTERVAL_MS = 37;
+
+ /**
+ * SIP Timer B's value in milliseconds. Timer B is the wait time for INVITE message to be,
+ * in milliseconds.
+ * Value is in Integer format.
+ * @see #setProvisioningIntValue(int, int)
+ * @see #getProvisioningIntValue(int)
+ */
+ public static final int KEY_SIP_INVITE_ACK_WAIT_TIME_MS = 38;
+
+ /**
+ * SIP Timer D's value in milliseconds. Timer D is the wait time for response retransmits of
+ * the invite client transactions, in milliseconds.
+ * Value is in Integer format.
+ * @see #setProvisioningIntValue(int, int)
+ * @see #getProvisioningIntValue(int)
+ */
+ public static final int KEY_SIP_INVITE_RESPONSE_RETRANSMIT_WAIT_TIME_MS = 39;
+
+ /**
+ * SIP Timer E's value in milliseconds. Timer E is the value Non-INVITE request retransmit
+ * interval (in milliseconds), for UDP only.
+ * Value is in Integer format.
+ * @see #setProvisioningIntValue(int, int)
+ * @see #getProvisioningIntValue(int)
+ */
+ public static final int KEY_SIP_NON_INVITE_REQUEST_RETRANSMIT_INTERVAL_MS = 40;
+
+ /**
+ * SIP Timer F's value in milliseconds. Timer F is the Non-INVITE transaction timeout timer,
+ * in milliseconds.
+ * Value is in Integer format.
+ * @see #setProvisioningIntValue(int, int)
+ * @see #getProvisioningIntValue(int)
+ */
+ public static final int KEY_SIP_NON_INVITE_TRANSACTION_TIMEOUT_TIMER_MS = 41;
+
+ /**
+ * SIP Timer G's value in milliseconds. Timer G is the value of INVITE response
+ * retransmit interval.
+ * Value is in Integer format.
+ * @see #setProvisioningIntValue(int, int)
+ * @see #getProvisioningIntValue(int)
+ */
+ public static final int KEY_SIP_INVITE_RESPONSE_RETRANSMIT_INTERVAL_MS = 42;
+
+ /**
+ * SIP Timer H's value in milliseconds. Timer H is the value of wait time for
+ * ACK receipt.
+ * Value is in Integer format.
+ * @see #setProvisioningIntValue(int, int)
+ * @see #getProvisioningIntValue(int)
+ */
+ public static final int KEY_SIP_ACK_RECEIPT_WAIT_TIME_MS = 43;
+
+ /**
+ * SIP Timer I's value in milliseconds. Timer I is the value of wait time for
+ * ACK retransmits.
+ * Value is in Integer format.
+ * @see #setProvisioningIntValue(int, int)
+ * @see #getProvisioningIntValue(int)
+ */
+ public static final int KEY_SIP_ACK_RETRANSMIT_WAIT_TIME_MS = 44;
+
+ /**
+ * SIP Timer J's value in milliseconds. Timer J is the value of wait time for
+ * non-invite request retransmission.
+ * Value is in Integer format.
+ * @see #setProvisioningIntValue(int, int)
+ * @see #getProvisioningIntValue(int)
+ */
+ public static final int KEY_SIP_NON_INVITE_REQUEST_RETRANSMISSION_WAIT_TIME_MS = 45;
+
+ /**
+ * SIP Timer K's value in milliseconds. Timer K is the value of wait time for
+ * non-invite response retransmits.
+ * Value is in Integer format.
+ * @see #setProvisioningIntValue(int, int)
+ * @see #getProvisioningIntValue(int)
+ */
+ public static final int KEY_SIP_NON_INVITE_RESPONSE_RETRANSMISSION_WAIT_TIME_MS = 46;
+
+ /**
+ * AMR WB octet aligned dynamic payload type.
+ * Value is in Integer format.
+ * @see #setProvisioningIntValue(int, int)
+ * @see #getProvisioningIntValue(int)
+ */
+ public static final int KEY_AMR_WB_OCTET_ALIGNED_PAYLOAD_TYPE = 47;
+
+ /**
+ * AMR WB bandwidth efficient payload type.
+ * Value is in Integer format.
+ * @see #setProvisioningIntValue(int, int)
+ * @see #getProvisioningIntValue(int)
+ */
+ public static final int KEY_AMR_WB_BANDWIDTH_EFFICIENT_PAYLOAD_TYPE = 48;
+
+ /**
+ * AMR octet aligned dynamic payload type.
+ * Value is in Integer format.
+ * @see #setProvisioningIntValue(int, int)
+ * @see #getProvisioningIntValue(int)
+ */
+ public static final int KEY_AMR_OCTET_ALIGNED_PAYLOAD_TYPE = 49;
+
+ /**
+ * AMR bandwidth efficient payload type.
+ * Value is in Integer format.
+ * @see #setProvisioningIntValue(int, int)
+ * @see #getProvisioningIntValue(int)
+ */
+ public static final int KEY_AMR_BANDWIDTH_EFFICIENT_PAYLOAD_TYPE = 50;
+
+ /**
+ * DTMF WB payload type.
+ * Value is in Integer format.
+ * @see #setProvisioningIntValue(int, int)
+ * @see #getProvisioningIntValue(int)
+ */
+ public static final int KEY_DTMF_WB_PAYLOAD_TYPE = 51;
+
+ /**
+ * DTMF NB payload type.
+ * Value is in Integer format.
+ * @see #setProvisioningIntValue(int, int)
+ * @see #getProvisioningIntValue(int)
+ */
+ public static final int KEY_DTMF_NB_PAYLOAD_TYPE = 52;
+
+ /**
+ * AMR Default encoding mode.
+ * Value is in Integer format.
+ * @see #setProvisioningIntValue(int, int)
+ * @see #getProvisioningIntValue(int)
+ */
+ public static final int KEY_AMR_DEFAULT_ENCODING_MODE = 53;
+
+ /**
+ * SMS Public Service Identity.
+ * Value is in String format.
+ */
+ public static final int KEY_SMS_PUBLIC_SERVICE_IDENTITY = 54;
+
+ /**
+ * Video Quality - VideoQualityFeatureValuesConstants.
+ * Valid values are: {@link #VIDEO_QUALITY_HIGH} and {@link #VIDEO_QUALITY_LOW}.
+ * Value is in Integer format.
+ * @see #setProvisioningIntValue(int, int)
+ * @see #getProvisioningIntValue(int)
+ */
+ public static final int KEY_VIDEO_QUALITY = 55;
+
+ /**
+ * Used with {@link #KEY_VIDEO_QUALITY} to indicate low video quality.
+ */
+ public static final int VIDEO_QUALITY_LOW = 0;
+
+ /**
+ * Used with {@link #KEY_VIDEO_QUALITY} to indicate high video quality.
+ */
+ public static final int VIDEO_QUALITY_HIGH = 1;
+
+ /**
+ * LTE to WIFI handover threshold.
+ * Handover from LTE to WiFi if LTE < THLTE1 and WiFi >= {@link #KEY_WIFI_THRESHOLD_A}.
+ * Value is in Integer format.
+ * @see #setProvisioningIntValue(int, int)
+ * @see #getProvisioningIntValue(int)
+ */
+ public static final int KEY_LTE_THRESHOLD_1 = 56;
+
+ /**
+ * WIFI to LTE handover threshold.
+ * Handover from WiFi to LTE if LTE >= {@link #KEY_LTE_THRESHOLD_3} or (WiFi < {@link
+ * #KEY_WIFI_THRESHOLD_B} and LTE >= {@link #KEY_LTE_THRESHOLD_2}).
+ * Value is in Integer format.
+ *
+ * @see #setProvisioningIntValue(int, int)
+ * @see #getProvisioningIntValue(int)
+ */
+ public static final int KEY_LTE_THRESHOLD_2 = 57;
+
+ /**
+ * LTE to WIFI handover threshold.
+ * Handover from WiFi to LTE if LTE >= {@link #KEY_LTE_THRESHOLD_3} or (WiFi < {@link
+ * #KEY_WIFI_THRESHOLD_B} and LTE >= {@link #KEY_LTE_THRESHOLD_2}).
+ * Value is in Integer format.
+ *
+ * @see #setProvisioningIntValue(int, int)
+ * @see #getProvisioningIntValue(int)
+ */
+ public static final int KEY_LTE_THRESHOLD_3 = 58;
+
+ /**
+ * 1x to WIFI handover threshold.
+ * Handover from 1x to WiFi if 1x < {@link #KEY_1X_THRESHOLD}.
+ * Value is in Integer format.
+ * @see #setProvisioningIntValue(int, int)
+ * @see #getProvisioningIntValue(int)
+ */
+ public static final int KEY_1X_THRESHOLD = 59;
+
+ /**
+ * LTE to WIFI threshold A.
+ * Handover from LTE to WiFi if LTE < {@link #KEY_LTE_THRESHOLD_1} and WiFi >= {@link
+ * #KEY_WIFI_THRESHOLD_A}.
+ * Value is in Integer format.
+ *
+ * @see #setProvisioningIntValue(int, int)
+ * @see #getProvisioningIntValue(int)
+ */
+ public static final int KEY_WIFI_THRESHOLD_A = 60;
+
+ /**
+ * WiFi to LTRE handover threshold B.
+ * Handover from WiFi to LTE if LTE >= {@link #KEY_LTE_THRESHOLD_3} or (WiFi <
+ * {@link #KEY_WIFI_THRESHOLD_B} and LTE >= {@link #KEY_LTE_THRESHOLD_2}).
+ * Value is in Integer format.
+ * @see #setProvisioningIntValue(int, int)
+ * @see #getProvisioningIntValue(int)
+ */
+ public static final int KEY_WIFI_THRESHOLD_B = 61;
+
+ /**
+ * LTE ePDG timer (in seconds).
+ * Device shall not handover back to LTE until the T_ePDG_LTE timer expires.
+ * Value is in Integer format.
+ * @see #setProvisioningIntValue(int, int)
+ * @see #getProvisioningIntValue(int)
+ */
+ public static final int KEY_LTE_EPDG_TIMER_SEC = 62;
+
+ /**
+ * WiFi ePDG timer (in seconds).
+ * Device shall not handover back to WiFi until the T_ePDG_WiFi timer expires.
+ * Value is in Integer format.
+ * @see #setProvisioningIntValue(int, int)
+ * @see #getProvisioningIntValue(int)
+ */
+ public static final int KEY_WIFI_EPDG_TIMER_SEC = 63;
+
+ /**
+ * 1x ePDG timer (in seconds).
+ * Device shall not re-register on 1x until the T_ePDG_1x timer expires.
+ */
+ public static final int KEY_1X_EPDG_TIMER_SEC = 64;
+
+ /**
+ * MultiEndpoint status: Enabled (1), or Disabled (0).
+ * Value is in Integer format.
+ * @see #setProvisioningIntValue(int, int)
+ * @see #getProvisioningIntValue(int)
+ */
+ public static final int KEY_MULTIENDPOINT_ENABLED = 65;
+
+ /**
+ * RTT status: Enabled (1), or Disabled (0).
+ * Value is in Integer format.
+ * @see #setProvisioningIntValue(int, int)
+ * @see #getProvisioningIntValue(int)
+ */
+ public static final int KEY_RTT_ENABLED = 66;
+
+ /**
* Callback for IMS provisioning changes.
*/
public static class Callback {
diff --git a/telephony/java/com/android/ims/ImsConfig.java b/telephony/java/com/android/ims/ImsConfig.java
index 0d86e2b7c2b1..0f6ce13a6ce4 100644
--- a/telephony/java/com/android/ims/ImsConfig.java
+++ b/telephony/java/com/android/ims/ImsConfig.java
@@ -135,374 +135,596 @@ public class ImsConfig {
/**
* AMR CODEC Mode Value set, 0-7 in comma separated sequence.
* Value is in String format.
+ * @deprecated use {@link ProvisioningManager#KEY_AMR_CODEC_MODE_SET_VALUES} instead.
*/
- public static final int VOCODER_AMRMODESET = CONFIG_START;
+ @Deprecated
+ public static final int VOCODER_AMRMODESET =
+ ProvisioningManager.KEY_AMR_CODEC_MODE_SET_VALUES;
/**
* Wide Band AMR CODEC Mode Value set,0-7 in comma separated sequence.
* Value is in String format.
+ * @deprecated use {@link ProvisioningManager#KEY_AMR_WB_CODEC_MODE_SET_VALUES} instead.
*/
- public static final int VOCODER_AMRWBMODESET = 1;
+ @Deprecated
+ public static final int VOCODER_AMRWBMODESET =
+ ProvisioningManager.KEY_AMR_WB_CODEC_MODE_SET_VALUES;
/**
* SIP Session Timer value (seconds).
* Value is in Integer format.
+ * @deprecated use {@link ProvisioningManager#KEY_SIP_SESSION_TIMER_SEC} instead.
*/
- public static final int SIP_SESSION_TIMER = 2;
+ @Deprecated
+ public static final int SIP_SESSION_TIMER = ProvisioningManager.KEY_SIP_SESSION_TIMER_SEC;
/**
* Minimum SIP Session Expiration Timer in (seconds).
* Value is in Integer format.
+ * @deprecated use
+ * {@link ProvisioningManager#KEY_MINIMUM_SIP_SESSION_EXPIRATION_TIMER_SEC} instead.
*/
- public static final int MIN_SE = 3;
+ @Deprecated
+ public static final int MIN_SE =
+ ProvisioningManager.KEY_MINIMUM_SIP_SESSION_EXPIRATION_TIMER_SEC;
/**
* SIP_INVITE cancellation time out value (in milliseconds). Integer format.
* Value is in Integer format.
+ * @deprecated use {@link ProvisioningManager#KEY_SIP_INVITE_CANCELLATION_TIMER_MS} instead.
*/
- public static final int CANCELLATION_TIMER = 4;
+ @Deprecated
+ public static final int CANCELLATION_TIMER =
+ ProvisioningManager.KEY_SIP_INVITE_CANCELLATION_TIMER_MS;
/**
* Delay time when an iRAT transition from eHRPD/HRPD/1xRTT to LTE.
* Value is in Integer format.
+ * @deprecated use {@link ProvisioningManager#KEY_TRANSITION_TO_LTE_DELAY_MS} instead.
*/
- public static final int TDELAY = 5;
+ @Deprecated
+ public static final int TDELAY = ProvisioningManager.KEY_TRANSITION_TO_LTE_DELAY_MS;
/**
* Silent redial status of Enabled (True), or Disabled (False).
* Value is in Integer format.
+ * @deprecated use {@link ProvisioningManager#KEY_ENABLE_SILENT_REDIAL} instead.
*/
- public static final int SILENT_REDIAL_ENABLE = 6;
+ @Deprecated
+ public static final int SILENT_REDIAL_ENABLE = ProvisioningManager.KEY_ENABLE_SILENT_REDIAL;
/**
* SIP T1 timer value in milliseconds. See RFC 3261 for define.
* Value is in Integer format.
+ * @deprecated use {@link ProvisioningManager#KEY_T1_TIMER_VALUE_MS} instead.
*/
+ @Deprecated
public static final int SIP_T1_TIMER = ProvisioningManager.KEY_T1_TIMER_VALUE_MS;
/**
* SIP T2 timer value in milliseconds. See RFC 3261 for define.
* Value is in Integer format.
+ * @deprecated use {@link ProvisioningManager#KEY_T2_TIMER_VALUE_MS} instead.
*/
- public static final int SIP_T2_TIMER = 8;
+ @Deprecated
+ public static final int SIP_T2_TIMER = ProvisioningManager.KEY_T2_TIMER_VALUE_MS;
- /**
+ /**
* SIP TF timer value in milliseconds. See RFC 3261 for define.
* Value is in Integer format.
+ * @deprecated use {@link ProvisioningManager#KEY_TF_TIMER_VALUE_MS} instead.
*/
- public static final int SIP_TF_TIMER = 9;
+ @Deprecated
+ public static final int SIP_TF_TIMER = ProvisioningManager.KEY_TF_TIMER_VALUE_MS;
/**
* VoLTE status for VLT/s status of Enabled (1), or Disabled (0).
* Value is in Integer format.
+ * @deprecated use {@link ProvisioningManager#KEY_VOLTE_PROVISIONING_STATUS} instead.
*/
+ @Deprecated
public static final int VLT_SETTING_ENABLED =
ProvisioningManager.KEY_VOLTE_PROVISIONING_STATUS;
/**
* VoLTE status for LVC/s status of Enabled (1), or Disabled (0).
* Value is in Integer format.
+ * @deprecated use {@link ProvisioningManager#KEY_VT_PROVISIONING_STATUS} instead.
*/
+ @Deprecated
public static final int LVC_SETTING_ENABLED =
ProvisioningManager.KEY_VT_PROVISIONING_STATUS;
+
/**
* Domain Name for the device to populate the request URI for REGISTRATION.
* Value is in String format.
+ * @deprecated use {@link ProvisioningManager#KEY_REGISTRATION_DOMAIN_NAME}.
*/
- public static final int DOMAIN_NAME = 12;
+ @Deprecated
+ public static final int DOMAIN_NAME = ProvisioningManager.KEY_REGISTRATION_DOMAIN_NAME;
+
/**
* Device Outgoing SMS based on either 3GPP or 3GPP2 standards.
* Value is in Integer format. 3GPP2(0), 3GPP(1)
- */
- public static final int SMS_FORMAT = 13;
+ * @deprecated use {@link ProvisioningManager#KEY_SMS_FORMAT}.
+ */
+ @Deprecated
+ public static final int SMS_FORMAT = ProvisioningManager.KEY_SMS_FORMAT;
+
/**
* Turns IMS ON/OFF on the device.
* Value is in Integer format. ON (1), OFF(0).
- */
- public static final int SMS_OVER_IP = 14;
+ * @deprecated use {@link ProvisioningManager#KEY_SMS_OVER_IP_ENABLED}.
+ */
+ @Deprecated
+ public static final int SMS_OVER_IP = ProvisioningManager.KEY_SMS_OVER_IP_ENABLED;
+
/**
* Requested expiration for Published Online availability.
* Value is in Integer format.
+ * @deprecated use {@link ProvisioningManager#KEY_RCS_PUBLISH_TIMER_SEC}.
*/
+ @Deprecated
public static final int PUBLISH_TIMER = ProvisioningManager.KEY_RCS_PUBLISH_TIMER_SEC;
+
/**
* Requested expiration for Published Offline availability.
* Value is in Integer format.
+ * @deprecated use {@link ProvisioningManager#KEY_RCS_PUBLISH_TIMER_EXTENDED_SEC}.
*/
+ @Deprecated
public static final int PUBLISH_TIMER_EXTENDED =
ProvisioningManager.KEY_RCS_PUBLISH_TIMER_EXTENDED_SEC;
+
/**
*
* Value is in Integer format.
+ * @deprecated use {@link ProvisioningManager#KEY_RCS_CAPABILITY_DISCOVERY_ENABLED}.
*/
+ @Deprecated
public static final int CAPABILITY_DISCOVERY_ENABLED =
ProvisioningManager.KEY_RCS_CAPABILITY_DISCOVERY_ENABLED;
+
/**
- * Period of time the capability information of the contact is cached on handset.
+ * Period of time the capability information of the contact is cached on handset.
* Value is in Integer format.
+ * @deprecated use {@link ProvisioningManager#KEY_RCS_CAPABILITIES_CACHE_EXPIRATION_SEC}.
*/
+ @Deprecated
public static final int CAPABILITIES_CACHE_EXPIRATION =
ProvisioningManager.KEY_RCS_CAPABILITIES_CACHE_EXPIRATION_SEC;
+
/**
* Peiod of time the availability information of a contact is cached on device.
* Value is in Integer format.
+ * @deprecated use {@link ProvisioningManager#KEY_RCS_AVAILABILITY_CACHE_EXPIRATION_SEC}.
*/
+ @Deprecated
public static final int AVAILABILITY_CACHE_EXPIRATION =
ProvisioningManager.KEY_RCS_AVAILABILITY_CACHE_EXPIRATION_SEC;
+
/**
* Interval between successive capabilities polling.
* Value is in Integer format.
+ * @deprecated use {@link ProvisioningManager#KEY_RCS_CAPABILITIES_POLL_INTERVAL_SEC}.
*/
+ @Deprecated
public static final int CAPABILITIES_POLL_INTERVAL =
ProvisioningManager.KEY_RCS_CAPABILITIES_POLL_INTERVAL_SEC;
+
/**
* Minimum time between two published messages from the device.
* Value is in Integer format.
+ * @deprecated use {@link ProvisioningManager#KEY_RCS_PUBLISH_SOURCE_THROTTLE_MS}.
*/
+ @Deprecated
public static final int SOURCE_THROTTLE_PUBLISH =
ProvisioningManager.KEY_RCS_PUBLISH_SOURCE_THROTTLE_MS;
+
/**
* The Maximum number of MDNs contained in one Request Contained List.
* Value is in Integer format.
+ * @deprecated use {@link ProvisioningManager#KEY_RCS_MAX_NUM_ENTRIES_IN_RCL}.
*/
+ @Deprecated
public static final int MAX_NUMENTRIES_IN_RCL =
ProvisioningManager.KEY_RCS_MAX_NUM_ENTRIES_IN_RCL;
+
/**
* Expiration timer for subscription of a Request Contained List, used in capability
* polling.
* Value is in Integer format.
+ * @deprecated use {@link ProvisioningManager#KEY_RCS_CAPABILITY_POLL_LIST_SUB_EXP_SEC}.
*/
+ @Deprecated
public static final int CAPAB_POLL_LIST_SUB_EXP =
ProvisioningManager.KEY_RCS_CAPABILITY_POLL_LIST_SUB_EXP_SEC;
+
/**
* Applies compression to LIST Subscription.
* Value is in Integer format. Enable (1), Disable(0).
+ * @deprecated use {@link ProvisioningManager#KEY_USE_GZIP_FOR_LIST_SUBSCRIPTION}.
*/
- public static final int GZIP_FLAG = 24;
+ @Deprecated
+ public static final int GZIP_FLAG = ProvisioningManager.KEY_USE_GZIP_FOR_LIST_SUBSCRIPTION;
+
/**
* VOLTE Status for EAB/s status of Enabled (1), or Disabled (0).
* Value is in Integer format.
+ * @deprecated use {@link ProvisioningManager#KEY_EAB_PROVISIONING_STATUS}.
*/
+ @Deprecated
public static final int EAB_SETTING_ENABLED =
ProvisioningManager.KEY_EAB_PROVISIONING_STATUS;
+
/**
* Wi-Fi calling roaming status.
* Value is in Integer format. ON (1), OFF(0).
+ * @deprecated use {@link ProvisioningManager#KEY_VOICE_OVER_WIFI_ROAMING_ENABLED_OVERRIDE}
+ * instead.
*/
+ @Deprecated
public static final int VOICE_OVER_WIFI_ROAMING =
ProvisioningManager.KEY_VOICE_OVER_WIFI_ROAMING_ENABLED_OVERRIDE;
+
/**
- * Wi-Fi calling modem - WfcModeFeatureValueConstants.
+ * Wi-Fi calling mode - WfcModeFeatureValueConstants.
* Value is in Integer format.
+ * @deprecated use {@link ProvisioningManager#KEY_VOICE_OVER_WIFI_MODE_OVERRIDE}
+ * instead.
*/
+ @Deprecated
public static final int VOICE_OVER_WIFI_MODE =
ProvisioningManager.KEY_VOICE_OVER_WIFI_MODE_OVERRIDE;
+
/**
* VOLTE Status for voice over wifi status of Enabled (1), or Disabled (0).
* Value is in Integer format.
+ * @deprecated use {@link ProvisioningManager#KEY_VOICE_OVER_WIFI_ENABLED_OVERRIDE}.
*/
- public static final int VOICE_OVER_WIFI_SETTING_ENABLED = 28;
+ @Deprecated
+ public static final int VOICE_OVER_WIFI_SETTING_ENABLED =
+ ProvisioningManager.KEY_VOICE_OVER_WIFI_ENABLED_OVERRIDE;
+
+
/**
* Mobile data enabled.
* Value is in Integer format. On (1), OFF(0).
+ * @deprecated use {@link ProvisioningManager#KEY_MOBILE_DATA_ENABLED}.
*/
- public static final int MOBILE_DATA_ENABLED = 29;
+ @Deprecated
+ public static final int MOBILE_DATA_ENABLED = ProvisioningManager.KEY_MOBILE_DATA_ENABLED;
+
/**
* VoLTE user opted in status.
* Value is in Integer format. Opted-in (1) Opted-out (0).
+ * @deprecated use {@link ProvisioningManager#KEY_VOLTE_USER_OPT_IN_STATUS}.
*/
- public static final int VOLTE_USER_OPT_IN_STATUS = 30;
+ @Deprecated
+ public static final int VOLTE_USER_OPT_IN_STATUS =
+ ProvisioningManager.KEY_VOLTE_USER_OPT_IN_STATUS;
+
/**
* Proxy for Call Session Control Function(P-CSCF) address for Local-BreakOut(LBO).
* Value is in String format.
+ * @deprecated use {@link ProvisioningManager#KEY_LOCAL_BREAKOUT_PCSCF_ADDRESS}.
*/
- public static final int LBO_PCSCF_ADDRESS = 31;
+ @Deprecated
+ public static final int LBO_PCSCF_ADDRESS =
+ ProvisioningManager.KEY_LOCAL_BREAKOUT_PCSCF_ADDRESS;
+
/**
* Keep Alive Enabled for SIP.
* Value is in Integer format. On(1), OFF(0).
+ * @deprecated use {@link ProvisioningManager#KEY_SIP_KEEP_ALIVE_ENABLED}.
*/
- public static final int KEEP_ALIVE_ENABLED = 32;
+ @Deprecated
+ public static final int KEEP_ALIVE_ENABLED = ProvisioningManager.KEY_SIP_KEEP_ALIVE_ENABLED;
+
/**
* Registration retry Base Time value in seconds.
* Value is in Integer format.
+ * @deprecated use {@link ProvisioningManager#KEY_REGISTRATION_RETRY_BASE_TIME_SEC}.
*/
- public static final int REGISTRATION_RETRY_BASE_TIME_SEC = 33;
+ @Deprecated
+ public static final int REGISTRATION_RETRY_BASE_TIME_SEC =
+ ProvisioningManager.KEY_REGISTRATION_RETRY_BASE_TIME_SEC;
+
/**
* Registration retry Max Time value in seconds.
* Value is in Integer format.
+ * @deprecated use {@link ProvisioningManager#KEY_REGISTRATION_RETRY_MAX_TIME_SEC}.
*/
- public static final int REGISTRATION_RETRY_MAX_TIME_SEC = 34;
+ @Deprecated
+ public static final int REGISTRATION_RETRY_MAX_TIME_SEC =
+ ProvisioningManager.KEY_REGISTRATION_RETRY_MAX_TIME_SEC;
+
/**
* Smallest RTP port for speech codec.
* Value is in integer format.
+ * @deprecated use {@link ProvisioningManager#KEY_RTP_SPEECH_START_PORT}.
*/
- public static final int SPEECH_START_PORT = 35;
+ @Deprecated
+ public static final int SPEECH_START_PORT = ProvisioningManager.KEY_RTP_SPEECH_START_PORT;
+
/**
* Largest RTP port for speech code.
* Value is in Integer format.
+ * @deprecated use {@link ProvisioningManager#KEY_RTP_SPEECH_END_PORT}.
*/
- public static final int SPEECH_END_PORT = 36;
+ @Deprecated
+ public static final int SPEECH_END_PORT = ProvisioningManager.KEY_RTP_SPEECH_END_PORT;
+
/**
* SIP Timer A's value in milliseconds. Timer A is the INVITE request
* retransmit interval, for UDP only.
* Value is in Integer format.
+ * @deprecated use {@link ProvisioningManager#KEY_SIP_INVITE_REQUEST_TRANSMIT_INTERVAL_MS}.
*/
- public static final int SIP_INVITE_REQ_RETX_INTERVAL_MSEC = 37;
+ @Deprecated
+ public static final int SIP_INVITE_REQ_RETX_INTERVAL_MSEC =
+ ProvisioningManager.KEY_SIP_INVITE_REQUEST_TRANSMIT_INTERVAL_MS;
+
/**
* SIP Timer B's value in milliseconds. Timer B is the wait time for
* INVITE message to be acknowledged.
* Value is in Integer format.
+ * @deprecated use {@link ProvisioningManager#KEY_SIP_INVITE_ACK_WAIT_TIME_MS}.
*/
- public static final int SIP_INVITE_RSP_WAIT_TIME_MSEC = 38;
+ @Deprecated
+ public static final int SIP_INVITE_RSP_WAIT_TIME_MSEC =
+ ProvisioningManager.KEY_SIP_INVITE_ACK_WAIT_TIME_MS;
+
/**
* SIP Timer D's value in milliseconds. Timer D is the wait time for
* response retransmits of the invite client transactions.
* Value is in Integer format.
+ * @deprecated use
+ * {@link ProvisioningManager#KEY_SIP_INVITE_RESPONSE_RETRANSMIT_WAIT_TIME_MS}.
*/
- public static final int SIP_INVITE_RSP_RETX_WAIT_TIME_MSEC = 39;
+ @Deprecated
+ public static final int SIP_INVITE_RSP_RETX_WAIT_TIME_MSEC =
+ ProvisioningManager.KEY_SIP_INVITE_RESPONSE_RETRANSMIT_WAIT_TIME_MS;
+
/**
* SIP Timer E's value in milliseconds. Timer E is the value Non-INVITE
* request retransmit interval, for UDP only.
* Value is in Integer format.
+ * @deprecated use
+ * {@link ProvisioningManager#KEY_SIP_NON_INVITE_REQUEST_RETRANSMIT_INTERVAL_MS}.
*/
- public static final int SIP_NON_INVITE_REQ_RETX_INTERVAL_MSEC = 40;
+ @Deprecated
+ public static final int SIP_NON_INVITE_REQ_RETX_INTERVAL_MSEC =
+ ProvisioningManager.KEY_SIP_NON_INVITE_REQUEST_RETRANSMIT_INTERVAL_MS;
+
/**
* SIP Timer F's value in milliseconds. Timer F is the Non-INVITE transaction
* timeout timer.
* Value is in Integer format.
+ * @deprecated use
+ * {@link ProvisioningManager#KEY_SIP_NON_INVITE_TRANSACTION_TIMEOUT_TIMER_MS}.
*/
- public static final int SIP_NON_INVITE_TXN_TIMEOUT_TIMER_MSEC = 41;
+ @Deprecated
+ public static final int SIP_NON_INVITE_TXN_TIMEOUT_TIMER_MSEC =
+ ProvisioningManager.KEY_SIP_NON_INVITE_TRANSACTION_TIMEOUT_TIMER_MS;
+
/**
* SIP Timer G's value in milliseconds. Timer G is the value of INVITE response
* retransmit interval.
* Value is in Integer format.
+ * @deprecated use
+ * {@link ProvisioningManager#KEY_SIP_INVITE_RESPONSE_RETRANSMIT_INTERVAL_MS}.
*/
- public static final int SIP_INVITE_RSP_RETX_INTERVAL_MSEC = 42;
+ @Deprecated
+ public static final int SIP_INVITE_RSP_RETX_INTERVAL_MSEC =
+ ProvisioningManager.KEY_SIP_INVITE_RESPONSE_RETRANSMIT_INTERVAL_MS;
+
/**
* SIP Timer H's value in milliseconds. Timer H is the value of wait time for
* ACK receipt.
* Value is in Integer format.
+ * @deprecated use {@link ProvisioningManager#KEY_SIP_ACK_RECEIPT_WAIT_TIME_MS}.
*/
- public static final int SIP_ACK_RECEIPT_WAIT_TIME_MSEC = 43;
+ @Deprecated
+ public static final int SIP_ACK_RECEIPT_WAIT_TIME_MSEC =
+ ProvisioningManager.KEY_SIP_ACK_RECEIPT_WAIT_TIME_MS;
+
/**
* SIP Timer I's value in milliseconds. Timer I is the value of wait time for
* ACK retransmits.
* Value is in Integer format.
+ * @deprecated use {@link ProvisioningManager#KEY_SIP_ACK_RETRANSMIT_WAIT_TIME_MS}.
*/
- public static final int SIP_ACK_RETX_WAIT_TIME_MSEC = 44;
+ @Deprecated
+ public static final int SIP_ACK_RETX_WAIT_TIME_MSEC =
+ ProvisioningManager.KEY_SIP_ACK_RETRANSMIT_WAIT_TIME_MS;
+
/**
* SIP Timer J's value in milliseconds. Timer J is the value of wait time for
* non-invite request retransmission.
* Value is in Integer format.
+ * @deprecated use
+ * {@link ProvisioningManager#KEY_SIP_NON_INVITE_REQUEST_RETRANSMISSION_WAIT_TIME_MS}.
*/
- public static final int SIP_NON_INVITE_REQ_RETX_WAIT_TIME_MSEC = 45;
+ @Deprecated
+ public static final int SIP_NON_INVITE_REQ_RETX_WAIT_TIME_MSEC =
+ ProvisioningManager.KEY_SIP_NON_INVITE_REQUEST_RETRANSMISSION_WAIT_TIME_MS;
+
/**
* SIP Timer K's value in milliseconds. Timer K is the value of wait time for
* non-invite response retransmits.
* Value is in Integer format.
+ * @deprecated use
+ * {@link ProvisioningManager#KEY_SIP_NON_INVITE_RESPONSE_RETRANSMISSION_WAIT_TIME_MS}.
*/
- public static final int SIP_NON_INVITE_RSP_RETX_WAIT_TIME_MSEC = 46;
+ @Deprecated
+ public static final int SIP_NON_INVITE_RSP_RETX_WAIT_TIME_MSEC =
+ ProvisioningManager.KEY_SIP_NON_INVITE_RESPONSE_RETRANSMISSION_WAIT_TIME_MS;
+
/**
* AMR WB octet aligned dynamic payload type.
* Value is in Integer format.
+ * @deprecated use {@link ProvisioningManager#KEY_AMR_WB_OCTET_ALIGNED_PAYLOAD_TYPE}.
*/
- public static final int AMR_WB_OCTET_ALIGNED_PT = 47;
+ @Deprecated
+ public static final int AMR_WB_OCTET_ALIGNED_PT =
+ ProvisioningManager.KEY_AMR_WB_OCTET_ALIGNED_PAYLOAD_TYPE;
+
/**
* AMR WB bandwidth efficient payload type.
* Value is in Integer format.
+ * @deprecated use {@link ProvisioningManager#KEY_AMR_WB_BANDWIDTH_EFFICIENT_PAYLOAD_TYPE}.
*/
- public static final int AMR_WB_BANDWIDTH_EFFICIENT_PT = 48;
+ @Deprecated
+ public static final int AMR_WB_BANDWIDTH_EFFICIENT_PT =
+ ProvisioningManager.KEY_AMR_WB_BANDWIDTH_EFFICIENT_PAYLOAD_TYPE;
+
/**
* AMR octet aligned dynamic payload type.
* Value is in Integer format.
+ * @deprecated use {@link ProvisioningManager#KEY_AMR_OCTET_ALIGNED_PAYLOAD_TYPE}.
*/
- public static final int AMR_OCTET_ALIGNED_PT = 49;
+ @Deprecated
+ public static final int AMR_OCTET_ALIGNED_PT =
+ ProvisioningManager.KEY_AMR_OCTET_ALIGNED_PAYLOAD_TYPE;
+
/**
* AMR bandwidth efficient payload type.
* Value is in Integer format.
+ * @deprecated use {@link ProvisioningManager#KEY_AMR_BANDWIDTH_EFFICIENT_PAYLOAD_TYPE}.
*/
- public static final int AMR_BANDWIDTH_EFFICIENT_PT = 50;
+ @Deprecated
+ public static final int AMR_BANDWIDTH_EFFICIENT_PT =
+ ProvisioningManager.KEY_AMR_BANDWIDTH_EFFICIENT_PAYLOAD_TYPE;
+
/**
* DTMF WB payload type.
* Value is in Integer format.
+ * @deprecated use {@link ProvisioningManager#KEY_DTMF_WB_PAYLOAD_TYPE}.
*/
- public static final int DTMF_WB_PT = 51;
+ @Deprecated
+ public static final int DTMF_WB_PT = ProvisioningManager.KEY_DTMF_WB_PAYLOAD_TYPE;
+
/**
* DTMF NB payload type.
* Value is in Integer format.
+ * @deprecated use {@link ProvisioningManager#KEY_DTMF_NB_PAYLOAD_TYPE}.
*/
- public static final int DTMF_NB_PT = 52;
+ @Deprecated
+ public static final int DTMF_NB_PT = ProvisioningManager.KEY_DTMF_NB_PAYLOAD_TYPE;
+
/**
* AMR Default encoding mode.
* Value is in Integer format.
+ * @deprecated use {@link ProvisioningManager#KEY_AMR_DEFAULT_ENCODING_MODE}.
*/
- public static final int AMR_DEFAULT_MODE = 53;
+ @Deprecated
+ public static final int AMR_DEFAULT_MODE =
+ ProvisioningManager.KEY_AMR_DEFAULT_ENCODING_MODE;
+
/**
* SMS Public Service Identity.
* Value is in String format.
+ * @deprecated use {@link ProvisioningManager#KEY_SMS_PUBLIC_SERVICE_IDENTITY}.
*/
- public static final int SMS_PSI = 54;
+ @Deprecated
+ public static final int SMS_PSI = ProvisioningManager.KEY_SMS_PUBLIC_SERVICE_IDENTITY;
+
/**
* Video Quality - VideoQualityFeatureValuesConstants.
* Value is in Integer format.
+ * @deprecated use {@link ProvisioningManager#KEY_VIDEO_QUALITY}.
*/
- public static final int VIDEO_QUALITY = 55;
+ @Deprecated
+ public static final int VIDEO_QUALITY = ProvisioningManager.KEY_VIDEO_QUALITY;
+
/**
* LTE threshold.
* Handover from LTE to WiFi if LTE < THLTE1 and WiFi >= VOWT_A.
+ * @deprecated use {@link ProvisioningManager#KEY_LTE_THRESHOLD_1}.
*/
- public static final int TH_LTE1 = 56;
+ @Deprecated
+ public static final int TH_LTE1 = ProvisioningManager.KEY_LTE_THRESHOLD_1;
+
/**
* LTE threshold.
* Handover from WiFi to LTE if LTE >= THLTE3 or (WiFi < VOWT_B and LTE >= THLTE2).
+ * @deprecated use {@link ProvisioningManager#KEY_LTE_THRESHOLD_2}.
*/
- public static final int TH_LTE2 = 57;
+ @Deprecated
+ public static final int TH_LTE2 = ProvisioningManager.KEY_LTE_THRESHOLD_2;
+
/**
* LTE threshold.
* Handover from WiFi to LTE if LTE >= THLTE3 or (WiFi < VOWT_B and LTE >= THLTE2).
+ * @deprecated use {@link ProvisioningManager#KEY_LTE_THRESHOLD_3}.
*/
- public static final int TH_LTE3 = 58;
+ @Deprecated
+ public static final int TH_LTE3 = ProvisioningManager.KEY_LTE_THRESHOLD_3;
+
/**
* 1x threshold.
* Handover from 1x to WiFi if 1x < TH1x
+ * @deprecated use {@link ProvisioningManager#KEY_1X_THRESHOLD}.
*/
- public static final int TH_1x = 59;
+ @Deprecated
+ public static final int TH_1x = ProvisioningManager.KEY_1X_THRESHOLD;
+
/**
* WiFi threshold.
* Handover from LTE to WiFi if LTE < THLTE1 and WiFi >= VOWT_A.
+ * @deprecated use {@link ProvisioningManager#KEY_WIFI_THRESHOLD_A}.
*/
- public static final int VOWT_A = 60;
+ @Deprecated
+ public static final int VOWT_A = ProvisioningManager.KEY_WIFI_THRESHOLD_A;
+
/**
* WiFi threshold.
* Handover from WiFi to LTE if LTE >= THLTE3 or (WiFi < VOWT_B and LTE >= THLTE2).
+ * @deprecated use {@link ProvisioningManager#KEY_WIFI_THRESHOLD_B}.
*/
- public static final int VOWT_B = 61;
+ @Deprecated
+ public static final int VOWT_B = ProvisioningManager.KEY_WIFI_THRESHOLD_B;
+
/**
* LTE ePDG timer.
* Device shall not handover back to LTE until the T_ePDG_LTE timer expires.
+ * @deprecated use {@link ProvisioningManager#KEY_LTE_EPDG_TIMER_SEC}.
*/
- public static final int T_EPDG_LTE = 62;
+ @Deprecated
+ public static final int T_EPDG_LTE = ProvisioningManager.KEY_LTE_EPDG_TIMER_SEC;
+
/**
* WiFi ePDG timer.
* Device shall not handover back to WiFi until the T_ePDG_WiFi timer expires.
+ * @deprecated use {@link ProvisioningManager#KEY_WIFI_EPDG_TIMER_SEC}.
*/
- public static final int T_EPDG_WIFI = 63;
+ @Deprecated
+ public static final int T_EPDG_WIFI = ProvisioningManager.KEY_WIFI_EPDG_TIMER_SEC;
+
/**
* 1x ePDG timer.
* Device shall not re-register on 1x until the T_ePDG_1x timer expires.
+ * @deprecated use {@link ProvisioningManager#KEY_1X_EPDG_TIMER_SEC}.
*/
- public static final int T_EPDG_1X = 64;
+ @Deprecated
+ public static final int T_EPDG_1X = ProvisioningManager.KEY_1X_EPDG_TIMER_SEC;
+
/**
* MultiEndpoint status: Enabled (1), or Disabled (0).
* Value is in Integer format.
+ * @deprecated use {@link ProvisioningManager#KEY_MULTIENDPOINT_ENABLED}.
*/
- public static final int VICE_SETTING_ENABLED = 65;
+ @Deprecated
+ public static final int VICE_SETTING_ENABLED = ProvisioningManager.KEY_MULTIENDPOINT_ENABLED;
/**
* RTT status: Enabled (1), or Disabled (0).
* Value is in Integer format.
+ * @deprecated use {@link ProvisioningManager#KEY_RTT_ENABLED}.
*/
- public static final int RTT_SETTING_ENABLED = 66;
+ @Deprecated
+ public static final int RTT_SETTING_ENABLED = ProvisioningManager.KEY_RTT_ENABLED;
// Expand the operator config items as needed here, need to change
// PROVISIONED_CONFIG_END after that.
diff --git a/telephony/java/com/android/internal/telephony/IBooleanConsumer.aidl b/telephony/java/com/android/internal/telephony/IBooleanConsumer.aidl
new file mode 100644
index 000000000000..eb5bedabf15f
--- /dev/null
+++ b/telephony/java/com/android/internal/telephony/IBooleanConsumer.aidl
@@ -0,0 +1,23 @@
+/*
+ * Copyright (C) 2020 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.internal.telephony;
+
+// Copies consumer pattern for an operation that requires a boolean result from another process to
+// finish.
+oneway interface IBooleanConsumer {
+ void accept(boolean result);
+} \ No newline at end of file
diff --git a/telephony/java/com/android/internal/telephony/ITelephony.aidl b/telephony/java/com/android/internal/telephony/ITelephony.aidl
index e88c7736f094..9b4553957bef 100644
--- a/telephony/java/com/android/internal/telephony/ITelephony.aidl
+++ b/telephony/java/com/android/internal/telephony/ITelephony.aidl
@@ -38,8 +38,10 @@ import android.telephony.ICellInfoCallback;
import android.telephony.ModemActivityInfo;
import android.telephony.NeighboringCellInfo;
import android.telephony.NetworkScanRequest;
+import android.telephony.PhoneCapability;
import android.telephony.PhoneNumberRange;
import android.telephony.RadioAccessFamily;
+import android.telephony.RadioAccessSpecifier;
import android.telephony.ServiceState;
import android.telephony.SignalStrength;
import android.telephony.TelephonyHistogram;
@@ -54,6 +56,7 @@ import android.telephony.ims.aidl.IImsRegistration;
import android.telephony.ims.aidl.IImsRegistrationCallback;
import com.android.ims.internal.IImsServiceFeatureCallback;
import com.android.internal.telephony.CellNetworkScanResult;
+import com.android.internal.telephony.IBooleanConsumer;
import com.android.internal.telephony.IIntegerConsumer;
import com.android.internal.telephony.INumberVerificationCallback;
import com.android.internal.telephony.OperatorInfo;
@@ -1825,12 +1828,17 @@ interface ITelephony {
/**
* Return the network selection mode on the subscription with id {@code subId}.
*/
- int getNetworkSelectionMode(int subId);
+ int getNetworkSelectionMode(int subId);
- /**
+ /**
+ * Return the PhoneCapability for the device.
+ */
+ PhoneCapability getPhoneCapability(int subId, String callingPackage, String callingFeatureId);
+
+ /**
* Return true if the device is in emergency sms mode, false otherwise.
*/
- boolean isInEmergencySmsMode();
+ boolean isInEmergencySmsMode();
/**
* Return the modem radio power state for slot index.
@@ -2126,6 +2134,9 @@ interface ITelephony {
boolean isApnMetered(int apnType, int subId);
+ oneway void setSystemSelectionChannels(in List<RadioAccessSpecifier> specifiers,
+ int subId, IBooleanConsumer resultCallback);
+
boolean isMvnoMatched(int subId, int mvnoType, String mvnoMatchData);
/**
diff --git a/telephony/java/com/android/internal/telephony/RILConstants.java b/telephony/java/com/android/internal/telephony/RILConstants.java
index 9ee26c28f906..0db86d6054b3 100644
--- a/telephony/java/com/android/internal/telephony/RILConstants.java
+++ b/telephony/java/com/android/internal/telephony/RILConstants.java
@@ -493,6 +493,7 @@ public interface RILConstants {
int RIL_REQUEST_SWITCH_DUAL_SIM_CONFIG = 207;
int RIL_REQUEST_ENABLE_UICC_APPLICATIONS = 208;
int RIL_REQUEST_GET_UICC_APPLICATIONS_ENABLEMENT = 209;
+ int RIL_REQUEST_SET_SYSTEM_SELECTION_CHANNELS = 210;
/* Responses begin */
int RIL_RESPONSE_ACKNOWLEDGEMENT = 800;
diff --git a/wifi/java/android/net/wifi/rtt/ResponderLocation.java b/wifi/java/android/net/wifi/rtt/ResponderLocation.java
index 970a75d7c418..218b2dcae71d 100644
--- a/wifi/java/android/net/wifi/rtt/ResponderLocation.java
+++ b/wifi/java/android/net/wifi/rtt/ResponderLocation.java
@@ -21,6 +21,7 @@ import static java.lang.annotation.RetentionPolicy.SOURCE;
import android.annotation.IntDef;
import android.annotation.NonNull;
import android.annotation.Nullable;
+import android.annotation.SuppressLint;
import android.annotation.SystemApi;
import android.location.Address;
import android.location.Location;
@@ -1367,7 +1368,8 @@ public final class ResponderLocation implements Parcelable {
*
*/
@Nullable
- public SparseArray toCivicLocationSparseArray() {
+ @SuppressLint("ChangedType")
+ public SparseArray<String> toCivicLocationSparseArray() {
if (mCivicLocation != null && mCivicLocation.isValid()) {
return mCivicLocation.toSparseArray();
} else {
diff --git a/wifi/tests/src/android/net/wifi/rtt/ResponderLocationTest.java b/wifi/tests/src/android/net/wifi/rtt/ResponderLocationTest.java
index b02eebbe9a01..271339cecf1e 100644
--- a/wifi/tests/src/android/net/wifi/rtt/ResponderLocationTest.java
+++ b/wifi/tests/src/android/net/wifi/rtt/ResponderLocationTest.java
@@ -20,6 +20,7 @@ import android.location.Address;
import android.location.Location;
import android.net.MacAddress;
import android.os.Parcel;
+import android.util.SparseArray;
import android.webkit.MimeTypeMap;
import static junit.framework.Assert.assertEquals;
@@ -505,6 +506,30 @@ public class ResponderLocationTest {
}
/**
+ * Test that a Civic Location sparseArray can be extracted from a valid lcr buffer.
+ */
+ @Test
+ public void testLcrTestCivicLocationSparseArray() {
+ byte[] testLciBuffer = concatenateArrays(sTestLciIeHeader, sTestLciSE);
+ byte[] testLcrBuffer =
+ concatenateArrays(sTestLcrBufferHeader, sTestCivicLocationSEWithAddress);
+ ResponderLocation responderLocation = new ResponderLocation(testLciBuffer, testLcrBuffer);
+
+ boolean valid = responderLocation.isValid();
+ SparseArray<String> civicLocationSparseArray = responderLocation
+ .toCivicLocationSparseArray();
+
+ assertTrue(valid);
+ assertEquals("15", civicLocationSparseArray.get(CivicLocationKeys.HNO));
+ assertEquals("Alto",
+ civicLocationSparseArray.get(CivicLocationKeys.PRIMARY_ROAD_NAME));
+ assertEquals("Road",
+ civicLocationSparseArray.get(CivicLocationKeys.STREET_NAME_POST_MODIFIER));
+ assertEquals("Mtn View", civicLocationSparseArray.get(CivicLocationKeys.CITY));
+ assertEquals("94043", civicLocationSparseArray.get(CivicLocationKeys.POSTAL_CODE));
+ }
+
+ /**
* Test that a URL can be extracted from a valid lcr buffer with a map image subelement.
*/
@Test